cancel
Showing results for 
Search instead for 
Did you mean: 

BLE HeartRateMonitor FREERTOS notify problem

KMeld.1
Associate III

Dear ST

I'm working on a custom board, trying to adapt the BLE_HeartRateFreeRTOS to work on a STM32WB55CEU6. So far i have been able to discover and connect to the MCU and call the characteristics in the Heart Rate service:

  • Body Sensor Location
  • Heart Rate Control point
  • As well as the generic and device services.

I can see the MCU does receive the HRS_NOTIFICATION_ENABLED/DISABLED notifications, as I'm able to toggle an LED in this callback. It seems like the HW-timer does not run properly. NOTE: the MCU does not crash, it just doesn't notify the client.

Setup:

  • MCU: STM32WB55CEU6
  • Code generated with CubeMX 6.2.1
  • Toolchain: Makefile

Relevant code:

Below is the void HRS_Notification(HRS_App_Notification_evt_t *pNotification) implementation:

void HRS_Notification(HRS_App_Notification_evt_t *pNotification) {
    /* USER CODE BEGIN HRS_Notification_1 */
 
    /* USER CODE END HRS_Notification_1 */
    switch (pNotification->HRS_Evt_Opcode) {
/* USER CODE BEGIN HRS_Notification_HRS_Evt_Opcode */
 
/* USER CODE END HRS_Notification_HRS_Evt_Opcode */
#if (BLE_CFG_HRS_ENERGY_EXPENDED_INFO_FLAG != 0)
        case HRS_RESET_ENERGY_EXPENDED_EVT:
            /* USER CODE BEGIN HRS_RESET_ENERGY_EXPENDED_EVT */
            HRSAPP_Context.MeasurementvalueChar.EnergyExpended = 0;
            HRSAPP_Context.ResetEnergyExpended = 1;
            /* USER CODE END HRS_RESET_ENERGY_EXPENDED_EVT */
            break;
#endif
 
        case HRS_NOTIFICATION_ENABLED:
            /* USER CODE BEGIN HRS_NOTIFICATION_ENABLED */
            /**
             * It could be the enable notification is received twice without the disable notification in between
             */
 
            HW_TS_Stop(HRSAPP_Context.TimerMeasurement_Id);
            HW_TS_Start(HRSAPP_Context.TimerMeasurement_Id, HRSAPP_MEASUREMENT_INTERVAL);
            led1_blink_delay = 100;
            /* USER CODE END HRS_NOTIFICATION_ENABLED */
            break;
 
        case HRS_NOTIFICATION_DISABLED:
            /* USER CODE BEGIN HRS_NOTIFICATION_DISABLED */
            led1_blink_delay = 500;
            HW_TS_Stop(HRSAPP_Context.TimerMeasurement_Id);
            /* USER CODE END HRS_NOTIFICATION_DISABLED */
            break;
 
#if (BLE_CFG_OTA_REBOOT_CHAR != 0)
        case HRS_STM_BOOT_REQUEST_EVT:
            /* USER CODE BEGIN HRS_STM_BOOT_REQUEST_EVT */
            *(uint32_t *)SRAM1_BASE = *(uint32_t *)pNotification->DataTransfered.pPayload;
            NVIC_SystemReset();
            /* USER CODE END HRS_STM_BOOT_REQUEST_EVT */
            break;
#endif
 
        default:
            /* USER CODE BEGIN HRS_Notification_Default */
 
            /* USER CODE END HRS_Notification_Default */
            break;
    }
    /* USER CODE BEGIN HRS_Notification_2 */
 
    /* USER CODE END HRS_Notification_2 */
    return;
}

Clock config (sorry for poor resolution):

0693W00000BbDDVQA3.png 

Regards

1 ACCEPTED SOLUTION

Accepted Solutions
KMeld.1
Associate III

Dear @Walid ZRELLI​  & @Remi QUINTIN​ 

I've done some digging around on in the forum. It seems the Hardware timers is a viable substitute for the Hardware-Time-server - My application is not using all of them.

I'm getting the results a want with (periodic notify that updates a characteristic):

Logic:

