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

Serial port interrupt

I have a serial port set upp with the serial port library like this:

#define UART_PIN_DISCONNECTED           0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
#define RX_PIN_NUMBER                   7
#define TX_PIN_NUMBER                   8
#define CTS_PIN_NUMBER                  UART_PIN_DISCONNECTED
#define RTS_PIN_NUMBER                  UART_PIN_DISCONNECTED
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_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_9600,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);

#define SERIAL_FIFO_TX_SIZE 32
#define SERIAL_FIFO_RX_SIZE 32

NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);


#define SERIAL_BUFF_TX_SIZE 1
#define SERIAL_BUFF_RX_SIZE 1

NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);

NRF_SERIAL_UART_DEF(serial_uart, 0);
NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ,
                      &serial_queues, &serial_buffs, on_serial_evt, sleep_handler);

and in main:

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

In on_serial_evt i have the following code:

case NRF_SERIAL_EVENT_RX_DATA:
        err_code = app_sched_event_put(NULL, NULL, on_serial_evt_handler);
        APP_ERROR_CHECK(err_code);
        NRF_LOG_INFO("NRF_SERIAL_EVENT_RX_DATA\r\n");

And finally in on_serial_evt_handler:

static void on_serial_evt_handler()
{
    NRF_LOG_INFO("handler\r\n")
    ret_code_t err_code;
    uint8_t c[26];
    memset(c, 0, sizeof(c));
    size_t p_read;
    err_code = nrf_serial_read(&serial_uart, c, sizeof(c), &p_read, 3000);
    NRF_LOG_INFO("p_read:%d\r\n", p_read);
    NRF_LOG_INFO("c[0]:%c\r\n", c[0]);
    NRF_LOG_INFO("error%d\r\n", err_code);

When I start the app everything works as expected with nothing happening. Then I send 1 byte of data to the mcu and the NRF_SERIAL_EVENT_RX_DATA event gets triggered. I can then read the data as expected. Now the problem is that the nrf_serial_read seems to trigger another NRF_SERIAL_EVENT_RX_DATA event. This results in a infinite loop of 0's recieved and the . No matter if i set the timeout of nrf_serial_read to 0 it still always returns NRF_ERROR_TIMEOUT.

I understand the need for triggering NRF_SERIAL_EVENT_RX_DATA if i use none blocking mode but then how can i tell the difference between "new data in buffer" and "data fetched by nrf_serial_read ready"?

I use a nRF52832_xxaa with sdk 13 and S132 4.0.2.

Thankful for any pointers!

Parents
  • I think if the rx and tx queues are defined for the port instance they will not empty if you read the buffers directly. It is better to read from the port receive queue.

    In this test code I use nrf_queue_read to read from the p_rxq queue instance echoing it back to the sender:

    static void serial_event_handler(struct nrf_serial_s const * p_serial,
    nrf_serial_event_t event) 
    {
        switch (event)
    	{
    	case NRF_SERIAL_EVENT_TX_DONE:
    	    break;
    	case NRF_SERIAL_EVENT_RX_DATA:
    	    ret_code_t ret;
    	    char c;
    	    //Read one char from queue
    	    ret = nrf_queue_read(p_serial->p_ctx->p_config->p_queues->p_rxq, &c, sizeof(c));
    	    //Echo char back to port
    	    (void)nrf_serial_write(p_serial, &c, sizeof(c), NULL, 0);
    	    break;
    	case NRF_SERIAL_EVENT_DRV_ERR:
    	    break;
    	case NRF_SERIAL_EVENT_FIFO_ERR:
    	    break;
    	default:
    	    break;
    	}
    	
    }
    

    Maybe formally the queue should be read until empty but I blindly assume the event fires for each character received

Reply
  • I think if the rx and tx queues are defined for the port instance they will not empty if you read the buffers directly. It is better to read from the port receive queue.

    In this test code I use nrf_queue_read to read from the p_rxq queue instance echoing it back to the sender:

    static void serial_event_handler(struct nrf_serial_s const * p_serial,
    nrf_serial_event_t event) 
    {
        switch (event)
    	{
    	case NRF_SERIAL_EVENT_TX_DONE:
    	    break;
    	case NRF_SERIAL_EVENT_RX_DATA:
    	    ret_code_t ret;
    	    char c;
    	    //Read one char from queue
    	    ret = nrf_queue_read(p_serial->p_ctx->p_config->p_queues->p_rxq, &c, sizeof(c));
    	    //Echo char back to port
    	    (void)nrf_serial_write(p_serial, &c, sizeof(c), NULL, 0);
    	    break;
    	case NRF_SERIAL_EVENT_DRV_ERR:
    	    break;
    	case NRF_SERIAL_EVENT_FIFO_ERR:
    	    break;
    	default:
    	    break;
    	}
    	
    }
    

    Maybe formally the queue should be read until empty but I blindly assume the event fires for each character received

Children
Related