cancel
Showing results for 
Search instead for 
Did you mean: 

Watchdog functionality in Sleep mode for STM32U535CET microcontroller

shwetapal02
Associate II

Hello,

I am facing reset problem when I am waking up from Sleep mode. I am using WWDG in Software mode.

APB1 Frequency as 40MHz. COnfiguration of WWDG:

hwwdg.Instance = WWDG;

hwwdg.Init.Prescaler = WWDG_PRESCALER_128;

hwwdg.Init.Window = 127;

hwwdg.Init.Counter = 127;

hwwdg.Init.EWIMode = WWDG_EWI_DISABLE;

 

I am calling MX_WWDG_Init function after initialization of peripherals and functionality needed.

Then I am refreshing it in while loop of main function.

1st Tested Scenario:

While entering sleep mode I just refresh the WWDG. Then by waking up

from sleep mode by push button, I am getting reset and it's started from main function again instead of Re-init function.

2nd Tested Scenario:

While entering in sleep mode, I am refreshing WWDG first, then disabling APB1 clock and after that

when I wake up from push button I am enabling the APB1 clock. In this scenario I assumed that WWDG

clock should be stop in sleep mode and it should resume after wakeup.

When controller wakes up by pressing button, I am getting reset.

Please suggest me the setting if I am missing anything.

 

1 ACCEPTED SOLUTION

Accepted Solutions
Sarra.S
ST Employee

so, just before entering stop mode, refresh the WWDG counter: 

void SleepControlTask(void)
{
    delayStop(&SleepWakeUpDelay);
    SleepACK = false;
    HAL_WWDG_Refresh(&hwwdg); // Refresh WWDG before entering sleep mode
    SleepWakeUpMode();
}
void SleepWakeUpMode(void)
{
    GPIO_deInit();
    __HAL_RCC_RTC_DISABLE();
    HAL_PWR_EnableBkUpAccess();
    HAL_SuspendTick();
    HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
    __HAL_RCC_RTC_ENABLE();
    HAL_ResumeTick();
    SystemClock_Config();
    HAL_WWDG_Refresh(&hwwdg); // Refresh WWDG immediately after waking up
}

and when exiting stop mode, re-enable the WWDG clock and re-initialize it  

// After waking up from sleep mode
__HAL_RCC_WWDG_CLK_SLEEP_ENABLE(); // Re-enable the WWDG clock after waking up
MX_WWDG_Init(); // Re-initialize the WWDG
HAL_WWDG_Refresh(&hwwdg); // Refresh the WWDG counter

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

7 REPLIES 7
Sarra.S
ST Employee

Hello @shwetapal02, Welcome to ST Community, 

Please check this bit in the RCC_APB1SMENR1 register

SarraS_0-1732723813359.png

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello @Sarra.S

Thanks for reply. I am setting and resetting the suggested bit by calling below function.

I am calling __HAL_RCC_WWDG_CLK_SLEEP_ENABLE(); after waking up and calling __HAL_RCC_WWDG_CLK_SLEEP_DISABLE(); function during going in sleep mode. But Once it woke up from sleep mode (by pressing button) it is giving me reset. 

I am not able to understand why?

I tried this scenario with WWDG_SW 0 and 1 in both case. But it's not working.

Please help me ASAP.

Hello,

I need support for the above issue on urgent basis. Please help for the same.

Thanks, your understanding and kind support!!

Hello again, 

can you share you code so I can quickly help you!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello,
Please find the code details:

typedef enum
{
INIT_STATE = 0U,
RE_INIT_STATE,
DE_INIT_STATE
}InitStateInfo_te;

uint16_t TaskControl(const uint8_t taskID, const uint8_t taskCtl, task_ts* scheduleTable){

return (scheduleTable[taskID].control = taskCtl);

}

