55 */
66
77#include <stdint.h>
8+ #include "unity.h"
89#include "tinyusb.h"
910#include "tinyusb_default_config.h"
1011#include "class/hid/hid_device.h"
1112#include "hid_mock_device.h"
1213
13- static tusb_iface_count_t tusb_iface_count = 0 ;
14+ static enum test_hid_mock_device _test_hid_mock_device_mode = TEST_HID_MOCK_DEVICE_MAX ;
1415
1516/************* TinyUSB descriptors ****************/
1617#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN)
@@ -34,6 +35,31 @@ const uint8_t hid_mouse_report_descriptor[] = {
3435 TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (HID_ITF_PROTOCOL_MOUSE ) )
3536};
3637
38+ /**
39+ * Valid HID report descriptor of 1905 bytes.
40+ *
41+ * This large descriptor is intentionally sized to exceed the default 512-byte buffer
42+ * used for HID report descriptors. The size is larger than the default buffer limit,
43+ * forcing the HID Host driver to realloc the memory for CTRL transfer.
44+ */
45+ const uint8_t hid_report_descriptor_1905B [] = {
46+ TUD_HID_REPORT_DESC_KEYBOARD (HID_REPORT_ID (HID_ITF_PROTOCOL_KEYBOARD ) ),
47+ TUD_HID_REPORT_DESC_MOUSE (HID_REPORT_ID (HID_ITF_PROTOCOL_MOUSE ) ),
48+ TUD_HID_REPORT_DESC_LIGHTING (3 ),
49+ TUD_HID_REPORT_DESC_CONSUMER (HID_REPORT_ID (4 )),
50+ TUD_HID_REPORT_DESC_GAMEPAD (HID_REPORT_ID (5 )),
51+ TUD_HID_REPORT_DESC_SYSTEM_CONTROL (HID_REPORT_ID (6 )),
52+ TUD_HID_REPORT_DESC_LIGHTING (7 ),
53+ TUD_HID_REPORT_DESC_LIGHTING (8 ),
54+ TUD_HID_REPORT_DESC_LIGHTING (9 ),
55+ TUD_HID_REPORT_DESC_LIGHTING (10 ),
56+ };
57+
58+ /**
59+ * Empty HID report descriptor of 32 KB.
60+ */
61+ const uint8_t hid_report_descriptor_32KB [32 * 1024 ] = {0 };
62+
3763/**
3864 * @brief String descriptor
3965 */
@@ -69,9 +95,30 @@ static const uint8_t hid_configuration_descriptor_two_ifaces[] = {
6995 TUD_HID_DESCRIPTOR (2 , 4 , HID_ITF_PROTOCOL_MOUSE , sizeof (hid_mouse_report_descriptor ), 0x82 , 16 , 10 ),
7096};
7197
72- static const uint8_t * hid_configuration_descriptor_list [TUSB_IFACE_COUNT_MAX ] = {
98+ static const uint8_t hid_configuration_descriptor_report_1905B [] = {
99+ // Configuration number, interface count, string index, total length, attribute, power in mA
100+ TUD_CONFIG_DESCRIPTOR (1 , CFG_TUD_HID , 0 , TUSB_DESC_TOTAL_LEN , TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP , 100 ),
101+
102+ // Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval
103+ TUD_HID_DESCRIPTOR (0 , 4 , false, sizeof (hid_report_descriptor_1905B ), 0x81 , 16 , 10 ),
104+ TUD_HID_DESCRIPTOR (1 , 4 , false, sizeof (hid_report_descriptor_1905B ), 0x82 , 16 , 10 ),
105+ };
106+
107+ static const uint8_t hid_configuration_descriptor_report_32K [] = {
108+ // Configuration number, interface count, string index, total length, attribute, power in mA
109+ TUD_CONFIG_DESCRIPTOR (1 , CFG_TUD_HID , 0 , TUSB_DESC_TOTAL_LEN , TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP , 100 ),
110+
111+ // Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval
112+ TUD_HID_DESCRIPTOR (0 , 4 , false, 32 * 1024 , 0x81 , 16 , 10 ),
113+ TUD_HID_DESCRIPTOR (1 , 4 , false, 32 * 1024 , 0x82 , 16 , 10 ),
114+ };
115+
116+
117+ static const uint8_t * hid_configuration_descriptor_list [TEST_HID_MOCK_DEVICE_MAX ] = {
73118 hid_configuration_descriptor_one_iface ,
74- hid_configuration_descriptor_two_ifaces
119+ hid_configuration_descriptor_two_ifaces ,
120+ hid_configuration_descriptor_report_1905B ,
121+ hid_configuration_descriptor_report_32K
75122};
76123
77124/**
@@ -99,15 +146,17 @@ static const tusb_desc_device_qualifier_t device_qualifier = {
99146// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
100147uint8_t const * tud_hid_descriptor_report_cb (uint8_t instance )
101148{
102- switch (tusb_iface_count ) {
103- case TUSB_IFACE_COUNT_ONE :
149+ switch (_test_hid_mock_device_mode ) {
150+ case TEST_HID_MOCK_DEVICE_WITH_ONE_IFACE :
104151 return hid_report_descriptor ;
105-
106- case TUSB_IFACE_COUNT_TWO :
152+ case TEST_HID_MOCK_DEVICE_WITH_TWO_IFACES :
107153 return (!!instance ) ? hid_mouse_report_descriptor : hid_keyboard_report_descriptor ;
108-
154+ case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_1905B :
155+ return hid_report_descriptor_1905B ;
156+ case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_32KB :
157+ return hid_report_descriptor_32KB ;
109158 default :
110- break ;
159+ TEST_FAIL_MESSAGE ( "HID mock device, unhandled test mode" ) ;
111160 }
112161 return NULL ;
113162}
@@ -178,36 +227,69 @@ void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_
178227
179228}
180229
230+ // HID Mock Device
231+
181232/**
182- * @brief HID Mock device start
233+ * @brief Callback for device events.
183234 *
184- * @param[in] iface_count Interface count, when TUSB_IFACE_COUNT_ONE then there is two Interfaces, but equal (Protocol=None).
185- * when TUSB_IFACE_COUNT_TWO then HID device mocked with two independent Interfaces (Protocol=BootKeyboard, Protocol=BootMouse).
235+ * @note
236+ * For Linux-based Hosts: Reflects the SetConfiguration() request from the Host Driver.
237+ * For Win-based Hosts: SetConfiguration() request is present only with available Class in device descriptor.
186238 */
187- void hid_mock_device ( tusb_iface_count_t iface_count )
239+ static void hid_mock_device_event_handler ( tinyusb_event_t * event , void * arg )
188240{
189- if (iface_count > TUSB_IFACE_COUNT_MAX ) {
190- printf ("HID mock device, wrong iface_count parameter (%d)\n" ,
191- iface_count );
192- return ;
241+ switch (event -> id ) {
242+ case TINYUSB_EVENT_ATTACHED :
243+ printf ("\t --> Attached\n" );
244+ break ;
245+ case TINYUSB_EVENT_DETACHED :
246+ printf ("\t <-- Detached\n" );
247+ break ;
248+ default :
249+ break ;
193250 }
251+ }
252+
253+ void hid_mock_device_set_mode (const enum test_hid_mock_device mode )
254+ {
255+ // Validate test mode parameter, should be less than max value
256+ TEST_ASSERT_LESS_THAN_MESSAGE (TEST_HID_MOCK_DEVICE_MAX , mode , "HID mock device set mode, wrong test mode" );
257+ _test_hid_mock_device_mode = mode ;
258+ }
259+
260+ void hid_mock_device_run (void )
261+ {
262+ tinyusb_config_t tusb_cfg = TINYUSB_DEFAULT_CONFIG (hid_mock_device_event_handler );
194263
195- // Global Interfaces count value
196- tusb_iface_count = iface_count ;
264+ TEST_ASSERT_LESS_THAN_MESSAGE (TEST_HID_MOCK_DEVICE_MAX , _test_hid_mock_device_mode , "HID mock device run, wrong test mode" );
197265
198- tinyusb_config_t tusb_cfg = TINYUSB_DEFAULT_CONFIG ();
199- tusb_cfg .descriptor .full_speed_config = hid_configuration_descriptor_list [tusb_iface_count ];
266+ tusb_cfg .descriptor .full_speed_config = hid_configuration_descriptor_list [_test_hid_mock_device_mode ];
200267#if (TUD_OPT_HIGH_SPEED )
201- tusb_cfg .descriptor .high_speed_config = hid_configuration_descriptor_list [tusb_iface_count ];
268+ tusb_cfg .descriptor .high_speed_config = hid_configuration_descriptor_list [_test_hid_mock_device_mode ];
202269 tusb_cfg .descriptor .qualifier = & device_qualifier ;
203270#endif // TUD_OPT_HIGH_SPEED
204271 tusb_cfg .descriptor .string = hid_string_descriptor ;
205272 tusb_cfg .descriptor .string_count = sizeof (hid_string_descriptor ) / sizeof (hid_string_descriptor [0 ]);
206273
207274 ESP_ERROR_CHECK (tinyusb_driver_install (& tusb_cfg ));
208275
209- printf ("HID mock device with %s has been started\n" ,
210- (TUSB_IFACE_COUNT_ONE == tusb_iface_count )
211- ? "1xInterface (Protocol=None)"
212- : "2xInterfaces (Protocol=BootKeyboard, Protocol=BootMouse)" );
276+ // Print the message about the mode
277+ // Note: these messages are used in the pytest, so change them carefully
278+ switch (_test_hid_mock_device_mode ) {
279+ case TEST_HID_MOCK_DEVICE_WITH_ONE_IFACE :
280+ printf ("HID mock device with 1xInterface (Protocol=None) has been started\n" );
281+ break ;
282+ case TEST_HID_MOCK_DEVICE_WITH_TWO_IFACES :
283+ printf ("HID mock device with 2xInterfaces (Protocol=BootKeyboard, Protocol=BootMouse) has been started\n" );
284+ break ;
285+ case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_1905B :
286+ printf ("HID mock device with large report descriptor has been started\n" );
287+ break ;
288+ case TEST_HID_MOCK_DEVICE_WITH_REPORT_DESC_32KB :
289+ printf ("HID mock device with extra large report descriptor has been started\n" );
290+ break ;
291+ default :
292+ TEST_FAIL_MESSAGE ("HID mock device, unhandled test mode" );
293+ break ;
294+ }
213295}
0 commit comments