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

NRF51822 UART hangs and requires power cycle

Hi,

I am making a GPS tracking system using NRF51822-QFAC. I am using 2 UARTs, one of the (external) GPRS IC and one for (external) RS485 communication.

The UART peripheral hangs after some time. I don't know if it is UART1 or UART2. As a result, both the UART do not work for a period ranging from 1 hour to 5 hours. There is an external IC that lowers NRF_SWIO (programming pin) to reset the NRF periodically every 30 minutes. But this issue persists beyond that and needs a Power Cycle.

There was a similar issue reported, but it had something to do with Segger, which I am not using. I am not using BLE or any stack. Application is built on this example location:

\nRF5_SDK_12.2.0_f012efa\examples\peripheral\uart\pca10028\blank\arm5_no_packs

We made 15 devices and the issue occurs randomly in most of them. I am logging data on an SD card (through SPI and FATFS) and in the card the data comes Zero (that is how I know UART hangs). The pattern is not periodic.

This is the UART initialization code:

define MAX_TEST_DATA_BYTES     (15U)				/**< max number of test bytes to be used for tx and rx. */
define UART_TX_BUF_SIZE 				256					/**< UART TX buffer size. */
define UART_RX_BUF_SIZE 				256					/**< UART RX buffer size. */
define MRST  								15
define HWFC            			false
define RS485_RX_PIN_NUMBER  	12
define RS485_TX_PIN_NUMBER  	11
define GPS_RX_PIN_NUMBER	  	14
define GPS_TX_PIN_NUMBER  		13
define GEN_CTS_PIN_NUMBER 		17
define GEN_RTS_PIN_NUMBER 		18

const app_uart_comm_params_t comm_params_A =
	{
			GPS_RX_PIN_NUMBER,
			GPS_TX_PIN_NUMBER,
			GEN_RTS_PIN_NUMBER,
			GEN_CTS_PIN_NUMBER,
			APP_UART_FLOW_CONTROL_DISABLED,
			false,
			UART_BAUDRATE_BAUDRATE_Baud9600
	};

APP_UART_FIFO_INIT(&comm_params_A,
										 UART_RX_BUF_SIZE,
										 UART_TX_BUF_SIZE,
										 uart_error_handle_A,
										 APP_IRQ_PRIORITY_LOW,
										 err_code_GPS);

APP_ERROR_CHECK(err_code_GPS);	

And this is snippet of how data is transmitted (the packet is generally more than 256 bytes in length):

strcpy(uploadString, "&x_no=0&x_gs=00");

for (i=0; i<strlen(uploadString); i++)
{
	app_uart_put(uploadString[i]);
}

Is there a problem with pin numbers? Or Initialization method? Or transmission method? Or should I not use app_uart library? Or should I not use FIFO?

Please suggest, as this is becoming source of data inconsistency.

  • I can't see anything wrong with using the library or FIFO.

    Could it be that the UART experiences an error (framing or parity error for example) and ends up in an endless loop in an error handler somewhere? If this is the case it is strange that it doesn't help with a pin reset though. Have you used a debugger to check where the code is at when it hangs? Are you checking for, and gracefully handling, errors in your uart_error_handle_A() handler?

  • It happens once in couple of days, and also not on each device. It seems to be framing issue. Also feels like overflow.

    As of now, the uart_error_handle_A() does nothing. What should I write into it? Probably resetting all registers, clearing all buffers and restarting UART there should work.

  • You should check what kind of events you get in the error handler:

    void uart_error_handle_A(app_uart_evt_t * p_event)
    {
        if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_communication);
        }
        else if (p_event->evt_type == APP_UART_FIFO_ERROR)
        {
            APP_ERROR_HANDLER(p_event->data.error_code);
        }
    }
    

    I suspect you get APP_UART_COMMUNICATION_ERROR so you should check the value in p_event->data.error_communication and compare it to the ERRORSRC register to get a hint of what is wrong. When you are in the event handler you should also check what sensor you are communicating with at that time to figure out where the error stems from.

Related