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

nRF52840 DK - UART Stops

Hi All,

I've got an nRF 52840 PDK and I'm connecting a GPS module (Adafruit Ultimate GPS Logger Shield) to it to read the data using nrf_serial.h library. I get about 5-10 messages from the GPS module before the feed stops. Using oscilloscope, I can see that the GPS module is outputting data fine, but it doesn't seem like the data is being read by nRF DK. The application also prints out the data it receives over serial monitor; when GPS module output stops, I can send a few messages over serial monitor before this part of application also stops working. Power cycling helps until you hit the same roadblock again.

I've tried changing the UART pins hoping that it would resolve this as suggested in this link, but no luck. I've also changed baud rate to no avail.

The (latest) UART connection is setup as follows on nRF:

Rx: NRF_GPIO_PIN_MAP(0, 24)

Tx: NRF_GPIO_PIN_MAP(0, 23)

RTS: NRF_UART_PSEL_DISCONNECTED

DTS: NRF_UART_PSEL_DISCONNECTED

HW Flow Control: NRF_UART_HWFC_DISABLED

Bit Parity: NRF_UART_PARITY_EXCLUDED

Baudrate: NRF_UART_BAUDRATE_9600

Event Handler: NULL

Sleep Handler: NULL

I've been trying to debug this issue for a while, but I can't think of anything new to debug this as I've been playing with this kit for only a few days now. Any advice or suggestion is welcome.

Here are the project details:

Project: examples > peripheral > serial > pca10056 (modified; main.c provided below)

SDK version 15.2.0

OS: Windows 10

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

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

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

/** @file
* @defgroup nrf_serial_example main.c
* @{
* @ingroup nrf_serial_example
* @brief Example of @ref nrf_serial usage. Simple loopback.
*
*/

#define OP_QUEUES_SIZE 3
#define APP_TIMER_PRESCALER NRF_SERIAL_APP_TIMER_PRESCALER

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

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

NRF_SERIAL_DRV_UART_CONFIG_DEF(m_uart1_drv_config,
NRF_GPIO_PIN_MAP(0, 24), NRF_GPIO_PIN_MAP(0, 23),
NRF_UART_PSEL_DISCONNECTED, NRF_UART_PSEL_DISCONNECTED,
NRF_UART_HWFC_DISABLED, NRF_UART_PARITY_EXCLUDED,
NRF_UART_BAUDRATE_9600,
UART_DEFAULT_CONFIG_IRQ_PRIORITY);

#define SERIAL_FIFO_RX_SIZE 32
#define SERIAL_FIFO_TX_SIZE 32

NRF_SERIAL_QUEUES_DEF(serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);
NRF_SERIAL_QUEUES_DEF(gps_serial_queues, SERIAL_FIFO_TX_SIZE, SERIAL_FIFO_RX_SIZE);

#define SERIAL_BUFF_RX_SIZE 1
#define SERIAL_BUFF_TX_SIZE 1

NRF_SERIAL_BUFFERS_DEF(serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);
NRF_SERIAL_BUFFERS_DEF(gps_serial_buffs, SERIAL_BUFF_TX_SIZE, SERIAL_BUFF_RX_SIZE);

NRF_SERIAL_CONFIG_DEF(serial_config, NRF_SERIAL_MODE_DMA,
&serial_queues, &serial_buffs, NULL, NULL);
NRF_SERIAL_CONFIG_DEF(gps_serial_config, NRF_SERIAL_MODE_DMA,
&gps_serial_queues, &gps_serial_buffs, NULL, NULL);

NRF_SERIAL_UART_DEF(serial_uart, 0);
NRF_SERIAL_UART_DEF(gps_uart, 1);

int main(void) {
ret_code_t ret;
ret_code_t gps_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);
gps_ret = nrf_serial_init(&gps_uart, &m_uart1_drv_config, &gps_serial_config);
APP_ERROR_CHECK(gps_ret);

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

while (true) {
char c = 0x30;
ret = nrf_serial_read(&serial_uart, &c, sizeof(c), NULL, 1);
if (ret == NRF_SUCCESS) {
(void)nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);
(void)nrf_serial_flush(&serial_uart, 0);
}

gps_ret = nrf_serial_read(&gps_uart, &c, sizeof(c), NULL, 1);
if (gps_ret == NRF_SUCCESS) {
(void)nrf_serial_write(&serial_uart, &c, sizeof(c), NULL, 0);
(void)nrf_serial_flush(&serial_uart, 0);
}
}
}

/** @} */

