otError otPlatUartEnable(void) { otError error = OT_ERROR_NONE; otEXPECT_ACTION(sUartEnabled == false, error = OT_ERROR_ALREADY); // Set up TX and RX pins. nrf_gpio_pin_set(UART_PIN_TX); nrf_gpio_cfg_output(UART_PIN_TX); nrf_gpio_cfg_input(UART_PIN_RX, NRF_GPIO_PIN_NOPULL); nrf_uart_txrx_pins_set(UART_INSTANCE, UART_PIN_TX, UART_PIN_RX); #if (UART_HWFC == NRF_UART_HWFC_ENABLED) // Set up CTS and RTS pins. nrf_gpio_cfg_input(UART_PIN_CTS, NRF_GPIO_PIN_NOPULL); nrf_gpio_pin_set(UART_PIN_RTS); nrf_gpio_cfg_output(UART_PIN_RTS); nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_PIN_RTS, UART_PIN_CTS); #endif // Configure baudrate. nrf_uart_baudrate_set(UART_INSTANCE, UART_BAUDRATE); // Configure parity and hardware flow control. nrf_uart_configure(UART_INSTANCE, UART_PARITY, UART_HWFC); // Clear UART specific events. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY); nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR); nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY); // Enable interrupts for TX. nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY); // Enable interrupts for RX. nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); // Configure NVIC to handle UART interrupts. NVIC_SetPriority(UART_IRQN, UART_IRQ_PRIORITY); NVIC_ClearPendingIRQ(UART_IRQN); NVIC_EnableIRQ(UART_IRQN); // Start HFCLK nrf_drv_clock_hfclk_request(NULL); while (!nrf_drv_clock_hfclk_is_running()) { } // Enable UART instance, and start RX on it. nrf_uart_enable(UART_INSTANCE); nrf_uart_task_trigger(UART_INSTANCE, NRF_UART_TASK_STARTRX); sUartEnabled = true; exit: return error; }
static void interrupts_enable(nrfx_uart_t const * p_instance, uint8_t interrupt_priority) { nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY); nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO); nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_TXDRDY | NRF_UART_INT_MASK_RXTO); NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number((void *)p_instance->p_reg), interrupt_priority); NRFX_IRQ_ENABLE(nrfx_get_irq_number((void *)p_instance->p_reg)); }
static void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { if (!p_cb->rx_buffer_length) { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); // Byte received when buffer is not set - data lost. (void) nrf_uart_rxd_get(p_uart); return; } nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart); p_cb->rx_counter++; }
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); }
void UART0_IRQHandler(void) { if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR)) { nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); } if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY) && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) { rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_IND); } if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_TXDRDY) && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) { rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_TX_DONE); } if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO)) { rt_hw_serial_isr(working_cfg->serial, RT_SERIAL_EVENT_RX_TIMEOUT); } }
/** * @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 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(); } } }
nrfx_err_t nrfx_uart_tx(nrfx_uart_t const * p_instance, uint8_t const * p_data, size_t length) { uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); NRFX_ASSERT(p_data); NRFX_ASSERT(length > 0); nrfx_err_t err_code; if (nrfx_uart_tx_in_progress(p_instance)) { err_code = NRFX_ERROR_BUSY; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } p_cb->tx_buffer_length = length; p_cb->p_tx_buffer = p_data; p_cb->tx_counter = 0; p_cb->tx_abort = false; NRFX_LOG_INFO("Transfer tx_len: %d.", p_cb->tx_buffer_length); NRFX_LOG_DEBUG("Tx data:"); NRFX_LOG_HEXDUMP_DEBUG(p_cb->p_tx_buffer, p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer[0])); err_code = NRFX_SUCCESS; nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_TXDRDY); nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTTX); tx_byte(p_instance->p_reg, p_cb); if (p_cb->handler == NULL) { if (!tx_blocking(p_instance->p_reg, p_cb)) { // The transfer has been aborted. err_code = NRFX_ERROR_FORBIDDEN; } else { // Wait until the last byte is completely transmitted. while (!nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_TXDRDY)) {} nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPTX); } p_cb->tx_buffer_length = 0; } NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }
void nrf5UartInit(void) { // Set up TX and RX pins. nrf_gpio_pin_set(UART_PIN_TX); nrf_gpio_cfg_output(UART_PIN_TX); nrf_gpio_cfg_input(UART_PIN_RX, NRF_GPIO_PIN_NOPULL); nrf_uart_txrx_pins_set(UART_INSTANCE, UART_PIN_TX, UART_PIN_RX); #if (UART_HWFC == NRF_UART_HWFC_ENABLED) // Set up CTS and RTS pins. nrf_gpio_cfg_input(UART_PIN_CTS, NRF_GPIO_PIN_NOPULL); nrf_gpio_pin_set(UART_PIN_RTS); nrf_gpio_cfg_output(UART_PIN_RTS); nrf_uart_hwfc_pins_set(UART_INSTANCE, UART_PIN_RTS, UART_PIN_CTS); #endif // Configure baudrate. nrf_uart_baudrate_set(UART_INSTANCE, UART_BAUDRATE); // Configure parity and hardware flow control. nrf_uart_configure(UART_INSTANCE, UART_PARITY, UART_HWFC); // Clear UART specific events. nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_TXDRDY); nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_ERROR); nrf_uart_event_clear(UART_INSTANCE, NRF_UART_EVENT_RXDRDY); // Enable interrupts for TX. nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_TXDRDY); // Enable interrupts for RX. nrf_uart_int_enable(UART_INSTANCE, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); // Configure NVIC to handle UART interrupts. NVIC_SetPriority(UART_IRQN, UART_IRQ_PRIORITY); NVIC_ClearPendingIRQ(UART_IRQN); NVIC_EnableIRQ(UART_IRQN); }
static int uart_nrfx_poll_in(struct device *dev, unsigned char *c) { if (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) { return -1; } /* Clear the interrupt */ nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY); /* got a character */ *c = nrf_uart_rxd_get(NRF_UART0); return 0; }
/** 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; }
/** Interrupt driven FIFO read function */ static int uart_nrfx_fifo_read(struct device *dev, u8_t *rx_data, const int size) { u8_t num_rx = 0; while ((size - num_rx > 0) && nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) { /* Clear the interrupt */ nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY); /* Receive a character */ rx_data[num_rx++] = (u8_t)nrf_uart_rxd_get(NRF_UART0); } return num_rx; }
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; }
static int _uart_getc(struct rt_serial_device *serial) { int ch = -1; 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; } if (nrf_uart_event_check(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY)) { nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); ch = (int)(nrf_uart_rxd_get(instance->uart.reg.p_uart)); } return ch; }
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; }
nrfx_err_t nrfx_uart_rx(nrfx_uart_t const * p_instance, uint8_t * p_data, size_t length) { uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_INITIALIZED); NRFX_ASSERT(p_data); NRFX_ASSERT(length > 0); nrfx_err_t err_code; bool second_buffer = false; if (p_cb->handler) { nrf_uart_int_disable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); } if (p_cb->rx_buffer_length != 0) { if (p_cb->rx_secondary_buffer_length != 0) { if (p_cb->handler) { nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); } err_code = NRFX_ERROR_BUSY; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } second_buffer = true; } if (!second_buffer) { p_cb->rx_buffer_length = length; p_cb->p_rx_buffer = p_data; p_cb->rx_counter = 0; p_cb->rx_secondary_buffer_length = 0; } else { p_cb->p_rx_secondary_buffer = p_data; p_cb->rx_secondary_buffer_length = length; } NRFX_LOG_INFO("Transfer rx_len: %d.", length); if ((!p_cb->rx_enabled) && (!second_buffer)) { rx_enable(p_instance); } if (p_cb->handler == NULL) { nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXTO); bool rxrdy; bool rxto; bool error; do { do { error = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_ERROR); rxrdy = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXDRDY); rxto = nrf_uart_event_check(p_instance->p_reg, NRF_UART_EVENT_RXTO); } while ((!rxrdy) && (!rxto) && (!error)); if (error || rxto) { break; } rx_byte(p_instance->p_reg, p_cb); } while (p_cb->rx_buffer_length > p_cb->rx_counter); p_cb->rx_buffer_length = 0; if (error) { err_code = NRFX_ERROR_INTERNAL; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } if (rxto) { err_code = NRFX_ERROR_FORBIDDEN; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } if (p_cb->rx_enabled) { nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX); } else { // Skip stopping RX if driver is forced to be enabled. nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STOPRX); } } else { nrf_uart_int_enable(p_instance->p_reg, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); } err_code = NRFX_SUCCESS; NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }
static void rx_enable(nrfx_uart_t const * p_instance) { nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR); nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_RXDRDY); nrf_uart_task_trigger(p_instance->p_reg, NRF_UART_TASK_STARTRX); }
static rt_err_t _uart_cfg(struct rt_serial_device *serial, struct serial_configure *cfg) { nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; UART_CFG_T *instance = &uart0; RT_ASSERT(serial != RT_NULL); RT_ASSERT(cfg != RT_NULL); if (serial->parent.user_data != RT_NULL) { instance = (UART_CFG_T*)serial->parent.user_data; } nrf_uart_disable(instance->uart.reg.p_uart); switch (cfg->baud_rate) { case 115200: config.baudrate = NRF_UART_BAUDRATE_115200; break; case 9600: config.baudrate = NRF_UART_BAUDRATE_9600; break; default: config.baudrate = NRF_UART_BAUDRATE_115200; break; } if (cfg->parity == PARITY_NONE) { config.parity = NRF_UART_PARITY_EXCLUDED; } else { config.parity = NRF_UART_PARITY_INCLUDED; } config.hwfc = NRF_UART_HWFC_DISABLED; config.interrupt_priority = APP_IRQ_PRIORITY_LOWEST; config.pselcts = 0; config.pselrts = 0; config.pselrxd = instance->rx_pin; config.pseltxd = instance->tx_pin; nrf_gpio_pin_set(config.pseltxd); nrf_gpio_cfg_output(config.pseltxd); nrf_gpio_pin_clear(config.pseltxd); nrf_gpio_cfg_input(config.pselrxd, NRF_GPIO_PIN_NOPULL); nrf_uart_baudrate_set(instance->uart.reg.p_uart, config.baudrate); nrf_uart_configure(instance->uart.reg.p_uart, config.parity, config.hwfc); nrf_uart_txrx_pins_set(instance->uart.reg.p_uart, config.pseltxd, config.pselrxd); if (config.hwfc == NRF_UART_HWFC_ENABLED) { nrf_uart_hwfc_pins_set(instance->uart.reg.p_uart, config.pselrts, config.pselcts); } nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_TXDRDY); nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXTO); nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_ERROR); nrf_uart_int_enable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_RXTO | NRF_UART_INT_MASK_ERROR); nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart), config.interrupt_priority); nrf_uart_enable(instance->uart.reg.p_uart); // nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); working_cfg = instance; return RT_EOK; }
uint32_t nrfx_uart_errorsrc_get(nrfx_uart_t const * p_instance) { nrf_uart_event_clear(p_instance->p_reg, NRF_UART_EVENT_ERROR); return nrf_uart_errorsrc_get_and_clear(p_instance->p_reg); }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 on success */ static int uart_nrfx_init(struct device *dev) { struct device *gpio_dev; int err; gpio_dev = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME); __ASSERT(gpio_dev, "UART init failed. Cannot find %s", CONFIG_GPIO_NRF5_P0_DEV_NAME); /* Setting default height state of the TX PIN to avoid glitches * on the line during peripheral activation/deactivation. */ gpio_pin_write(gpio_dev, CONFIG_UART_0_NRF_TX_PIN, 1); gpio_pin_configure(gpio_dev, CONFIG_UART_0_NRF_TX_PIN, GPIO_DIR_OUT); gpio_pin_configure(gpio_dev, CONFIG_UART_0_NRF_RX_PIN, GPIO_DIR_IN); nrf_uart_txrx_pins_set(NRF_UART0, CONFIG_UART_0_NRF_TX_PIN, CONFIG_UART_0_NRF_RX_PIN); #ifdef CONFIG_UART_0_NRF_FLOW_CONTROL /* Setting default height state of the RTS PIN to avoid glitches * on the line during peripheral activation/deactivation. */ gpio_pin_write(gpio_dev, CONFIG_UART_0_NRF_RTS_PIN, 1); gpio_pin_configure(gpio_dev, CONFIG_UART_0_NRF_RTS_PIN, GPIO_DIR_OUT); gpio_pin_configure(gpio_dev, CONFIG_UART_0_NRF_CTS_PIN, GPIO_DIR_IN); nrf_uart_hwfc_pins_set(NRF_UART0, CONFIG_UART_0_NRF_RTS_PIN, CONFIG_UART_0_NRF_CTS_PIN); #endif /* CONFIG_UART_0_NRF_FLOW_CONTROL */ nrf_uart_configure(NRF_UART0, #ifdef CONFIG_UART_0_NRF_PARITY_BIT NRF_UART_PARITY_INCLUDED, #else NRF_UART_PARITY_EXCLUDED, #endif /* CONFIG_UART_0_NRF_PARITY_BIT */ #ifdef CONFIG_UART_0_NRF_FLOW_CONTROL NRF_UART_HWFC_ENABLED); #else NRF_UART_HWFC_DISABLED); #endif /* CONFIG_UART_0_NRF_PARITY_BIT */ /* Set baud rate */ err = baudrate_set(dev, CONFIG_UART_0_BAUD_RATE); if (err) { return err; } /* Enable receiver and transmitter */ nrf_uart_enable(NRF_UART0); nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY); nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTTX); nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTRX); #ifdef CONFIG_UART_INTERRUPT_DRIVEN IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_UART0), CONFIG_UART_0_IRQ_PRI, uart_nrfx_isr, DEVICE_GET(uart_nrfx_uart0), 0); irq_enable(NRFX_IRQ_NUMBER_GET(NRF_UART0)); #endif return 0; }
static void uart_irq_handler(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) && nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR)) { nrfx_uart_event_t event; nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR); NRFX_LOG_DEBUG("Event: %s.", EVT_TO_STR(NRF_UART_EVENT_ERROR)); nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); if (!p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); } event.type = NRFX_UART_EVT_ERROR; event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart); event.data.error.rxtx.bytes = p_cb->rx_buffer_length; event.data.error.rxtx.p_data = p_cb->p_rx_buffer; // Abort transfer. p_cb->rx_buffer_length = 0; p_cb->rx_secondary_buffer_length = 0; p_cb->handler(&event,p_cb->p_context); } else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) && nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY)) { rx_byte(p_uart, p_cb); if (p_cb->rx_buffer_length == p_cb->rx_counter) { if (p_cb->rx_secondary_buffer_length) { uint8_t * p_data = p_cb->p_rx_buffer; size_t rx_counter = p_cb->rx_counter; // Switch to secondary buffer. p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; p_cb->rx_secondary_buffer_length = 0; p_cb->rx_counter = 0; rx_done_event(p_cb, rx_counter, p_data); } else { if (!p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); } nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); p_cb->rx_buffer_length = 0; rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } } } if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY)) { if (p_cb->tx_counter < p_cb->tx_buffer_length && !p_cb->tx_abort) { tx_byte(p_uart, p_cb); } else { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); if (p_cb->tx_buffer_length) { tx_done_event(p_cb, p_cb->tx_buffer_length); } } } if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO)) { nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO); // RXTO event may be triggered as a result of abort call. In th if (p_cb->rx_enabled) { nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX); } if (p_cb->rx_buffer_length) { p_cb->rx_buffer_length = 0; rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } } }
static rt_err_t _uart_ctrl(struct rt_serial_device *serial, int cmd, void *arg) { 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; } switch (cmd) { /* disable interrupt */ case RT_DEVICE_CTRL_CLR_INT: nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STOPRX); nrf_uart_int_disable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_RXTO | NRF_UART_INT_MASK_ERROR); nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart)); break; /* enable interrupt */ case RT_DEVICE_CTRL_SET_INT: nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXDRDY); nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_RXTO); nrf_uart_event_clear(instance->uart.reg.p_uart, NRF_UART_EVENT_ERROR); /* Enable RX interrupt. */ nrf_uart_int_enable(instance->uart.reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_RXTO | NRF_UART_INT_MASK_ERROR); nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)instance->uart.reg.p_uart), APP_IRQ_PRIORITY_LOWEST); nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); break; case RT_DEVICE_CTRL_CUSTOM: if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_9600) { instance->serial->config.baud_rate = 9600; nrf_uart_baudrate_set(instance->uart.reg.p_uart, NRF_UART_BAUDRATE_9600); } else if ((rt_uint32_t)(arg) == UART_CONFIG_BAUD_RATE_115200) { instance->serial->config.baud_rate = 115200; nrf_uart_baudrate_set(instance->uart.reg.p_uart, NRF_UART_BAUDRATE_115200); } // _uart_cfg(instance->serial, &(instance->serial->config)); // nrf_uart_task_trigger(instance->uart.reg.p_uart, NRF_UART_TASK_STARTRX); break; case RT_DEVICE_CTRL_PIN: if (working_cfg != instance) { _uart_cfg(instance->serial, &(instance->serial->config)); } break; case RT_DEVICE_POWERSAVE: nrf_uart_disable(instance->uart.reg.p_uart); nrf_uart_txrx_pins_disconnect(instance->uart.reg.p_uart); nrf_gpio_pin_clear(instance->rx_pin); nrf_gpio_cfg_output(instance->rx_pin); nrf_gpio_pin_clear(instance->tx_pin); nrf_gpio_cfg_output(instance->tx_pin); break; case RT_DEVICE_WAKEUP: _uart_cfg(instance->serial, &(instance->serial->config)); break; default: return RT_ERROR; } return RT_EOK; }