Asynchronous UART API (DMA) not working like expected on nrf52840

hi,
i am trying to use the async uart api on a nrf52840 for communicating to a quectel bg95 modem.
no matter which timeout or buffer-size i am using, i am experiencing the problem that that some (1-2) bytes of the modem response are not received (or forwarded via the api) when they are arriving ... they are received with delay, when the next response of the modem comes in.

so the usual communication flow to the modem is:
(1) request from nrf -> modem
(2) response from the modem -> nrf (usually ending with "\r\n")
(3) some delay
(4) next request from nrf -> modem
(5) next response from the modem -> nrf

when using the async api it happens very often, that one or both of "\r\n" of (2) are missing as long as the response of (5) is beginning to come in. then the response of (5) is prepended with the missing "\r\n" of (2).

Parents
  • Can you please post some code snippets of how you have initialized the asyn uart and code snippets to show transfers from nrf side.

    Have you already verified on the the modem transmit lines (using logic analyzer of oscilloscope) that modem is sending the data correctly?

  • I made an interesting experience:
    The async dma uart handling works fine until the "CONFIG_NETWORKING" config option is added to the prj.conf file.
    Building and running the identical application code, it then runs into the described problem.

    I tried the app without CONFIG_NETWORKING ... then I had no problem with sending/receiving 2000 AT-commands to/from the modem.

    After adding CONFIG_NETWORKING with no other change ... then the app ran into the problem while waiting for the first two status messages from the modem.

    Networking is unfortunately required as the application is going to use mqtt as communication protocol.

  • The async uart dma driver counts the RXRDY events which are raised by the nrf-hardware immediately after detecting a fully received byte, but potentially before transferring it to the dma memory buffer (see nrf52840 datasheet). This counting is done within an ISR. And this counted value is used by the driver logic when executing the timer-timeout event.

    There is some comment within the driver source code (around line 1075 in uart_nrfx_uarte.c) that it might happen that this counting is wrong due to latencies in handling interrupts.

    With the debugger I can confirm, that the driver falls into this "if (len<0) {...}", where wrong counts are handled, in the case that the problem occurs.

    It does not fall into this branch, when CONFIG_NETWORKING is disabled.This is the case where everything works fine.

    So for me it seems that CONFIG_NETWORKING does some ISR handling which takes too long time, blocking the RXRDY isr handling for too long time, which leads to wrong byte counting.

    CONFIG_NETWORKING adds quite a big amount of source code to the project, therefore I am kind of lost where to look for the long-lasting isr handling.

    So I would really appreciate any hint for how to get out of this problem!

  • Finally I managed to find the solution by myself:

    add the following lines to prj.conf:

    CONFIG_UART_0_ASYNC=y
    CONFIG_UART_0_NRF_HW_ASYNC=y
    CONFIG_UART_0_NRF_HW_ASYNC_TIMER=0

    some kind of documentation about this would have helped me a lot.
    menuconfig did not help either, because when setting the timer instance number there, compilation fails afterwards.

Reply Children
No Data
Related