Skip to content

Commit 7ef9fa9

Browse files
ppescherbenwaffle
authored andcommitted
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 0b81b96 commit 7ef9fa9

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
@@ -686,12 +686,14 @@ void uart_attach_rx_callback(serial_t *obj, void (*callback)(serial_t *))
686686
rx_callback[obj->index] = callback;
687687
rx_callback_obj[obj->index] = obj;
688688

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

697699
/**
@@ -710,14 +712,15 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))
710712
tx_callback[obj->index] = callback;
711713
tx_callback_obj[obj->index] = obj;
712714

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

723726
/**

0 commit comments

Comments
 (0)