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");
}

Related