Skip to content

Commit 3249420

Browse files
Avoid CDC transmit blocking on USB disconnect
1 parent 4d2ccf1 commit 3249420

File tree

8 files changed

+80
-226
lines changed

8 files changed

+80
-226
lines changed

cores/stm32l4/CDC.cpp

Lines changed: 30 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ CDC::CDC(struct _stm32l4_usbd_cdc_t *usbd_cdc, bool serialEvent)
5454
_tx_count = 0;
5555
_tx_size = 0;
5656

57-
_tx_data2 = NULL;
58-
_tx_size2 = 0;
59-
60-
_completionCallback = NULL;
6157
_receiveCallback = NULL;
6258

6359
stm32l4_usbd_cdc_create(usbd_cdc);
@@ -103,10 +99,6 @@ int CDC::availableForWrite(void)
10399
return 0;
104100
}
105101

106-
if (_tx_size2 != 0) {
107-
return 0;
108-
}
109-
110102
return CDC_TX_BUFFER_SIZE - _tx_count;
111103
}
112104

@@ -178,10 +170,6 @@ void CDC::flush()
178170
stm32l4_usbd_cdc_poll(_usbd_cdc);
179171
}
180172

181-
while (_tx_size2 != 0) {
182-
stm32l4_usbd_cdc_poll(_usbd_cdc);
183-
}
184-
185173
while (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
186174
stm32l4_usbd_cdc_poll(_usbd_cdc);
187175
}
@@ -190,10 +178,6 @@ void CDC::flush()
190178
armv7m_core_yield();
191179
}
192180

193-
while (_tx_size2 != 0) {
194-
armv7m_core_yield();
195-
}
196-
197181
while (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
198182
armv7m_core_yield();
199183
}
@@ -210,24 +194,13 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
210194
unsigned int tx_read, tx_write, tx_count, tx_size;
211195
size_t count;
212196

213-
if ((_usbd_cdc->state < USBD_CDC_STATE_READY) || !(stm32l4_usbd_cdc_info.lineState & 2)) {
197+
if ((_usbd_cdc->state < USBD_CDC_STATE_READY) || !(stm32l4_usbd_cdc_info.lineState & 1)) {
214198
return 0;
215199
}
216200

217201
if (size == 0) {
218202
return 0;
219203
}
220-
221-
// If there is an async write pending, wait till it's done
222-
if (_tx_size2 != 0) {
223-
if (!_blocking || (__get_IPSR() != 0)) {
224-
return 0;
225-
}
226-
227-
while (_tx_size2 != 0) {
228-
armv7m_core_yield();
229-
}
230-
}
231204

232205
count = 0;
233206

@@ -255,7 +228,11 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
255228

256229
_tx_size = tx_size;
257230

258-
stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size);
231+
if (!stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size)) {
232+
_tx_size = 0;
233+
_tx_count = 0;
234+
_tx_read = _tx_write;
235+
}
259236
}
260237

261238
while (CDC_TX_BUFFER_SIZE == _tx_count) {
@@ -298,57 +275,17 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
298275

299276
_tx_size = tx_size;
300277

301-
stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size);
278+
if (!stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size)) {
279+
_tx_size = 0;
280+
_tx_count = 0;
281+
_tx_read = _tx_write;
282+
}
302283
}
303284
}
304285

305286
return count;
306287
}
307288

