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

UART Overrun Error after Reset

Hi all,

I see there are similar questions posted on this forum, but none answers my question satisfactorily.

What I have:

  • we use the nRF52 we use UART0 to
  • transmit / receive data (totally
  • straight forward circuit) we use the nrf_drv_uart driver plus our own event handler, as per Nordic example

What I experience:

  • with the Softdevice S132 disabled, data transmission / reception works flawlessly
  • with the S132 enabled, we experience more than not that UART0 is unable to receive data. Instead, overruns are reported (event->data.error.error_mask = 0x00000001)
  • if the nRF52 starts up without overrun error, Tx / Rx works fine
  • once I see overrun errors reported, I need to reset the device a couple of times before I get Tx / Rx back again.

What is your suggestion?

Thank you for your help M

Parents
  • This can happen if you disable hardware flow control on one or both sides. The softdevice can reserve CPU when there is BLE activity and when the peer side is transmitting data in UART fast while the RX buffer overflow then there will be overrun errors. Enable hardware flow control so that the other side stops transmitting uart data when the DUT have RX buffer filled.

    If the data loss is not a big problem then you can clear this error in uart irq handler so that the uart driver continues working as normal.

  • Can you please answer these questions?

    1. What is the baudrate for the UART?
    2. Have you enabled hardware flow control on both sides?
    3. Which SDK and softdevice version are you using?

    The most probable reason for you not to recover from this is that when you get error you are reading one byte to make a slot for the next receive byte. But if the baud rate is high, then it wont help you much and the overrun error will happen as a chain reaction.

    Try this.

    else if (event->type == NRF_DRV_UART_EVT_RX_DONE)
    {
        ...
        ....
    }
    else if ((event->type == NRF_DRV_UART_EVT_ERROR) && (event.data.error.error_mask & UART_ERRORSRC_OVERRUN_Msk))
    {
        mUartErrors++;
        mUartErrorMask = event->data.error.error_mask;
    
      /* Receive next 6 byte, attempt to empty RX fifo */
      for(uint32_t i = 0; i < 6; i++)
      {
          someBuffer[i] = nrf_uart_rxd_get(&mUart);
      }
    }
    

    Make sure someBuffer have enough space to accomodate this. Now hopefully there will enough space in RX FIFO to stop the chain reaction

Reply
  • Can you please answer these questions?

    1. What is the baudrate for the UART?
    2. Have you enabled hardware flow control on both sides?
    3. Which SDK and softdevice version are you using?

    The most probable reason for you not to recover from this is that when you get error you are reading one byte to make a slot for the next receive byte. But if the baud rate is high, then it wont help you much and the overrun error will happen as a chain reaction.

    Try this.

    else if (event->type == NRF_DRV_UART_EVT_RX_DONE)
    {
        ...
        ....
    }
    else if ((event->type == NRF_DRV_UART_EVT_ERROR) && (event.data.error.error_mask & UART_ERRORSRC_OVERRUN_Msk))
    {
        mUartErrors++;
        mUartErrorMask = event->data.error.error_mask;
    
      /* Receive next 6 byte, attempt to empty RX fifo */
      for(uint32_t i = 0; i < 6; i++)
      {
          someBuffer[i] = nrf_uart_rxd_get(&mUart);
      }
    }
    

    Make sure someBuffer have enough space to accomodate this. Now hopefully there will enough space in RX FIFO to stop the chain reaction

Children
No Data
Related