@@ -97,6 +97,7 @@ static void hw_cdc_isr_handler(void *arg) {
97
97
}
98
98
} else {
99
99
usb_serial_jtag_ll_clr_intsts_mask (USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
100
+ // should we just flush internal CDC buffer??
100
101
}
101
102
}
102
103
@@ -281,9 +282,23 @@ int HWCDC::availableForWrite(void)
281
282
return a;
282
283
}
283
284
285
+ static void flushTXBuffer ()
286
+ {
287
+ if (!tx_ring_buf) return ;
288
+ UBaseType_t uxItemsWaiting = 0 ;
289
+ vRingbufferGetInfo (tx_ring_buf, NULL , NULL , NULL , NULL , &uxItemsWaiting);
290
+
291
+ size_t queued_size = 0 ;
292
+ uint8_t *queued_buff = (uint8_t *)xRingbufferReceiveUpTo (tx_ring_buf, &queued_size, 0 , uxItemsWaiting);
293
+ if (queued_size && queued_buff != NULL ) {
294
+ vRingbufferReturnItem (tx_ring_buf, (void *)queued_buff);
295
+ }
296
+ // flush internal CDC
297
+ }
298
+
284
299
size_t HWCDC::write (const uint8_t *buffer, size_t size)
285
300
{
286
- uint32_t tx_timeout_ms = 0 ; // if not connected, no timeout
301
+ uint32_t tx_timeout_ms = 0 ; // if not connected, no timeout
287
302
if (buffer == NULL || size == 0 || tx_ring_buf == NULL || tx_lock == NULL ){
288
303
return 0 ;
289
304
}
@@ -301,6 +316,7 @@ size_t HWCDC::write(const uint8_t *buffer, size_t size)
301
316
space = size;
302
317
}
303
318
// Non-Blocking method, Sending data to ringbuffer, and handle the data in ISR.
319
+ // USB may be plugged, but CDC may be not connected ==> do not block and flush TX buffer, keeping in the buffer just the lastest data
304
320
if (xRingbufferSend (tx_ring_buf, (void *) (buffer), space, 0 ) != pdTRUE){
305
321
size = 0 ;
306
322
} else {
@@ -324,6 +340,8 @@ size_t HWCDC::write(const uint8_t *buffer, size_t size)
324
340
usb_serial_jtag_ll_ena_intr_mask (USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
325
341
}
326
342
}
343
+ // there is no more space in CDC Endpoint internal buffer ==> flush all data from TX buffer and only keep last written data
344
+ if (to_send && !usb_serial_jtag_ll_txfifo_writable ()) flushTXBuffer ();
327
345
xSemaphoreGive (tx_lock);
328
346
return size;
329
347
}
@@ -345,16 +363,21 @@ void HWCDC::flush(void)
345
363
if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS){
346
364
return ;
347
365
}
366
+ // USB may be plugged, but CDC may be not connected ==> do not block and flush TX buffer, keeping in the buffer just the lastest data
348
367
UBaseType_t uxItemsWaiting = 0 ;
349
368
vRingbufferGetInfo (tx_ring_buf, NULL , NULL , NULL , NULL , &uxItemsWaiting);
350
369
if (uxItemsWaiting){
351
370
// Now trigger the ISR to read data from the ring buffer.
352
371
usb_serial_jtag_ll_ena_intr_mask (USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
353
372
}
354
- while (uxItemsWaiting){
373
+ uint8_t tries = 3 ;
374
+ while (tries && uxItemsWaiting){
355
375
delay (5 );
376
+ UBaseType_t lastUxItemsWaiting = uxItemsWaiting; // is it flushing CDC?
356
377
vRingbufferGetInfo (tx_ring_buf, NULL , NULL , NULL , NULL , &uxItemsWaiting);
378
+ if (lastUxItemsWaiting == uxItemsWaiting) tries--; // avoids locking when USB is plugged, but CDC is not connected
357
379
}
380
+ if (!tries) flushTXBuffer (); // flush TX Buffer
358
381
xSemaphoreGive (tx_lock);
359
382
}
360
383
0 commit comments