Skip to content

Commit 0d61048

Browse files
Cleanup CDC/Uart; add async writes again, this time the working variant
1 parent f90e5b6 commit 0d61048

File tree

9 files changed

+175
-73
lines changed

9 files changed

+175
-73
lines changed

cores/stm32l4/CDC.cpp

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ CDC::CDC(struct _stm32l4_usbd_cdc_t *usbd_cdc, bool serialEvent)
4444
{
4545
_usbd_cdc = usbd_cdc;
4646

47-
_blocking = true;
48-
4947
_rx_read = 0;
5048
_rx_write = 0;
5149
_rx_count = 0;
@@ -54,6 +52,10 @@ CDC::CDC(struct _stm32l4_usbd_cdc_t *usbd_cdc, bool serialEvent)
5452
_tx_count = 0;
5553
_tx_size = 0;
5654

55+
_tx_data2 = NULL;
56+
_tx_size2 = 0;
57+
58+
_completionCallback = NULL;
5759
_receiveCallback = NULL;
5860

5961
stm32l4_usbd_cdc_create(usbd_cdc);
@@ -99,6 +101,10 @@ int CDC::availableForWrite(void)
99101
return 0;
100102
}
101103

104+
if (_tx_size2 != 0) {
105+
return 0;
106+
}
107+
102108
return CDC_TX_BUFFER_SIZE - _tx_count;
103109
}
104110

@@ -170,19 +176,11 @@ size_t CDC::read(uint8_t *buffer, size_t size)
170176
void CDC::flush()
171177
{
172178
if (armv7m_core_priority() <= STM32L4_USB_IRQ_PRIORITY) {
173-
while (_tx_count != 0) {
174-
stm32l4_usbd_cdc_poll(_usbd_cdc);
175-
}
176-
177-
while (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
179+
while ((_tx_count != 0) || (_tx_size2 != 0) || !stm32l4_usbd_cdc_done(_usbd_cdc)) {
178180
stm32l4_usbd_cdc_poll(_usbd_cdc);
179181
}
180182
} else {
181-
while (_tx_count != 0) {
182-
armv7m_core_yield();
183-
}
184-
185-
while (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
183+
while ((_tx_count != 0) || (_tx_size2 != 0) || !stm32l4_usbd_cdc_done(_usbd_cdc)) {
186184
armv7m_core_yield();
187185
}
188186
}
@@ -205,6 +203,16 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
205203
if (size == 0) {
206204
return 0;
207205
}
206+
207+
if (_tx_size2 != 0) {
208+
if (__get_IPSR() != 0) {
209+
return 0;
210+
}
211+
212+
while (_tx_size2 != 0) {
213+
armv7m_core_yield();
214+
}
215+
}
208216

209217
count = 0;
210218

@@ -214,7 +222,7 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
214222

215223
if (tx_count == 0) {
216224

217-
if (!_blocking || (__get_IPSR() != 0)) {
225+
if (__get_IPSR() != 0) {
218226
break;
219227
}
220228

@@ -290,19 +298,54 @@ size_t CDC::write(const uint8_t *buffer, size_t size)
290298
return count;
291299
}
292300

293-
void CDC::onReceive(void(*callback)(void))
301+
bool CDC::write(const uint8_t *buffer, size_t size, void(*callback)(void))
294302
{
295-
_receiveCallback = callback;
303+
if ((_usbd_cdc->state < USBD_CDC_STATE_READY) || !(stm32l4_usbd_cdc_info.lineState & 1)) {
304+
return false;
305+
}
306+
307+
if (size == 0) {
308+
return false;
309+
}
310+
311+
if (_tx_size2 != 0) {
312+
return false;
313+
}
314+
315+
_completionCallback = callback;
316+
_tx_data2 = buffer;
317+
_tx_size2 = size;
318+
319+
if (stm32l4_usbd_cdc_done(_usbd_cdc)) {
320+
if (!stm32l4_usbd_cdc_transmit(_usbd_cdc, _tx_data2, _tx_size2)) {
321+
_tx_data2 = NULL;
322+
_tx_size2 = 0;
323+
}
324+
}
325+
326+
return true;
296327
}
297328

298-
void CDC::blockOnOverrun(bool block)
329+
bool CDC::done()
299330
{
300-
_blocking = block;
331+
if (_tx_count) {
332+
return false;
333+
}
334+
335+
if (_tx_size2) {
336+
return false;
337+
}
338+
339+
if (!stm32l4_usbd_cdc_done(_usbd_cdc)) {
340+
return false;
341+
}
342+
343+
return true;
301344
}
302345

303-
bool CDC::isEnabled()
346+
void CDC::onReceive(void(*callback)(void))
304347
{
305-
return (_usbd_cdc->state >= USBD_CDC_STATE_READY);
348+
_receiveCallback = callback;
306349
}
307350

308351
void CDC::EventCallback(uint32_t events)
@@ -372,12 +415,24 @@ void CDC::EventCallback(uint32_t events)
372415
_tx_size = tx_size;
373416

374417
stm32l4_usbd_cdc_transmit(_usbd_cdc, &_tx_data[tx_read], tx_size);
418+
} else {
419+
if (_tx_size2 != 0) {
420+
stm32l4_usbd_cdc_transmit(_usbd_cdc, _tx_data2, _tx_size2);
421+
}
375422
}
376-
}
377-
else {
423+
} else {
378424
_tx_count = 0;
379425
_tx_read = _tx_write;
380426
}
427+
} else {
428+
_tx_size2 = 0;
429+
_tx_data2 = NULL;
430+
431+
if (_completionCallback) {
432+
armv7m_pendsv_enqueue((armv7m_pendsv_routine_t)_completionCallback, NULL, 0);
433+
434+
_completionCallback = NULL;
435+
}
381436
}
382437
}
383438
}