/** In custom_app.c **/
...
void Custom_APP_Init(void)
{
/* USER CODE BEGIN CUSTOM_APP_Init */
	// Register additional tasks - eg for notify
	APP_DBG_MSG("\n**APP INIT BEGINING**\n");
	UTIL_SEQ_RegTask(1<<CFG_TASK_SAMPLES_NOTIFY, UTIL_SEQ_RFU, vibration_sample_action );
 
	// register timers - for notify callback
 
//	HW_TS_Create(CFG_TIM_PROC_ID_ISR, &Custom_App_Context.Update_timer_Id, hw_ts_Repeated, Sample_update_callback);
 
	// Init the context
	Custom_App_Context.Sample_not_value.Max = 0xFF;
	Custom_App_Context.Sample_not_value.Min = 0x00;
	Custom_App_Context.Sample_not_value.Value = Custom_App_Context.Sample_not_value.Min;
	Custom_STM_App_Update_Char(CUSTOM_STM_VIB_SAM, DUMMY_DATA);
 
	APP_DBG_MSG("\n**APP_INIT FINISHED!**\n");
/* USER CODE END CUSTOM_APP_Init */
  return;
}
 
...
 
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
 
	if (htim == &htim16){
		// callback to SAMPLE_NOTIFY_CHARACTERISTIC enabled
//		APP_DBG_MSG("\n## Sample_update_callback() ##\n");
		UTIL_SEQ_SetTask(1<<CFG_TASK_SAMPLES_NOTIFY, CFG_SCH_PRIO_0);
	}
}
 
static void vibration_sample_action(void){
	NotifyCharData[0] = Custom_App_Context.Sample_not_value.Value;
	++Custom_App_Context.Sample_not_value.Value;
	NotifyCharData[1] = Custom_App_Context.Sample_not_value.Value;
	++Custom_App_Context.Sample_not_value.Value;
 
	if (Custom_App_Context.Sample_not_value.Value > Custom_App_Context.Sample_not_value.Max){
		// reset
		Custom_App_Context.Sample_not_value.Value = Custom_App_Context.Sample_not_value.Min;
	}
 
//	Custom_Vib_not_Update_Char();
	Custom_Vib_not_Send_Notification();
}
/* USER CODE END FD_LOCAL_FUNCTIONS*/

Timer configuration:

0693W00000Bbf6IQAR.png+ TIM16 --> NVIC Settings --> Enable interupt

View solution in original post

5 REPLIES 5

Hello @KMeld.1​ ,

Can you give us more details about your problem and how we can reproduce it?

Otherwise, are you using the example provided by ST?

BeST Regards,

Walid

KMeld.1
Associate III

Hi @Walid ZRELLI​ - thanks for getting back so quickly.

EDIT:

After watching the workshops (from 2019) again, https://www.youtube.com/watch?v=zNfIGh30kSs & https://www.youtube.com/watch?v=tPqHUqiWsvs, I think this could be related to the LSE and RF-wakeup? Though I'm pretty sure my custom board is build according to the recomendations given by ST. 

Steps to reproduce

CubeMX

  • Create a new STM32CubeMX project
    • Select the STM32WB55CEUx MCU
  • Configure the MCU 1:1 with the BLE_HeartRateFreeRTOS:
    • System Core
      • HSEM: activated
      • IPCC avticated
        • RX/TX interrupts enabled
      • Select "Crystal/Ceramic Resonator" for both HSE & LSE (32MHz and 33.768kHz respectively - both within specs in application note)
      • Sys->Timebase Source: TIM17
      • In my case: SYS->Debug: JTAG 5 pins
    • Timers
      • RTC-> Activate Clock source
    • Middleware
      • FreeRTOS -> Interface: CMSIS_V2
        • Configuration is 1:1 with example
      • STM32_WPAN -> BLE: check
        • Server mode --> BT SIG Heart Rate Sensor: enabled
        • Otherwise 1:1 with example
    • Clock Config: See image in my initial post
    • GPIO
      • I have set PB1 as GPIO_Output (labeled LED_1)
  • Generate Code using Makefile toolchain

Code:

  • main.h
    • declare extern "debugging" variable (yes this is not to pretty):
/* USER CODE BEGIN Private defines */
extern uint16_t led1_blink_delay;
/* USER CODE END Private defines */
  •  
  • app_freertos.c
    • Add:
