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

Stuck TX interrupt with nrf_serial_write

We are trying to use serial port library for simple UART comms in IRQ mode at 115200, but experiencing what looks like stuck TX interrupt.  PCA10040 with SDK 15.3.

In the attached example code, when cli_init() is called it should simply print the prompt 20 times with 1sec pauses between, and it should write each prompt fully since we are setting MAX timeout on the write (blocking)

However, what we see is that it prints an incomplete prompt, the waits 1sec. Then when the next write occurs the remainder of last prompt is printed before the next etc.etc.. In other words, when all is done, the right output is produced, but it does not complete in the blocking mode we expect.

PS: That looks exactly like when the TX reg empty interrupt is not firing or handled correctly and only gets restarted in next write, but maybe I'm over-implying what it might be.


#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "nordic_common.h"
#include "sdk_common.h"
#include "boards.h"
#include "nrf_serial.h"
#include "nrf_delay.h"
#include "ble.h"

#define NRF_LOG_MODULE_NAME rscli
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();


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

// for BT832X
//#define TX_PIN_NUMBER   12 
//#define RX_PIN_NUMBER   11
//#define RTS_PIN_NUMBER  0xFFFFFFFF
//#define CTS_PIN_NUMBER  0xFFFFFFFF


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


NRF_SERIAL_UART_DEF(serial_uart, 0);

static char cli_prompt[] = "\r\nranch-ble>";


void rscli_puts(char *str)
{
  ret_code_t ret;

  ret = nrf_serial_write(&serial_uart,
                         str,
                         strlen(str),
                         NULL,
                         NRF_SERIAL_MAX_TIMEOUT);
  if (ret!=NRF_SUCCESS) NRF_LOG_INFO("Write error %d", ret);
  APP_ERROR_CHECK(ret);
  ret = nrf_serial_flush(&serial_uart,NRF_SERIAL_MAX_TIMEOUT);
  if (ret!=NRF_SUCCESS) NRF_LOG_INFO("Flush error %d", ret);
  APP_ERROR_CHECK(ret);
}


/**
  Init Ranch CLI
*/
void rscli_init() 
{
  ret_code_t ret;

  // open command line
  ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
  APP_ERROR_CHECK(ret); 

  int i;
  for (i=0; i<20; i++) {
    rscli_puts(cli_prompt);
    nrf_delay_ms(1000);
  }

  NRF_LOG_INFO("CLI init complete");
}

  • Hi,

    I tested your code with the serial example in sdk 15.3.0, but it seems to work here. 

    main.c used for the test:

    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nordic_common.h"
    #include "sdk_common.h"
    #include "boards.h"
    #include "nrf_serial.h"
    #include "nrf_delay.h"
    
    
    #define NRF_LOG_MODULE_NAME rscli
    #include "nrf_log.h"
    NRF_LOG_MODULE_REGISTER();
    
    
    static void sleep_handler(void)
    {
        __WFE();
        __SEV();
        __WFE();
    }
    
    // for BT832X
    //#define TX_PIN_NUMBER   12 
    //#define RX_PIN_NUMBER   11
    //#define RTS_PIN_NUMBER  0xFFFFFFFF
    //#define CTS_PIN_NUMBER  0xFFFFFFFF
    
    
    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_115200,
                          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_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_IRQ,
                          &serial_queues, &serial_buffs, NULL, sleep_handler);
    
    
    NRF_SERIAL_UART_DEF(serial_uart, 0);
    
    static char cli_prompt[] = "\r\nranch-ble>";
    
    
    void rscli_puts(char *str)
    {
      ret_code_t ret;
    
      ret = nrf_serial_write(&serial_uart,
                             str,
                             strlen(str),
                             NULL,
                             NRF_SERIAL_MAX_TIMEOUT);
      if (ret!=NRF_SUCCESS) NRF_LOG_INFO("Write error %d", ret);
      APP_ERROR_CHECK(ret);
      ret = nrf_serial_flush(&serial_uart,NRF_SERIAL_MAX_TIMEOUT);
      if (ret!=NRF_SUCCESS) NRF_LOG_INFO("Flush error %d", ret);
      APP_ERROR_CHECK(ret);
    }
    
    
    /**
      Init Ranch CLI
    */
    void rscli_init() 
    {
      ret_code_t ret;
    
      // open command line
      ret = nrf_serial_init(&serial_uart, &m_uart0_drv_config, &serial_config);
      APP_ERROR_CHECK(ret); 
    
      int i;
      for (i=0; i<20; i++) {
        rscli_puts(cli_prompt);
        nrf_delay_ms(1000);
      }
    
      NRF_LOG_INFO("CLI init complete");
    }
    
    void main(void)
    {
        rscli_init();
        
        for(;;);
    
    }
    

    And the terminal output:

    Could you try the code above with the serial example to check if you still get the same result? Also, I guess you may have considered it already, but I would suggest trying our CLI example if you haven't done it already. The project can be found in <sdk root>/examples/peripheral/cli.

  • We resolved this - it was the receiving terminal that was buggy!  

    I tried deleting the ticket right after posting,but it was in some sort of review state, so couldnt access -- sorry.

Related