USB Data Protocol
Applies to: USB HVS cameras (APX003 / APX014 sensors). This page documents the low-level wire protocol of the camera's USB stream — device identification, binary framing of APS/EVS data, ep0 control requests, and timestamp domains — for driver-level development that reads the USB stream directly (libusb / pyusb, etc.), bypassing the SDK. For regular development, start with the Toolkit SDK and the Programming Guides; for recorded-file formats (RAW8 / EVT2 / CSV) see Data Formats Reference.
Device Identification
- VID:
0x1D6BPID:0x0105 - Interface 0, 3 bulk endpoints: EP1 IN = APS image, EP2 IN = EVS events, EP3 OUT = firmware upgrade
Sensor Identification
| APS first-frame length | Sensor |
|---|---|
| 700,424 B | APX003 |
| 983,048 B | APX014 |
APS Frame (EP1 IN)
┌─────────────────────────────┐
│ NV12 raw frame │ 003: 768×608 = 700,416 B
│ (Y plane + interleaved UV) │ 014: 640×1024 = 983,040 B
├─────────────────────────────┤
│ Trailing timestamp (8B │ Same source and domain as
│ little-endian u64) │ the EVS frame timestamp
└─────────────────────────────┘| APX003 | APX014 | |
|---|---|---|
| Total frame length | 700,424 B | 983,048 B |
| Trailing timestamp unit | microseconds | raw ticks (not microseconds) |
EVS Frame (EP2 IN)
APX003 (chunk = 524,288 B = 16 subframes × 32,768 B)
Each subframe covers one spatial quadrant (384×304 @2bit); four quadrants tile into the 768×608 event grid.
Subframe header (16 B):
+0x00 u64 bits[0:15]=0xFFFF magic, bits[24:63]=40-bit timestamp (5ns/tick, ÷200=µs)
+0x08 u64 bits[44:47]=quadrant number (0-3)
+0x10 ... event payload 29,184 BPixel encoding: each u64 holds 32 pixels (2bit/px, LSB-first); code>0 marks an event, polarity=code>>1. Coordinates: x = quadrant x offset + column×2, y = quadrant y offset + row×2.
APX014 (chunk = constant 164,864 B = 32 subframes × 5,152 B)
Each subframe covers 320×64 @2bit; 32 subframes tile into a 640×1024 packed grid, ×2 interpolated to 1280×1024 output.
Subframe header (24 B):
+0x00 u32 low 24 bits = 0x0000FFFF magic
+0x04 u32 timestamp (raw ticks)
+0x0C u32 frame number (low 24 bits; spread across a frame's 32 subframes ≤1)
+0x16 u16 SubFrame=bits[5:10], Vflip=bit11, Hflip=bit12
+0x18 ... event payload 5,120 B
tail 8B paddingPixel encoding is the same as 003 (2bit LSB-first). The subframe position is derived from the SubFrame number through the flip mapping table onto the 16-row × 2-column grid; rows interleave as y = m×16 + row, interpolation x_out = 2x + offset.
Validation: if any subframe magic is invalid or the frame-number spread >1 → discard the whole frame.
ep0 Control Requests (vendor request)
| bRequest | Name | Direction/payload | Description |
|---|---|---|---|
| 0x0A | CLEAR_SHM | OUT, 1B (0x01) | Clear shared memory, restore stream alignment |
| 0x14 | SET_EVS_FPS | OUT, 2B (u16 big-endian) | Switch frame rate (triggers a device reboot) |
| 0x15 | GET_EVS_FPS | IN, 2B (u16 big-endian) | Read frame rate |
| 0x07 | REBOOT | OUT | Reboot the device (older SDKs used it to clear shared memory; newer firmware changed it to REBOOT) |
FPS options: 003 = 120/240/500/750/1000; 014 = 240/300/480/600.
Frame Boundaries
- APS: the trailing 8-byte timestamp is not a multiple of 512 → forms a short packet, so bulk returns exactly at the frame end
- EVS: chunks are always multiples of 1024, no short packets → must read by exact chunk length to stay aligned
Timestamp Units
| Location | APX003 | APX014 |
|---|---|---|
| Sensor raw domain | 40-bit, 5ns/tick | 32-bit tick (~24MHz) |
| EVS event t | µs (÷200) | µs (self-calibrated) |
| APS trailing 8B | µs | raw ticks |
