cancel
Showing results for 
Search instead for 
Did you mean: 

STM32wb55 go to sleep in standby mode but do not wake up with sequencer

PierreL
Associate II

I am trying to use the standby mode. As the datasheet specifies, it can only wake up from this mode from the reset pin, wake-up pin, or RTC trigger.

PierreL_0-1736417343918.png

 


I searched on the internet to find out how to do it.

PierreL_1-1736417376838.pngPierreL_2-1736417393084.png

If I use standby mode like this in the main it works correctly (so without the sequencer):

 

 

  while (1)
  {
    /* USER CODE END WHILE */
    //MX_APPE_Process();

    /* USER CODE BEGIN 3 */
    for (int i = 0; i<5;i++)
    {
    	HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
    	HAL_Delay(50);

    }
	HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN4);
	HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4_LOW);
	/* Clear the WU FLAG */
	 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
		HAL_PWR_EnterSTANDBYMode();
}

 

 



But I use Bluetooth and I have to use the sequencer. And I have a function like this:

void task_foo()
{
	HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);
	count++;
		if (count > 5)
		{
			count = 0;
			HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN4);



			/* Enable WakeUp Pin PWR_WAKEUP_PIN4 connected to PA2 */
			HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4_LOW);
			/* Clear the WU FLAG */
			__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

			/* Enter the Standby mode */
			HAL_PWR_EnterSTANDBYMode();
		}
}

Which is call by a timer:

void TIM1_UP_TIM16_IRQHandler(void)
{
  /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 */
  /* USER CODE END TIM1_UP_TIM16_IRQn 0 */
  HAL_TIM_IRQHandler(&htim16);
  /* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */
  UTIL_SEQ_SetTask(1 << CFG_TASK_FOO, CFG_SCH_PRIO_0);

  /* USER CODE END TIM1_UP_TIM16_IRQn 1 */
}

In this case it does not work.

I found this and this online.

And indeed there is UTIL_SEQ_Idle()

void UTIL_SEQ_Idle(void)
{
#if (CFG_LPM_SUPPORTED == 1)
  UTIL_LPM_EnterLowPower();
#endif /* CFG_LPM_SUPPORTED == 1 */
  return;
}

But you need to set CFG_LPM_SUPPORTED in app_conf.h to 1

/******************************************************************************
 * Low Power
 ******************************************************************************/
/**
 *  When set to 1, the low power mode is enable
 *  When set to 0, the device stays in RUN mode
 */
#define CFG_LPM_SUPPORTED    1

 

 

But now the app goes to sleep immediately because UTIL_SEQ_Idle is used in UTIL_SEQ_run

  if ((local_taskset & local_taskmask & SuperMask) == 0U)
  {
    if ((local_evtset & EvtWaited)== 0U)
    {
      UTIL_SEQ_Idle( );
    }
  }

This can be explain by what the ST employee say :

The reason is that all code added there is unkown from the sequencer that executes UTIL_SEQ_Run() as long as there are pending tasks. When there is no more tasks pending, it calls UTIL_SEQ_Idle() which in turn calls UTIL_LPM_EnterLowPower() that may stop the CPU. So, the code added after UTIL_SEQ_Run() is executed only on the next wakeup which is likely not something you want to do.

But I do always have tasks added to my sequencer so it should never go to sleep until I want it
And if I set CFG_LPM_SUPPORTED to 0 and use UTIL_LPM_EnterLowPower() directly in my task it does not go to sleep. And I am not able to wake up because In this case nothing configure the pin for the wake up before…
I have read the AN5289 and it does say

void UTIL_SEQ_Idle( void )
Called under the critical section (set with the CortexM PRIMASK bit - all interrupts are
masked) when the sequencer does not have any function to execute. This is where the
application must enter the Low-power mode.

I suppose it should look something like this in the end :

HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN4);
/* Enable WakeUp Pin PWR_WAKEUP_PIN4 connected to PA2*/
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN4_LOW);
/* Clear the WU FLAG */
 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
/* Enter the Standby mode */
UTIL_SEQ_Idle();


Environment :
- Target: STM32wb55rg
- Target OS: Baremetal (with seq)
- Host OS: Windows
- Toolchain: CubeIde

 

 

0 REPLIES 0