cancel
Showing results for 
Search instead for 
Did you mean: 

Connection interval update using BLE_SVC_L2CAP_Conn_Update

Alexander1
Associate II

Hi.

I'm currently implementing an application for test purposes on the STM32WB Nucleo Demoboard. So far I'm very pleased with the experience of adding new services and transvering data. However, to save some energy I want to change the connection interval on my device to 1s or higher. I've enabled L2CAP_REQUEST_NEW_CONN_PARAM and called BLE_SVC_L2CAP_Conn_Update as in the p2p server demo application.

That should start the connection interval change. However, in my case the application gets stuck in UTIL_SEQ_WaitEvt() in while((EvtSet & EvtWaited) == 0) with EvtSet = 0. The p2p server demo application doesn't. I can't find any differences regarding this function so far.

If I understand correctly EvtSet is set by the M0 core handling the BLE stack. Is there anything else i need to set or change to enable the interval change of an established connection?

thank you

1 ACCEPTED SOLUTION

Accepted Solutions
Stecklo
Senior

Maybe you're trying to change connection interval in an interrupt thread?

View solution in original post

7 REPLIES 7
Stecklo
Senior

I'm currently using some outdated version of Cube_FW_WB, so there might be some discrepancy.

The point is: you're right, M0 sets those events, but not directly. It calls handlers that should be implemented on M4.

One pair of them is

void hci_cmd_resp_release(uint32_t flag)
{
  SCH_SetEvt(1 << CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID);
}
 
void hci_cmd_resp_wait(uint32_t timeout)
{
  SCH_WaitEvt(1 << CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID);
}

Another one is set in hci_init()

I'm not really sure which one of those is the one you are looking for, but I think you'll manage to figure it out.

Alexander1
Associate II

Yes. Those are available and are called in other occations (init and connection,...).

However they are not called when I want to change the connection interval while having a established connection as in the p2p server application.

To rule out the chance that I have changed anything while adding my application I started again from scratch according to the STM32WB Workshop and built the p2p server application on my own ( https://www.youtube.com/watch?v=zNfIGh30kSs ). After that I tried to change the connection interval again: Still same result.

Stecklo
Senior

Maybe you're trying to change connection interval in an interrupt thread?

Alexander1
Associate II

Thats it! I had the interval change called in an interrupt handler... which was set to the same priority as all others... ******. Changed the priority and.. it works.

Thank you!

Christophe Arnal
ST Employee

​Hello,

Whatever is the priority of your interrupts, you should not send an ACI command from an interrupt handler.

The reason is that most of the time, ACI commands are sent from the background. When a command is sent, the dedicated channel used is said to be busy as long as the command is waiting for a response.

if you send an ACI command from an interrupt handler, you may just break the requirement to not send a command when the previous one is still pending.

There is one Tx buffer per channel. What may likely happen is that the command sent in interrupt context will overwrite the tx buffer which is currently being processed.

So more or less, you are breaking everything and thr behavior in unpredictable.

A safe way is to just trig a background task from the interrupt handler. This background task is responsible to send the required command.

This is basically what is done in all our examples.

Regards.

In that case I just wanted to test the function as you did in the p2p-server example. Where you also sent the ACI command to change the connection interval in the HAL_GPIO_EXTI interrupt routine. To make it work you also set the that interrupt to the lowest priority.

Now I implemented it in a backround task.

/* Enable and set Button EXTI Interrupt to the lowest priority */
    HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
    HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));

void HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
{
  switch (GPIO_Pin)
  {
    case BUTTON_SW1_PIN:
     APP_BLE_Key_Button1_Action();
      break; 
 
    case BUTTON_SW2_PIN:
      APP_BLE_Key_Button2_Action();
      break; 
 
    case BUTTON_SW3_PIN:
      APP_BLE_Key_Button3_Action();
      break;
 
    default:
      break;
 
  }
  return;
}
void APP_BLE_Key_Button2_Action(void)
{
#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0 )    
    if (BleApplicationContext.Device_Connection_Status != APP_BLE_FAST_ADV && BleApplicationContext.Device_Connection_Status != APP_BLE_IDLE)
  {
    BLE_SVC_L2CAP_Conn_Update(BleApplicationContext.BleApplicationContext_legacy.connectionHandle);
 
  }
  return;
#endif    
}
void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle)
{
/* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_1 */
 
/* USER CODE END BLE_SVC_L2CAP_Conn_Update_1 */
  if(mutex == 1) { 
    mutex = 0;
    index_con_int = (index_con_int + 1)%SIZE_TAB_CONN_INT;
    uint16_t interval_min = CONN_P(tab_conn_interval[index_con_int]);
    uint16_t interval_max = CONN_P(tab_conn_interval[index_con_int]);
    uint16_t slave_latency = L2CAP_SLAVE_LATENCY;
    uint16_t timeout_multiplier = L2CAP_TIMEOUT_MULTIPLIER;
    tBleStatus result;
 
    result = aci_l2cap_connection_parameter_update_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle,
                                                       interval_min, interval_max,
                                                       slave_latency, timeout_multiplier);
    if( result == BLE_STATUS_SUCCESS )
    {
      APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r");
    }
    else
    {
      APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Failed \r\n\r");
    }
  }
/* USER CODE BEGIN BLE_SVC_L2CAP_Conn_Update_2 */
 
/* USER CODE END BLE_SVC_L2CAP_Conn_Update_2 */
  return;
}

Christophe Arnal
ST Employee

​Hello,

Thanks for reporting this.

This should be classified as a bug for the reason I provided.

If the Button2 is pressed at the same time an ACI command is already pending, this will corrupt the tx buffer in the mailbox.

Please, have a look the way APP_BLE_Key_Button1_Action() implemented. That should be the right way to do.

Regards.