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

app_ble_uart Data Loss - APP UART COMMUNICATION ERROR

Hello All,

I have 2 evaluation boards nrf52840 EVB "PCA10056".

I would like to run on them the "ble_app_uart"  in "nRF5_SDK_15.3.0_59ac345" as following:

  • A custom board send via uart a buffer of "N" characters ending with "\n" to the peripheral on the pin P0.26 every "S" ms.
  • The Board "peripheral" send this packet via bluetooth to the "central board" (where I uploaded the "ble_app_uart_c" code)
  • The "central board" print via uart the packet received.

At the beginning, if for example I increased the distance between the 2 Evaluation boards or moved them quickly, a disconnection occurred because the "peripheral" went to "APP_UART_COMMUNICATION_ERROR" (I believe that an interrupt of the softdevice with higher priority of the UART is triggered and the byte on the UART is not read) but, despite the disconnection, the custom board continued to send data over the Uart to the peripheral,  which could no longer get out of this error.

So checking on the forum and thanks to some tickets like this: 

https://devzone.nordicsemi.com/f/nordic-q-a/23796/app-uart-communication-error/93601#93601 

I was able to manage this error commenting out " APP_ERROR_HANDLER" in  case APP_UART_COMMUNICATION_ERROR, but ignoring the communication error on UART I have some loss of data.

This data loss drags my throughput down dramatically, because if my buffer instead of having N characters has less, it can't be sent to the central device over Bluetooth.

I could decrease "S", but I have experimentally noticed that decreasing "S" the frequency of the error increases and therefore under a certain value of "S" I don't get more improvements.

In another ticket I've read about LIBUARTE: 

https://devzone.nordicsemi.com/f/nordic-q-a/41012/uart---losing-data-when-writing-to-nrf52840-with-pyserial-over-jlink-com-port

but to be honest I did not get how can I change the ble_app_uart using this library (if it is a solution).

Anyone can help me?

Thanks

Parents
  • Hi,

    APP_UART_COMMUNICATION_ERROR is caused by a hardware error on the UART line, you should figure out why this happens and fix it. Could you be introducing noise when moving the board, leading to the error on the UART pins? You can see the error in app_uart_evt_t.data.error_communication, which corresponds to one or more of the errors described in the ERRORSRC register in the UART peripheral.

    Best regards,
    Jørgen

  • Did you check the error code?

    LIBUARTE can be used for reliable communication over UART, eliminating the data loss issue.

  • Did you check the error code?

    ERROR 1 [NRF_ERROR_SVC_HANDLER_MISSING];  ERROR 4 [NRF_ERROR_NO_MEM]

    those are the errors that I can see when the "case" is APP_UART_COMMUNICATION_ERROR.

    Anyway, how I mentioned already, in other posts many users had problems with ble_app_uart increasing the speed. I have many doubts about uart and how it is managed. I do not understand for example why is used the DMA if then I have an interrupt for every byte received. Then I did not get why there are 2 uart handler 1 in app_uart_fifo and another in main that use app_uart_get.....I really did not get how the bytes are managed on the peripheral side.

    I would like to modify the ble_app_uart in order to:

    -Use the DMA (circular for example) that receives byte in background and when the buffer is full (for example 50 bytes) an interrupt occurs.

    - In the interrupt I check the buffer, if it is ok (full and the last byte is a "\n") send it with ble_nus_data_send.

    But I'm in trouble to do it at the moment.

    Thanks

  • Like I said above, the error codes reported in APP_UART_COMMUNICATION_ERROR event correlates to errors in the ERRORSRC register. 1 means OVERRUN and 4 means FRAMING. If you want to increase the speed, you should use HW flow control pins, or you could use the reliable transfer library LIBUARTE.

    The library will use EasyDMA if the UARTE peripheral is used, but it also support using the legacy UART peripheral. In many use-cases the length of the transfer is not know, and it makes sense to read a single byte at a time to avoid requiring 50 bytes to be received before the handler is called. The received bytes are put into a FIFO, that can be read from application.

    The app_uart library is built on top of the UART driver (nrf_drv_uart), and it implements a handler to receive events from the driver. The handler in main is used to receive events from app_uart library in the application. Further down, the UART driver implements a IRQ handler, which receive the hardware interrupt events.

    If you want more control of the transfer sizes, etc., you can have a look at the nrf_serial library.

Reply
  • Like I said above, the error codes reported in APP_UART_COMMUNICATION_ERROR event correlates to errors in the ERRORSRC register. 1 means OVERRUN and 4 means FRAMING. If you want to increase the speed, you should use HW flow control pins, or you could use the reliable transfer library LIBUARTE.

    The library will use EasyDMA if the UARTE peripheral is used, but it also support using the legacy UART peripheral. In many use-cases the length of the transfer is not know, and it makes sense to read a single byte at a time to avoid requiring 50 bytes to be received before the handler is called. The received bytes are put into a FIFO, that can be read from application.

    The app_uart library is built on top of the UART driver (nrf_drv_uart), and it implements a handler to receive events from the driver. The handler in main is used to receive events from app_uart library in the application. Further down, the UART driver implements a IRQ handler, which receive the hardware interrupt events.

    If you want more control of the transfer sizes, etc., you can have a look at the nrf_serial library.

Children
No Data
Related