Recover from APP_UART_COMMUNICATION_ERROR

Hi, We are using SDK17 and are implementing the UART y APP_UART_FIFO_INIT. Every now and then we encounter APP_UART_COMMUNICATION_ERROR. I know this is related to buffer overrun during reception. How do we gracefully recover from this? If the data in the buffer is lost, we can handle this in an other way. But for now, the error is not cleared and the only way to get it working again is reset the device.

  • Hi,

    Yes, we indeed was not on the same page... I am afraid I still am not on the same page yet though. Slight smile

    I am quite confused about the code snippets you sent me. Are you using the UART Module (app_uart.h) or are you using the driver directly? Or are you perhaps using a modified implementation of app_uart.c/app_uart_fifo.c?

    Your UART event handler is for the UART Module, but you are using nrfx_uart_tx() to send bytes. What makes it look strange to me is that the UART Module wrap the entire nrfx_uart_t instance within itself, hiding it from you. Therefore if you are using the UART Module you should not be using nrfx_uart_t.

    What do I need to do (except from avoiding the situation in the first place).

    By this, do you mean you are not able to modify the current implementation at the moment?

    Best regards,

    Hieu

  • Hi,

    Yes, I use a slightly modified version of the app_uart and app_uart_fifo files. In those file we replaced all nrf_drv_* for nrfx_*. 

    The reason why I used nrfx_uart_tx is that app_uart_put is using that call. However using the app_uart_put I need to repeat the app_uart_put cal for every character I want to send. With nrfx_uart_tx I can send the whole string at once
    This all works fine for several minutes. Than I encounter the APP_UART_COMMUNICATION_ERROR. From other questions about this on the forum, I think this is due an overrun error. 
    I want a methode to just go on with the next (or repeated) transmission to my external device. But the answers from the device cannot be handled anymore. It looks like the underlying software is in an error state still. I want to reset this state or flag(s) somehow.

  • Ok I think we are on the same page now. One final thing before I dig deeper into this. Are you open to changing your implementation?

  • Yes, anything that will create a more reliable solution.

  • Hi,

    Firstly, regarding what can be done, here are a few ideas:

    1. Revert to the original implementation of app_uart_fifo and use either app_uart_tx or printf.

      app_uart_tx provide a software buffer for processing data which needs to be send, and it already implements some graceful handling when data are being produced faster than consumed.

      app_uart_tx() can be used without terribly bloated code:
      uint32_t buf_len, buf_idx;
      
      buf_len = snprintf(buf, BUF_MAX_LEN, "your format", ...);
      for (buf_idx = 0; buf_idx < buf_len; buf_idx++)
      {
          app_uart_put(buf[buf_idx]);
      }
      



      With \libraries\uart\retarget.c, you can also just use printf()
      A point to note is Segger Embedded Studio v6.20a and later added a feature which causes incompatibility with retarget.c and printf()
      If printf() is highly desirable I recommend using SES v5.42a, which SDK v17.1.0 was released and tested with.

    2. Increase your baud rate so that HW can consume data faster, and thus less data queue up in the application software.

    3. As a complete alternative options, you can take a look at the Advanced UARTE Driver library: https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/lib_libuarte.html

      The example for this library locates at: <SDK Root>/examples/peripheral/libuarte
      The documentation of the example is at: https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/libuarte_example.html

    I tested both printf() and app_uart_put() methods.
    With baud 1M, I can push ~500-550 bytes out at once just fine even with a app_uart_fifo buffer of mere 16 bytes.

    Regarding your original code and problem, I tried to look into the nrfx_uart driver, nrfx_uart_tx() in particular, to see what could cause your software to hang but nothing immediately stood out.
    If there is an interest in what is going on, enable RTT logging, and logging for the NRFX_UART module and give me the log.

    Best regards,

    Hieu

Related