37
37
38
38
// English
39
39
#define LANGUAGE_ID 0x0409
40
+ #define BUF_COUNT 4
41
+
42
+
43
+ tusb_desc_device_t desc_device ;
44
+
45
+ uint8_t buf_pool [BUF_COUNT ][64 ];
46
+ uint8_t buf_owner [BUF_COUNT ] = { 0 }; // device address that owns buffer
40
47
41
48
//--------------------------------------------------------------------+
42
49
// MACRO CONSTANT TYPEDEF PROTYPES
@@ -47,12 +54,8 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len);
47
54
void print_device_descriptor (tuh_xfer_t * xfer );
48
55
void parse_config_descriptor (uint8_t dev_addr , tusb_desc_configuration_t const * desc_cfg );
49
56
50
- tusb_desc_device_t desc_device ;
51
-
52
- #define BUF_COUNT 4
53
-
54
- uint8_t buf_pool [BUF_COUNT ][64 ];
55
- uint8_t buf_owner [BUF_COUNT ] = { 0 }; // device address that owns buffer
57
+ uint8_t * get_hid_buf (uint8_t daddr );
58
+ void free_hid_buf (uint8_t daddr );
56
59
57
60
/*------------- MAIN -------------*/
58
61
int main (void )
@@ -88,6 +91,7 @@ void tuh_mount_cb (uint8_t daddr)
88
91
void tuh_umount_cb (uint8_t daddr )
89
92
{
90
93
printf ("Device removed, address = %d\r\n" , daddr );
94
+ free_hid_buf (daddr );
91
95
}
92
96
93
97
//--------------------------------------------------------------------+
@@ -150,63 +154,90 @@ void print_device_descriptor(tuh_xfer_t* xfer)
150
154
}
151
155
}
152
156
153
-
154
157
//--------------------------------------------------------------------+
155
158
// Configuration Descriptor
156
159
//--------------------------------------------------------------------+
157
160
158
- // get an buffer from pool
159
- uint8_t * get_hid_buf (uint8_t daddr )
161
+ // count total length of an interface
162
+ uint16_t count_interface_total_len (tusb_desc_interface_t const * desc_itf , uint8_t itf_count , uint16_t max_len );
163
+
164
+ void open_hid_interface (uint8_t daddr , tusb_desc_interface_t const * desc_itf , uint16_t max_len );
165
+
166
+ // simple configuration parser to open and listen to HID Endpoint IN
167
+ void parse_config_descriptor (uint8_t dev_addr , tusb_desc_configuration_t const * desc_cfg )
160
168
{
161
- for (size_t i = 0 ; i < BUF_COUNT ; i ++ )
169
+ uint8_t const * desc_end = ((uint8_t const * ) desc_cfg ) + tu_le16toh (desc_cfg -> wTotalLength );
170
+ uint8_t const * p_desc = tu_desc_next (desc_cfg );
171
+
172
+ // parse each interfaces
173
+ while ( p_desc < desc_end )
162
174
{
163
- if (buf_owner [i ] == 0 )
175
+ uint8_t assoc_itf_count = 1 ;
176
+
177
+ // Class will always starts with Interface Association (if any) and then Interface descriptor
178
+ if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type (p_desc ) )
164
179
{
165
- buf_owner [i ] = daddr ;
166
- return buf_pool [i ];
180
+ tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const * ) p_desc ;
181
+ assoc_itf_count = desc_iad -> bInterfaceCount ;
182
+
183
+ p_desc = tu_desc_next (p_desc ); // next to Interface
167
184
}
168
- }
169
185
170
- // out of memory, increase BUF_COUNT
171
- return NULL ;
172
- }
186
+ // must be interface from now
187
+ if ( TUSB_DESC_INTERFACE != tu_desc_type ( p_desc ) ) return ;
188
+ tusb_desc_interface_t const * desc_itf = ( tusb_desc_interface_t const * ) p_desc ;
173
189
174
- // free all buffer owned by device
175
- void free_hid_buf (uint8_t daddr )
176
- {
177
- for (size_t i = 0 ; i < BUF_COUNT ; i ++ )
178
- {
179
- if (buf_owner [i ] == daddr ) buf_owner [i ] = 0 ;
190
+ uint16_t const drv_len = count_interface_total_len (desc_itf , assoc_itf_count , desc_end - p_desc );
191
+
192
+ // probably corrupted descriptor
193
+ if (drv_len < sizeof (tusb_desc_interface_t )) return ;
194
+
195
+ // only open and listen to HID endpoint IN
196
+ if (desc_itf -> bInterfaceClass == TUSB_CLASS_HID )
197
+ {
198
+ open_hid_interface (dev_addr , desc_itf , drv_len );
199
+ }
200
+
201
+ // next Interface or IAD descriptor
202
+ p_desc += drv_len ;
180
203
}
181
204
}
182
205
183
- void hid_report_received ( tuh_xfer_t * xfer )
206
+ uint16_t count_interface_total_len ( tusb_desc_interface_t const * desc_itf , uint8_t itf_count , uint16_t max_len )
184
207
{
185
- // Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram
186
- // For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback
187
- uint8_t * buf = (uint8_t * ) xfer -> user_data ;
208
+ uint8_t const * p_desc = (uint8_t const * ) desc_itf ;
209
+ uint16_t len = 0 ;
188
210
189
- if ( xfer -> result == XFER_RESULT_SUCCESS )
211
+ while ( itf_count -- )
190
212
{
191
- printf ("[dev %u: ep %02x] HID Report:" , xfer -> daddr , xfer -> ep_addr );
192
- for (uint32_t i = 0 ; i < xfer -> actual_len ; i ++ )
213
+ // Next on interface desc
214
+ len += tu_desc_len (desc_itf );
215
+ p_desc = tu_desc_next (p_desc );
216
+
217
+ while (len < max_len )
193
218
{
194
- if (i %16 == 0 ) printf ("\r\n " );
195
- printf ("%02X " , buf [i ]);
219
+ // return on IAD regardless of itf count
220
+ if ( tu_desc_type (p_desc ) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len ;
221
+
222
+ if ( (tu_desc_type (p_desc ) == TUSB_DESC_INTERFACE ) &&
223
+ ((tusb_desc_interface_t const * ) p_desc )-> bAlternateSetting == 0 )
224
+ {
225
+ break ;
226
+ }
227
+
228
+ len += tu_desc_len (p_desc );
229
+ p_desc = tu_desc_next (p_desc );
196
230
}
197
- printf ("\r\n" );
198
231
}
199
232
200
- // continue to submit transfer, with updated buffer
201
- // other field remain the same
202
- xfer -> buflen = 64 ;
203
- xfer -> buffer = buf ;
204
-
205
- tuh_edpt_xfer (xfer );
233
+ return len ;
206
234
}
207
235
208
- // count total length of an interface
209
- uint16_t count_interface_total_len (tusb_desc_interface_t const * desc_itf , uint8_t itf_count , uint16_t max_len );
236
+ //--------------------------------------------------------------------+
237
+ // HID Interface
238
+ //--------------------------------------------------------------------+
239
+
240
+ void hid_report_received (tuh_xfer_t * xfer );
210
241
211
242
void open_hid_interface (uint8_t daddr , tusb_desc_interface_t const * desc_itf , uint16_t max_len )
212
243
{
@@ -260,77 +291,60 @@ void open_hid_interface(uint8_t daddr, tusb_desc_interface_t const *desc_itf, ui
260
291
}
261
292
}
262
293
263
- // simple configuration parser to open and listen to HID Endpoint IN
264
- void parse_config_descriptor (uint8_t dev_addr , tusb_desc_configuration_t const * desc_cfg )
294
+ void hid_report_received (tuh_xfer_t * xfer )
265
295
{
266
- uint8_t const * desc_end = ((uint8_t const * ) desc_cfg ) + tu_le16toh (desc_cfg -> wTotalLength );
267
- uint8_t const * p_desc = tu_desc_next (desc_cfg );
296
+ // Note: not all field in xfer is available for use (i.e filled by tinyusb stack) in callback to save sram
297
+ // For instance, xfer->buffer is NULL. We have used user_data to store buffer when submitted callback
298
+ uint8_t * buf = (uint8_t * ) xfer -> user_data ;
268
299
269
- // parse each interfaces
270
- while ( p_desc < desc_end )
300
+ if (xfer -> result == XFER_RESULT_SUCCESS )
271
301
{
272
- uint8_t assoc_itf_count = 1 ;
273
-
274
- // Class will always starts with Interface Association (if any) and then Interface descriptor
275
- if ( TUSB_DESC_INTERFACE_ASSOCIATION == tu_desc_type (p_desc ) )
302
+ printf ("[dev %u: ep %02x] HID Report:" , xfer -> daddr , xfer -> ep_addr );
303
+ for (uint32_t i = 0 ; i < xfer -> actual_len ; i ++ )
276
304
{
277
- tusb_desc_interface_assoc_t const * desc_iad = (tusb_desc_interface_assoc_t const * ) p_desc ;
278
- assoc_itf_count = desc_iad -> bInterfaceCount ;
279
-
280
- p_desc = tu_desc_next (p_desc ); // next to Interface
305
+ if (i %16 == 0 ) printf ("\r\n " );
306
+ printf ("%02X " , buf [i ]);
281
307
}
308
+ printf ("\r\n" );
309
+ }
282
310
283
- // must be interface from now
284
- if ( TUSB_DESC_INTERFACE != tu_desc_type (p_desc ) ) return ;
285
- tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const * ) p_desc ;
311
+ // continue to submit transfer, with updated buffer
312
+ // other field remain the same
313
+ xfer -> buflen = 64 ;
314
+ xfer -> buffer = buf ;
286
315
287
- uint16_t const drv_len = count_interface_total_len (desc_itf , assoc_itf_count , desc_end - p_desc );
316
+ tuh_edpt_xfer (xfer );
317
+ }
288
318
289
- // probably corrupted descriptor
290
- if (drv_len < sizeof (tusb_desc_interface_t )) return ;
319
+ //--------------------------------------------------------------------+
320
+ // Buffer helper
321
+ //--------------------------------------------------------------------+
291
322
292
- // only open and listen to HID endpoint IN
293
- if (desc_itf -> bInterfaceClass == TUSB_CLASS_HID )
323
+ // get an buffer from pool
324
+ uint8_t * get_hid_buf (uint8_t daddr )
325
+ {
326
+ for (size_t i = 0 ; i < BUF_COUNT ; i ++ )
327
+ {
328
+ if (buf_owner [i ] == 0 )
294
329
{
295
- open_hid_interface (dev_addr , desc_itf , drv_len );
330
+ buf_owner [i ] = daddr ;
331
+ return buf_pool [i ];
296
332
}
297
-
298
- // next Interface or IAD descriptor
299
- p_desc += drv_len ;
300
333
}
334
+
335
+ // out of memory, increase BUF_COUNT
336
+ return NULL ;
301
337
}
302
338
303
- uint16_t count_interface_total_len (tusb_desc_interface_t const * desc_itf , uint8_t itf_count , uint16_t max_len )
339
+ // free all buffer owned by device
340
+ void free_hid_buf (uint8_t daddr )
304
341
{
305
- uint8_t const * p_desc = (uint8_t const * ) desc_itf ;
306
- uint16_t len = 0 ;
307
-
308
- while (itf_count -- )
342
+ for (size_t i = 0 ; i < BUF_COUNT ; i ++ )
309
343
{
310
- // Next on interface desc
311
- len += tu_desc_len (desc_itf );
312
- p_desc = tu_desc_next (p_desc );
313
-
314
- while (len < max_len )
315
- {
316
- // return on IAD regardless of itf count
317
- if ( tu_desc_type (p_desc ) == TUSB_DESC_INTERFACE_ASSOCIATION ) return len ;
318
-
319
- if ( (tu_desc_type (p_desc ) == TUSB_DESC_INTERFACE ) &&
320
- ((tusb_desc_interface_t const * ) p_desc )-> bAlternateSetting == 0 )
321
- {
322
- break ;
323
- }
324
-
325
- len += tu_desc_len (p_desc );
326
- p_desc = tu_desc_next (p_desc );
327
- }
344
+ if (buf_owner [i ] == daddr ) buf_owner [i ] = 0 ;
328
345
}
329
-
330
- return len ;
331
346
}
332
347
333
-
334
348
//--------------------------------------------------------------------+
335
349
// Blinking Task
336
350
//--------------------------------------------------------------------+
@@ -350,7 +364,7 @@ void led_blinking_task(void)
350
364
}
351
365
352
366
//--------------------------------------------------------------------+
353
- // Helper
367
+ // String Descriptor Helper
354
368
//--------------------------------------------------------------------+
355
369
356
370
static void _convert_utf16le_to_utf8 (const uint16_t * utf16 , size_t utf16_len , uint8_t * utf8 , size_t utf8_len ) {
0 commit comments