Prophesee GENX320 Linux Driver for NVIDIA Jetson Orin NX
Introduction
This page documents RidgeRun's Linux driver integration for the Prophesee GENX320 event sensor on NVIDIA Jetson Orin NX. It covers how to customize the transport layer, which controls are exposed through the V4L2 subdevice, and a few practical examples for day-to-day use. For platform bring-up, build, and installation steps, use the Jetson getting-started guide and use this page as the control and customization reference.
This reference covers RidgeRun's GENX320 driver patch for JetPack 6.2.1.
Driver customization
The transport configuration is defined in the DTBO source through the macros below:
#define GENX320_TRANSPORT_MODE "variable" #define GENX320_TRANSPORT_PACKET_SIZE 1024 #define GENX320_TRANSPORT_FRAME_SIZE 32 #define GENX320_TRANSPORT_WINDOW_US 1008
Edit the macros in the DTBO source that matches your setup:
| Use case | DTBO source file |
|---|---|
| Dual capture on the Jetson Orin NX | hardware/nvidia/t23x/nv-public/overlay/tegra234-camera-genx320-dual.dtsi
|
| Single camera on port 0 | hardware/nvidia/t23x/nv-public/overlay/tegra234-camera-genx320.dtsi
|
After updating the macros, rebuild and reinstall the DTBO.
For build instructions, see the software installation section in the Jetson getting-started guide:
The transport macros control the transmission mode and the buffer dimensions reported to userspace:
| Macro | Meaning | Effect on the driver |
|---|---|---|
GENX320_TRANSPORT_MODE
|
Selects the transport mode. | variable uses the configured packet size and frame-window timing, allowing the amount of event data per transport frame to vary. fixed-frame-size uses the configured packet size and packets-per-frame count; low event rates can increase frame time and cause capture timeouts.
|
GENX320_TRANSPORT_PACKET_SIZE
|
Packet payload size in bytes. | Defines the packet size used by the transport. The driver reports the frame width as this value, so userspace allocates buffers accordingly. |
GENX320_TRANSPORT_FRAME_SIZE
|
Number of packets per frame in fixed-frame-size mode. | Defines the frame height reported to userspace. The driver reports the frame size as GENX320_TRANSPORT_PACKET_SIZE x GENX320_TRANSPORT_FRAME_SIZE.
|
GENX320_TRANSPORT_WINDOW_US
|
Frame window in microseconds. | Sets the frame-window timing in variable mode. It does not set the fixed packets-per-frame count. Valid range: 16..65520 microseconds, in multiples of 16.
|
Here, a frame is a transport container for event data, not a conventional image. The driver supports two transport modes:
| Mode | Behavior | When to use | Notes |
|---|---|---|---|
variable
|
Uses the configured frame window while the amount of event data per frame can vary. | Default configuration shown above, when the receiver supports variable frame sizes. Better power and performance. | GENX320_TRANSPORT_WINDOW_US sets the frame-window timing.
|
fixed-frame-size
|
Uses a fixed packet size and packets-per-frame count. Filling the frame can take longer at low event rates. | When the receiver requires fixed frame dimensions. | GENX320_TRANSPORT_FRAME_SIZE sets the packets-per-frame count. Fixed size does not guarantee fixed cadence. Reported buffer dimensions are GENX320_TRANSPORT_PACKET_SIZE x GENX320_TRANSPORT_FRAME_SIZE.
|
Available controls and examples
Inspect available controls
List the available controls with:
v4l2-ctl -d /dev/v4l-subdev2 --list-ctrls
To inspect menu values such as evt_format, use:
v4l2-ctl -d /dev/v4l-subdev2 --list-ctrls-menus
Common control examples
Set the event format:
v4l2-ctl -d /dev/v4l-subdev2 --set-ctrl=evt_format=1
Enable ERC and set the target rate:
v4l2-ctl -d /dev/v4l-subdev2 --set-ctrl=erc_enable=1,erc_rate=10000000
Adjust a few common bias controls:
v4l2-ctl -d /dev/v4l-subdev2 --set-ctrl=bias_diff=51,bias_refr=10
Control reference
The controls exposed by the driver are summarized below:
| Control | Type | Description | Notes |
|---|---|---|---|
erc_rate
|
int64
|
Event rate control limit. | Range: 0..200000000, default 10000000.
|
erc_enable
|
bool
|
Enables or disables event rate control. | Default 0.
|
evt_format
|
menu
|
Event format selection. | 0: EVT2, 1: EVT21, 2: EVT3. Default 1 (EVT21).
|
width
|
int
|
Sensor width. | Read-only. Fixed at 320.
|
height
|
int
|
Sensor height. | Read-only. Fixed at 320.
|
bias_fo
|
int
|
Pixel low-pass cut-off frequency. | Range: 19..50, default 34.
|
bias_hpf
|
int
|
Pixel high-pass cut-off frequency. | Range: 0..127, default 40.
|
bias_diff_on
|
int
|
Positive comparator contrast threshold. | Range: 24..78, default 25.
|
bias_diff
|
int
|
Comparator reference voltage. | Range: 41..51, default 51.
|
bias_diff_off
|
int
|
Negative comparator contrast threshold. | Range: 19..127, default 28.
|
bias_refr
|
int
|
Refractory period. | Range: 0..127, default 10.
|
roi_reset
|
button
|
Clears the ROI configuration. | Write-only, execute on write. |
roi_set
|
payload | Sets the ROI configuration. | List of x,y,width,height ROI windows.
|
roi_roni
|
bool
|
Selects Region of Interest (ROI, 0) or Region of Non-Interest (RONI, 1). | Default 0.
|
pxl_reset
|
button
|
Clears the pixel configuration. | Restores the full 320x320 pixel map to enabled. |
pxl_set
|
payload | Sets the pixel configuration. | Full 320x320 pixel mask. Bit 1 enables a pixel.
|
Prophesee also documents bias_pr as the front-end photoreceptor
control, which affects the pixel dynamic range.
ROI configuration
The ROI-related controls are used as follows:
roi_resetclears the current ROI window list.roi_roniselects whether the configured windows are included or excluded:0= ROI: include the configured regions.1= RONI: exclude the configured regions.
roi_setprograms one or more windows asx,y,width,heighttuples.
The reset and mode controls can be set directly with v4l2-ctl:
v4l2-ctl -d /dev/v4l-subdevX --set-ctrl=roi_reset=1 v4l2-ctl -d /dev/v4l-subdevX --set-ctrl=roi_roni=0 v4l2-ctl -d /dev/v4l-subdevX --set-ctrl=roi_roni=1
There is no direct v4l2-ctl syntax for the compound
roi_set payload. The payload is a list of ROI windows, each one
expressed as x,y,width,height, for example 0,0,64,64
and 128,128,32,32.
The following C snippets illustrate control payloads. Include the required headers, open the appropriate V4L2 subdevice to obtain fd, and check the return value of each ioctl() call.
If you want to program it directly from your application, use the V4L2
extended-controls API and pass the payload with VIDIOC_S_EXT_CTRLS:
#define PSEE_ROI_CLASS 0x4000
#define PSEE_CID_ROI_CTRL (V4L2_CID_USER_BASE | PSEE_ROI_CLASS)
#define PSEE_CID_ROI_WINDOW_SET (PSEE_CID_ROI_CTRL + 4)
struct genx320_roi {
uint32_t x;
uint32_t y;
uint32_t width;
uint32_t height;
};
struct genx320_roi_set {
uint32_t n;
struct genx320_roi rois[18];
};
struct genx320_roi_set roi = {
.n = 2,
.rois = {
{ .x = 0, .y = 0, .width = 64, .height = 64 },
{ .x = 128, .y = 128, .width = 32, .height = 32 },
},
};
struct v4l2_ext_control ctrl = {
.id = PSEE_CID_ROI_WINDOW_SET,
.size = sizeof(roi),
.ptr = &roi,
};
struct v4l2_ext_controls ctrls = {
.which = V4L2_CTRL_ID2WHICH(PSEE_CID_ROI_WINDOW_SET),
.count = 1,
.controls = &ctrl,
};
ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
Pixel mask configuration
The pixel-mask controls behave as follows:
pxl_resetrestores the full 320x320 map to enabled pixels.pxl_setprograms the full pixel bitmap.
The reset control can be set directly with v4l2-ctl:
v4l2-ctl -d /dev/v4l-subdevX --set-ctrl=pxl_reset=1
For pxl_set, use VIDIOC_S_EXT_CTRLS with the pixel
grid payload:
#define GENX320_PIXEL_ARRAY_WIDTH 320U
#define GENX320_PIXEL_ARRAY_HEIGHT 320U
#define GENX320_PIXEL_ARRAY_WORDS (GENX320_PIXEL_ARRAY_WIDTH / 32U)
#define PSEE_ROI_CLASS 0x4000
#define PSEE_CID_ROI_CTRL (V4L2_CID_USER_BASE | PSEE_ROI_CLASS)
#define GENX320_CID_ROI_PIXEL_ARRAY (PSEE_CID_ROI_CTRL + 8)
struct genx320_pixel_row {
uint32_t vectors[GENX320_PIXEL_ARRAY_WORDS];
};
struct genx320_pixel_grid {
uint32_t width;
uint32_t height;
struct genx320_pixel_row rows[GENX320_PIXEL_ARRAY_HEIGHT];
};
struct genx320_pixel_grid grid = { 0 };
grid.width = GENX320_PIXEL_ARRAY_WIDTH;
grid.height = GENX320_PIXEL_ARRAY_HEIGHT;
/* Example: enable a 64x64 block at (10, 20). */
for (uint32_t y = 20; y < 84; y++) {
for (uint32_t x = 10; x < 74; x++)
grid.rows[y].vectors[x / 32U] |= 1U << (x % 32U);
}
struct v4l2_ext_control ctrl = {
.id = GENX320_CID_ROI_PIXEL_ARRAY,
.size = sizeof(grid),
.ptr = &grid,
};
struct v4l2_ext_controls ctrls = {
.which = V4L2_CTRL_ID2WHICH(GENX320_CID_ROI_PIXEL_ARRAY),
.count = 1,
.controls = &ctrl,
};
ioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);