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

  • 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?

  • static void Qud_Init()
    {
        uart_callback_set( Qud_uartDevice, 
                           Qud_DmaUartCallback, 
                           NULL );
    
        uart_rx_enable( Qud_uartDevice,
                        dmaBuffer->data,  
                        sizeof( dmaBuffer->data ), 
                        1000 /* us */ );
    }
    
    
    
    
    static void Qud_DmaUartCallback( const struct device* dev,
                                     struct uart_event*   evt,
                                     void*                user_data)
    {
        switch ( evt->type )
        {
            case UART_RX_RDY:
                {
                    Qud_RxQueueEntry_T e = QUD_RX_QUEUE_ENTRY_INIT;
    
                    e.length = evt->data.rx.len;
                    memcpy( e.data, 
                            &( evt->data.rx.buf[ evt->data.rx.offset ] ),
                            evt->data.rx.len );
    
                    k_msgq_put( &Qud_rxQueue, 
                                &e, 
                                K_NO_WAIT );
                }
                break;
                
            default:
                break;
        }
    }

    There is also a logic analyzer connected. The modem sends the data properly.


    As mentioned in my post before: The data is not lost, but it is received with a more or less big delay .... depending on point when the modem sends the next bytes (usually part of the next command).

    The code is part of a battery-powered device, where the activation time of the modem is quite critical for the overall power-consumption. Therefore we are interested in having as short delays as possible during the modem communication.

    As the uart-callback function is called from an isr-context I tried various different message passing variants. It seemed that all of them did not make any difference for this problem. The one here uses a very simple message queue without any optimizations.

  • I made the observation that the problem seems to show up only in debug mode. When building in release mode, I cannot see that kind of problem.
    In our configuration the debug mode is mainly specified as:

    CONFIG_DEBUG=y
    CONFIG_SIZE_OPTIMIZATIONS=n
    CONFIG_DEBUG_OPTIMIZATIONS=y
    CONFIG_ASSERT=y
    CONFIG_LOG=y

  • After some more hours of testing the problem occurred also in release mode. But substantially less often.

  • That kind of issues normally happens in some variables (normally global variables) when accessed in different contexts. 

    In you code 

    k_msgq_put( &Qud_rxQueue, &e, K_NO_WAIT );

    Check how you declared "e" and how you are accessing it. It looks like there could data access issue. I cannot be sure that the issue is just with this variable, but there is not much code to review.  In any case, i am quite confident that the issue is most likely in the code changes you did in your application. It would help to attach the whole setup (files) so that I can replicate this issue and assist you better.

Related