Skip to content

Commit bb98ce0

Browse files
Marcus Changc1728p9
authored andcommitted
Make serial_putc for NRF52 non-blocking
Busy-wait before sending a charecter instead of after. If serial_writeable has been called first, the busy-wait loop will be skipped. Added initialization code to ensure NRF_UARTE_EVENT_TXDRDY is armed correctly.
1 parent 4cda158 commit bb98ce0

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

targets/TARGET_NORDIC/TARGET_NRF5x/TARGET_NRF52/serial_api.c

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,37 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
10851085
if (nordic_nrf5_uart_state[instance].usage_counter == 1) {
10861086

10871087
nrf_uarte_enable(nordic_nrf5_uart_register[instance]);
1088+
1089+
/* In order to support printing with interrupts disabled serial_putc
1090+
* must busy wait on NRF_UARTE_EVENT_TXDRDY. This event cannot be set
1091+
* manually but must be set by the UARTE module after a character has
1092+
* been sent.
1093+
*
1094+
* The following code sends a dummy character into the void so that
1095+
* NRF_UARTE_EVENT_TXDRDY is correctly set.
1096+
*/
1097+
1098+
/* Ensure pins are disconnected. */
1099+
nrf_uarte_txrx_pins_set(nordic_nrf5_uart_register[instance],
1100+
NRF_UART_PSEL_DISCONNECTED,
1101+
NRF_UART_PSEL_DISCONNECTED);
1102+
1103+
/* Set maximum baud rate to minimize waiting. */
1104+
nrf_uarte_baudrate_set(nordic_nrf5_uart_register[instance],
1105+
NRF_UARTE_BAUDRATE_1000000);
1106+
1107+
/* Send character. */
1108+
nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[instance],
1109+
&nordic_nrf5_uart_state[instance].tx_data,
1110+
1);
1111+
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
1112+
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);
1113+
1114+
/* Wait until NRF_UARTE_EVENT_TXDRDY is set before proceeding. */
1115+
bool done = false;
1116+
do {
1117+
done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
1118+
} while(done == false);
10881119
}
10891120

10901121
/* Store pins in serial object. */
@@ -1488,19 +1519,26 @@ void serial_putc(serial_t *obj, int character)
14881519
int instance = uart_object->instance;
14891520

14901521
nordic_nrf5_serial_configure(obj);
1522+
1523+
/* Wait until UART is ready to send next character. */
1524+
do {
1525+
done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
1526+
} while(done == false);
1527+
1528+
nrf_uarte_event_extra_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
1529+
14911530
/* Arm Tx DMA buffer. */
14921531
nordic_nrf5_uart_state[instance].tx_data = character;
14931532
nrf_uarte_tx_buffer_set(nordic_nrf5_uart_register[instance],
14941533
&nordic_nrf5_uart_state[instance].tx_data,
14951534
1);
1496-
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
1497-
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);
14981535

1499-
do {
1500-
done = nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
1501-
} while(done == false);
1536+
/* Clear Tx event and enable Tx interrupts. */
1537+
nrf_uarte_event_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_ENDTX);
1538+
nrf_uarte_int_enable(nordic_nrf5_uart_register[instance], NRF_UARTE_INT_ENDTX_MASK);
15021539

1503-
nrf_uarte_event_extra_clear(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY);
1540+
/* Start transfer. */
1541+
nrf_uarte_task_trigger(nordic_nrf5_uart_register[instance], NRF_UARTE_TASK_STARTTX);
15041542
}
15051543

15061544
/** Check if the serial peripheral is readable
@@ -1549,7 +1587,8 @@ int serial_writable(serial_t *obj)
15491587

15501588
int instance = uart_object->instance;
15511589

1552-
return (nordic_nrf5_uart_state[instance].tx_in_progress == 0);
1590+
return ((nordic_nrf5_uart_state[instance].tx_in_progress == 0) &&
1591+
(nrf_uarte_event_extra_check(nordic_nrf5_uart_register[instance], NRF_UARTE_EVENT_TXDRDY)));
15531592
}
15541593

15551594
/***

0 commit comments

Comments
 (0)