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

serial_uartes example RX interrupt never fires

Hi there,

I am using nRF5_SDK 16 with PCA10056 and Fanstel EV-BT840-V4. I am testing my example with BT-840 module as we will use it for our final product.

First i tried the peripheral uart example and it works perfectly as expected but i prefer to use 2 UARTS if possible.

Now i am trying serial_uartes example, i can TX on both ports(both are connected to PC terminals) and then i do receive NRF_SERIAL_EVENT_TX_DONE event.

But RX interrupt is never fired without a call to nrf_serial_read(), i was expecting in interrupt mode RX interrupt should be fired as soon byte is received without a read call.

Is it possible to get RX interrupts without read call ?

Here are my changes in main.c, i only pasted the changes here. Full main.c is attached.

...

//UART 0 on 
#define RX_PIN_NUMBER_0  26   //8
#define TX_PIN_NUMBER_0  27  // 6
#define CTS_PIN_NUMBER_0 0 //7
#define RTS_PIN_NUMBER_0 0   //5

//UART 1 on 
#define RX_PIN_NUMBER_1  02   //8
#define TX_PIN_NUMBER_1  03  // 6
#define CTS_PIN_NUMBER_1 0 //7
#define RTS_PIN_NUMBER_1 0   //5

....

static void serial_event_handler(nrf_serial_t const * p_serial,nrf_serial_event_t event)
{
  if(event == NRF_SERIAL_EVENT_FIFO_ERR)
  {
    printf("\nNRF_SERIAL_EVENT_FIFO_ERR  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_DRV_ERR)
  {
    printf("\nNRF_SERIAL_EVENT_DRV_ERR  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_TX_DONE)
  {
    printf("\nNRF_SERIAL_EVENT_TX_DONE  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_RX_DATA)
  {
    printf("\nNRF_SERIAL_EVENT_RX_DATA  on serial id = %d\n",p_serial->instance);
  }

}


...

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte0_drv_config,
                      RX_PIN_NUMBER_0, TX_PIN_NUMBER_0,
                      RTS_PIN_NUMBER_0, CTS_PIN_NUMBER_0,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte1_drv_config,
                      RX_PIN_NUMBER_1, TX_PIN_NUMBER_1,
                      RTS_PIN_NUMBER_1, CTS_PIN_NUMBER_1,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);
                      

...

NRF_SERIAL_CONFIG_DEF(serial0_config, NRF_SERIAL_MODE_DMA,&serial0_queues, &serial0_buffs, serial_event_handler, sleep_handler);
NRF_SERIAL_CONFIG_DEF(serial1_config, NRF_SERIAL_MODE_DMA,&serial1_queues, &serial1_buffs, serial_event_handler, sleep_handler);

...

in main()

static char tx_message0[] = "Hello nrf_serial port = 0!\n\r";
static char tx_message1[] = "Hello nrf_serial port = 1!\n\r";

    ret = nrf_serial_write(&serial0_uarte,
                           tx_message0,
                           strlen(tx_message0),
                           NULL,
                           NRF_SERIAL_MAX_TIMEOUT);
    (void)nrf_serial_flush(&serial0_uarte, 0);
    
    ret = nrf_serial_write(&serial1_uarte,
                           tx_message1,
                           strlen(tx_message1),
                           NULL,
                           NRF_SERIAL_MAX_TIMEOUT);
    (void)nrf_serial_flush(&serial1_uarte, 0);

    while (true)
    {}
                      

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

#include "nrf.h"
#include "nrf_drv_clock.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_drv_power.h"
#include "nrf_serial.h"
#include "app_timer.h"


#include "app_error.h"
#include "app_util.h"
#include "boards.h"


//UART 0 on 
#define RX_PIN_NUMBER_0  26   //8
#define TX_PIN_NUMBER_0  27  // 6
#define CTS_PIN_NUMBER_0 0 //7
#define RTS_PIN_NUMBER_0 0   //5

//UART 1 on 
#define RX_PIN_NUMBER_1  02   //8
#define TX_PIN_NUMBER_1  03  // 6
#define CTS_PIN_NUMBER_1 0 //7
#define RTS_PIN_NUMBER_1 0   //5


/** @file
 * @defgroup nrf_serial_uartes_example main.c
 * @{
 * @ingroup nrf_serial_uartes_example
 * @brief Example of @ref nrf_serial usage. Loopback example using two UARTE peripherals.
 *        Please short Arduino SCL and SDA GPIOs to start transmission.
 *
 */

#define OP_QUEUES_SIZE          3
#define APP_TIMER_PRESCALER     NRF_SERIAL_APP_TIMER_PRESCALER

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

static void serial_event_handler(nrf_serial_t const * p_serial,nrf_serial_event_t event)
{
  if(event == NRF_SERIAL_EVENT_FIFO_ERR)
  {
    printf("\nNRF_SERIAL_EVENT_FIFO_ERR  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_DRV_ERR)
  {
    printf("\nNRF_SERIAL_EVENT_DRV_ERR  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_TX_DONE)
  {
    printf("\nNRF_SERIAL_EVENT_TX_DONE  on serial id = %d\n",p_serial->instance);
  }
  if(event == NRF_SERIAL_EVENT_RX_DATA)
  {
    printf("\nNRF_SERIAL_EVENT_RX_DATA  on serial id = %d\n",p_serial->instance);
  }

}

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte0_drv_config,
                      RX_PIN_NUMBER_0, TX_PIN_NUMBER_0,
                      RTS_PIN_NUMBER_0, CTS_PIN_NUMBER_0,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uarte1_drv_config,
                      RX_PIN_NUMBER_1, TX_PIN_NUMBER_1,
                      RTS_PIN_NUMBER_1, CTS_PIN_NUMBER_1,
                      NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
                      NRF_UART_BAUDRATE_115200,
                      UART_DEFAULT_CONFIG_IRQ_PRIORITY);


#define SERIAL_FIFO_TX_SIZE 256
#define SERIAL_FIFO_RX_SIZE 256

NRF_SERIAL_QUEUES_DEF(serial0_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
NRF_SERIAL_QUEUES_DEF(serial1_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);


#define SERIAL_BUFF_TX_SIZE 64
#define SERIAL_BUFF_RX_SIZE 64

NRF_SERIAL_BUFFERS_DEF(serial0_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
NRF_SERIAL_BUFFERS_DEF(serial1_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);


NRF_SERIAL_CONFIG_DEF(serial0_config, NRF_SERIAL_MODE_DMA,&serial0_queues, &serial0_buffs, serial_event_handler, sleep_handler);
NRF_SERIAL_CONFIG_DEF(serial1_config, NRF_SERIAL_MODE_DMA,&serial1_queues, &serial1_buffs, serial_event_handler, sleep_handler);
//NRF_SERIAL_CONFIG_DEF(serial0_config, NRF_SERIAL_MODE_IRQ,&serial0_queues, &serial0_buffs, serial_event_handler, sleep_handler);
//NRF_SERIAL_CONFIG_DEF(serial1_config, NRF_SERIAL_MODE_DMA,&serial1_queues, &serial1_buffs, serial_event_handler, sleep_handler);


NRF_SERIAL_UART_DEF(serial0_uarte, 0);
NRF_SERIAL_UART_DEF(serial1_uarte, 1);


int main(void)
{
    uint32_t ret;
    uint32_t pinnum = 13;
        
    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);

    nrf_gpio_cfg_output(pinnum);
    nrf_gpio_pin_write(pinnum,1);
    nrf_gpio_pin_write(pinnum,0);

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

    ret = nrf_serial_init(&serial0_uarte, &m_uarte0_drv_config, &serial0_config);
    APP_ERROR_CHECK(ret);

    ret = nrf_serial_init(&serial1_uarte, &m_uarte1_drv_config, &serial1_config);
    APP_ERROR_CHECK(ret);

    static char tx_message0[] = "Hello nrf_serial port = 0!\n\r";
    static char tx_message1[] = "Hello nrf_serial port = 1!\n\r";

    ret = nrf_serial_write(&serial0_uarte,
                           tx_message0,
                           strlen(tx_message0),
                           NULL,
                           NRF_SERIAL_MAX_TIMEOUT);
    (void)nrf_serial_flush(&serial0_uarte, 0);
    
    ret = nrf_serial_write(&serial1_uarte,
                           tx_message1,
                           strlen(tx_message1),
                           NULL,
                           NRF_SERIAL_MAX_TIMEOUT);
    (void)nrf_serial_flush(&serial1_uarte, 0);

    while (true)
    {
        char c;
       // nrf_serial_read(&serial0_uarte, &c, sizeof(c), NULL, 0);
        //nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 0);
      

        /*char c;
        if(nrf_serial_read(&serial0_uarte, &c, sizeof(c), NULL, 0) == NRF_SUCCESS)
            //printf("received on port = 0, c= %c\n",c);

        if(nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 0) == NRF_SUCCESS)
            //printf("received on port = 1, c= %c\n",c);
      
        ret = nrf_serial_read(&serial0_uarte, &c, sizeof(c), NULL, 1000);
        if (ret != NRF_SUCCESS)
        {
            continue;
        }
        (void)nrf_serial_write(&serial0_uarte, &c, sizeof(c), NULL, 0);
        (void)nrf_serial_flush(&serial0_uarte, 0);

        ret = nrf_serial_read(&serial1_uarte, &c, sizeof(c), NULL, 1000);
        if (ret != NRF_SUCCESS)
        {
            continue;
        }
        (void)nrf_serial_write(&serial1_uarte, &c, sizeof(c), NULL, 0);
        (void)nrf_serial_flush(&serial1_uarte, 0);
        */
    }
}

/** @} */

Parents Reply Children
  • Hi there,

    I am getting both of these events NRF_SERIAL_EVENT_RX_DATA and NRF_DRV_UART_EVT_RX_DONE. 

    When i say interrupt it means when i do not have to make  un-necessary calls to function nrf_serial_read().

    When i only use one uart port in UART driver example (peripheral/uart) i get APP_UART_DATA_READY interrupt when something is received on rx line. Then in APP_UART_DATA_READY ISR, I can call app_uart_get() to read data.

    But in Serial Library example (peripheral/serial_uartes) , there is no RX interrupt. Once we call nrf_serial_read() then i get NRF_SERIAL_EVENT_RX_DATA event.

    Basically i just need to use 2 UARTs with interrupt functionality, when something is received on the port then i will read it.

    I don't care for serial library, is it possible to do only with UART driver to have 2 functional ports? if yes please point to some sample where i can test 2 uarts.

    Best Regards, Rishi

  • I'm still not sure I understand your question. I tested the serial_uartes example in SDK 15.3, modified it to not make any calls to nrf_serial_read(), and added the serial_event_handler you have posted in your code. When I set breakpoints in the event_handler, I receive the NRF_SERIAL_EVENT_RX_DATA event when I send a byte from the PC terminal.

    You can use the driver directly as well, but unfortunately, we do not have any examples of this. I would also recommend you to check out the libUARTE library. Much more work have recently been put into this library, and this is recommended over nrf_serial.

  • Well now i am also getting NRF_SERIAL_EVENT_RX_DATA in my SDK 16 example as expected. 

    Real issue was #define SERIAL_BUFF_RX_SIZE 64 in my main .c i posted, That's why i was not getting the interrupt for each character.

    Anyways thanks for your help !

    Best Regards, Rishi

Related