@@ -70,8 +70,11 @@ enum {
7070static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED ;
7171
7272static bool is_print [CFG_TUH_DEVICE_MAX + 1 ] = { 0 };
73+ static tusb_desc_device_t descriptor_device [CFG_TUH_DEVICE_MAX + 1 ];
7374
7475static void print_utf16 (uint16_t * temp_buf , size_t buf_len );
76+ static void print_device_info (uint8_t daddr , const tusb_desc_device_t * desc_device );
77+
7578void led_blinking_task (void );
7679void cdc_task (void );
7780
@@ -135,92 +138,99 @@ void tud_resume_cb(void) {
135138 blink_interval_ms = tud_mounted () ? BLINK_MOUNTED : BLINK_NOT_MOUNTED ;
136139}
137140
138- #if 1
141+ void cdc_task (void ) {
142+ if (!tud_cdc_connected ()) {
143+ // delay a bit otherwise we can outpace host's terminal. Linux will set LineState (DTR) then Line Coding.
144+ // If we send data before Linux's terminal set Line Coding, it can be ignored --> missing data with hardware test loop
145+ board_delay (20 );
146+ return ;
147+ }
148+
149+ for (uint8_t daddr = 1 ; daddr <= CFG_TUH_DEVICE_MAX ; daddr ++ ) {
150+ if (tuh_mounted (daddr )) {
151+ if (is_print [daddr ]) {
152+ is_print [daddr ] = false;
153+ print_device_info (daddr , & descriptor_device [daddr ]);
154+ tud_cdc_write_flush ();
155+ }
156+ }
157+ }
158+ }
159+
160+ //--------------------------------------------------------------------+
161+ // Host Get device information
162+ //--------------------------------------------------------------------+
139163#define cdc_printf (...) \
140164 do { \
141165 char _tempbuf[256]; \
142- int count = sprintf(_tempbuf, __VA_ARGS__); \
143- tud_cdc_write(_tempbuf, (uint32_t) count); \
144- tud_cdc_write_flush(); \
145- tud_task(); \
166+ char* _bufptr = _tempbuf; \
167+ uint32_t count = (uint32_t) sprintf(_tempbuf, __VA_ARGS__); \
168+ while (count > 0) { \
169+ uint32_t wr_count = tud_cdc_write(_bufptr, count); \
170+ count -= wr_count; \
171+ _bufptr += wr_count; \
172+ if (count > 0){ \
173+ tud_task();\
174+ tud_cdc_write_flush(); \
175+ } \
176+ } \
146177 } while(0)
147- #endif
148-
149- //#define cdc_printf printf
150-
151- void print_device_info (uint8_t daddr ) {
152- tusb_desc_device_t desc_device ;
153- uint8_t xfer_result = tuh_descriptor_get_device_sync (daddr , & desc_device , 18 );
154- if (XFER_RESULT_SUCCESS != xfer_result ) {
155- tud_cdc_write_str ("Failed to get device descriptor\r\n" );
156- return ;
157- }
158178
179+ static void print_device_info (uint8_t daddr , const tusb_desc_device_t * desc_device ) {
159180 // Get String descriptor using Sync API
160181 uint16_t serial [64 ];
161182 uint16_t buf [128 ];
183+ (void ) buf ;
162184
163- cdc_printf ("Device %u: ID %04x:%04x SN " , daddr , desc_device . idVendor , desc_device . idProduct );
164- xfer_result = tuh_descriptor_get_serial_string_sync (daddr , LANGUAGE_ID , serial , sizeof (serial ));
185+ cdc_printf ("Device %u: ID %04x:%04x SN " , daddr , desc_device -> idVendor , desc_device -> idProduct );
186+ uint8_t xfer_result = tuh_descriptor_get_serial_string_sync (daddr , LANGUAGE_ID , serial , sizeof (serial ));
165187 if (XFER_RESULT_SUCCESS != xfer_result ) {
166188 serial [0 ] = 'n' ;
167189 serial [1 ] = '/' ;
168190 serial [2 ] = 'a' ;
169191 serial [3 ] = 0 ;
170192 }
171193 print_utf16 (serial , TU_ARRAY_SIZE (serial ));
172- tud_cdc_write_str ("\r\n" );
194+ cdc_printf ("\r\n" );
173195
174196 cdc_printf ("Device Descriptor:\r\n" );
175- cdc_printf (" bLength %u\r\n" , desc_device . bLength );
176- cdc_printf (" bDescriptorType %u\r\n" , desc_device . bDescriptorType );
177- cdc_printf (" bcdUSB %04x\r\n" , desc_device . bcdUSB );
178- cdc_printf (" bDeviceClass %u\r\n" , desc_device . bDeviceClass );
179- cdc_printf (" bDeviceSubClass %u\r\n" , desc_device . bDeviceSubClass );
180- cdc_printf (" bDeviceProtocol %u\r\n" , desc_device . bDeviceProtocol );
181- cdc_printf (" bMaxPacketSize0 %u\r\n" , desc_device . bMaxPacketSize0 );
182- cdc_printf (" idVendor 0x%04x\r\n" , desc_device . idVendor );
183- cdc_printf (" idProduct 0x%04x\r\n" , desc_device . idProduct );
184- cdc_printf (" bcdDevice %04x\r\n" , desc_device . bcdDevice );
185-
186- cdc_printf (" iManufacturer %u " , desc_device . iManufacturer );
197+ cdc_printf (" bLength %u\r\n" , desc_device -> bLength );
198+ cdc_printf (" bDescriptorType %u\r\n" , desc_device -> bDescriptorType );
199+ cdc_printf (" bcdUSB %04x\r\n" , desc_device -> bcdUSB );
200+ cdc_printf (" bDeviceClass %u\r\n" , desc_device -> bDeviceClass );
201+ cdc_printf (" bDeviceSubClass %u\r\n" , desc_device -> bDeviceSubClass );
202+ cdc_printf (" bDeviceProtocol %u\r\n" , desc_device -> bDeviceProtocol );
203+ cdc_printf (" bMaxPacketSize0 %u\r\n" , desc_device -> bMaxPacketSize0 );
204+ cdc_printf (" idVendor 0x%04x\r\n" , desc_device -> idVendor );
205+ cdc_printf (" idProduct 0x%04x\r\n" , desc_device -> idProduct );
206+ cdc_printf (" bcdDevice %04x\r\n" , desc_device -> bcdDevice );
207+
208+ cdc_printf (" iManufacturer %u " , desc_device -> iManufacturer );
187209 xfer_result = tuh_descriptor_get_manufacturer_string_sync (daddr , LANGUAGE_ID , buf , sizeof (buf ));
188- if (XFER_RESULT_SUCCESS == xfer_result ) {
210+ if (XFER_RESULT_SUCCESS == xfer_result ) {
189211 print_utf16 (buf , TU_ARRAY_SIZE (buf ));
190212 }
191- tud_cdc_write_str ("\r\n" );
213+ cdc_printf ("\r\n" );
192214
193- cdc_printf (" iProduct %u " , desc_device . iProduct );
215+ cdc_printf (" iProduct %u " , desc_device -> iProduct );
194216 xfer_result = tuh_descriptor_get_product_string_sync (daddr , LANGUAGE_ID , buf , sizeof (buf ));
195217 if (XFER_RESULT_SUCCESS == xfer_result ) {
196218 print_utf16 (buf , TU_ARRAY_SIZE (buf ));
197219 }
198- tud_cdc_write_str ("\r\n" );
220+ cdc_printf ("\r\n" );
199221
200- cdc_printf (" iSerialNumber %u " , desc_device . iSerialNumber );
201- tud_cdc_write_str ((char * )serial ); // serial is already to UTF-8
202- tud_cdc_write_str ("\r\n" );
222+ cdc_printf (" iSerialNumber %u " , desc_device -> iSerialNumber );
223+ cdc_printf ((char * )serial ); // serial is already to UTF-8
224+ cdc_printf ("\r\n" );
203225
204- cdc_printf (" bNumConfigurations %u\r\n" , desc_device . bNumConfigurations );
226+ cdc_printf (" bNumConfigurations %u\r\n" , desc_device -> bNumConfigurations );
205227}
206228
207- void cdc_task (void ) {
208- if (tud_cdc_connected ()) {
209- for (uint8_t daddr = 1 ; daddr <= CFG_TUH_DEVICE_MAX ; daddr ++ ) {
210- if (tuh_mounted (daddr )) {
211- if (is_print [daddr ]) {
212- is_print [daddr ] = false;
213- print_device_info (daddr );
214- tud_cdc_write_flush ();
215- }
216- }
217- }
218- }
229+ void tuh_enum_descriptor_device_cb (uint8_t daddr , tusb_desc_device_t const * desc_device ) {
230+ (void ) daddr ;
231+ descriptor_device [daddr ] = * desc_device ; // save device descriptor
219232}
220233
221- //--------------------------------------------------------------------+
222- // Host Get device information
223- //--------------------------------------------------------------------+
224234void tuh_mount_cb (uint8_t daddr ) {
225235 printf ("mounted device %u\r\n" , daddr );
226236 is_print [daddr ] = true;
@@ -296,7 +306,5 @@ static void print_utf16(uint16_t *temp_buf, size_t buf_len) {
296306 _convert_utf16le_to_utf8 (temp_buf + 1 , utf16_len , (uint8_t * ) temp_buf , sizeof (uint16_t ) * buf_len );
297307 ((uint8_t * ) temp_buf )[utf8_len ] = '\0' ;
298308
299- tud_cdc_write (temp_buf , utf8_len );
300- tud_cdc_write_flush ();
301- tud_task ();
309+ cdc_printf ((char * ) temp_buf );
302310}
0 commit comments