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