void Init(void)
{
/* system clock initialization */
SystemClock_Config();
/* GPIO initialization */
MX_GPIO_Init();
/* GPDMA1 initialization */
MX_GPDMA1_Init();
/* SAI1 initialization */
MX_SAI1_Init();
/* CRC initialization */
MX_CRC_Init();
/* USART1 initialization */
MX_USART1_UART_Init();
/* I2C1 initialization */
MX_I2C1_Init();
/* i2C2 initialization */
MX_I2C2_Init();
/* call the charger initialization function */
MP2722ChargerInitialisation();
/* call the charger initialization function */
AudioUSBInit();
BatteryStateMachine(BATTERY_CONFIGURATION_INIT);

MX_WWDG_Init();

InitInfo.InitState = ALL_INIT_COMPLETED_U8;
}

/********************************************************************************
 * Function Name: ReInit
 * Description: ReInit function will re-initialization the system peripherals
 * Power-Up from sleep.
 * There are following peripherals which need to initialize
 * @ ReInitialization()
 * @ MX_GPDMA1_Init()
 * @ MX_SAI1_Init()
 * @ MP2722ChargerInitialisation()
 * @ AudioUSBInit()
 * Parameter: void
 * Return: void
 *******************************************************************************/
void ReInit(void)
{
/* GPIO re-initialization */
ReInitialization();
/* GPDMA1 re-initialization */
MX_GPDMA1_Init();
/* SAI1 re-initialization */
MX_SAI1_Init();
/* Audio re-initialization */
AudioUSBInit();
HAL_SAI_DMAResume(&hsai_BlockA1);
/* call the charger re-initialization function */
MP2722ChargerInitialisation();
MX_Watchdog_Refresh();
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
MX_WWDG_Init();
MX_Watchdog_Refresh();
/* set the information in initalization state */
InitInfo.InitState = ALL_INIT_COMPLETED_U8;
}

void ApplicationInit(void)
{
/* Initstateinfo will define the current iniit state */
switch(InitStateInfo)
{
/* Init state will work when first time battery will insert */
case INIT_STATE:
{
/* init function call which initialize the all system peripherals first */
Init();
if(ALL_INIT_COMPLETED_U8 == InitInfo.InitState)
{
/* On sucessfully complete the all system initialization state will change to De-init
* to go into Sleep Mode on first System Power On
*/
InitStateInfo = DE_INIT_STATE;
}
break;
}
case RE_INIT_STATE:
{
/* Re-init function will call when user will Power On the system */
//RCC->APB1ENR1 |= RCC_APB1ENR1_WWDGEN; // Enable WWDG clock
//WWDG->CR = WWDG_CONTROL_CONFIG;      // Reinitialize WWDG control register
ReInit();
/* check the initialization is completed or not. */
if(ALL_INIT_COMPLETED_U8 == InitInfo.InitState)
{
SetAppicationState(RUNNING_STATE_U8);
TaskControl(APPLICATION_INTI_TASK_ID, SCH_TASK_DISABLE, ApplicationTask);
TaskControl(BATTERY_CONTROL_TASK_ID, SCH_TASK_ENABLE, ApplicationTask);
BatteryStateMachine(BATTERY_DATA_FATCHING);
SetLEDStates(LED_RUNNING_STATE);
TaskControl(BUTTON_CONTROL_TASK_ID, SCH_TASK_ENABLE, ApplicationTask);
TaskControl(CHARGER_CONTROL_TASK_ID, SCH_TASK_ENABLE, ApplicationTask);
TaskControl(POWER_CONTROL_TASK_ID, SCH_TASK_ENABLE, ApplicationTask);
TaskControl(DEBOUNCE_CONTROL_TASK_ID, SCH_TASK_ENABLE, ApplicationTask);
//HAL_TIM_Base_Stop_IT(&htim3);
}
break;
}
/* De-init state will set when system is going into sleep and need to de-init specific
* system peripherals
*/
case DE_INIT_STATE:
{

MX_Watchdog_Refresh();

//RCC->APB1ENR1 = 0x00000000; // Disable all APB1 peripherals in ENR1
//RCC->APB1ENR2 = 0x00000000; // Disable all APB1 peripherals in ENR2
HAL_SAI_DeInit(&hsai_BlockA1);
BatteryStateMachine(BATTERY_DATA_FATCHING);
SetLEDStates(LED_SLEEP_STATE);
TaskControl(BUTTON_CONTROL_TASK_ID, SCH_TASK_DISABLE, ApplicationTask);
TaskControl(CHARGER_CONTROL_TASK_ID, SCH_TASK_DISABLE, ApplicationTask);
TaskControl(POWER_CONTROL_TASK_ID, SCH_TASK_DISABLE, ApplicationTask);
RCC->APB1ENR1 &= ~RCC_APB1ENR1_TIM2EN;//disable APB1 clock
SetAppicationState(SLEEP_STATE_U8);
}
default:
{
/* Do Nothing */
break;
}
}
}