Parents
  • Brief update on the progress:

    I've tried a few things to see what's going on.

    1. As I'm using two UARTs, I decided to change the VCP pins (UART0) to different pins on the board eg P0.30 and P0.31. No luck there. So, I reverted to original settings and use VCP as normal.

    2. Temporarily, as I'm not using Rx pin on the GPS module, I decided to utilize it to send messages and use an FTDI chip to read the data from P0.31. It works for longer but it stops after 5-6 mins. Although the ret_code from nrf_serial_read is printed out on VCP, it's always showing up as 0x00 which indicates NRF_SUCCESS even after the output at P0.31 stops; I'm a bit dubious about how reliable this test can be given that VCP output stops even in the default serial example.

    So, at this point, the questions that I have in mind are:

    a. Is this problem due to the interface MCU as mentioned in some other posts? Is there any workaround for it? Is there any way to isolate the interface MCU after downloading the code?

    b. Is there anything special needed for UART initialization?

  • Hello,

    How long does your application run before it stops responding?

    I can't see anything obviously wrong with your setup. Can you test a couple of things?

    Does it work, or work longer if you only use one of the UARTS? 

    Does the behavior change if you use the sleep_handler?

    When it stops receiving, is the application still running through your main loop? Or does it stop somewhere?

    Is there any way for me to reproduce this issue? Is it possible to zip the project that you use and send it so that I can test it on a DK? If so, can you give some instructions on how to reproduce? Note that I don't have the GPS, but maybe I can simulate one by sending messages through an UART terminal to the DK.

    BR,

    Edvin

  • Hello,

    Pardon the late reply! I've been caught up in a few other projects and looks like I'll have to come back to this in a while. Thank you for the debugging suggestions. I'll go through them one by one and post an update later.

  • Hello Edven,

    It appears that I had a bit of an issue using the I2C functions when I was trying to read values from the sensor. It was a little difficult. Using the following functions helped in reading from and writing to the sensor.

    char readBytes(char address, unsigned char *values, char length)
    // Read an array of bytes from device
    // values: external array to hold data. Put starting register in values[0].
    // length: number of bytes to read
    {
    #if DEBUG_ENABLED
      NRF_LOG_INFO("Start readBytes");
      for (int i = 0; i < length; ++i)
        NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
      NRF_LOG_FLUSH();
    #endif
      ret_code_t _error = nrf_drv_twi_tx(&m_twi, address, values, 1, true);
      APP_ERROR_CHECK(_error);
    #if DEBUG_ENABLED
      NRF_LOG_INFO("Waiting for transfer completion.");
      NRF_LOG_FLUSH();
    #endif
      while (m_tx_done == false)
        ;
      m_tx_done = false;
      //#if DEBUG_ENABLED
      //  for (int i = 0; i < length; ++i)
      //    NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
      //#endif
      if (_error == 0) {
        ret_code_t _error = nrf_drv_twi_rx(&m_twi, address, values, length);
        APP_ERROR_CHECK(_error);
        while (m_rx_done == false)
          ;
    #if DEBUG_ENABLED
        NRF_LOG_INFO("Rx readBytes");
        for (int i = 0; i < length; ++i)
          NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
        NRF_LOG_INFO("End readBytes\r\n");
        NRF_LOG_FLUSH();
    #endif
        m_rx_done = false;
    
        return 1;
      } else
        return 0;
    }
    
    char writeBytes(char address, unsigned char *values, char length) {
      ret_code_t _error = nrf_drv_twi_tx(&m_twi, address, values, length, false);
      APP_ERROR_CHECK(_error);
      while (m_tx_done == false)
        ;
      m_tx_done = false;
      return 1;
    }

    As you can see, I'm using NRF_LOG_INFO() macros to speed up the debug (instead of UART). 

    I re-visited this part about 2 weeks ago and I couldn't remember the old issues I posted about Slight smile Thanks for the troubleshooting hints and also offering to reproduce the issue UART! Cheers

Reply
  • Hello Edven,

    It appears that I had a bit of an issue using the I2C functions when I was trying to read values from the sensor. It was a little difficult. Using the following functions helped in reading from and writing to the sensor.

    char readBytes(char address, unsigned char *values, char length)
    // Read an array of bytes from device
    // values: external array to hold data. Put starting register in values[0].
    // length: number of bytes to read
    {
    #if DEBUG_ENABLED
      NRF_LOG_INFO("Start readBytes");
      for (int i = 0; i < length; ++i)
        NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
      NRF_LOG_FLUSH();
    #endif
      ret_code_t _error = nrf_drv_twi_tx(&m_twi, address, values, 1, true);
      APP_ERROR_CHECK(_error);
    #if DEBUG_ENABLED
      NRF_LOG_INFO("Waiting for transfer completion.");
      NRF_LOG_FLUSH();
    #endif
      while (m_tx_done == false)
        ;
      m_tx_done = false;
      //#if DEBUG_ENABLED
      //  for (int i = 0; i < length; ++i)
      //    NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
      //#endif
      if (_error == 0) {
        ret_code_t _error = nrf_drv_twi_rx(&m_twi, address, values, length);
        APP_ERROR_CHECK(_error);
        while (m_rx_done == false)
          ;
    #if DEBUG_ENABLED
        NRF_LOG_INFO("Rx readBytes");
        for (int i = 0; i < length; ++i)
          NRF_LOG_INFO("data[%d]: %02x", i, values[i]);
        NRF_LOG_INFO("End readBytes\r\n");
        NRF_LOG_FLUSH();
    #endif
        m_rx_done = false;
    
        return 1;
      } else
        return 0;
    }
    
    char writeBytes(char address, unsigned char *values, char length) {
      ret_code_t _error = nrf_drv_twi_tx(&m_twi, address, values, length, false);
      APP_ERROR_CHECK(_error);
      while (m_tx_done == false)
        ;
      m_tx_done = false;
      return 1;
    }

    As you can see, I'm using NRF_LOG_INFO() macros to speed up the debug (instead of UART). 

    I re-visited this part about 2 weeks ago and I couldn't remember the old issues I posted about Slight smile Thanks for the troubleshooting hints and also offering to reproduce the issue UART! Cheers

Children
No Data
Related