/* USER CODE BEGIN RTOS_THREADS */
    /* add threads, ... */
    // start BLE threads
    APPE_Init();
    /* USER CODE END RTOS_THREADS */
  • and implement defaultTask:
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument) {
    /* USER CODE BEGIN StartDefaultTask */
    led1_blink_delay = 500;  // [ms]
    /* Infinite loop */
    for (;;) {
        HAL_GPIO_TogglePin(LED_1_GPIO_Port, LED_1_Pin);
        vTaskDelay(led1_blink_delay / portTICK_PERIOD_MS);
    }
    /* USER CODE END StartDefaultTask */
}
  •  
  • hrs_app.c
    • I have bassically copied the implementation from example (whole file)
    • In 'HRS_NOTIFICATION_ENABLED' & 'HRS_NOTIFICATION_DISABLED' i set the extern variable 'led1_blink_delay' for debugging.

Notes:

  • I have NOT implemented 'Config_HSE()' in main.c as i have not calibrated the Crystal - I assumed it is not needed as I'm able to pair with the MCU from smartphone.

Hope all this makes sense.

Regards

Hello @KMeld.1​ ,

In order to check if there's an issue with the clock, could you configure the MCO pin to output the clock and view it in a scope. If there's a perturbation it should be (after some looking around) visible there.

Maybe @Remi QUINTIN​  can provide some more hints regarding this case.

BeST Regards,

Walid

KMeld.1
Associate III

Dear @Walid ZRELLI​  & @Remi QUINTIN​ 

I've done some digging around on in the forum. It seems the Hardware timers is a viable substitute for the Hardware-Time-server - My application is not using all of them.

I'm getting the results a want with (periodic notify that updates a characteristic):

Logic:

/** In custom_app.c **/
...
void Custom_APP_Init(void)
{
/* USER CODE BEGIN CUSTOM_APP_Init */
	// Register additional tasks - eg for notify
	APP_DBG_MSG("\n**APP INIT BEGINING**\n");
	UTIL_SEQ_RegTask(1<<CFG_TASK_SAMPLES_NOTIFY, UTIL_SEQ_RFU, vibration_sample_action );
 
	// register timers - for notify callback
 
//	HW_TS_Create(CFG_TIM_PROC_ID_ISR, &Custom_App_Context.Update_timer_Id, hw_ts_Repeated, Sample_update_callback);
 
	// Init the context
	Custom_App_Context.Sample_not_value.Max = 0xFF;
	Custom_App_Context.Sample_not_value.Min = 0x00;
	Custom_App_Context.Sample_not_value.Value = Custom_App_Context.Sample_not_value.Min;
	Custom_STM_App_Update_Char(CUSTOM_STM_VIB_SAM, DUMMY_DATA);
 
	APP_DBG_MSG("\n**APP_INIT FINISHED!**\n");
/* USER CODE END CUSTOM_APP_Init */
  return;
}
 
...
 
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
 
	if (htim == &htim16){
		// callback to SAMPLE_NOTIFY_CHARACTERISTIC enabled
//		APP_DBG_MSG("\n## Sample_update_callback() ##\n");
		UTIL_SEQ_SetTask(1<<CFG_TASK_SAMPLES_NOTIFY, CFG_SCH_PRIO_0);
	}
}
 
static void vibration_sample_action(void){
	NotifyCharData[0] = Custom_App_Context.Sample_not_value.Value;
	++Custom_App_Context.Sample_not_value.Value;
	NotifyCharData[1] = Custom_App_Context.Sample_not_value.Value;
	++Custom_App_Context.Sample_not_value.Value;
 
	if (Custom_App_Context.Sample_not_value.Value > Custom_App_Context.Sample_not_value.Max){
		// reset
		Custom_App_Context.Sample_not_value.Value = Custom_App_Context.Sample_not_value.Min;
	}
 
//	Custom_Vib_not_Update_Char();
	Custom_Vib_not_Send_Notification();
}
/* USER CODE END FD_LOCAL_FUNCTIONS*/

Timer configuration:

0693W00000Bbf6IQAR.png+ TIM16 --> NVIC Settings --> Enable interupt

Hello @KMeld.1​ ,

Glad to see that you resolved your issue and thanks for sharing the solution.

BeST Regards,

Walid