void AppInitTask(void)
{
/* function define for init return state */
uint8_t CheckAppInitReturnStatus = INIT_OK_U8;
ApplicationInit();
/* case for check the return state */
switch(CheckAppInitReturnStatus)
{
/* case for init is completed sucessfully */
case INIT_OK_U8:
{
break;
}
/* case for when init will failted */
case INIT_FAILED_U8:
{
break;
}
/* case when init hase some error */
case INIT_ERROR_U8:
{
break;
}
default:
{
/* Do Nothing */
}
}
}
typedef enum
{
INIT_STATE_U8 = 0U,
RUNNING_STATE_U8 = 1U,
FAULT_HANDLING_STATE_U8 = 2U,
SLEEP_STATE_U8 = 3U,
WAKEUP_STATE = 4U,
CHARGER_MODE = 5U,
USB_MODE = 6U,
USB_TYPE_DETECTION = 7U,
}ApplicationStateType_te;

void Application(void)
{
/* cases for define the different state */
switch(CurrentStateInfo.ApplicationStateType)
{
/* Initialization state for perform the initialization */
case INIT_STATE_U8:
{
AppInitTask();
delayStart(&DebugLogPrintTimout);
break;
}
/* perform the running state */
case RUNNING_STATE_U8:
{
DebugPrintText("APP: Running State");
scheduler(ApplicationTask, 8);
break;
}
/* perform the fault handling state */
case FAULT_HANDLING_STATE_U8:
{
DebugPrintText("APP: Fault State");
CurrentStateInfo.ApplicationStateType = INIT_STATE_U8;
break;
}
/* perform the sleep and wake-up state */
case SLEEP_STATE_U8:
{
MX_Watchdog_Refresh();
DebugPrintText("APP: Sleep State");
SleepControlTask();
break;
}
case WAKEUP_STATE:
{
DebugPrintText("APP: Wakeup State");
WakeUpControlTask();
scheduler(SleepTask, 3);
break;
}
case CHARGER_MODE:
{
DebugPrintText("APP: Charger Mode State");
scheduler(ApplicationTask, 8);
break;
}
case USB_MODE:
{
DebugPrintText("APP: USB Mode State");
scheduler(ApplicationTask, 8);
break;
}
case USB_TYPE_DETECTION:
{
//DebugPrintText("APP: USB type Detection State");
//ChargerControlTask();
break;
}
default:
{
/* Do Nothing */
break;
}
}
}


int main(void)
{
  HAL_Init();
  SystemClock_Config();
  while (1)
  {
  Application();
  HAL_WWDG_Refresh(&hwwdg);
  }
}
These are the task info:
#define NUMBER_OF_TASK_IN_APPLICATION 8

#define APPLICATION_INTI_TASK_TIMEOUT_MS 10

#define CHARGER_CONTROL_TASK_TIMEOUT_IN_MS 500

#define LED_CONTROL_TASK_TIMEOUT_IN_MS 500

#define DEBUG_LOG_TASK_TIMEOUT_IN_MS 2000

