static int uarte_instance_init(struct device *dev, const struct uarte_init_config *config, u8_t interrupts_active) { int err; NRF_UARTE_Type *uarte = get_uarte_instance(dev); struct uarte_nrfx_data *data = get_dev_data(dev); nrf_gpio_pin_write(config->pseltxd, 1); nrf_gpio_cfg_output(config->pseltxd); nrf_gpio_cfg_input(config->pselrxd, NRF_GPIO_PIN_NOPULL); nrf_uarte_txrx_pins_set(uarte, config->pseltxd, config->pselrxd); if (config->hwfc == NRF_UARTE_HWFC_ENABLED) { nrf_gpio_pin_write(config->pselrts, 1); nrf_gpio_cfg_output(config->pselrts); nrf_gpio_cfg_input(config->pselcts, NRF_GPIO_PIN_NOPULL); nrf_uarte_hwfc_pins_set(uarte, config->pselrts, config->pselcts); } /* Configure flow control and parity checking */ nrf_uarte_configure(uarte, config->parity, config->hwfc); err = baudrate_set(dev, config->baudrate); if (err) { return err; } /* Enable receiver and transmitter */ nrf_uarte_enable(uarte); nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX); nrf_uarte_rx_buffer_set(uarte, &data->rx_data, 1); nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTRX); #if UARTE_INTERRUPT_DRIVEN if (interrupts_active) { /* Set ENDTX event by requesting fake (zero-length) transfer. * Pointer to RAM variable (data->tx_buffer) is set because * otherwise such operation may result in HardFault or RAM * corruption. */ nrf_uarte_tx_buffer_set(uarte, data->tx_buffer, 0); nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTTX); /* switch off transmitter to save an energy */ nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STOPTX); } #endif /* UARTE_INTERRUPT_DRIVEN */ return 0; }
nrfx_err_t nrfx_uarte_rx(nrfx_uarte_t const * p_instance, uint8_t * p_data, size_t length) { uarte_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_ASSERT(UARTE_LENGTH_VALIDATE(p_instance->drv_inst_idx, length)); nrfx_err_t err_code; // EasyDMA requires that transfer buffers are placed in DataRAM, // signal error if the are not. if (!nrfx_is_in_ram(p_data)) { err_code = NRFX_ERROR_INVALID_ADDR; NRFX_LOG_WARNING("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; } bool second_buffer = false; if (p_cb->handler) { nrf_uarte_int_disable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); } if (p_cb->rx_buffer_length != 0) { if (p_cb->rx_secondary_buffer_length != 0) { if (p_cb->handler) { nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); } 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_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); err_code = NRFX_SUCCESS; nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX); nrf_uarte_event_clear(p_instance->p_reg, NRF_UARTE_EVENT_RXTO); nrf_uarte_rx_buffer_set(p_instance->p_reg, p_data, length); if (!second_buffer) { nrf_uarte_task_trigger(p_instance->p_reg, NRF_UARTE_TASK_STARTRX); } else { nrf_uarte_shorts_enable(p_instance->p_reg, NRF_UARTE_SHORT_ENDRX_STARTRX); } if (m_cb[p_instance->drv_inst_idx].handler == NULL) { bool endrx; bool rxto; bool error; do { endrx = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ENDRX); rxto = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_RXTO); error = nrf_uarte_event_check(p_instance->p_reg, NRF_UARTE_EVENT_ERROR); } while ((!endrx) && (!rxto) && (!error)); m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0; if (error) { err_code = NRFX_ERROR_INTERNAL; } if (rxto) { err_code = NRFX_ERROR_FORBIDDEN; } } else { nrf_uarte_int_enable(p_instance->p_reg, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); } NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); return err_code; }