Skip to main content
nfei
Associate
March 19, 2019
Question

Something wrong with BLENRG-MS and STM32CubeExpansion_BLE1_4.2.0 sdk, program will trap in infinite loop at SPI_IRQ.

  • March 19, 2019
  • 13 replies
  • 4223 views

I use BLENRG-MS and stm32l07 mcu. Mcu call the APIs to control the BLENRG-MS module.

MCU initialize the ble module and start observer process by calling API,and the process will be terminated in three seconds.

The problem is that program may trap in infinite loop many times. The hci_tl driver is from STM32CubeExpansion_BLE1_4.2.0 packet. so whats the problem?

I found "while()" statement at hci_tl_lowlevel_isr() in STM32CubeExpansion_BLE1_4.2.0 sdk.

thanks.

/**
 * @brief HCI Transport Layer Low Level Interrupt Service Routine
 *
 * @param None
 * @retval None
 */
void hci_tl_lowlevel_isr(void)
{
 /* Call hci_notify_asynch_evt() */
#ifdef HCI_TL
 while(IsDataAvailable())
 {
 hci_notify_asynch_evt(NULL);
 }
#endif /* HCI_TL */
 
 /* USER CODE BEGIN hci_tl_lowlevel_isr */
 
 /* USER CODE END hci_tl_lowlevel_isr */ 
}
static int32_t IsDataAvailable(void)
{
 return (HAL_GPIO_ReadPin(HCI_TL_SPI_EXTI_PORT, HCI_TL_SPI_EXTI_PIN) == GPIO_PIN_SET);
} 

This topic has been closed for replies.

13 replies

francois06
Associate II
June 18, 2019

I've got the same problem in some typical case : when I do an update of firmware by OTA from the PC, I've got a lot of data flowing through the BLUENRG-MS and sometimes (not all the time) the MCU gets stuck inside this infinite loop.

Because the SPI_IRQ pin of the BLUENRG stays high but the list of data is empty.

I don't know how to fix it for the moment.

If someone has an idea please tell us.

francois06
Associate II
June 18, 2019

I've found out that on X-BLE1.4.4.0 they corrected the loop with a return. So the MCU isn't stuck anymore but the problem is still present since the SPI_IRQ of the BLUENRG-MS is still high but the list of data is still empty.

Maybe the BLUENRG-MS itself gets stuck ?

VTell.17
Visitor II
June 27, 2019

Hi. Facing the same problem. Were you guys able to find a solution. Thanks

VRodr
Associate
November 11, 2019

I've got the same problem. I think the problem is related with IRQ/CS specification described in en.DM00133230. ( https://www.st.com/content/ccc/resource/technical/document/errata_sheet/42/a1/65/c4/26/c1/49/2a/DM00133230.pdf/files/DM00133230.pdf/jcr:content/translations/en.DM00133230.pdf ). I'll try to find a solution of this problem following the en.DM00133230.pdf or is there anyone who has found a solution?. Thanks

EHill.19
Associate II
November 29, 2019

I have the same problem

Darren Legge
Associate
December 13, 2019

I have this problem too, if I have a poor bluetooth signal this happens in my application, possibly when the connection drops or is about to.

Did anybody figure out what's going on ?

VTell.17
Visitor II
March 28, 2020

Same problem. Here is what seems to work for me.

Problem description:

Sometime the program is stuck in a forever loop in the interrupt hci_tl_lowlevel_isr. This interrupt is called when the Bluenrg module sets the BNRG_IRQ line high to inform the processor that he has new data ready for him.

The problem occurs when the BNRG_IRQ interrupt is activated while the program is already communicating with the Bluenrg module in the normal thread. The interrupt routine will try to get the new data from the module but will be denied because the SPI interface is locked. Then the program is trapped in hci_tl_lowlevel_isr because the BNRG_IRQ line is always high but it is not possible to access the SPI interface to read the data.

Solution:

This is not the perfect solution because the code generated by CubeMX is modified. Therefor you will need to add the extra code everytime you generate a new code from CubeMX.

In the interrupt routine hci_tl_lowlevel_isr I check if the SPI interface is accessible. In case it is not accessible (HAL_LOCKED) I setup a flag so the program can check the new data later outside the interrupt.

void hci_tl_lowlevel_isr(void)

{

      if (hspi1.Lock == HAL_LOCKED){

             SPIwasLocked = 1;

             return;

      }

 while(IsDataAvailable())

 {       

   if (hci_notify_asynch_evt(NULL))

   {

     return;

   }

 }

 /* USER CODE BEGIN hci_tl_lowlevel_isr */

 /* USER CODE END hci_tl_lowlevel_isr */

}

Then in the MX_BlueNRG_MS_Process function I check the previous flag. In case it is set I call the interrupt routine to process the pending data

void MX_BlueNRG_MS_Process(void)

{

 /* USER CODE BEGIN BlueNRG_MS_Process_PreTreatment */

      if (SPIwasLocked == 1){

             SPIwasLocked = 0;

             hci_tl_lowlevel_isr();

      }

      User_Process();

      hci_user_evt_proc();

 /* USER CODE END BlueNRG_MS_Process_PreTreatment */

 /* USER CODE BEGIN BlueNRG_MS_Process_PostTreatment */

 /* USER CODE END BlueNRG_MS_Process_PostTreatment */

}

Let me know if you have other suggestion.

BErik.1
Associate
February 26, 2024

We're using a work-around similar to yours:

void hci_tl_lowlevel_isr(void) {
 if (hspi1.Lock == HAL_LOCKED){
 SPIwasLocked = 1;
 return;
 }


but perhaps this problem was fixed in https://github.com/STMicroelectronics/stm32l4xx_hal_driver/commit/e49465048ae4329091e031dd9ae93fed1c2e3389 ?

aj.sk
Associate III
October 26, 2021

Has this issue ever been analyzed by STM? I seem to run into the same problem but the approach with checking the hspi1.Lock doesn't work reliably. Sometimes the state is HAL_UNLOCKED but I'm still stuck in the while-loop.

Darren Legge
Associate
October 26, 2021

I never quite got to the bottom of it and was very careful to disable the interrupt when using SPI during non-interrupt time.

In the end, I just disabled the interrupt in the ISR if I detected it was stuck there. Basically, this :

void hci_tl_lowlevel_isr(void) {
 /* USER CODE BEGIN hci_tl_lowlevel_isr */
 /* Call hci_notify_asynch_evt() */
 static uint8_t bt_stuck_counter;
 
 while(IsDataAvailable()) {
 if (hci_notify_asynch_evt(NULL)) {
 // If we get stuck here, disable the interrupt (and flag to reset BT controller?)
 if (bt_stuck_counter++ > 10) {
 HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
 break;	// Out of while.
 }
 }
 else
 bt_stuck_counter = 0;
 }
 /* USER CODE END hci_tl_lowlevel_isr */
}

The interrupt is re-enabled frequently in the main code (just after any normal SPI access is performed). It seems to work as far as I have tested it.

aj.sk
Associate III
October 26, 2021

And will this usually terminate the connection or would the master just have to re-send the request?