When the SDVX Controller is connected over USB, the host operating system enumerates it as a standard HID Joystick device (Generic Desktop page, Usage 0x04). No driver installation is required on Windows, macOS, or Linux. The firmware sends a compact 5-byte report at the end of every 1 ms main-loop iteration, provided the USB device is in theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/MrJefter/sdvx-controller/llms.txt
Use this file to discover all available pages before exploring further.
USBD_STATE_CONFIGURED state.
Report structure
The joystick report is defined inmain.c as:
JOYSTICK_REPORT_SIZE = 5).
Byte-level breakdown
| Byte(s) | Bits | Field | Type | Range | Description |
|---|---|---|---|---|---|
| 0 | 0 | Button 1 — BT-A | bit | 0–1 | 1 = pressed |
| 0 | 1 | Button 2 — BT-B | bit | 0–1 | 1 = pressed |
| 0 | 2 | Button 3 — BT-C | bit | 0–1 | 1 = pressed |
| 0 | 3 | Button 4 — BT-D | bit | 0–1 | 1 = pressed |
| 0 | 4 | Button 5 — FX-L | bit | 0–1 | 1 = pressed |
| 0 | 5 | Button 6 — FX-R | bit | 0–1 | 1 = pressed |
| 0 | 6 | Button 7 — START | bit | 0–1 | 1 = pressed |
| 0 | 7 | Padding | const | 0 | Always 0 (required by HID spec) |
| 1–2 | — | Axis X — VOL-L | uint16_t | 0–65535 | Smoothed VOL-L (left encoder) value |
| 3–4 | — | Axis Y — VOL-R | uint16_t | 0–65535 | Smoothed VOL-R (right encoder) value |
axis_x and axis_y are transmitted little-endian (LSB first), which is the natural byte order for uint16_t on the Cortex-M4.
Button mapping
The firmware builds thebuttons byte by iterating over the buttons[] array and shifting each stable button state into its corresponding bit position:
button_stable_state[]. A 3 ms debounce lockout prevents spurious transitions.
Axis values and smoothing
The axis values are cumulative (not delta) and are derived from the 16-bit hardware timer counters (TIM3 for VOL-L, TIM4 for VOL-R):- The per-frame delta is computed as a signed 16-bit difference from the previous counter value, correctly handling wrap-around at the 0 / 65535 boundary.
- The delta is accumulated into a raw 32-bit integer (
current_axis_x_raw,current_axis_y_raw). - An Exponential Moving Average (EMA) with
α = 0.15is applied to smooth out jitter:
- The smoothed value is divided by 10.0, rounded, and cast to
uint16_tfor the report.
Because the axis value accumulates continuously, it will wrap around at the uint16_t boundaries (0 → 65535 and 65535 → 0) as the encoder spins. This is expected behaviour — rhythm game clients treat the axis as a relative spinner and compute their own delta from successive report values.
Raw HID report descriptor
The complete HID report descriptor, as it appears inusbd_custom_hid_if.c, is shown below. It declares 7 one-bit buttons (bits 0–6), one padding bit (bit 7), and two 16-bit absolute axes (X and Y) with a logical range of 0–65535.