Hello! I am using a nRF52832 device, along with SDK 12.1.0 and S132 v3.0.0. Data is being sent data through BLE and received on an Android phone.
After some tests I noticed that I was not achieving the expected data throughput on the BLE connection. To check what is going on, whenever a TX_COMPLETE
was received, I print the time that has passed since the previous event. The printed times are never bellow 1 connection interval. Since the phone is able to receive more than 1 packet per connection interval, I took the Android BLE snoop file, and analyzed it with Wireshark. I came to the same conclusion, only 1 packet is being transmitted in each connection interval.
I then tried to manually configure the connection for high bandwidth, but achieved the same results. BY default, a peripheral connection is already configured for high bandwidth, a change would also be strange.
To ensure I send the maximum packets possible, I submit packets to be sent until I receive BUSY
, and then wait for a TX_COMPLETE
event to queue some more.
Are there any additional configurations needed in order to send more than 1 packet per connection interval?
Bellow is the function I used to configure the connection.
#define CENTRAL_LINK_COUNT 0
#define PERIPHERAL_LINK_COUNT 1
static void ble_stack_init(void) {
ble_enable_params_t ble_enable_params;
APP_ERROR_CHECK(softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
PERIPHERAL_LINK_COUNT, &ble_enable_params));
// Check the ram settings against the used number of links
CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT, PERIPHERAL_LINK_COUNT);
ble_enable_params.common_enable_params.vs_uuid_count = 2;
ble_conn_bw_counts_t conn_bw_counts = {
.tx_counts = {.high_count = 1, .mid_count = 0, .low_count = 0},
.rx_counts = {.high_count = 1, .mid_count = 0, .low_count = 0}
};
ble_enable_params.common_enable_params.p_conn_bw_counts = &conn_bw_counts;
ble_enable_params.gatts_enable_params.attr_tab_size = 0x800;
// Enable BLE stack.
APP_ERROR_CHECK(softdevice_enable(&ble_enable_params));
ble_opt_t ble_opt;
/* Configure bandwidth and connect as a peripheral */
ble_common_opt_conn_bw_t conn_bw =
{
.role = BLE_GAP_ROLE_PERIPH,
.conn_bw =
{
.conn_bw_rx = BLE_CONN_BW_HIGH,
.conn_bw_tx = BLE_CONN_BW_HIGH
}
};
ble_opt.common_opt.conn_bw = conn_bw;
APP_ERROR_CHECK( sd_ble_opt_set(BLE_COMMON_OPT_CONN_BW, &ble_opt) );
// Register with the SoftDevice handler module for BLE events.
APP_ERROR_CHECK(softdevice_ble_evt_handler_set(ble_on_evt));
// Register with the SoftDevice handler module for BLE events.
APP_ERROR_CHECK(softdevice_sys_evt_handler_set(ble_on_sys_evt));
}
EDIT: Adding notification code for clarification.
uint8_t waiting = 0;
notif_packet_t packet;
static uint32_t send(){
uint32_t ret_code;
while( waiting || get_next_notif_packet( &packet ) ){
ret_code = dispatch( packet );
if( ret_code == BLE_ERROR_NO_TX_PACKETS ){
waiting = 1;
return NRF_SUCCESS;
}
}
waiting = 0;
return NRF_SUCCESS;
}
void on_ble_evt(ble_evt_t * p_ble_evt){
switch (p_ble_evt->header.evt_id) {
case BLE_EVT_TX_COMPLETE:
NRF_LOG_INFO("TX_COMPLETE count: %d. Period = %d \n", p_ble_evt->evt.common_evt.params.tx_complete.count, get_time_diff() );
//Prints count = 1 and period ~ 1 CI
if(waiting)
send();
break;
}
}