‎2020-03-19 06:33 AM
Hi,
I guess this question has been asked over and over, i have tried my best to read what i can to understand sleep mode.
However I am having difficulty as i am not using the HAL library that everyone refers to.
I use a program called Flowcode, basically a graphical interface to write programs.
I have the ability to write in C, but i dont know what code to write to get into stop mode since every example has only the name of the function... "HAL_PWR_EnterSTOPMode"
Can anyone point me to the full function code.
My device will wake on interrupt of A0pin. What must i do within the interrupt? I assume set the system clock? Is that all?
Finally something i am a bit unclear of. When the device comes out of sleep, does the program start from the very beginning?
Thanks
‎2020-03-19 06:42 AM
Even if you're not using HAL, it can be useful as a reference:
https://github.com/STMicroelectronics/STM32CubeF4
Here's the function you're looking for:
When the device exits sleep, execution continues right where it left off.
‎2020-03-19 07:05 AM
Hi TDK,
Thanks for the quick reply. Extremely helpful and much simpler than i thought it was going to be...i think...
I had another question tho now i have seen the function itself. I think i am reading it correctly that once the stop bit is set, it waits for an interrupt.
Can i enter a command to just tell it to go to sleep instead of using an external interrupt??
‎2020-03-19 07:47 AM
‎2020-03-19 08:01 AM
Sorry, i dont know the differences of how WFI or WFE are used, i dont find a difference in my mind between an interrupt or an event, they are both the same to me at this point because i dont understand how the STM differenciates them.
What i mean is that i want my device to go to sleep, but only because it is being told to in code. I dont have any form of external event or interrupt that can send it to sleep.
So i was looking for something like a sleep command. Sort of like a software reset command, but to sleep instead.?
How does one go about putting a device to sleep when there is no external event or interrupt to tell it to go to sleep?
‎2020-03-19 08:02 AM
What happens is that __WFI or __WFE puts the CPU in sleep mode - the peripherals keep functioning but the CPU halts. Getting an interrupt wakes the CPU back up and starts it running at the instruction following the __WFI or __WFE. So yes, in effect the CPU waits for an interrupt (or reset).
‎2020-03-19 08:02 AM
‎2020-03-19 09:22 AM
Thanks for the explanations guys.
I am feeling a bit stupid here looking at this function. I can read roughly what its doing, but where do all the values come from for these variables?
What is MODIFY_REG, SET_BIT, CLEAR_BIT ? Are these functions all of their own. They arent defined anywhere that i can see so cant tell whats inside them.
I still dont get this __WFI, __WFE thing at the moment. This is my first ever time trying to get a uC into sleep.
This line : SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); sets the sleep bit although i cannot find out what value SCB_SCR_SLEEPDEEP_Msk is supposed to have?? Currently trying to find the section in the datasheet for these registers.
So am i right in that once you set this bit that the CPU goes to sleep as soon as it is set?
Then is this part waiting for the interrupt to wake the CPU back up??
if(STOPEntry == PWR_STOPENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__SEV();
__WFE();
__WFE();
}
When the interrupt triggers do i then clear the bit inside the interrupt and the CPU starts back up? using this line?
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
Below is the whole function:
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
{
/* Check the parameters */
assert_param(IS_PWR_REGULATOR(Regulator));
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
/* Select the regulator state in Stop mode: Set PDDS and LPDS bits according to PWR_Regulator value */
MODIFY_REG(PWR->CR, (PWR_CR_PDDS | PWR_CR_LPDS), Regulator);
/* Set SLEEPDEEP bit of Cortex System Control Register */
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
/* Select Stop mode entry --------------------------------------------------*/
if(STOPEntry == PWR_STOPENTRY_WFI)
{
/* Request Wait For Interrupt */
__WFI();
}
else
{
/* Request Wait For Event */
__SEV();
__WFE();
__WFE();
}
/* Reset SLEEPDEEP bit of Cortex System Control Register */
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
}
‎2020-03-19 09:27 AM
The MODIFY_REG and SET_BIT macros are defined in "stm32f4xx.h" which is the top-level include. It also includes definitions for PWR_CR_PDDS and similar.
The __WFI/__WFE puts the processor to sleep. The SLEEPDEEP is set beforehand to indicate to the processor that it should go into deep sleep. There are different modes of sleep.
The interrupt will wake up the processor from sleep. No other action on your part is required. Execution will continue after the __WFI/__WFE command after the interrupt handler is complete.
‎2020-03-19 09:50 AM
The guys at Flowcode have already written all of this into their software by the looks of it. All i had to do was call the function... Thanks for your help its been educating for me.
I seem to have it working now =) I think...
I just wanted to check something if i could. When the device goes into STOP mode, should the communication to the STM32 utility be disconnected. While asleep i dont seem to be able to connect to the device, which is why i think it is working and is actually in stop mode.