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

UARTE Frame error receiving

Hi

I am seing framing errors when receiving using UARTE.

It is not external hardware, I have checked with different other interfaces and measured timing, no problems there.

BUT, doing the same with UART instead of UARTE I do not get any framing errors (same hardware setup).

Actually with UARTE I only get one rx character then framing errors....

  • This could be related to the use of double buffering. I set up a two single byte buffers to receive on each rx interrupt.

  • Hi,

    I am not sure what is going on. A typical reason for UART framing errors is if you have a baud-rate mismatch between the two UART devices, for instance, if you have not started the high-frequency crystal oscillator. Can you try doing that? If that is not the problem (which may be unlikely, since you see a difference between using UART and UARTE), then we should probably look at your code.

  • There is no baudrate mismatch. Verified with analyzer and checked by using different second device (not nRF). Tested with both PC serial interface and other embedded device.

    As I wrote it works when using UART. Problem occurs with the use of UARTE which I need because I need both UART's in the nRF52840.

  • // Initialize uarte 
    
          nrfx_uarte_config_t config = NRFX_UARTE_DEFAULT_CONFIG;
    
          // Initialize uart 
          result = nrfx_uarte_init(&m_serial[id].uart, &config, SerialInterfaceEventHandler);
          APP_ERROR_CHECK(result);
          
          // Start receiving and specify buffer for double buffering
          result = nrfx_uarte_rx(&m_serial[id].uart, &m_serial[id].rxBuffer[0], 1);
          APP_ERROR_CHECK(result);
          result = nrfx_uarte_rx(&m_serial[id].uart, &m_serial[id].rxBuffer[1], 1);
          APP_ERROR_CHECK(result);
    
    // Event handler
    
    static void SerialInterfaceEventHandler(nrfx_uarte_event_t const * p_event, void* p_context)
    {
       ret_code_t ret;
       int id = (uint32_t)p_context;
       
       switch (p_event->type)
       {
          case NRFX_UARTE_EVT_TX_DONE:   //!< Chunk of data has been sent.
             SerialCallEventHandler(id, SE_TX_COMPLETE);
             break;
          
          case NRFX_UARTE_EVT_RX_DONE:   //!< New chunk of data has been received.
             rxCount++;
             if (p_event->data.rxtx.bytes > 0)
             {
                SerialReceiveInsert(id, p_event->data.rxtx.p_data[0]);
             }
    // Previous test, not sure if a new nrfx_uarte_rx call is needed when using 
    // double buffering (but it works like below for UART interface
    //         SerialReceiveInsert(id, m_serial[id].rxBuffer[m_serial[id].rxIndex]);
    //         ret = nrfx_uarte_rx(&m_serial[id].uart, &m_serial[id].rxBuffer[m_serial[id].rxIndex], 1);
    //         APP_ERROR_CHECK(ret);
    //         m_serial[id].rxIndex = 1-m_serial[id].rxIndex;
             SerialCallEventHandler(id, SE_RX_READY);
             break;
             
          case NRFX_UARTE_EVT_ERROR:
             serError++;
             error = p_event->data.error.error_mask;
             SerialCallEventHandler(id, SE_ERROR);
             break;
       }
    }
    

    I have attached the basic initialization and eventhandler code. 

  • Hi Thomas,

    I see. I assume you are using this approach to be able to receive an arbitrary number of bytes and/or be able to process data as they arrive, working around the UARTE peripheral imitations? The problem with this approach, especially if you are not using very low baud rates, is that it becomes timing-sensitive with only single-byte buffers.

    I suggest you use larger buffers and consider using the libUARTE asynchronous library.

Related