308-
bool CDC::write(const uint8_t *buffer, size_t size, void(*callback)(void))
309-
{
310-
if ((_usbd_cdc->state < USBD_CDC_STATE_READY) || !(stm32l4_usbd_cdc_info.lineState & 2)) {
311-
return false;
312-
}
313-
314-
if (size == 0) {
315-
return false;
316-
}
317-
318-
if (_tx_size2 != 0) {
319-
return false;
320-
}
321-
322-
_completionCallback = callback;
323-
_tx_data2 = buffer;
324-
_tx_size2 = size;
325-
326-
if (stm32l4_usbd_cdc_done(_usbd_cdc)) {
327-
if (_tx_size2 != 0) {
328-
stm32l4_usbd_cdc_transmit(_usbd_cdc, _tx_data2, _tx_size2);
329-
}
330-
}
331-
332-
return true;
333-
}
334-
335-
bool CDC::done()
336-
{
337-
if (_tx_count) {
338-
return false;
339-
}
340-
341-
if (_tx_size2) {
342-
return false;
343-
}
344-
345-
if (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
346-
return false;
347-
}
348-
349-
return true;
350-
}
351-
352289
void CDC::onReceive(void(*callback)(int))
353290
{
354291
_receiveCallback = callback;
@@ -422,35 +359,27 @@ void CDC::EventCallback(uint32_t events)
422359

423360
_tx_size = 0;
424361

425-
if (_tx_count != 0) {
426-
tx_size = _tx_count;
427-
tx_read = _tx_read;
428-
429-
if (tx_size > (CDC_TX_BUFFER_SIZE - tx_read)) {
430-
tx_size = (CDC_TX_BUFFER_SIZE - tx_read);
431-
}
432-
433-
if (tx_size > CDC_TX_PACKET_SIZE) {
434-
tx_size = CDC_TX_PACKET_SIZE;
435-
}
436-
437-
_tx_size = tx_size;
438-
439-
stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size);
440-
} else {
441-
if (_tx_size2 != 0) {
442-
stm32l4_usbd_cdc_transmit(_usbd_cdc, _tx_data2, _tx_size2);
362+
if (stm32l4_usbd_cdc_info.lineState & 1) {
363+
if (_tx_count != 0) {
364+
tx_size = _tx_count;
365+
tx_read = _tx_read;
366+
367+
if (tx_size > (CDC_TX_BUFFER_SIZE - tx_read)) {
368+
tx_size = (CDC_TX_BUFFER_SIZE - tx_read);
369+
}
370+
371+
if (tx_size > CDC_TX_PACKET_SIZE) {
372+
tx_size = CDC_TX_PACKET_SIZE;
373+
}
374+
375+
_tx_size = tx_size;
376+
377+
stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size);
443378
}
444379
}
445-
} else {
446-
_tx_size2 = 0;
447-
_tx_data2 = NULL;
448-
449-
callback = _completionCallback;
450-
_completionCallback = NULL;
451-
452-
if (callback) {
453-
(*callback)();
380+
else {
381+
_tx_count = 0;
382+
_tx_read = _tx_write;
454383
}
455384
}
456385
}

cores/stm32l4/USBAPI.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,6 @@ class CDC : public HardwareSerial
100100
// STM32L4 EXTENSTION: non-blocking multi-byte read
101101
size_t read(uint8_t *buffer, size_t size);
102102

103-
// STM32L4 EXTENSTION: asynchronous write with callback
104-
bool write(const uint8_t *buffer, size_t size, void(*callback)(void));
105-
bool done(void);
106-
107103
// STM32L4 EXTENSTION: asynchronous receive
108104
void onReceive(void(*callback)(int));
109105

@@ -126,10 +122,6 @@ class CDC : public HardwareSerial
126122
volatile uint32_t _tx_count;
127123
volatile uint32_t _tx_size;
128124

129-
const uint8_t *_tx_data2;
130-
volatile uint32_t _tx_size2;
131-
132-
void (*_completionCallback)(void);
133125
void (*_receiveCallback)(int);
134126

135127
static void _event_callback(void *context, uint32_t events);

cores/stm32l4/Uart.cpp

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ Uart::Uart(struct _stm32l4_uart_t *uart, unsigned int instance, const struct _st
4646
_tx_count = 0;
4747
_tx_size = 0;
4848

49-
_tx_data2 = NULL;
50-
_tx_size2 = 0;
51-
52-
_completionCallback = NULL;
5349
_receiveCallback = NULL;
5450

5551
stm32l4_uart_create(uart, instance, pins, priority, mode);
@@ -93,10 +89,6 @@ int Uart::availableForWrite()
9389
return 0;
9490
}
9591

96-
if (_tx_size2 != 0) {
97-
return 0;
98-
}
99-
10092
return UART_TX_BUFFER_SIZE - _tx_count;
10193
}
10294

