Skip to content

Commit 41824de

Browse files
committed
Merge pull request #1047 from marcuschangarm/master
Fixed interrupt handler in serial_api.c for the Nordic NRF51
2 parents f14d0a9 + e34e16d commit 41824de

File tree

1 file changed

+30
-11
lines changed
  • libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822

1 file changed

+30
-11
lines changed

libraries/mbed/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
7676
obj->uart->TXD = 0;
7777

7878
obj->index = 0;
79-
79+
8080
obj->uart->PSELRTS = RTS_PIN_NUMBER;
8181
obj->uart->PSELTXD = tx; //TX_PIN_NUMBER;
8282
obj->uart->PSELCTS = CTS_PIN_NUMBER;
@@ -162,14 +162,20 @@ extern "C" {
162162
#endif
163163
void UART0_IRQHandler()
164164
{
165-
uint32_t irtype = 0;
166-
167-
if((NRF_UART0->INTENSET & 0x80) && NRF_UART0->EVENTS_TXDRDY) {
168-
irtype = 1;
169-
} else if((NRF_UART0->INTENSET & 0x04) && NRF_UART0->EVENTS_RXDRDY) {
170-
irtype = 2;
165+
if((NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk) && NRF_UART0->EVENTS_TXDRDY)
166+
{
167+
uart_irq(1, 0);
168+
169+
/* Explicitly clear TX flag to prevent interrupt from firing
170+
immediately after returning from ISR. This ensures that the
171+
last interrupt in a transmission sequence is correcly handled.
172+
*/
173+
NRF_UART0->EVENTS_TXDRDY = 0;
174+
}
175+
else if((NRF_UART0->INTENSET & UART_INTENSET_RXDRDY_Msk) && NRF_UART0->EVENTS_RXDRDY)
176+
{
177+
uart_irq(2, 0);
171178
}
172-
uart_irq(irtype, 0);
173179
}
174180

175181
#ifdef __cplusplus
@@ -239,11 +245,24 @@ int serial_getc(serial_t *obj)
239245

240246
void serial_putc(serial_t *obj, int c)
241247
{
242-
while (!serial_writable(obj)) {
248+
/* In interrupt mode, send character immediately. Otherwise, block until
249+
UART is ready to receive next character before sending.
250+
251+
The TXDRDY flag is cleared in interrupt handler to ensure that it is
252+
cleared even if there are no more characters to send.
253+
*/
254+
if (NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk)
255+
{
256+
obj->uart->TXD = (uint8_t)c;
243257
}
258+
else
259+
{
260+
while (!serial_writable(obj)) {
261+
}
244262

245-
obj->uart->EVENTS_TXDRDY = 0;
246-
obj->uart->TXD = (uint8_t)c;
263+
obj->uart->EVENTS_TXDRDY = 0;
264+
obj->uart->TXD = (uint8_t)c;
265+
}
247266
}
248267

249268
int serial_readable(serial_t *obj)

0 commit comments

Comments
 (0)