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

More than 1 packet per CI with S132 V3.0.0

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;
    }
}
Related