This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF_SERIAL_EVENT_RX_DATA never triggered

With SDK 14.2.0 and S332 softdevice, I'm using UART to control ESP8266 WiFi module with AT commands and I'd like to replace app_uart (+FIFO) with nrf_serial, in order to get better control over UART communication. My UART connection uses 115200 baudrate with flow control enabled, and it worked fine with app_uart.

With nrf_serial, I wanted to configure it the similar way, i.e. with DMA and using event handler to retrieve data. I'm however not receiving NRF_SERIAL_EVENT_RX_DATA event at all. Numerous NRF_SERIAL_EVENT_DRV_ERR events are generated instead, and I investigated the error flags to find out that it's either due to framing error (which is expected and non-critical) or overrun.

I tried various solutions to deal with overrun error, including extending the RX buffer and FIFO or adjusting UART IRQ priority, but that didn't help. I ended up reducing the baudrate to 38400 and the overrun error is gone, but I'm still not receiving RX_DATA events. My TX data seems to be transferred just fine, at least according to the p_written parameter returned from nrf_serial_write (I'm also getting NRF_SERIAL_EVENT_TX_DONE events).

Am I missing something obvious here? Thanks in advance for your help.

FWIW, my configuration is pretty straightforward, based on the minimal SDK example:

static void sleep_handler(void)
{
    __WFE();
    __SEV();
    __WFE();
}

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
                      RX_PIN_NUMBER, TX_PIN_NUMBER,
                      RTS_PIN_NUMBER, CTS_PIN_NUMBER,
                      NRF_UART_HWFC_ENABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_38400,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);

#define SERIAL_FIFO_TX_SIZE 256
#define SERIAL_FIFO_RX_SIZE 256
NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);

#define SERIAL_BUFF_TX_SIZE 32
#define SERIAL_BUFF_RX_SIZE 1
NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);

NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_DMA,
                      &serial_queues, &serial_buffs, on_serial_event, sleep_handler);

NRF_SERIAL_UART_DEF(serial_uart, 0);

Parents
  • Hi Dkap,

    Can you try debugging the application, set a breakpoint inside the NRF_DRV_UART_EVT_ERROR case in uart_event_handler (line 161 in nrf_serial.c), and check what the error_mask is set to (p_event->data.error.error_mask)?

    I think you can avoid this framing error by enabling the internal pull-up on the RX pin after you've initialized the serial module. 

    ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
    APP_ERROR_CHECK(ret);

    NRF_P0->PIN_CNF[RX_PIN_NUMBER] |= GPIO_PIN_CNF_PULL_Msk;  // Overrides the no-pull configuration set by the UARTE drivers.   

    Handling of error conditions are typically application dependent, and is the reason why error events are forwarded to the user callback.

    That said, I think it should be possible to recover (enable Rx) without having to re-initialize the driver

Reply
  • Hi Dkap,

    Can you try debugging the application, set a breakpoint inside the NRF_DRV_UART_EVT_ERROR case in uart_event_handler (line 161 in nrf_serial.c), and check what the error_mask is set to (p_event->data.error.error_mask)?

    I think you can avoid this framing error by enabling the internal pull-up on the RX pin after you've initialized the serial module. 

    ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
    APP_ERROR_CHECK(ret);

    NRF_P0->PIN_CNF[RX_PIN_NUMBER] |= GPIO_PIN_CNF_PULL_Msk;  // Overrides the no-pull configuration set by the UARTE drivers.   

    Handling of error conditions are typically application dependent, and is the reason why error events are forwarded to the user callback.

    That said, I think it should be possible to recover (enable Rx) without having to re-initialize the driver

Children
  • Hi Martin,

    thanks for your help and suggestions but I wasn't really asking about framing errors, that I observed also with app_uart and I could live with it. The RX pin pull-up didn't make a difference either.

    Anyways, I managed to get the nrf_serial working just by reducing the amount of code in the interrupt handler. It appears that what worked well with app_uart, won't necessarily work with nrf_serial. So I stripped down the interrupt handler to just raising a flag that I handle in the event loop, and it works great now.

    Thank you.

Related