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

Introducing FIFO buffer in uart_data_handler function..

I am working with ble_app_uart code, in that I am trying to send continuous data over BLE. But the BLE getting disconnected while sending large data.

So I planned to have an FIFO buffer which should continuously receive and stores the data(whatever the data size). Then the data should be processed and then it should be sent as frame with the length of 20 bytes. So how to introduce a new buffer and how to handle it with default app_uart_get() buffer.

  • Hi Mani

    The problem is that the example doesn't check if there are any BLE buffers available before calling app_uart_get(..).

    If the call to ble_nus_string_send(..) returns the NRF_ERROR_RESOURCES error it means that all the BLE buffers in the SoftDevice are full, and that you can not upload any more notifications until the BLE_GATTS_EVT_HVN_TX_COMPLETE event occurs.

    In this case you can set a flag in the code to say that the BLE buffers are full, so that you don't read any more data from the UART. Once the BLE_GATTS_EVT_HVN_TX_COMPLETE event occurs there is more room in the buffers, and you can start pulling UART data again.

    For this to work properly you should also use flow control on the UART. Otherwise you might lose bytes over the UART if the UART communication is quicker than the BLE link.

    Using a separate buffer in the application for UART data should not be necessary, since you already have internal buffers in the UART driver and in the SoftDevice.

    Best regards
    Torbjørn

  • BLE_GATTS_EVT_HVN_TX_COMPLETE occurs in which handler, how to check it?

  • The event will be propagated through the main BLE event handler, typically implemented by the following function in main.c:

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    

    If the BLE_GATTS_EVT_HVN_TX_COMPLETE case is not handled you have to add it to the switch case.

    Best regards

  • Hi ..i have the same problem . so to be ensure is it i need to paste the BLE_GATTS_EVT_HVN_TX_COMPLETE in this part ??

    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
    uint32_t err_code;
    ble_nus_t * p_nus = (ble_nus_t *)p_context;
    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_CONNECTED:
    NRF_LOG_INFO("Connected");
    err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
    APP_ERROR_CHECK(err_code);
    m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    ble_nus_t * p_nus = (ble_nus_t *)p_context;
    break;

    case BLE_GAP_EVT_DISCONNECTED:
    NRF_LOG_INFO("Disconnected");
    // LED indication will be changed when advertising starts.
    m_conn_handle = BLE_CONN_HANDLE_INVALID;
    break;

    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
    {
    //notify with empty data that some tx was completed.
    ble_nus_evt_t evt = {
    .type = BLE_NUS_EVT_TX_RDY,
    .p_nus = p_nus
    };
    p_nus->data_handler(&evt);
    app_uart_flush();
    break;
    }

  • Hi Saffiq

    The BLE_GATTS_EVT_HVN_TX_COMPLETE event must be handled in that function, that is correct. 

    Looking at your code I see that the BLE_GATTS_EVT_HVN_TX_COMPLETE case is already there, so you don't have to add it again. 

    What version of the  SDK are you using?
    In the later versions the BLE_GATTS_EVT_HVN_TX_COMPLETE event is handled internally by the ble_nus module itself, and you shouldn't need to do it explicitly in the application. 

    Best regards
    Torbjørn

     

Related