2025-01-13 05:49 AM
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.
I searched on the internet to find out how to do it.
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.
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
Solved! Go to Solution.
2025-01-20 01:12 AM
I found a solution.
I recreated a project based on the ioc from my previous project to try to add a step until it failed or I found the solution.
As the documentation said, you must have no task schedule to enter sleep mode if the sequencer is running. If so the µc will automatically enter sleep mode (if you have CFG_LPM_SUPPORTED to 1).
To wake up you need to configure the pin as interrupt and in the interruption, you have to relaunch a specific task (of the scheduler).
But be careful because it is not the same mode as standby. When you wake up from sleep it does not go to the start (like the reset pin would do). (So I think the consumption is more important than a true standby)
2025-01-15 06:48 AM
Here's some update.
I tried to use the STOP mode 2 in my task like this :
UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_DISABLE);
HAL_DBGMCU_DisableDBGStopMode();
UTIL_LPM_EnterLowPower();
With CFG_LPM_SUPPORTED set to 0, it does not go to sleep.
Of course, in this mode, I change my ioc to be in interrupt rather than wake up pin.
2025-01-20 01:12 AM
I found a solution.
I recreated a project based on the ioc from my previous project to try to add a step until it failed or I found the solution.
As the documentation said, you must have no task schedule to enter sleep mode if the sequencer is running. If so the µc will automatically enter sleep mode (if you have CFG_LPM_SUPPORTED to 1).
To wake up you need to configure the pin as interrupt and in the interruption, you have to relaunch a specific task (of the scheduler).
But be careful because it is not the same mode as standby. When you wake up from sleep it does not go to the start (like the reset pin would do). (So I think the consumption is more important than a true standby)