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....

Parents
  • 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.

  • // 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. 

  • I will try to copy the version from SDK 16 to SDK 15.3 and see if I succeed.

  • I'm getting a problem with setup (maybe timer) when initialising the first uart.

    I have defined the following.

    NRF_LIBUARTE_ASYNC_DEFINE(libuarte0, 0, 0, 0, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);
    NRF_LIBUARTE_ASYNC_DEFINE(libuarte1, 1, 1, 1, NRF_LIBUARTE_PERIPHERAL_NOT_USED, 255, 3);

    With libuart1 it is OK and my code can run, if Im instead using libuart0 the application crashes with a SOFTDEVICE: INVALID MEMORY ACCESS.

    My configuration is like this:

    nrf_libuarte_async_config_t nrf_libuarte_async_config = {
    .tx_pin = id == 0 ? TX1_PIN_NUMBER : TX2_PIN_NUMBER,
    .rx_pin = id == 0 ? RX1_PIN_NUMBER : RX2_PIN_NUMBER,
    .baudrate = baudrate,
    .parity = parity,
    .hwfc = NRF_UARTE_HWFC_DISABLED,
    .timeout_us = 4000,
    .int_prio =APP_IRQ_PRIORITY_LOW_MID
    };

    Inside nrf_libuarte_async_init() the application jumps to the app_error_fault_handler with id 0x00001001.

    It is a little difficult to see exactly what happens. As stepping througth the initialization changes the position of where it happens. (some background interrupt maybe).

  • Hi,

    This error is expected since you specify that you should use TIMER0, and that is used by the SoftDevice.

  • Great thanks a lot - that fixed it.

    Since nrfx_timer was not enabled I just took the first two.....

    With all the other macro things I would suggest a check that if SD is used timer 0 should then not be available or at least generate and error if you try to enable it in the sdk_config.

  • I do experience a little bit of problems with the timeout function.

    I have configured the timeout at 4 ms (4000 us).

    What I see is really a timeout around 7-8 ms. I did configure the timer default values similar to the example, but is there anything else I could be missing?

    Also I sometimes get a timeout, even though there were really no "hole" in the packet on the line. In this case I fixed it by assembling the messages from two NRF_LIBUARTE_ASYNC_EVT_RX_DATA events which should really not be expected when messages on the line has no holes between bytes and there is a timeout similar to 4 bytes (at 9600 baud).

Reply
  • I do experience a little bit of problems with the timeout function.

    I have configured the timeout at 4 ms (4000 us).

    What I see is really a timeout around 7-8 ms. I did configure the timer default values similar to the example, but is there anything else I could be missing?

    Also I sometimes get a timeout, even though there were really no "hole" in the packet on the line. In this case I fixed it by assembling the messages from two NRF_LIBUARTE_ASYNC_EVT_RX_DATA events which should really not be expected when messages on the line has no holes between bytes and there is a timeout similar to 4 bytes (at 9600 baud).

Children
  • Actually I found a little bit more with the timer. 

    I am testing system with a good serial protocol analyzer to look for any problems.

    I am also seeing some situations where there is a timeout only 100 us after reception of the last character.

    (With the current testing I am running 38400 with a timeout of 2000 us. Also in this case the normal timeout seems to end up being around 7-8 ms. Is there a minimum...) NOT CORRECT, it was 4 ms.

    So I do think there must be some kind of problem related to the handling of timer and timeout.

  • The timing issue seems to be that I always get around double timeout compared to what I configure.

    So I guess it is some rather simple configuration potentially on the time I have not figured out what to set. There's not really any description on how to do it. Maybe I should simply configure it to twice what I need.

    The observation above regarding timeout of 2000 also giving 7-8 ms was wrong, it gives 3-4 ms.

Related