static void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter]; p_cb->tx_counter++; nrf_uart_txd_set(p_uart, txd); }
/** * @brief Output a character in polled mode. * * @param dev UART device struct * @param c Character to send * * @return Sent character */ static unsigned char uart_nrfx_poll_out(struct device *dev, unsigned char c) { /* The UART API dictates that poll_out should wait for the transmitter * to be empty before sending a character. However, without locking, * this introduces a rare yet possible race condition if the thread is * preempted between sending the byte and checking for completion. * Because of this race condition, the while loop has to be placed * after the write to TXD, and we can't wait for an empty transmitter * before writing. This is a trade-off between losing a byte once in a * blue moon against hanging up the whole thread permanently */ /* reset transmitter ready state */ nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); /* send a character */ nrf_uart_txd_set(NRF_UART0, (u8_t)c); /* Wait for transmitter to be ready */ while (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) { } return c; }
/** Interrupt driven FIFO fill function */ static int uart_nrfx_fifo_fill(struct device *dev, const u8_t *tx_data, int len) { u8_t num_tx = 0; while ((len - num_tx > 0) && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) { /* Clear the interrupt */ nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); /* Send a character */ nrf_uart_txd_set(NRF_UART0, (u8_t)tx_data[num_tx++]); } return (int)num_tx; }
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength) { otError error = OT_ERROR_NONE; otEXPECT_ACTION(sTransmitBuffer == NULL, error = OT_ERROR_BUSY); // Set up transmit buffer and its size without counting first triggered byte. sTransmitBuffer = aBuf; sTransmitLength = aBufLength - 1; // Initiate Transmission process. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY); nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++); nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTTX); exit: return error; }
/** * Interrupt handler of UART0 peripherial. */ void UARTE0_UART0_IRQHandler(void) { // Check if any error has been detected. if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_ERROR)) { // Clear error event and ignore erronous byte in RXD register. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR); nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY); } else if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_RXDRDY)) { // Clear RXDRDY event. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY); // Read byte from the UART buffer. uint8_t byte = nrf_uart_rxd_get(UART_INSTANCE); if (!isRxBufferFull()) { sReceiveBuffer[sReceiveHead] = byte; sReceiveHead = (sReceiveHead + 1) % UART_RX_BUFFER_SIZE; otSysEventSignalPending(); } } if (nrf_uart_event_check(UART_INSTANCE, NRF_UART_EVENT_TXDRDY)) { // Clear TXDRDY event. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY); // Send any more bytes if available or call application about TX done. if (sTransmitLength) { nrf_uart_txd_set(UART_INSTANCE, *sTransmitBuffer++); sTransmitLength--; } else { sTransmitDone = true; nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STOPTX); otSysEventSignalPending(); } } }
static int _uart_putc(struct rt_serial_device *serial, char c) { UART_CFG_T *instance = working_cfg; RT_ASSERT(serial != RT_NULL); if (serial->parent.user_data != RT_NULL) { instance = (UART_CFG_T*)serial->parent.user_data; } nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY); nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTTX); nrf_uart_txd_set(instance->uart.reg.p_uart, (uint8_t)c); while (!nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY)) { } return 1; }