Skip to content

Commit dbf87a2

Browse files
committed
fix(srv/stm32-uart): Fix TX interrupt handling in FIFO mode (default now)
1 parent ed2aa99 commit dbf87a2

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

services/stm32-uart/stm32-uart.c

+13-8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#define MODULE_NAME "stm32-uart"
2323

24+
#define USART_CR1_FIFOEN (1 << 29)
25+
2426

2527
/*********************************************************************************************************************
2628
* Uart interface implementation
@@ -292,6 +294,10 @@ stm32_uart_ret_t stm32_uart_init(Stm32Uart *self, uint32_t port) {
292294
usart_set_stopbits(self->port, USART_STOPBITS_1);
293295
usart_set_parity(self->port, USART_PARITY_NONE);
294296
usart_set_flow_control(self->port, USART_FLOWCONTROL_NONE);
297+
298+
/* Enable FIFO mode */
299+
USART_CR1(self->port) |= USART_CR1_FIFOEN;
300+
295301
usart_enable(self->port);
296302

297303
/* Allocate IPC primitives. */
@@ -305,6 +311,7 @@ stm32_uart_ret_t stm32_uart_init(Stm32Uart *self, uint32_t port) {
305311
goto err;
306312
}
307313

314+
308315
/* Enable RX not empty interrupt to receive data. */
309316
USART_CR3(self->port) |= USART_CR3_OVRDIS;
310317
USART_CR1(self->port) |= USART_CR1_RXNEIE;
@@ -338,18 +345,18 @@ stm32_uart_ret_t stm32_uart_free(Stm32Uart *self) {
338345

339346

340347
stm32_uart_ret_t stm32_uart_interrupt_handler(Stm32Uart *self) {
341-
/** @TODO tested on L4 only */
348+
BaseType_t woken = pdFALSE;
342349

343-
if ((USART_ISR(self->port) & USART_ISR_TXE)) {
350+
while ((USART_ISR(self->port) & USART_ISR_TXE)) {
344351
uint8_t b = 0;
345352
size_t r = xStreamBufferReceiveFromISR(self->txbuf, &b, sizeof(b), 0);
346353
if (r > 0) {
347354
usart_send(self->port, b);
348355
}
349356
if (r == 0) {
350-
/* No more bytes to send. Clear and disable the interrupt. */
351-
USART_RQR(self->port) |= USART_RQR_TXFRQ;
357+
/* No more bytes to send. Disable the interrupt. */
352358
USART_CR1(self->port) &= ~USART_CR1_TXEIE;
359+
break;
353360
}
354361
}
355362

@@ -362,10 +369,9 @@ stm32_uart_ret_t stm32_uart_interrupt_handler(Stm32Uart *self) {
362369
USART_ICR(self->port) |= USART_ICR_TCCF;
363370
}
364371

365-
if ((USART_ISR(self->port) & USART_ISR_RXNE)) {
372+
while ((USART_ISR(self->port) & USART_ISR_RXNE)) {
366373
uint8_t b = usart_recv(self->port);
367374

368-
BaseType_t woken = pdFALSE;
369375
/* For any character < 0x20, prepend ESC */
370376
if (b < 0x20) {
371377
const uint8_t esc = 0x1b;
@@ -374,13 +380,11 @@ stm32_uart_ret_t stm32_uart_interrupt_handler(Stm32Uart *self) {
374380
/* Do not check the return value. If there was not enough space to save
375381
* the received byte, we have nothing else to do. */
376382
xStreamBufferSendFromISR(self->rxbuf, &b, sizeof(b), &woken);
377-
portYIELD_FROM_ISR(woken);
378383
}
379384

380385
if (USART_ISR(self->port) & USART_ISR_RTOF) {
381386
USART_ICR(self->port) |= USART_ICR_RTOCF;
382387

383-
BaseType_t woken = pdFALSE;
384388
const uint8_t etb = 0x17;
385389
xStreamBufferSendFromISR(self->rxbuf, &etb, sizeof(etb), &woken);
386390
portYIELD_FROM_ISR(woken);
@@ -391,6 +395,7 @@ stm32_uart_ret_t stm32_uart_interrupt_handler(Stm32Uart *self) {
391395
USART_ICR(self->port) |= USART_ICR_ORECF;
392396
}
393397

398+
portYIELD_FROM_ISR(woken);
394399
return STM32_UART_RET_OK;
395400
}
396401

0 commit comments

Comments
 (0)