I have an nRF 52832 running the SDK 15.2 as peripheral and have tried connecting to different Windows PCs: a laptop running a native bluetooth 5 adapter and a desktop PC running a Laird 851 bluetooth dongle (this is BLE 5 too).
On the connection event, I'm calling the routine sd_ble_gap_phy_update to request an update to 2M PHY, as shown in the following code.
static void ble_stack_init( void )
{
ret_code_t err_code;
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK( err_code );
// Configure the BLE stack using the default settings.
// Fetch the start address of the application RAM.
uint32_t ram_start = 0;
err_code = nrf_sdh_ble_default_cfg_set( APP_BLE_CONN_CFG_TAG, &ram_start );
APP_ERROR_CHECK( err_code );
// Enable BLE stack.
err_code = nrf_sdh_ble_enable( &ram_start );
APP_ERROR_CHECK( err_code );
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER( m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL );
}
static void ble_evt_handler( ble_evt_t const * p_ble_evt, void * p_context )
{
uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
uint16_t role = ble_conn_state_role( conn_handle );
pm_handler_secure_on_connection( p_ble_evt );
switch ( role ) {
case BLE_GAP_ROLE_PERIPH:
periph_mgmt_evt_handler( p_ble_evt, p_context );
break;
case BLE_GAP_ROLE_CENTRAL:
central_evt_handler( p_ble_evt, p_context );
break;
default:
break;
}
}
void periph_mgmt_evt_handler( ble_evt_t const * p_ble_evt, void * p_context )
{
ret_code_t err_code = NRF_SUCCESS;
uint16_t conn_handle;
switch ( p_ble_evt->header.evt_id ) {
case BLE_GAP_EVT_CONNECTED: {
NRF_LOG_INFO( "Connected." );
conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
periph_on_connected_event( common_mgmt_get_conn( conn_handle ), conn_handle );
ble_gap_phys_t const phys = {
.rx_phys = BLE_GAP_PHY_2MBPS,
.tx_phys = BLE_GAP_PHY_2MBPS,
};
err_code = sd_ble_gap_phy_update( p_ble_evt->evt.gap_evt.conn_handle, &phys );
APP_ERROR_CHECK_NON_CRITICAL( err_code );
adjust_advertising();
}
break;
With the Windows laptop this goes as expected, and the connection changes the PHY to 2M. However, with the Laird dongle they get into this weird loop where the nRF is saying it prefers the 2M PHY and the PC says it prefers the coded PHY.
The whole exchange is included here. It appears the nRF is sending an LL_PHY_REQ but, for some reason, the PC is sending 4 identical answers LL_PHY_RSP.
The nRF sends this request, stating that it prefers 2M, as expected.
The PC answers with 4 identical packets (even the sequence number), saying that it prefers coded (not sure why). However, they never seem to agree. I'd expect the nRF to stop sending the request, because the PC is not offering 2M (not sure why).
If I don't send the request, everything works as expected, i.e. they stay in 1M PHY and are able to communicate succesfully.
Thanks!