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

NRF UART RX done event only fires once

I'm trying to communicate between two devices (nrf52840 and teensy 3.6) over RS485, but I'm having some issues using the UART library in the SDK. I'm trying to create an interrupt-based response to a packet received over the 485 line, so I've taken the example found under Nordic\examples\peripheral\serial\ and created my own event handler to respond to RX events. 

#define OP_QUEUES_SIZE          3
#define APP_TIMER_PRESCALER     NRF_SERIAL_APP_TIMER_PRESCALER

#define RS485_EN                ARDUINO_2_PIN
#define RS485_TX                ARDUINO_1_PIN
#define RS485_RX                ARDUINO_0_PIN

static void rs485_evt_handler(nrf_serial_t const * p_serial,
                              nrf_serial_event_t event)
{
    uint32_t ret = 0;
    uint8_t rxbyte;
    switch(event)
    {
        case NRF_SERIAL_EVENT_RX_DATA:
        {
            printf("RX event!\n");
            break;
        }
        case NRF_SERIAL_EVENT_TX_DONE:
        {
            break;
        }
        default:
        {
            printf("UART EVENT - %#010x\n", nrf_drv_uart_errorsrc_get(&p_serial->instance));
            break;
        }
    }
}
 
static void sleep_handler(void)
{
    __WFE();
    __SEV();
    __WFE();
}

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart0_drv_config,
                      RS485_RX, RS485_TX,
                      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 255

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_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ,
                      &serial_queues, &serial_buffs, rs485_evt_handler, sleep_handler);

NRF_SERIAL_UART_DEF(serial_uart, 0);

int main(void)
{
    ret_code_t ret;

    ret = nrf_drv_clock_init();
    APP_ERROR_CHECK(ret);
    ret = nrf_drv_power_init(NULL);
    APP_ERROR_CHECK(ret);

    nrf_drv_clock_lfclk_request(NULL);
    ret = app_timer_init();
    APP_ERROR_CHECK(ret);

    // Initialize LEDs and buttons.
    bsp_board_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS);

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

//    static char tx_message[] = "Hello nrf_serial!\n\r";
//
//    ret = nrf_serial_write(&serial_uart,
//                           tx_message,
//                           strlen(tx_message),
//                           NULL,
//                           NRF_SERIAL_MAX_TIMEOUT);
//    APP_ERROR_CHECK(ret);
    
    printf("UART ERROR OVERRUN - %#10x\n", NRF_UART_ERROR_OVERRUN_MASK);
    printf("UART ERROR BREAK - %#10x\n", NRF_UART_ERROR_BREAK_MASK);
    printf("UART ERROR FRAMING - %#10x\n", NRF_UART_ERROR_FRAMING_MASK);
    printf("UART ERROR PARITY - %#10x\n", NRF_UART_ERROR_PARITY_MASK);

    while (true)
    {
//        char c;
//        ret = nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 1000);
//        if (ret != NRF_SUCCESS)
//        {
//            continue;
//        }
//        (void)nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);
//        (void)nrf_serial_flush(&serial_uart, 0);
        bsp_board_led_invert(0);
        nrf_delay_ms(1000);
        printf("UART Ready? %d\n", nrf_drv_uart_rx_ready(&serial_uart.instance));
    }
}

/** @} */

I'm toggling an activity LED and I've added some prints and comments just for debugging. I've defined SERIAL_BUFF_RX_SIZE to 1, so that the event should fire on every byte received and I made sure to pass my custom event handler to NRF_SERIAL_CONFIG_DEF. Baud rate is set to 9600 and the UART is in IRQ mode.

The problem is that the NRF_SERIAL_EVENT_RX_DATA only fires once, and then the UART appears to lock up and the event doesn't fire again unless I restart the device. I've searched through the UART source files to see why this might be happening, but I can't find anything. My guess is that the RX buffer is overflowing/overrunning, but to be honest the documentation on this module is quite light so I thought I'd post on here to see if anyone could help.

Thanks!

Parents Reply Children
No Data
Related