cancel
Showing results for 
Search instead for 
Did you mean: 

How to update BLE characteristics via timer interrupt in STM32WB55 ?

AndreasC
Associate II

Hello everyone,

I'm trying to use the timer interrupt callback to modify the GATT characteristics and send out a notification (see code excerpt below). This only works once and after sending the message the timer no longer triggers and I no longer see any advertisements from my board. If I send the data via the USB-COM port, it works using the timer interrupt. So there seems to be something wrong with the IPCC but I don't know what it is and how I can fix it/get around it.  can someone help me ?

 

Many Greetings,

Andreas 

 

 

 

 

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  MX_USB_Device_Init();
  MX_TIM16_Init();
  MX_RF_Init();
  /* USER CODE BEGIN 2 */

static uint8_t cnt = 0;
const  uint8_t  max_cnt = 255;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	// Check which version of the timer triggered this callback
	if (htim == &htim16 )
	{
		if (cnt % (max_cnt - 1) == 0) cnt = 0;

		uint8_t data[1];
		memcpy(data, &cnt, sizeof(cnt));
		cnt++;
                
                // only one of the two is active at a time!

                // This part for BLE, works just once!
		// Custom_STM_App_Update_Char(CUSTOM_STM_TEMPERATUR, data);
                
                // This USB-part works allways as desired
		uint16_t data_len = (uint16_t) sizeof(data)/sizeof(uint8_t);
		CDC_Transmit_FS((uint8_t*)data, data_len);
	}
}

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
STTwo-32
ST Employee

Hello @AndreasC 

In fact, you have to add a task that do this on the Sequencer that run all code tasks. So, whenever the sequencer starts, the execution will be only for tasks included on this Sequencer. For the timer, you can use a HW_Timer. More details that can be helpful are available on the AN5289 specially the part 4.5.

Best Regards.

STTwo-32

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

4 REPLIES 4
STTwo-32
ST Employee

Hello @AndreasC 

In fact, you have to add a task that do this on the Sequencer that run all code tasks. So, whenever the sequencer starts, the execution will be only for tasks included on this Sequencer. For the timer, you can use a HW_Timer. More details that can be helpful are available on the AN5289 specially the part 4.5.

Best Regards.

STTwo-32

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello STTwo-32,

thank u for the reply. 

 

I solved my problem just by introducing a simple flag in the interrupt routine which I evaluate in the main loop as follows:

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	// Check which version of the timer triggered this callback
	if (htim == &htim16 )
	{
		if (tim16_cnt >= 5)	// for IPPC sync.
			tim16_flag = 1;
		else
			tim16_cnt++;
	}
}

while (1)
  {
	  __disable_irq();
	  if (tim16_flag){

		  BME280_cmd_res cmd_res = BME280_read_env_data(&bme280);
		  if (cmd_res != BME280_CMD_OK) {
			  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);	// indicate error with LED on PA10
		  }

		  // convert measurement data to the appropriate units for nRF-Connect Application
		  BME280_U32_t hum_prh = (float)bme280.H/kH * 100.0;	// relative humidity in Percent
		  BME280_U32_t pres_pa=  bme280.P/kP * 10;	//in Pascal

		  Custom_STM_App_Update_Char(CUSTOM_STM_TEMPERATURE, (uint8_t *)&bme280.T);
		  Custom_STM_App_Update_Char(CUSTOM_STM_HUMIDITY, (uint8_t *)&hum_prh);
		  Custom_STM_App_Update_Char(CUSTOM_STM_PRESSURE, (uint8_t *)&pres_pa);

		  tim16_flag = 0;
	  }
	  __enable_irq();

    /* USER CODE END WHILE */
    MX_APPE_Process();

    /* USER CODE BEGIN 3 */
  }

 

I was worried about race conditions (although in my case that's not a problem) and disabled the interrupts in the critical area. However, I use the BLE stack in the same area. Is it even allowed to disableoff the interrupts when the BLE stack is active, or how can you protect the critical area from interrupts without an OS when using the STM32WB?

Hello @AndreasC 

Could you please give a better description of what you want to do.

Best Regards.

STTwo-32

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.



Hello STTwo-32,

thanks for asking,
my setup looks like this: I have a custom board based on stm32wb with a sensor (BME280). I want to read the sensor measurement data via I2C in a timer-controlled manner and then distribute it to my devices via BLE. Since I wanted to keep it simple, I don't use a sequencer (as you recommended) but want to set a flag for timer interrupt and do the reading of the measurement data and sending it, in the main routine and then delete the flag again for the next timer interrupt cycle.

This means that I use the same shared variable "timer_flag" in the timer interrupt routine and in the main loop. And I wanted to prevent both from accessing this variable at the same time (this requirement is more of an academic nature, because it could be that I have more complex data than a flag and encounter a similar problem). Since the two events do not really run in parallel but the main loop is interrupted by the timer, I wanted to prevent the timer interrupt while the main loop uses shared variables. My idea was to disable the interrupt in the critical area using __disable_irq() and then enable it using __enable_irq(). This would prevent the timer from triggering and I would have achieved what I wanted. Of course I could stop the timer and remove the flags but I assumed that disabling the interrupts would be faster than stopping the timer and I could also have a similar problem with a pure interrupt (for example from a pin). Since I not only want to prevent the interrupt in the critical area but also use the BLE stack to send my data in the form of characteristics, I wondered whether this would work smoothly, after all the BLE stack relies on the interrupts. And I don't know whether the two cores in the STM32WB use separate interrupt mechanisms.

 

Many greetings,

Andreas