@@ -1085,6 +1085,37 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
1085
1085
if (nordic_nrf5_uart_state [instance ].usage_counter == 1 ) {
1086
1086
1087
1087
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);
1088
1119
}
1089
1120
1090
1121
/* Store pins in serial object. */
@@ -1488,19 +1519,26 @@ void serial_putc(serial_t *obj, int character)
1488
1519
int instance = uart_object -> instance ;
1489
1520
1490
1521
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
+
1491
1530
/* Arm Tx DMA buffer. */
1492
1531
nordic_nrf5_uart_state [instance ].tx_data = character ;
1493
1532
nrf_uarte_tx_buffer_set (nordic_nrf5_uart_register [instance ],
1494
1533
& nordic_nrf5_uart_state [instance ].tx_data ,
1495
1534
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 );
1498
1535
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 );
1502
1539
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 );
1504
1542
}
1505
1543
1506
1544
/** Check if the serial peripheral is readable
@@ -1549,7 +1587,8 @@ int serial_writable(serial_t *obj)
1549
1587
1550
1588
int instance = uart_object -> instance ;
1551
1589
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 )));
1553
1592
}
1554
1593
1555
1594
/***
0 commit comments