cores/stm32l4/USBAPI.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,15 @@ 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+
103107
// STM32L4 EXTENSTION: asynchronous receive
104108
void onReceive(void(*callback)(void));
105109

106-
// STM32L4 EXTENSTION: enable/disabe blocking writes
107-
void blockOnOverrun(bool enable);
108-
109-
// STM32L4 EXTENSTION: isEnabled() check
110-
bool isEnabled(void);
111-
112110
private:
113111
struct _stm32l4_usbd_cdc_t *_usbd_cdc;
114-
bool _blocking;
115112
uint8_t _rx_data[CDC_RX_BUFFER_SIZE];
116113
volatile uint16_t _rx_write;
117114
volatile uint16_t _rx_read;
@@ -122,6 +119,10 @@ class CDC : public HardwareSerial
122119
volatile uint32_t _tx_count;
123120
volatile uint32_t _tx_size;
124121

122+
const uint8_t *_tx_data2;
123+
volatile uint32_t _tx_size2;
124+
125+
void (*_completionCallback)(void);
125126
void (*_receiveCallback)(void);
126127

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

cores/stm32l4/Uart.cpp

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ Uart::Uart(struct _stm32l4_uart_t *uart, unsigned int instance, const struct _st
3636
{
3737
_uart = uart;
3838

39-
_blocking = true;
40-
4139
_rx_read = 0;
4240
_rx_write = 0;
4341
_rx_count = 0;
@@ -46,6 +44,10 @@ Uart::Uart(struct _stm32l4_uart_t *uart, unsigned int instance, const struct _st
4644
_tx_count = 0;
4745
_tx_size = 0;
4846

47+
_tx_data2 = NULL;
48+
_tx_size2 = 0;
49+
50+
_completionCallback = NULL;
4951
_receiveCallback = NULL;
5052

5153
stm32l4_uart_create(uart, instance, pins, priority, mode);
@@ -89,6 +91,10 @@ int Uart::availableForWrite()
8991
return 0;
9092
}
9193

94+
if (_tx_size2 != 0) {
95+
return 0;
96+
}
97+
9298
return UART_TX_BUFFER_SIZE - _tx_count;
9399
}
94100

@@ -160,19 +166,11 @@ size_t Uart::read(uint8_t *buffer, size_t size)
160166
void Uart::flush()
161167
{
162168
if (armv7m_core_priority() <= STM32L4_UART_IRQ_PRIORITY) {
163-
while (_tx_count != 0) {
164-
stm32l4_uart_poll(_uart);
165-
}
166-
167-
while (!stm32l4_uart_done(_uart)) {
169+
while ((_tx_count != 0) || (_tx_size2 != 0) || !stm32l4_uart_done(_uart)) {
168170
stm32l4_uart_poll(_uart);
169171
}
170172
} else {
171-
while (_tx_count != 0) {
172-
armv7m_core_yield();
173-
}
174-
175-
while (!stm32l4_uart_done(_uart)) {
173+
while ((_tx_count != 0) || (_tx_size2 != 0) || !stm32l4_uart_done(_uart)) {
176174
armv7m_core_yield();
177175
}
178176
}
@@ -196,6 +194,16 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
196194
return 0;
197195
}
198196

197+
if (_tx_size2 != 0) {
198+
if (__get_IPSR() != 0) {
199+
return 0;
200+
}
201+
202+
while (_tx_size2 != 0) {
203+
armv7m_core_yield();
204+
}
205+
}
206+
199207
count = 0;
200208

201209
while (count < size) {
@@ -204,7 +212,7 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
204212

205213
if (tx_count == 0) {
206214

207-
if (!_blocking || (__get_IPSR() != 0)) {
215+
if (__get_IPSR() != 0) {
208216
break;
209217
}
210218

@@ -272,19 +280,51 @@ size_t Uart::write(const uint8_t *buffer, size_t size)
272280
return count;
273281
}
274282

275-
void Uart::onReceive(void(*callback)(void))
283+
bool Uart::write(const uint8_t *buffer, size_t size, void(*callback)(void))
276284
{
277-
_receiveCallback = callback;
285+
if (_uart->state < UART_STATE_READY) {
286+
return false;
287+
}
288+
289+
if (size == 0) {
290+
return false;
291+
}
292+
293+
if (_tx_size2 != 0) {
294+
return false;
295+
}
296+
297+
_completionCallback = callback;
298+
_tx_data2 = buffer;
299+
_tx_size2 = size;
300+
301+
if (stm32l4_uart_done(_uart)) {
302+
stm32l4_uart_transmit(_uart, _tx_data2, _tx_size2);
303+
}
304+
305+
return true;
278306
}
279307

280-
void Uart::blockOnOverrun(bool block)
308+
bool Uart::done()
281309
{
282-
_blocking = block;
310+
if (_tx_count) {
311+
return false;
312+
}
313+
314+
if (_tx_size2) {
315+
return false;
316+
}
317+
318+
if (!stm32l4_uart_done(_uart)) {
319+
return false;
320+
}
321+
322+
return true;
283323
}
284324

285-
bool Uart::isEnabled()
325+
void Uart::onReceive(void(*callback)(void))
286326
{
287-
return (_uart->state >= UART_STATE_READY);
327+
_receiveCallback = callback;
288328
}
289329

290330
void Uart::EventCallback(uint32_t events)
@@ -353,6 +393,19 @@ void Uart::EventCallback(uint32_t events)
353393
_tx_size = tx_size;
354394

355395
stm32l4_uart_transmit(_uart, &_tx_data[tx_read], tx_size);
396+
} else {
397+
if (_tx_size2 != 0) {
398+
stm32l4_uart_transmit(_uart, _tx_data2, _tx_size2);
399+
}
400+
}
401+
} else {
402+
_tx_size2 = 0;
403+
_tx_data2 = NULL;
404+
405+
if (_completionCallback) {
406+
armv7m_pendsv_enqueue((armv7m_pendsv_routine_t)_completionCallback, NULL, 0);
407+
408+
_completionCallback = NULL;
356409
}
357410
}
358411
}

cores/stm32l4/Uart.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,15 @@ 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+
5761
// STM32L4 EXTENSTION: asynchronous receive
5862
void onReceive(void(*callback)(void));
5963

60-
// STM32L4 EXTENSTION: enable/disabe blocking writes
61-
void blockOnOverrun(bool block);
62-
63-
// STM32L4 EXTENSTION: isEnabled() check
64-
bool isEnabled(void);
65-
6664
private:
6765
struct _stm32l4_uart_t *_uart;
68-
bool _blocking;
6966
uint8_t _rx_fifo[16];
7067
uint8_t _rx_data[UART_RX_BUFFER_SIZE];
7168
volatile uint16_t _rx_write;
@@ -77,6 +74,10 @@ class Uart : public HardwareSerial
7774
volatile uint32_t _tx_count;
7875
volatile uint32_t _tx_size;
7976

77+
const uint8_t *_tx_data2;
78+
volatile uint32_t _tx_size2;
79+
80+
void (*_completionCallback)(void);
8081
void (*_receiveCallback)(void);
8182

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

system/STM32L4xx/Lib/libstm32l432.a

-184 Bytes
Binary file not shown.

system/STM32L4xx/Lib/libstm32l433.a

-180 Bytes
Binary file not shown.

system/STM32L4xx/Lib/libstm32l476.a

-184 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)