@@ -168,10 +160,6 @@ void Uart::flush()
168160
stm32l4_uart_poll(_uart);
169161
}
170162

171-
while (_tx_size2 != 0) {
172-
stm32l4_uart_poll(_uart);
173-
}
174-
175163
while (!stm32l4_uart_done(_uart)) {
176164
stm32l4_uart_poll(_uart);
177165
}
@@ -180,10 +168,6 @@ void Uart::flush()
180168
armv7m_core_yield();
181169
}
182170

183-
while (_tx_size2 != 0) {
184-
armv7m_core_yield();
185-
}
186-
187171
while (!stm32l4_uart_done(_uart)) {
188172
armv7m_core_yield();
189173
}
@@ -208,17 +192,6 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
208192
return 0;
209193
}
210194

211-
// If there is an async write pending, wait till it's done
212-
if (_tx_size2 != 0) {
213-
if (!_blocking || (__get_IPSR() != 0)) {
214-
return 0;
215-
}
216-
217-
while (_tx_size2 != 0) {
218-
armv7m_core_yield();
219-
}
220-
}
221-
222195
count = 0;
223196

224197
while (count < size) {
@@ -295,50 +268,6 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
295268
return count;
296269
}
297270

298-
bool Uart::write(const uint8_t *buffer, size_t size, void(*callback)(void))
299-
{
300-
if (_uart->state < UART_STATE_READY) {
301-
return false;
302-
}
303-
304-
if (size == 0) {
305-
return false;
306-
}
307-
308-
if (_tx_size2 != 0) {
309-
return false;
310-
}
311-
312-
_completionCallback = callback;
313-
_tx_data2 = buffer;
314-
_tx_size2 = size;
315-
316-
if (stm32l4_uart_done(_uart)) {
317-
if (_tx_size2 != 0) {
318-
stm32l4_uart_transmit(_uart, _tx_data2, _tx_size2);
319-
}
320-
}
321-
322-
return true;
323-
}
324-
325-
bool Uart::done()
326-
{
327-
if (_tx_count) {
328-
return false;
329-
}
330-
331-
if (_tx_size2) {
332-
return false;
333-
}
334-
335-
if (!stm32l4_uart_done(_uart)) {
336-
return false;
337-
}
338-
339-
return true;
340-
}
341-
342271
void Uart::onReceive(void(*callback)(int))
343272
{
344273
_receiveCallback = callback;
@@ -427,20 +356,6 @@ void Uart::EventCallback(uint32_t events)
427356
_tx_size = tx_size;
428357

429358
stm32l4_uart_transmit(_uart, &_tx_data[tx_read], tx_size);
430-
} else {
431-
if (_tx_size2 != 0) {
432-
stm32l4_uart_transmit(_uart, _tx_data2, _tx_size2);
433-
}
434-
}
435-
} else {
436-
_tx_size2 = 0;
437-
_tx_data2 = NULL;
438-
439-
callback = _completionCallback;
440-
_completionCallback = NULL;
441-
442-
if (callback) {
443-
(*callback)();
444359
}
445360
}
446361
}

cores/stm32l4/Uart.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,6 @@ class Uart : public HardwareSerial
5454
// STM32L4 EXTENSTION: non-blocking multi-byte read
5555
size_t read(uint8_t *buffer, size_t size);
5656

57-
// STM32L4 EXTENSTION: asynchronous write with callback
58-
bool write(const uint8_t *buffer, size_t size, void(*callback)(void));
59-
bool done(void);
60-
6157
// STM32L4 EXTENSTION: asynchronous receive
6258
void onReceive(void(*callback)(int));
6359

@@ -81,10 +77,6 @@ class Uart : public HardwareSerial
8177
volatile uint32_t _tx_count;
8278
volatile uint32_t _tx_size;
8379

84-
const uint8_t *_tx_data2;
85-
volatile uint32_t _tx_size2;
86-
87-
void (*_completionCallback)(void);
8880
void (*_receiveCallback)(int);
8981

9082
static void _event_callback(void *context, uint32_t events);
348 Bytes
Binary file not shown.
348 Bytes
Binary file not shown.
348 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)