@@ -62,63 +62,40 @@ void tud_cdc_rx_cb(uint8_t itf)
62
62
63
63
// Invoked when received send break
64
64
void tud_cdc_send_break_cb (uint8_t itf, uint16_t duration_ms){
65
- // isr_log_v ("itf: %u, duration_ms: %u", itf, duration_ms);
65
+ // log_v ("itf: %u, duration_ms: %u", itf, duration_ms);
66
66
}
67
67
68
68
// Invoked when space becomes available in TX buffer
69
69
void tud_cdc_tx_complete_cb (uint8_t itf){
70
- if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL && devices[itf]->tx_sem != NULL ){
71
- xSemaphoreGive (devices[itf]->tx_sem );
70
+ if (itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL ){
72
71
devices[itf]->_onTX ();
73
72
}
74
73
}
75
74
76
- static size_t tinyusb_cdc_write ( uint8_t itf, const uint8_t *buffer, size_t size ){
77
- if (itf >= MAX_USB_CDC_DEVICES || devices[itf] == NULL || devices[itf]-> tx_sem = = NULL ){
78
- return 0 ;
75
+ static void ARDUINO_ISR_ATTR cdc0_write_char ( char c ){
76
+ if (devices[0 ] ! = NULL ){
77
+ devices[ 0 ]-> write (c) ;
79
78
}
80
- if (!tud_cdc_n_connected (itf)){
81
- return 0 ;
82
- }
83
- size_t tosend = size, sofar = 0 ;
84
- while (tosend){
85
- uint32_t space = tud_cdc_n_write_available (itf);
86
- if (!space){
87
- // make sure that we do not get previous semaphore
88
- xSemaphoreTake (devices[itf]->tx_sem , 0 );
89
- // wait for tx_complete
90
- if (xSemaphoreTake (devices[itf]->tx_sem , 200 / portTICK_PERIOD_MS) == pdTRUE){
91
- space = tud_cdc_n_write_available (itf);
92
- }
93
- if (!space){
94
- return sofar;
95
- }
96
- }
97
- if (tosend < space){
98
- space = tosend;
99
- }
100
- uint32_t sent = tud_cdc_n_write (itf, buffer + sofar, space);
101
- if (!sent){
102
- return sofar;
103
- }
104
- sofar += sent;
105
- tosend -= sent;
106
- tud_cdc_n_write_flush (itf);
107
- // xSemaphoreTake(devices[itf]->tx_sem, portMAX_DELAY);
108
- }
109
- return sofar;
110
- }
111
-
112
- static void ARDUINO_ISR_ATTR cdc0_write_char (char c)
113
- {
114
- tinyusb_cdc_write (0 , (const uint8_t *)&c, 1 );
115
79
}
116
80
117
81
static void usb_unplugged_cb (void * arg, esp_event_base_t event_base, int32_t event_id, void * event_data){
118
82
((USBCDC*)arg)->_onUnplugged ();
119
83
}
120
84
121
- USBCDC::USBCDC (uint8_t itfn) : itf(itfn), bit_rate(0 ), stop_bits(0 ), parity(0 ), data_bits(0 ), dtr(false ), rts(false ), connected(false ), reboot_enable(true ), rx_queue(NULL ), tx_sem(NULL ) {
85
+ USBCDC::USBCDC (uint8_t itfn)
86
+ : itf(itfn)
87
+ , bit_rate(0 )
88
+ , stop_bits(0 )
89
+ , parity(0 )
90
+ , data_bits(0 )
91
+ , dtr(false )
92
+ , rts(false )
93
+ , connected(false )
94
+ , reboot_enable(true )
95
+ , rx_queue(NULL )
96
+ , tx_lock(NULL )
97
+ , tx_timeout_ms(250 )
98
+ {
122
99
tinyusb_enable_interface (USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
123
100
if (itf < MAX_USB_CDC_DEVICES){
124
101
arduino_usb_event_handler_register_with (ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this );
@@ -153,9 +130,8 @@ size_t USBCDC::setRxBufferSize(size_t rx_queue_len){
153
130
154
131
void USBCDC::begin (unsigned long baud)
155
132
{
156
- if (tx_sem == NULL ){
157
- tx_sem = xSemaphoreCreateBinary ();
158
- xSemaphoreTake (tx_sem, 0 );
133
+ if (tx_lock == NULL ) {
134
+ tx_lock = xSemaphoreCreateMutex ();
159
135
}
160
136
setRxBufferSize (256 );// default if not preset
161
137
devices[itf] = this ;
@@ -166,12 +142,15 @@ void USBCDC::end()
166
142
connected = false ;
167
143
devices[itf] = NULL ;
168
144
setRxBufferSize (0 );
169
- if (tx_sem != NULL ) {
170
- vSemaphoreDelete (tx_sem);
171
- tx_sem = NULL ;
145
+ if (tx_lock != NULL ) {
146
+ vSemaphoreDelete (tx_lock);
172
147
}
173
148
}
174
149
150
+ void USBCDC::setTxTimeoutMs (uint32_t timeout){
151
+ tx_timeout_ms = timeout;
152
+ }
153
+
175
154
void USBCDC::_onUnplugged (void ){
176
155
if (connected){
177
156
connected = false ;
@@ -336,23 +315,73 @@ size_t USBCDC::read(uint8_t *buffer, size_t size)
336
315
337
316
void USBCDC::flush (void )
338
317
{
339
- if (itf >= MAX_USB_CDC_DEVICES || tx_sem == NULL ){
318
+ if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || !tud_cdc_n_connected (itf)){
319
+ return ;
320
+ }
321
+ if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS){
340
322
return ;
341
323
}
342
324
tud_cdc_n_write_flush (itf);
325
+ xSemaphoreGive (tx_lock);
343
326
}
344
327
345
328
int USBCDC::availableForWrite (void )
346
329
{
347
- if (itf >= MAX_USB_CDC_DEVICES || tx_sem == NULL ){
348
- return - 1 ;
330
+ if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || ! tud_cdc_n_connected (itf) ){
331
+ return 0 ;
349
332
}
350
- return tud_cdc_n_write_available (itf);
333
+ if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS){
334
+ return 0 ;
335
+ }
336
+ size_t a = tud_cdc_n_write_available (itf);
337
+ xSemaphoreGive (tx_lock);
338
+ return a;
351
339
}
352
340
353
341
size_t USBCDC::write (const uint8_t *buffer, size_t size)
354
342
{
355
- return tinyusb_cdc_write (itf, buffer, size);
343
+ if (itf >= MAX_USB_CDC_DEVICES || tx_lock == NULL || buffer == NULL || size == 0 || !tud_cdc_n_connected (itf)){
344
+ return 0 ;
345
+ }
346
+ if (xPortInIsrContext ()){
347
+ BaseType_t taskWoken = false ;
348
+ if (xSemaphoreTakeFromISR (tx_lock, &taskWoken) != pdPASS){
349
+ return 0 ;
350
+ }
351
+ } else if (xSemaphoreTake (tx_lock, tx_timeout_ms / portTICK_PERIOD_MS) != pdPASS){
352
+ return 0 ;
353
+ }
354
+ size_t to_send = size, so_far = 0 ;
355
+ while (to_send){
356
+ if (!tud_cdc_n_connected (itf)){
357
+ size = so_far;
358
+ break ;
359
+ }
360
+ size_t space = tud_cdc_n_write_available (itf);
361
+ if (!space){
362
+ tud_cdc_n_write_flush (itf);
363
+ continue ;
364
+ }
365
+ if (space > to_send){
366
+ space = to_send;
367
+ }
368
+ size_t sent = tud_cdc_n_write (itf, buffer+so_far, space);
369
+ if (sent){
370
+ so_far += sent;
371
+ to_send -= sent;
372
+ tud_cdc_n_write_flush (itf);
373
+ } else {
374
+ size = so_far;
375
+ break ;
376
+ }
377
+ }
378
+ if (xPortInIsrContext ()){
379
+ BaseType_t taskWoken = false ;
380
+ xSemaphoreGiveFromISR (tx_lock, &taskWoken);
381
+ } else {
382
+ xSemaphoreGive (tx_lock);
383
+ }
384
+ return size;
356
385
}
357
386
358
387
size_t USBCDC::write (uint8_t c)
0 commit comments