#define BUTTON_CONTROL_TASK_TIMEOUT_IN_MS 10

#define BATTERY_CONTROL_TASK_TIMEOUT_IN_MS 1000

#define POWER_CONTROL_TASK_TIMEOUT_IN_MS 10

task_ts ApplicationTask[NUMBER_OF_TASK_IN_APPLICATION] = { {SCH_TASK_ENABLE, APPLICATION_INTI_TASK_TIMEOUT_MS, 0, &AppInitTask},

{SCH_TASK_DISABLE, LED_CONTROL_TASK_TIMEOUT_IN_MS, 0, &LEDControlTask},

{SCH_TASK_DISABLE, DEBUG_LOG_TASK_TIMEOUT_IN_MS, 0, &DebugLogTask},

{SCH_TASK_DISABLE, BATTERY_CONTROL_TASK_TIMEOUT_IN_MS, 0, &BatteryControlTask},

{SCH_TASK_DISABLE, BUTTON_CONTROL_TASK_TIMEOUT_IN_MS, 0, &ButtonControlTask},

{SCH_TASK_DISABLE, CHARGER_CONTROL_TASK_TIMEOUT_IN_MS, 0, &ChargerControlTask},

{SCH_TASK_DISABLE, POWER_CONTROL_TASK_TIMEOUT_IN_MS, 0, &PowerStateMachine},

{SCH_TASK_DISABLE, DEBOUNCE_CONTROL_TASK_TIMEOUT__IN_WAKEUP_STATE_IN_MS, 0, &DebounceTask}

};



This is the flow of the code: Application->AppInitTask()->ApplicationInit()->Init() Then it will go in DE_INIT_STATE  with running mode and will go in sleep mode by scheduling all tasks.
Sleep Control Task is systick based task which is being as per scheduled time which is in ms.
Waking and sleep control tasks and functions:

/*Sleep task stuff*/

void HAL_PWR_EnableBkUpAccess(void)
{
  SET_BIT(PWR->DBPR, PWR_DBPR_DBP);
}
void SleepWakeUpMode(void)
{
  GPIO_deInit();
  /* disable the RTC */
  __HAL_RCC_RTC_DISABLE();
  /* Enable the backup register */
  HAL_PWR_EnableBkUpAccess();
  /* Suspend the tick before sleep */
  HAL_SuspendTick();
  /* enter in stop mode */
  HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
  /* resume the tick after wakeup */
  __HAL_RCC_RTC_ENABLE();
  HAL_ResumeTick();
  SystemClock_Config();

}

void SleepControlTask(void)
{
delayStop(&SleepWakeUpDelay);
SleepACK = false;
SleepWakeUpMode();
}

This is whole code functionality. Please check this.

Sarra.S
ST Employee

so, just before entering stop mode, refresh the WWDG counter: 

void SleepControlTask(void)
{
    delayStop(&SleepWakeUpDelay);
    SleepACK = false;
    HAL_WWDG_Refresh(&hwwdg); // Refresh WWDG before entering sleep mode
    SleepWakeUpMode();
}
void SleepWakeUpMode(void)
{
    GPIO_deInit();
    __HAL_RCC_RTC_DISABLE();
    HAL_PWR_EnableBkUpAccess();
    HAL_SuspendTick();
    HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
    __HAL_RCC_RTC_ENABLE();
    HAL_ResumeTick();
    SystemClock_Config();
    HAL_WWDG_Refresh(&hwwdg); // Refresh WWDG immediately after waking up
}

and when exiting stop mode, re-enable the WWDG clock and re-initialize it  

// After waking up from sleep mode
__HAL_RCC_WWDG_CLK_SLEEP_ENABLE(); // Re-enable the WWDG clock after waking up
MX_WWDG_Init(); // Re-initialize the WWDG
HAL_WWDG_Refresh(&hwwdg); // Refresh the WWDG counter

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thank you so much for your quick reply. It was really helpful. Now my code is working.

Thanks a lot!!