Skip to content

Commit 9dbb03b

Browse files
ppescherfpistm
authored andcommitted
[UART] Fix serial port full-duplex bug
When a receive IT fires while the HAL handle is locked, the receive callback fails to re-enable the IT and the serial port stops receiving anymore. This can happen when transmit IT is enabled outside the IRQ in HardwareSerial::write(), following a buffer full condition that disables transmit IT in HAL_UART_TxCpltCallback(). Solution is to temporarily disable the IRQ while the interrupt enable flags are modified.
1 parent b1fec1a commit 9dbb03b

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

cores/arduino/stm32/uart.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -685,12 +685,14 @@ void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t *))
685685
rx_callback[obj->index] = callback;
686686
rx_callback_obj[obj->index] = obj;
687687

688+
/* Must disable interrupt to prevent handle lock contention */
689+
HAL_NVIC_DisableIRQ(obj->irq);
690+
691+
HAL_UART_Receive_IT(uart_handlers[obj->index], &(obj->recv), 1);
692+
693+
/* Enable interrupt */
688694
HAL_NVIC_SetPriority(obj->irq, 0, 1);
689695
HAL_NVIC_EnableIRQ(obj->irq);
690-
691-
if (HAL_UART_Receive_IT(uart_handlers[obj->index], &(obj->recv), 1) != HAL_OK) {
692-
return;
693-
}
694696
}
695697

696698
/**
@@ -709,14 +711,15 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))
709711
tx_callback[obj->index] = callback;
710712
tx_callback_obj[obj->index] = obj;
711713

714+
/* Must disable interrupt to prevent handle lock contention */
715+
HAL_NVIC_DisableIRQ(obj->irq);
716+
717+
/* The following function will enable UART_IT_TXE and error interrupts */
718+
HAL_UART_Transmit_IT(uart_handlers[obj->index], &obj->tx_buff[obj->tx_tail], 1);
719+
712720
/* Enable interrupt */
713721
HAL_NVIC_SetPriority(obj->irq, 0, 2);
714722
HAL_NVIC_EnableIRQ(obj->irq);
715-
716-
/* The following function will enable UART_IT_TXE and error interrupts */
717-
if (HAL_UART_Transmit_IT(uart_handlers[obj->index], &obj->tx_buff[obj->tx_tail], 1) != HAL_OK) {
718-
return;
719-
}
720723
}
721724

722725
/**

0 commit comments

Comments
 (0)