@@ -91,7 +91,7 @@ const uint8_t *tud_descriptor_device_cb(void) {
9191 .iSerialNumber = USBD_STR_SERIAL,
9292 .bNumConfigurations = 1
9393 };
94- if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallMIDI) {
94+ if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick && ! __USBInstallMIDI) {
9595 // Can use as-is, this is the default USB case
9696 return (const uint8_t *)&usbd_desc_device;
9797 }
@@ -102,6 +102,9 @@ const uint8_t *tud_descriptor_device_cb(void) {
102102 if (__USBInstallMouse) {
103103 usbd_desc_device.idProduct |= 0x4000 ;
104104 }
105+ if (__USBInstallJoystick) {
106+ usbd_desc_device.idProduct |= 0x0100 ;
107+ }
105108 if (__USBInstallMIDI) {
106109 usbd_desc_device.idProduct |= 0x2000 ;
107110 }
@@ -120,6 +123,17 @@ int __USBGetMouseReportID() {
120123 return __USBInstallKeyboard ? 2 : 1 ;
121124}
122125
126+ int __USBGetJoystickReportID () {
127+ int i = 1 ;
128+ if (__USBInstallKeyboard) {
129+ i++;
130+ }
131+ if (__USBInstallMouse) {
132+ i++;
133+ }
134+ return i;
135+ }
136+
123137static int __hid_report_len = 0 ;
124138static uint8_t *__hid_report = nullptr ;
125139
@@ -131,37 +145,68 @@ static uint8_t *GetDescHIDReport(int *len) {
131145}
132146
133147void __SetupDescHIDReport () {
134- if (__USBInstallKeyboard && __USBInstallMouse) {
135- uint8_t desc_hid_report[] = {
136- TUD_HID_REPORT_DESC_KEYBOARD (HID_REPORT_ID (1 )),
137- TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (2 ))
138- };
139- __hid_report = (uint8_t *)malloc (sizeof (desc_hid_report));
140- if (__hid_report) {
141- __hid_report_len = sizeof (desc_hid_report);
142- memcpy (__hid_report, desc_hid_report, __hid_report_len);
148+ // allocate memory for the HID report descriptors. We don't use them, but need the size here.
149+ uint8_t desc_hid_report_mouse[] = { TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (1 )) };
150+ uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD (HID_REPORT_ID (1 )) };
151+ uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD (HID_REPORT_ID (1 )) };
152+ int size = 0 ;
153+
154+ // accumulate the size of all used HID report descriptors
155+ if (__USBInstallKeyboard) {
156+ size += sizeof (desc_hid_report_keyboard);
157+ }
158+ if (__USBInstallMouse) {
159+ size += sizeof (desc_hid_report_mouse);
160+ }
161+ if (__USBInstallJoystick) {
162+ size += sizeof (desc_hid_report_joystick);
163+ }
164+
165+ // no HID used at all
166+ if (size == 0 ) {
167+ __hid_report = nullptr ;
168+ __hid_report_len = 0 ;
169+ return ;
170+ }
171+
172+ // allocate the "real" HID report descriptor
173+ __hid_report = (uint8_t *)malloc (size);
174+ if (__hid_report) {
175+ __hid_report_len = size;
176+
177+ // now copy the descriptors
178+
179+ // 1.) keyboard descriptor, if requested
180+ if (__USBInstallKeyboard) {
181+ memcpy (__hid_report, desc_hid_report_keyboard, sizeof (desc_hid_report_keyboard));
143182 }
144- } else if (__USBInstallKeyboard && ! __USBInstallMouse) {
145- uint8_t desc_hid_report[] = {
146- TUD_HID_REPORT_DESC_KEYBOARD (HID_REPORT_ID (1 ))
147- };
148- __hid_report = (uint8_t *)malloc (sizeof (desc_hid_report));
149- if (__hid_report) {
150- __hid_report_len = sizeof (desc_hid_report);
151- memcpy (__hid_report, desc_hid_report, __hid_report_len);
183+
184+ // 2.) mouse descriptor, if necessary. Additional offset & new array is necessary if there is a keyboard.
185+ if (__USBInstallMouse) {
186+ // determine if we need an offset (USB keyboard is installed)
187+ if (__USBInstallKeyboard) {
188+ uint8_t desc_local[] = { TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (2 )) };
189+ memcpy (__hid_report + sizeof (desc_hid_report_keyboard), desc_local, sizeof (desc_local));
190+ } else {
191+ memcpy (__hid_report, desc_hid_report_mouse, sizeof (desc_hid_report_mouse));
192+ }
152193 }
153- } else if (! __USBInstallKeyboard && __USBInstallMouse) {
154- uint8_t desc_hid_report[] = {
155- TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (1 ))
156- };
157- __hid_report = (uint8_t *)malloc (sizeof (desc_hid_report));
158- if (__hid_report) {
159- __hid_report_len = sizeof (desc_hid_report);
160- memcpy (__hid_report, desc_hid_report, __hid_report_len);
194+
195+ // 3.) joystick descriptor. 2 additional checks are necessary for mouse and/or keyboard
196+ if (__USBInstallJoystick) {
197+ uint8_t reportid = 1 ;
198+ int offset = 0 ;
199+ if (__USBInstallKeyboard) {
200+ reportid++;
201+ offset += sizeof (desc_hid_report_keyboard);
202+ }
203+ if (__USBInstallMouse) {
204+ reportid++;
205+ offset += sizeof (desc_hid_report_mouse);
206+ }
207+ uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD (HID_REPORT_ID (reportid)) };
208+ memcpy (__hid_report + offset, desc_local, sizeof (desc_local));
161209 }
162- } else {
163- __hid_report = nullptr ;
164- __hid_report_len = 0 ;
165210 }
166211}
167212
@@ -181,7 +226,7 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
181226
182227void __SetupUSBDescriptor () {
183228 if (!usbd_desc_cfg) {
184- bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
229+ bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallJoystick ;
185230
186231 uint8_t interface_count = (__USBInstallSerial ? 2 : 0 ) + (hasHID ? 1 : 0 ) + (__USBInstallMIDI ? 2 : 0 );
187232
0 commit comments