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

NUS wait for message to be sent

Good morning/afternoon/night,

We've started migrating our code from 51822 to 52840.  All is working fine however we still have one issue with NUS (Ble UART).

We use this function to send data over BLE UART:

uint32_t ble_nus_data_send(ble_nus_t * p_nus,
uint8_t * p_data,
uint16_t * p_length,
uint16_t conn_handle)
{
ret_code_t err_code;
ble_gatts_hvx_params_t hvx_params;
ble_nus_client_context_t * p_client;

VERIFY_PARAM_NOT_NULL(p_nus);

err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client);
VERIFY_SUCCESS(err_code);

if ((conn_handle == BLE_CONN_HANDLE_INVALID) || (p_client == NULL))
{
return NRF_ERROR_NOT_FOUND;
}

if (!p_client->is_notification_enabled)
{
return NRF_ERROR_INVALID_STATE;
}

if (*p_length > BLE_NUS_MAX_DATA_LEN)
{
return NRF_ERROR_INVALID_PARAM;
}

memset(&hvx_params, 0, sizeof(hvx_params));

hvx_params.handle = p_nus->tx_handles.value_handle;
hvx_params.p_data = p_data;
hvx_params.p_len = p_length;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;

return sd_ble_gatts_hvx(conn_handle, &hvx_params);


}

We have however a problem when we send too many request using this function and our BT module crashes.

In previous version (nrf51822), we use a variable (called BtDataTxComplete) that was set to 1 once message was sent and set to 0 before each sending.

This variable was set to 1 here:

static void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;

switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
//err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
//APP_ERROR_CHECK(err_code);
LED_On();
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
break;

case BLE_GAP_EVT_DISCONNECTED:
//err_code = bsp_indication_set(BSP_INDICATE_IDLE);
//APP_ERROR_CHECK(err_code);
LED_Off();
isInPushMode = 0;
m_conn_handle = BLE_CONN_HANDLE_INVALID;
BtCommandWasReceived = COMMAND_EMPTY;
break;

case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
APP_ERROR_CHECK(err_code);
break;

case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;

case BLE_EVT_TX_COMPLETE:
BtDataTxComplete = 1;
break;

//case BLE_GATTS_EVT_TIMEOUT:
case BLE_GAP_EVT_TIMEOUT:
BtDataTxComplete = 0;
break;

default:
// No implementation needed.
break;
}
}

taking into account this:

enum BLE_COMMON_EVTS
{
BLE_EVT_TX_COMPLETE = BLE_EVT_BASE, /**< Transmission Complete. @ref ble_evt_tx_complete_t */
BLE_EVT_USER_MEM_REQUEST, /**< User Memory request. @ref ble_evt_user_mem_request_t */
BLE_EVT_USER_MEM_RELEASE /**< User Memory release. @ref ble_evt_user_mem_release_t */
};

and this

#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
#define BLE_EVT_LAST 0x0F /**< Total: 15. */

And we had this function with a small loop waiting for the message to be sent before continuing:

.....

BtDataTxComplete = 0;
err_code = ble_nus_string_send(&m_nus, abuffer, sublength); //Function to send over UART for 51822

if(err_code != NRF_SUCCESS) return 0;
//SYV
int timeout = 100000;
while((BtDataTxComplete == 0)&&(timeout))
{
timeout--;
}; 

....

This was preventing sending too much at the same time.

How should we proceed on nrf52840?

What event handler and what "CASE" should we use to detect message sent if we want to proceed the same way?

void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)?

void nrf_ble_gatt_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)?

We tried both and couldn't reach case "BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE". Is it another "CASE"?

Thank you in advance. Any help appreciated. :-)

Regards,


Francois

Related