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

How to check if the NUS TX Buffer is empty?

Hello,

in our project we have a nRF52840DK as Central and a custom nRF52832 board as Peripheral. The software on the Central is based on the ble_app_uart_c example and the software on the Peripheral is based on the ble_app_uart example. So we are using the NUS to send data over BLE.

We want to expand our software on the Peripheral. For this we need to check, if there are already NUS Packets in the TX Buffer before we call the ble_nus_data_send(...) function and add a new packet.

Can you please tell us, how to implement this properly?

Thank you very much in advance.

Parents Reply
  • Thank you very much for your quick response.

    So we have to add the BLE_GATTS_EVT_HVN_TX_COMPLETE case in the ble_evt_handler(...).

    Then we can create a counter which increases every time we call ble_nus_data_send() and decreases every time a BLE_GATTS_EVT_HVN_TX_COMPLETE event occured, is that right?

    Finally we can use the counter as an indicator for the amount of NUS packets in the TX buffer?

    Thank you very much in advance.

Children
  • Yes, that is correct. (Just make sure to check the count when you get a TX complete event, so that if e.g. it is 2, then you decrement the counter by 2 instead of 1.)

  • Thank you again for your fast reply.

    So when the BLE_NUS_TX_BUFFER variable is the counter for the amount of NUS packets in the TX buffer, then this would be the right implementation?

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint32_t err_code;
    
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_HVN_TX_COMPLETE:
                 BLE_NUS_TX_BUFFER -= p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
                 break;
                 
            ...
        ...
    ...

    Thank you very much in advance.

  • Hello,

    we implemented the counter for the amount of NUS packets in the TX buffer (BLE_NUS_TX_BUFFER) as recommended:

    static int16_t BLE_NUS_TX_BUFFER = 0;
    
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)    // Every 40ms
    {
        ...
        if(BLE_NUS_TX_BUFFER == 0)
        {
            err_code = ble_nus_data_send(&m_nus, stringA, &bytes_to_send, m_conn_handle);
        }
        else
        {
            err_code = ble_nus_data_send(&m_nus, stringB, &bytes_to_send, m_conn_handle);   
        }
        BLE_NUS_TX_BUFFER++;
        ...
    }
    
    
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        switch (p_ble_evt->header.evt_id)
        {
            case BLE_GATTS_EVT_HVN_TX_COMPLETE:
                 BLE_NUS_TX_BUFFER -= p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
                 break;
            ...
        ...
        }
    ...
    }

    We use a Connection Interval of 40ms (min. and max.). Equal to the SAADC callback.

    Our problem is, that our counter BLE_NUS_TX_BUFFER  contains always "1" or higher. It seems, that the TX Buffer is never empty. So the "stringA" gets never sent. 

    Do you know, why the counter BLE_NUS_TX_BUFFER never reach "zero"?

    Thank you very much in advance.

  • Hello,

    t know enough to say for sure, but if you for instance notify every 40 ms and have a connection interval of 40 ms (?) then a possible explanation is that the code snippet that checks buffer filing runs after you have queued a packet but before it has been sent. And this would just continue... Is that what is happening here?

Related