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

Recover from NRF_UARTE_EVENT_ERROR when UART RX pin pulled low

Greetings,

In my application I have another device (STM32) communicating to a NRF52 via UART. When the STM32 needs to be reset, the NRF52's RX pin is pulled low. When the RX pin is pulled low, a NRF_UARTE_EVENT_ERROR error is triggered in the uarte_irq_handler (in nrf_drv_uart.c).

One quick hack was to comment out the NRF_DRV_UART_EVT_ERROR case in the uart_event_handler. In this case, for me it is in nrf_serial_dfu.c (I'm using the secure serial bootloader). However, when an actual character is received EVENTS_ERROR is set.

Once a NRF_UARTE_EVENT_ERROR has been received, all subsequent characters received are treated as errors in the uarte_irq_handler.

Moreover, the NRF52’s RX pin is also connected to another GPIO line via an inline resistor. When the NRF52’s application detects this GPIO is held low for 30ms (i.e., much longer than a character at 9600 baud), a software reset is triggered. This GPIO line is also used by the secure serial bootloader as the indication that the STM32 is about to update the firmware of the NRF52. I had to connect the GPIO line to the RX line as it was not possible to route a separate line between the STM32 and the NRF52.

How do I change the NRF52 UART driver (nrf_drv_uart) such that it can handle the RX pin being pulled low (either by the STM32 being reset or the STM32 to put the NRF52 into bootloader mode to update its firmware) and still correctly receive uart characters? I would like to avoid reinitialising the NRF52s UART module.

I'm using SDK V13.0.0.

Note: This problem can be easily reproduced on the PCA10040. Load a program that uses the nrf_drv_uart (such as experimental_bootloader_secure_serial with 9600 baud and HWFC disabled). Temporarily disconnect the NRF52’s RX line from whatever is driving it, then pull this low via a 1K resistor. Re-connect the RX line and send a character. I've also attached a picture of the values of UARTE0 registers on the various test states: rx_low_error.png.

  • FormerMember
    0 FormerMember

    Is there a way for STM32 to indicate that it is about to reset? If so, STM32 can tell nRF52 that it is a about to reset. The nRF52 can then set a flag so that the application knows that it can ignore the error NRF_DRV_UART_EVT_ERROR.

  • Kirstin,

    I'm sure I could make a work around on this on the STM32 side and will do so.

    However, I'd also like to make the NRF52 firmware able to recover from this state. Any idea why the NRF52's UART sets the EVENTS_ERROR flag when a valid character is received after one EVENTS_ERROR is received from pulling the RX line low? This is despite the EVENTS_ERROR being cleared after it is first triggered in the uarte_irq_handler.

  • Kristin,

    Just re-read your reply. I'm not sure whether this scheme would fix the problem. When the error occurs, it enters the "uarte_irq_handler" function in nrf_drv_uart.c which then calls the event handler that was passed into "nrf_drv_uart_init". In the case of the secure serial bootloader, this is the "uart_event_handler" function. In this function, I've commented out the NRF_DRV_UART_EVT_ERROR case so that the error is ignored (and the "uarte_irq_handler" clears the error flag). However, when a valid character is received, it is reported as an error in the "uarte_irq_handler" interrupt routine.

    I'll see whether re-initialising the UART driver is able to fix the problem.

  • Another "fix" could be enabling the pull up on the NRF52's RX pin, this will at least get around the issue when the STM32 reboots.

  • I've tried two attempts of recovering from this error:

    1. Reinitialize the UART driver ("nrf_drv_uart_uninit" then "nrf_drv_uart_init"). Result: uarte_irq_handler triggers after a character is received, but is EVENTS_ERROR is set.
    2. Call "nrf_drv_uart_rx_abort" by itself, then followed by "nrf_drv_uart_rx_disable" then "nrf_drv_uart_rx_enable". Result: uarte_irq_handler is not triggered after a character is received. This is despite no change in the interrupt register values from prior to pulling the RX pin low.

    Both of these attempts were done in the NRF_DRV_UART_EVT_ERROR case in the "uart_event_handler".

    Could someone please confirm that there is no way to recover from this error, other than performing a software reset?

Related