2025-07-23 12:09 AM
I am working on an example project: MAC 802 (\STM32Cube\Repository\STM32Cube_FW_WB_V1.21.0\Projects\P-NUCLEO-WB55.Nucleo\Applications\Mac_802_15_4\Mac_802_15_4_Node).
I have added standby mode to this code, but I am unable to wake it up.
After entering standby using RTC, the system does not wake up after MX_APPE_Init();.
My code is as follows:
int main(void)
{
/* Initialize the HAL */
HAL_Init();
Check_Wakeup_Source();
ALGORTM.WakeUp_From_stopM = true;
/* Config code for STM32_WPAN (HSE Tuning must be done before system clock configuration) */
MX_APPE_Config();
ALGORTM.WakeUp_From_stopM = true;
Load_Values_From_FLASH();
/*Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* IPCC initialisation */
MX_IPCC_Init();
// LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
MX_GPIO_Init();
MX_RTC_Init();
MX_I2C3_Init();
MX_TIM1_Init();
MX_TIM2_Init();
MX_TIM17_Init();
// MX_ADC1_Init();
/* Configure RTC to use WUT */
Configure_RTC();
/* Note: On STM32WB, both CPU1 and CPU2 must be in standby mode to set the entire system in standby mode */
if ((LL_PWR_IsActiveFlag_C1SB() != 0)
&& (LL_PWR_IsActiveFlag_C2SB() != 0)
)
{
/* ##### Run after standby mode ##### */
/* Clear Standby flag */
LL_PWR_ClearFlag_C1STOP_C1STB();
LL_PWR_ClearFlag_C2STOP_C2STB();
/* Reset RTC Internal Wake up flag */
LL_RTC_ClearFlag_WUT(RTC);
/* Slow Toggle LED */
//LED_Blinking(LED_BLINK_SLOW);
}
else
{
/* ##### Run after normal reset ##### */
/* Fast Toggle LED in waiting for user-button press */
// WaitForUserButtonPress();
/* Enable wake-up timer and enter in standby mode */
}
ALGORTM.WakeUp_From_stopM = true;
sleep_UUID_sameconn = false;
HAL_GPIO_WritePin(Enable_DS_GPIO_Port,Enable_DS_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(EN_125_GPIO_Port, EN_125_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(PS_125_GPIO_Port,PS_125_Pin, GPIO_PIN_SET);
SET_CONFIG_PAGE(CF_PAGE_1+TXDIS); //0x51
HAL_Delay(37);
SET_CONFIG_PAGE(CF_PAGE_1+TXDIS); //0x51
HAL_Delay(41);
trycount = 0;
successcountuid = 0;
successcountslct = 0;
successchallengecnt = 0;
successtagreadcnt = 0;
i=7;
for(i=0; i<64; i++)
memset(&saverecord[i],0,4);
i=0;
UTTS_Routine(i); // init
//------------------------------------------------- Sensor ultra low power init -------------------------------//
Ism330_Init_ULP();
HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);
HAL_Delay(200);
//Enable_Wakeup_Pins();
//Enter_ULP();
HAL_GPIO_WritePin(Enable_DS_GPIO_Port,Enable_DS_Pin, GPIO_PIN_SET);
if (HAL_TIM_Base_Start_IT(&htim17) != HAL_OK)
{
Error_Handler();
}
int result = 0;
for (int attempt = 0; attempt < 2; ++attempt)
{
HAL_Delay(150);
result = VerifyCertifica();
if (result == 1) {
HAL_GPIO_TogglePin(LED7_GPIO_Port, LED7_Pin);
Flash_Erase_Pages(FLASH_ROM_BAT_ID_ADDRESS, 2);
uint8_t ROM_BAT_ID[4];
memcpy(ROM_BAT_ID, romID, sizeof(ROM_BAT_ID));
uint32_t ROM_BAT_ID_flash;
memcpy(&ROM_BAT_ID_flash, ROM_BAT_ID, sizeof(ROM_BAT_ID_flash));
Flash_Write_Data(FLASH_ROM_BAT_ID_ADDRESS, &ROM_BAT_ID_flash, 1);
ReadAndTransmitFromFlash(FLASH_ROM_BAT_ID_ADDRESS);
break;
}
}
MX_ADC1_Init();
HAL_Delay(10);
battery_typ = batType();
Device_info.bat_level = Read_Battery_Level(battery_typ);
if (HAL_TIM_Base_Stop_IT(&htim17) != HAL_OK)
{
Error_Handler();
}
HW_IPCC_Disable();
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
Configure_RTC();
RTC_WakeUpTimer_Set_LL(0x2524);
Enable_Wakeup_Pins();
EnterStandbyMode();
/* Application init */
MX_APPE_Init();
ALGORTM.TAG_Read_0 = true;
ALGORTM.TTO_config = false;
/* Main Loop */
while (1)
{
}
void Configure_RTC(void)
{
/*##-1- Enables the PWR Clock and Enables access to the backup domain #######*/
/* To change the source clock of the RTC feature (LSE, LSI), you have to:
- Enable the power clock
- Enable write access to configure the RTC clock source (to be done once after reset).
- Reset the Back up Domain
- Configure the needed RTC clock source */
LL_PWR_EnableBkUpAccess();
/*##-2- Configure LSE/LSI as RTC clock source ###############################*/
#ifdef RTC_CLOCK_SOURCE_LSE
/* Enable LSE only if disabled.*/
if (LL_RCC_LSE_IsReady() == 0)
{
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_RCC_LSE_Enable();
#if (USE_TIMEOUT == 1)
Timeout = LSE_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */
while (LL_RCC_LSE_IsReady() != 1)
{
#if (USE_TIMEOUT == 1)
if (LL_SYSTICK_IsActiveCounterFlag())
{
Timeout --;
}
if (Timeout == 0)
{
/* LSE activation error */
LED_Blinking(LED_BLINK_ERROR);
}
#endif /* USE_TIMEOUT */
}
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
/*##-3- Enable RTC peripheral Clocks #######################################*/
/* Enable RTC Clock */
LL_RCC_EnableRTC();
LL_APB2_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
}
#elif defined(RTC_CLOCK_SOURCE_LSI)
if (LL_RCC_LSI1_IsReady() == 0)
{
LL_RCC_ForceBackupDomainReset();
LL_RCC_ReleaseBackupDomainReset();
LL_RCC_LSI1_Enable();
#if (USE_TIMEOUT == 1)
Timeout = LSI_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */
while (LL_RCC_LSI1_IsReady() != 1)
{
#if (USE_TIMEOUT == 1)
if (LL_SYSTICK_IsActiveCounterFlag())
{
Timeout --;
}
if (Timeout == 0)
{
/* LSI1 activation error */
LED_Blinking(LED_BLINK_ERROR);
}
#endif /* USE_TIMEOUT */
}
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);
/*##-3- Enable RTC peripheral Clocks #######################################*/
/* Enable RTC Clock */
LL_RCC_EnableRTC();
LL_APB2_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
}
#else
//#error "configure clock for RTC"
#endif
/*##-4- Configure RTC ######################################################*/
/* Disable RTC registers write protection */
LL_RTC_DisableWriteProtection(RTC);
/* Set prescaler according to source clock */
LL_RTC_SetAsynchPrescaler(RTC, RTC_ASYNCH_PREDIV);
LL_RTC_SetSynchPrescaler(RTC, RTC_SYNCH_PREDIV);
/* Disable wake up timer to modify it */
LL_RTC_WAKEUP_Disable(RTC);
/* Wait until it is allow to modify wake up reload value */
#if (USE_TIMEOUT == 1)
Timeout = RTC_TIMEOUT_VALUE;
#endif /* USE_TIMEOUT */
while (LL_RTC_IsActiveFlag_WUTW(RTC) != 1)
{
#if (USE_TIMEOUT == 1)
if (LL_SYSTICK_IsActiveCounterFlag())
{
Timeout --;
}
if (Timeout == 0)
{
/* LSI activation error */
LED_Blinking(LED_BLINK_ERROR);
}
#endif /* USE_TIMEOUT */
}
/* Setting the Wakeup time to RTC_WUT_TIME s
If LL_RTC_WAKEUPCLOCK_CKSPRE is selected, the frequency is 1Hz,
this allows to get a wakeup time equal to RTC_WUT_TIME s
if the counter is RTC_WUT_TIME */
LL_RTC_WAKEUP_SetAutoReload(RTC, RTC_WUT_TIME);
LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_CKSPRE);
/* Enable RTC registers write protection */
LL_RTC_EnableWriteProtection(RTC);
}
/**
* @brief Function to configure and enter in STANDBY Mode.
* @PAram None
* @retval None
*/
void EnterStandbyMode(void)
{
/* ######## ENABLE WUT #################################################*/
/* Disable RTC registers write protection */
LL_RTC_DisableWriteProtection(RTC);
/* Enable wake up counter and wake up interrupt */
/* Note: Periodic wakeup interrupt should be enabled to exit the device
from low-power modes.*/
LL_RTC_EnableIT_WUT(RTC);
LL_RTC_WAKEUP_Enable(RTC);
/* Enable RTC registers write protection */
LL_RTC_EnableWriteProtection(RTC);
/* ######## ENTER IN STANDBY MODE ######################################*/
/** Request to enter STANDBY mode
* Following procedure describe in STM32WBxx Reference Manual
* See PWR part, section Low-power modes, Standby mode
*/
/* Reset Internal Wake up flag */
LL_RTC_ClearFlag_WUT(RTC);
/* Check that PWR Internal Wake-up is enabled */
if (LL_PWR_IsEnabledInternWU() == 0)
{
/* Need to enable the Internal Wake-up line */
LL_PWR_EnableInternWU();
}
/* Set Standby mode */
LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
/* Set Standby mode of CPU2 */
/* Note: On STM32WB, both CPU1 and CPU2 must be in Standby mode to set the entire system in Standby mode */
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
/* Set SLEEPDEEP bit of Cortex System Control Register */
LL_LPM_EnableDeepSleep();
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM)
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
void Enable_Wakeup_Pins(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// Wakeup pinleri için GPIO clock'larını aktif et
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
// 1. PA0 ve PC5 pinlerini default INPUT (pull yok) moduna al
// PA0 = WakeUp1
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// PC5 = WakeUp5
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// 2. Backup domain erişimini aç (gerekiyorsa)
LL_PWR_EnableBkUpAccess();
// 3. Önce eski konfigürasyonları sıfırla
// LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN1);
LL_PWR_DisableWakeUpPin(LL_PWR_WAKEUP_PIN5);
LL_PWR_ClearFlag_WU();
// 4. WakeUp Pin 1 ve 5'i aktif et (default rising edge ile)
// LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN1); // PA0
LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN5); // PC5
}
void RTC_WakeUpTimer_Set_LL(uint32_t wakeup_counter)
{
/* RTC write protection disable */
LL_RTC_DisableWriteProtection(RTC);
/* WakeUp timer disable before config */
LL_RTC_WAKEUP_Disable(RTC);
/* Wait for WUTWF flag (WakeUp Timer Write Flag) */
while (!LL_RTC_IsActiveFlag_WUTW(RTC));
/* Set wakeup auto-reload value */
LL_RTC_WAKEUP_SetAutoReload(RTC, wakeup_counter);
/* Set wakeup clock divider (RTC/16) */
LL_RTC_WAKEUP_SetClock(RTC, LL_RTC_WAKEUPCLOCK_DIV_16);
/* Clear WUTF flag */
LL_RTC_ClearFlag_WUT(RTC);
/* Enable wakeup interrupt */
LL_RTC_EnableIT_WUT(RTC);
/* Enable EXTI Line 22 for RTC WakeUp */
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_22);
LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_22);
/* Enable RTC WakeUp */
LL_RTC_WAKEUP_Enable(RTC);
/* RTC write protection enable */
LL_RTC_EnableWriteProtection(RTC);
/* Enable NVIC interrupt for RTC WakeUp */
NVIC_SetPriority(RTC_WKUP_IRQn, 0);
NVIC_EnableIRQ(RTC_WKUP_IRQn);
}