AnsweredAssumed Answered

Wake from standby issues

Question asked by Clonimus74 on Mar 20, 2016
Latest reply on Mar 22, 2016 by Clonimus74
Hi all,

I have a few problems with waking from Standby.
I use STM32L152, IAR V7.5, the MCU has constant power supplied to it.

I have a custom bootloader. If my MCU has only the bootloader I don't seem to have any problems. My aim is to use Standby as power off mode.

Here is my power on code in the bootloader:
01.__root static void PowerUp(void)
02.{
03.    const uint8_t kPOWER_OFF_BUTTON_PRESSING_TIME = 100;
04. 
05.    static uint8_t power_on_sequence = 1;
06.    static uint16_t button_timming = 0;
07. 
08.    GpioInit();
09.    LedsTimerInit();
10. 
11.    __enable_interrupt();
12. 
13.    while (power_on_sequence)
14.    {
15.        if (sys_tick_10ms)
16.        {
17.            sys_tick_10ms = 0;
18. 
19.            if (PowerButtonPressed() || ((bootloader_reached_from_application) &&  (PWR_GetFlagStatus(PWR_FLAG_SB) == RESET)))
20.            {
21.                button_timming++;
22. 
23.                if (button_timming >= kPOWER_OFF_BUTTON_PRESSING_TIME)
24.                {
25.                    button_timming = 0;
26.                    
27.                    Spi2Init();
28.                    InitOled();
29.                    current_state_function = &SystemInitialization;
30. 
31.                    while(PowerButtonPressed());
32. 
33.                    OledClearScreen();
34.           
35.                    power_on_sequence = 0;
36.                }
37.            }
38.            else
39.            {
40.                button_timming = 0;
41.        /* Enter standby */
42.        __disable_interrupt();
43.        RCC_LSICmd(DISABLE);
44.        PWR_UltraLowPowerCmd(ENABLE);
45.        PWR_WakeUpPinCmd(PWR_WakeUpPin_1, DISABLE);
46.        PWR_WakeUpPinCmd(PWR_WakeUpPin_2, DISABLE);
47.        PWR_WakeUpPinCmd(PWR_WakeUpPin_3, DISABLE);
48.        PWR_ClearFlag(PWR_FLAG_WU);
49.        PWR_ClearFlag(PWR_FLAG_SB);
50.        PWR_WakeUpPinCmd(PWR_WakeUpPin_1, ENABLE);
51.        PWR_EnterSTANDBYMode();
52.            }
53.        }
54.    }
55.}

The idea is not to turn on (stay in standby) if the power on button (PA0-WKUP) is not pressed for over 1sec.

Once I have an application programmed to the MCU (the bootloader detects there's an application and jumps to it) the issues begin-
Weird issue #1:
bootloader_reached_from_application is located at a known area in RAM and used to indicate (if not 0) that we jumped to the bootloader from the application (no need to wait for 1 sec button press). What happened was that after waking from Standby (using a short >sec button press) the system just turned on and jumped to the application even though the variable was not set (the application didn't set it before entering Standby and it is 0 after reset), well it seems the RAM value after reset is unknown, so I had to add a check that I came from standby to overcome this. can't figure out why.

here is the declaration of the variable (same in bootloader and application):
#pragma location=0x20000000
__no_init static uint8_t bootloader_reached_from_application;
It is reset at the beginning of the application, only set if erase command from PC bootloader arrives.

Weird issue #2:


If I power off the device in the application (go to standby), pressing the button (PA0) for 1sec will turn on the device (the MCU will reset as it exits the Standby mode and boot to the bootloader), but it works randomly, i.e. it might work (on-off cycles) a few times and suddenly gets stuck, the device is in unknown state. I tried toggling LED and I know that right after the application goes to Standby, pressing the button doesn't bring me to main() in the bootloader.

Here is the power off sequence in the application (at first line #19 wasn't there, it was added in order to try entering standby from the bootloader [code above] cleanly, didn't work):
01.void PowerOffSystem(void)
02.{
03.  /* 200ms vibration to indicate power off */
04.  haptic_feedbak_parameters.duration_in_10ms = 0x20;
05.  haptic_feedbak_parameters.enable_vibration = 1;
06.   
07.  DisableAnalogVoltage();
08.  TurnBlueLedOff();
09.  TurnRedLedOff();
10.  UpdateLoggerControlParametersInEeprom();
11.  oled_parameters.screen_refresh_disabled = 1;
12.  OledClearScreen();
13.  ResetBle();
14.   
15.  while(PowerButtonPressed())    //Wait for button release so we will not get to endless power on-off cycle
16.    IWDG_ReloadCounter();
17.   
18.  while (haptic_feedbak_parameters.busy);
19.  NVIC_SystemReset();
20. 
21.  DisableAllPeripherals();
22. 
23.  /* Enter standby */
24.  RCC_LSICmd(DISABLE);
25.  PWR_UltraLowPowerCmd(ENABLE);
26.  PWR_WakeUpPinCmd(PWR_WakeUpPin_1, DISABLE);
27.  PWR_WakeUpPinCmd(PWR_WakeUpPin_2, DISABLE);
28.  PWR_WakeUpPinCmd(PWR_WakeUpPin_3, DISABLE);
29.  PWR_ClearFlag(PWR_FLAG_WU);
30.  PWR_ClearFlag(PWR_FLAG_SB);
31.  PWR_WakeUpPinCmd(PWR_WakeUpPin_1, ENABLE);
32.  PWR_EnterSTANDBYMode();
33.}

Here is the main function in the bootloader, when the system gets stuck (pressing the button after entering Standby) it doesn't seem I get to line #5:

01.int main(void)
02.{
03.    __disable_interrupt();
04.   
05.    Set_System();
06. 
07.    /* Infinite loop */
08.    while (1)
09.    {
10.        current_state_function = &PowerUp;
11. 
12.        soft_reset = 1;
13. 
14.        while (soft_reset)
15.            current_state_function();
16.    }
17.}

Thank you in advance for your help

Outcomes