2025-01-18 04:17 AM - edited 2025-01-18 04:56 AM
I came across a nice tutorial (8-bit data) and successfully had the code work with the STM32F103C6/8. Win11 can see it as a joystick.
*** Original HID_MOUSE_ReportDesc ***
0xA1, 0x02, // Collection (Logical)
0x05, 0x01, // Usage Page (Generic Ctrls)
0x09, 0x30, // Usage X
0x09, 0x31, // Usage Y
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
0x75, 0x08, // Report Size (8) -> 8 bits (1 byte value)
0x95, 0x02, // Report Count (2) -> 2x = 2 bytes
Due to a higher resolution of the ADC (4095 max), 16-bit data would be preferable. I made a few changes to the Report Descriptor and the HID_MOUSE_REPORT_DESC_SIZE, 2 more bytes longer.
*** Modified HID_MOUSE_ReportDesc ***
0x09, 0x30, // Usage X
0x09, 0x31, // Usage Y
0x15, 0x00 // Logical Minimum (0)
0x26, 0xFF, 0x0F, // Logical Maximum (4095)
0x75, 0x10, // Report Size (16)
0x95, 0x02, // Report Count (2)
The new code works fine except wrong X&Y values sent to the PC.
The HID message structure is as follows:
struct gameHID_t {
// int8_t JoyX; // X 1 byte, signed value
// int8_t JoyY; // Y 1 byte, signed value
uint8_t JoyX[2]; // X 2 byte, unsigned value
uint8_t JoyY[2]; // Y 2 byte, unsigned value
uint8_t JoyB1; // Button
};
uint16_t readValueX&Y (ADC) have the default values around 2000 in decimal at the joystick's center position. The HID message is constructed as follows:
gameHID.JoyX[1] = (uint8_t) (readValueX & 0x00FF); // lowByte
gameHID.JoyX[0] = (uint8_t) (readValueX >> 8); // highByte
gameHID.JoyY[1] = (uint8_t) (readValueY & 0x00FF);
gameHID.JoyY[0] = (uint8_t) (readValueY >> 8);
I tried swapping the order of high&low bytes, of JoyX[0] & JoyX[1], and used simulated data. But it was still incorrect.
I wonder whether there is a tutorial how to send 16-bit data over HID USB. Any advice would be greatly appreciated.
Thank you.
BTW, the size of the firmware (HID USB & ADC functions) is around 31.7K, and it can fit into the STM32F103C6T6.