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

How to access BLE_EVT_TX_COMPLETE?

Hello,

I am getting the error code 0x3004, because I am transmitting data too quickly and filling up the transmission buffers.

From other posts, I know the solution is to wait for the TX_COMPLETE event before I transmit more data. I am transmitting data using the ble_nus_string_send function, then checking the err_code from it.

My question: how do I access the BLE_EVT_TX_COMPLETE event in the main file, so that I can set a condition that will allow me to start transmitting data again over ble_nus?

  • BLE_EVT_TX_COMPLETE is ble event.

    Lets see into one of the SDK example.

    SDK11\examples\ble_peripheral\ble_app_hids_keyboard

    In this example you see that you register a ble_dispatch handler that is called everytime you get BLE event from the softdevice

    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    

    Inside your main you implement this ble_evt_dispatch() funtion to call all the modules that need to listen to ble events. one such module is your main.c file. main.c for example listens to ble events and handles them using on_ble_evt()

    static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
    {
        dm_ble_evt_handler(p_ble_evt);
        bsp_btn_ble_on_ble_evt(p_ble_evt);
        on_ble_evt(p_ble_evt);                                <- This is for main.c
        ble_advertising_on_ble_evt(p_ble_evt);
        ble_conn_params_on_ble_evt(p_ble_evt);
        ble_hids_on_ble_evt(&m_hids, p_ble_evt);
        ble_bas_on_ble_evt(&m_bas, p_ble_evt);
    }
    

    inside on_ble_evt() you can handle BLE_EVT_TX_COMPLETE

    static void on_ble_evt(ble_evt_t * p_ble_evt)
    {
        uint32_t                              err_code;
        ble_gatts_rw_authorize_reply_params_t auth_reply;
    
        switch (p_ble_evt->header.evt_id)
        {
            .....
            .....
            case BLE_EVT_TX_COMPLETE:
                // here you can for example set a flag that the buffer is now free and main() can wait on that flag.
                buffer_is_free  true;
                break;
        }
    }
    

    hope this was clear enough for you

  • thanks Aryan, that was very clear. My implementation uses a global variable for the flag, which works. I was trying to use a boolean pointer, but I had to pass the pointer in on_ble_evt(), then through ble_evt_dispatch(), then through softdevice_ble_evt_handler_set(). I could not pass the pointer into softdevice_ble_evt_handler_set().

    In short, the global variable works, but would it be better to pass a pointer around for the flag?

  • global variable should work just fine, make it volatile so the behavior is predictable.

Related