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

LIBUARTE on ble_app_uart with DMA

Hi All,

I have 2 boards nrf52840 pc10056 and I need to run ble_app_uart using LIBUARTE with DMA in order to obtain a more robust uart communication

I would like to use an uart DMA that will work in background saving the byte received in a buffer (fixed length) and once that it is full having an interrupt where I can check this buffer and send it to the central unit.

Is there any easy way to set  everything up and change the code of ble_app_uart? Any suggestion??

Thanks

  • Hi

    Thank you for the clarification! Is by any chance the TX buffer not cleared after sending a message, and that is what is causing this error? If not, are you able to get an error code so we can see where exactly this error originates?

    Best regards,

    Simon

  • Hi,

    I do not use any TX buffer (not that I know). Because in this case I'm not writing on the UART, I'm just reading, sending to the central and make free the RX buffer. 

    I cannot get an error code. In the code that I put back here, there is APP_ERROR_CHECK(err_code), but the program does not go there.

    void uart_event_handler(void * context, nrf_libuarte_async_evt_t * p_evt)
    {
        nrf_libuarte_async_t * p_libuarte = (nrf_libuarte_async_t *)context;
        uint32_t       err_code;
        ret_code_t ret;
    
        switch (p_evt->type)
        {
            case NRF_LIBUARTE_ASYNC_EVT_ERROR:
                bsp_board_led_invert(1);
                break;
            case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
                bsp_board_led_invert(2);
                err_code= ble_nus_data_send(&m_nus, p_evt->data.rxtx.p_data, &p_evt->data.rxtx.length, m_conn_handle);
                do
                {
                    if ((err_code != NRF_ERROR_INVALID_STATE) &&
                        (err_code != NRF_ERROR_RESOURCES) &&
                        (err_code != NRF_ERROR_NOT_FOUND))
                    {
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_RESOURCES);
                nrf_libuarte_async_rx_free(p_libuarte, p_evt->data.rxtx.p_data , p_evt->data.rxtx.length);    // if I remove this line of code I will have more or less the same behavior 
                break;
            case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
                bsp_board_led_invert(3);
                break;
            default:
                break;
        }
    }

  • What about the RX buffer on the central side? Do you clear that one after printing as well, or does it just fill up?

    Have you stepped through your code to see why you never reach the APP_ERROR_CHECK()? If you set the check outside of the if-loop so you get it no matter what the error code, you should be able to see it.

    Best regards,

    Simon

  • Hello,

    I left the central in the way that it is on SDK 15.3 that Nordic released. The only thing I changed was to commented out the ECHO function in order to do not send back data to the peripheral. My idea was to work before on the peripheral and, once it works, moving on the central.

    The program stops here:

    SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));

    Assuming that the packet is long, for example, 75 characters. If I set a rx_buffer of 150 characters, from the "central" side I will see only 2 packets.

    NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 3, 0, 4, 150, 3);

    Basically the programs will call the following function 3 times:

    return sd_ble_gatts_hvx(conn_handle, &hvx_params);

    the first 2 times it works, in the third it will hang (On the peripheral side).

    If I increase the RX_buffer for example at 225 (3x75)

    NRF_LIBUARTE_ASYNC_DEFINE(libuarte, 0, 3, 0, 4, 225, 3);

    the program will call 4 times "sd_ble_gatts_hvx" but on the 4th it will stop. But from this function I cannot get any error because the program never return from there.

    The path of the error is:

    It will finish in:  "Unknown function at 0x00000A60"

  • Hi 

    You might be seeing a SoftDevice assert because you won't be able to step debug the application code when the SoftDevice is enabled. If you want to step through the code you need to use what is called Monitor Mode Debugging that you can read here. You need to get a return value from sd_ble_gatts_hvx for us to be able to see what exactly goes wrong.

    Are you employing double buffering in your application? I found this thread which explains this quite well. Could you try implementing something like that, and fill one RX buffer while the other one is transferring and emptying?

    Best regards,

    Simon

Related