cancel
Showing results for 
Search instead for 
Did you mean: 

Getting the source of wakeup from STANDBY

juraj2
Associate II
Posted on September 17, 2011 at 12:53

Hello,

I have an application where I have 2 sources that wake my STM32F from STANDBY: RTC and wakeup pin. Both work well as designed (they wake my MCU from STANDBY) but I cannot get the flag to tell what caused the MCU to wake up: if it was the WAKE pin or RTC alarm.

To be more specific, I can do that, when I start running the code with JTAG debugger.

When I disconnect the debugger during runtime (let the code run), everything works as before, i.e. the MCU goes to STANDBY and then leaves it after RTC or WAKE pin and determines correctly the source of reset (RTC or pin).

The only case the application is not running as designed is when I run target without JTAG, i.e. POR without debugging. In this case I see always RTC alarm not set even if it was the cause.

I check PWR_FLAG_SB to determine if I get POR or STANDBY-reset. After that I use RTC_FLAG_ALR status to determine if the RTC alarm was the cause of reset from STANDBY.

#stm32-standby-wake-rtc
5 REPLIES 5
Posted on September 17, 2011 at 14:53

The JTAG attachment isn't non-invasive, it may have set up certain registers, or been set to suspend things when it's busy/waiting for human interaction.

When debugging without JTAG you'd want to run telemetry to a serial terminal so you can diagnose the situation, and determine what's really going on.

The RTC is a bit of a pig to initialize, and re-enable. Look carefully at this code, and issues like enabling the RTC/PWR/BKP and synchronization between domains.

Also look at the RTC registers at these events, for instance what's the difference between the counter/alarm registers. I don't recall if RTC_FLAG_ALR clears if/as the counter advances.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
juraj2
Associate II
Posted on September 17, 2011 at 21:49

Hi Clive,

thank you for your answer.

In fact, I am following the code from examples/PWR/STANDBY from ST Microelectronics. 

I This is the code I am using to get the alarm flag:

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);

  // Allow access to BKP Domain

  PWR_BackupAccessCmd(ENABLE);

  RTC_WaitForSynchro();

  start_status = RTC->CRL;

and then later on I print out

start_status

value. It's value is 0x0028 if the WAKE pin resets the MCU. It's value is:

1) 0x002B if the RTC alarm woke up the MCU and JTAG is inserted

2) 0x0028 if the RTC alarm woke up the MCU and JTAG was not inserted on POR

3) 0x002B if the RTC alarm woke up the MCU and JTAG is not inserted (but was on POR)

It seems for me very suspicious, like a bug in the silicon.

Posted on September 18, 2011 at 05:24

It seems for me very suspicious, like a bug in the silicon.

This might be convenient to assume, but it sounds more like the JTAG break-in is initializing something you are not.

I don't have hardware configured in a manner to permit an external WAKEUP, but other's here have run into issues about pin states when RTC ALARM and WAKEUP are combined. They might chime in here. What I have done, is perform a lot of repetitive ALARM events over quite extensive periods. Not missed any alarms there, but also not explicitly checking the source either.

In fact, I am following the code from examples/PWR/STANDBY from ST Microelectronics.

Unfortunately I don't think they are very good, or comprehensive enough, and generally limited to demonstrating a single facet, rather than a realistic system application. The RTC is a pit in which hours of development time can be wasted, although I think this is due to a frustratingly stupid implementation rather than a buggy one. I don't have my code to hand, but I'm pretty sure it's more complicated than the ST examples suggest. I would certainly be enabling the PWR clock as well.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
juraj2
Associate II
Posted on September 18, 2011 at 09:06

Hi Clive,

thank you for reply, though you did not encouraqged me. I was ''playing'' with the settings many times, but did not succeed.

I would certainly be enabling the PWR clock as well.

I am also enabling clocks for PWR module, of course. I was trying also to reset RCC at the beginning- nothing helps.

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

  if ((PWR->CSR & (PWR_FLAG_SB | PWR_FLAG_WU)) == (PWR_FLAG_SB | PWR_FLAG_WU)) {

    // run from wake-up

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);

    // Allow access to BKP Domain

    PWR_BackupAccessCmd(ENABLE);

    RTC_WaitForSynchro();

    start_status = RTC->CRL;

  }

  else

    start_status = 0;

    

other's here have run into issues about pin states when RTC ALARM and WAKEUP are combined

I don't see any problem, for me everything works as should (both RTC and WAKE do reset the MCU from STANDBY even for a long time of period).

Unfortunately I don't think they are very good [code examples], or comprehensive enough, and generally limited to demonstrating a single facet, rather than a realistic system application. The RTC is a pit in which hours of development time can be wasted, although I think this is due to a frustratingly stupid implementation rather than a buggy one.

Well, you might be right about the stupid implementation, but my opinion about bug (or undocumented- unexpected behavior) comes from the fact that it is working after reset (not POR) without JTAG inserted. That's really interesting point. I have no other way to follow some example code than ST's one. However it does not mean that I do not experiment and I do not change things to get it working- after several hours without success.
Posted on September 19, 2011 at 01:42

Well, this is my implementation for RTC_Configuration(), like I said I don't care about the source of the exit from STANDBY in my application, and if I did I'd probably check it somewhere else. There are two ways my system can restart, a) power is applied, b) it reawakens from an alarm. In the case of a) it pulls UTC time from an external source, nominally GPS or NTP, because the RTC value is totally useless. Presumably b) could also be generated by a WAKEUP condition if I configured it that way, but this isn't something I've buried any time in evaluating.

One thing you should be very careful to do is to reset the flags, as I believe they are persistent, which would certainly screw up your ability to differentiate the true source later.

void RTC_Configuration(void)

{

     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); /* Enable PWR and BKP clocks */

  PWR_BackupAccessCmd(ENABLE); /* Allow access to BKP Domain */

  if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) /* Check if the StandBy flag is set */

  {

      puts(''RTC from STANDBY....'');

        /* System resumed from STANDBY mode */

    PWR_ClearFlag(PWR_FLAG_SB); /* Clear StandBy flag */

    RTC_WaitForSynchro(); /* Wait for RTC APB registers synchronisation */

    /* No need to configure the RTC as the RTC configuration(clock source, enable,

       prescaler,...) is kept after wake-up from STANDBY */

        SystemClockMillisecond  = 0; // Avoid a potential race condition

        SystemClock                         = (int)RTC_GetCounter();

        puts(''Setting Initial Time from RTC..'');

  }

  else

  {

    puts(''RTC from Cold Start....'');

        /* StandBy flag is not set */

      BKP_DeInit(); /* Reset Backup Domain */

      RCC_LSICmd(ENABLE); /* Enable LSI */

      while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /* Wait till LSI is ready */

      RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); /* Select LSI as RTC Clock Source */

      RCC_RTCCLKCmd(ENABLE); /* Enable RTC Clock */

      RTC_WaitForSynchro(); /* Wait for RTC registers synchronization */

      RTC_WaitForLastTask(); /* Wait until last write operation on RTC registers has finished */

        /* Set RTC prescaler: set RTC period to 1sec */

      RTC_SetPrescaler(39999); /* RTC period = RTCCLK/RTC_PR = (40.000 KHz)/(39999+1) */

      RTC_WaitForLastTask(); /* Wait until last write operation on RTC registers has finished */

    }

     RTC_ITConfig(RTC_IT_ALR, ENABLE); /* Enable the RTC Alarm */

     RTC_WaitForLastTask(); /* Wait until last write operation on RTC registers has finished */

}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..