diff options
| author | sakumisu <[email protected]> | 2026-07-15 17:52:13 +0800 |
|---|---|---|
| committer | sakumisu <[email protected]> | 2026-07-15 17:52:13 +0800 |
| commit | bcf74e9cdef573d4026cb5987076a263d8a8fc51 (patch) | |
| tree | 95c9b508ea897eb1184a66f8703482497ade17da | |
| parent | bce3346209445d8e8f9d60860c3e7ff6936d12b3 (diff) | |
update(gamepad): update xinput report and desc
Signed-off-by: sakumisu <[email protected]>
| -rw-r--r-- | class/gamepad/usb_gamepad.h | 6 | ||||
| -rw-r--r-- | class/gamepad/usbd_gamepad.c | 25 | ||||
| -rw-r--r-- | demo/gamepad_template.c | 2 |
3 files changed, 29 insertions, 4 deletions
diff --git a/class/gamepad/usb_gamepad.h b/class/gamepad/usb_gamepad.h index 28e2e646..8b93713a 100644 --- a/class/gamepad/usb_gamepad.h +++ b/class/gamepad/usb_gamepad.h @@ -143,12 +143,12 @@ struct xinput_out_report { } __PACKED; // clang-format off -#define XINPUT_DESCRIPTOR_LEN (9 + 16 + 7 + 7) +#define XINPUT_DESCRIPTOR_LEN (9 + 17 + 7 + 7) #define XINPUT_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \ USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, 0x02, 0xff, 0x5d, 0x01, 0x00), /* XInput proprietary descriptor (0x21) */ \ - 16, 0x21, 0x00, 0x01, 0x01, 0x24, in_ep, 0x14, 0x03, 0x00, 0x03, 0x13, out_ep, 0x00, 0x03, 0x00, \ - USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \ + 0x11, 0x21, 0x00, 0x01, 0x01, 0x25, in_ep, 0x14, 0x00, 0x00, 0x00, 0x00, 0x13, out_ep, 0x08, 0x00, 0x00, \ + USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \ USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x03, 32, 0x08) // clang-format on diff --git a/class/gamepad/usbd_gamepad.c b/class/gamepad/usbd_gamepad.c index 37eb040c..f59c07db 100644 --- a/class/gamepad/usbd_gamepad.c +++ b/class/gamepad/usbd_gamepad.c @@ -21,6 +21,24 @@ static int xinput_vendor_class_request_handler(uint8_t busid, struct usb_setup_p return 0; } +// Convert analog value from Joypad (0-255, center 128) to signed 16-bit +static int16_t convert_axis_to_s16(uint8_t value) +{ + int32_t scaled = ((int32_t)value - 128) * 256; + if (scaled < -32768) scaled = -32768; + if (scaled > 32767) scaled = 32767; + return (int16_t)scaled; +} + +// Convert and invert axis (for Y-axis where convention differs) +static int16_t convert_axis_to_s16_inverted(uint8_t value) +{ + int32_t scaled = -((int32_t)value - 128) * 256; + if (scaled < -32768) scaled = -32768; + if (scaled > 32767) scaled = 32767; + return (int16_t)scaled; +} + int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report) { struct xinput_in_report *xinput_report; @@ -68,6 +86,13 @@ int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *repor if (xinput_report->rt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_R2)) xinput_report->rt = 0xFF; + // Analog sticks (signed 16-bit, -32768 to +32767) + // Y-axis inverted: input 0=down, XInput convention positive=up + xinput_report->lx = convert_axis_to_s16(report->lx); + xinput_report->ly = convert_axis_to_s16_inverted(report->ly); + xinput_report->rx = convert_axis_to_s16(report->rx); + xinput_report->ry = convert_axis_to_s16_inverted(report->ry); + return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct xinput_in_report)); } diff --git a/demo/gamepad_template.c b/demo/gamepad_template.c index 171ab517..f9470678 100644 --- a/demo/gamepad_template.c +++ b/demo/gamepad_template.c @@ -89,7 +89,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed) static const char *string_descriptor_callback(uint8_t speed, uint8_t index) { - if (index >= (sizeof(string_descriptors) / sizeof(char *))) { + if (index >= 4) { return NULL; } |
