cancel
Showing results for 
Search instead for 
Did you mean: 

Stop mode problem

ubercraftworks
Associate
Posted on May 23, 2010 at 23:18

Stop mode problem

15 REPLIES 15
ubercraftworks
Associate
Posted on May 17, 2011 at 13:52

I forgot to mention that I currently setup the clock to the internet time via the network at every hour. Could it by setting the RTC clock using RTC_SetCounter() without the RTC_WaitForLastTask() be a problem and causing this intermittent problem?

Posted on May 17, 2011 at 13:52

There is a problem with how you are wrapping the RTC_Counter(), certainly one that might cause a stop time exceeding 24 hours. Another that would cause the wrap to fail if the counter ever exceed the rollover value.

Also if you are setting the time, from say NTP, why wouldn't you use the whole 32-bits of the RTC and track the time/date

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

Hello,

for everyone who has this problem with RTC_SetCounter . 

I found mistake in Examples from STD_Periph_Lib.

If you want change RTC_SetCounter you have to write your code like this:

if (RTC_GetCounter() == 86399) //Decimal value of 23:59:59 ((23*60 + 59)*60 + 59)

    {

     PWR_BackupAccessCmd(ENABLE);

     /* Wait until last write operation on RTC registers has finished */

     RTC_WaitForLastTask();

     /* Set initial value */

     RTC_SetCounter(0x0); 

     /* Wait until last write operation on RTC registers has finished */

     RTC_WaitForLastTask();

     PWR_BackupAccessCmd(DISABLE);

    }

It works for me.

Posted on May 17, 2011 at 13:52

if (RTC_GetCounter() == 86399) //Decimal value of 23:59:59 ((23*60 + 59)*60 + 59)

    {

 

     PWR_BackupAccessCmd(ENABLE);

     /* Wait until last write operation on RTC registers has finished */

     RTC_WaitForLastTask();

 

     /* Set initial value */

     RTC_SetCounter(0x0); 

 

     /* Wait until last write operation on RTC registers has finished */

     RTC_WaitForLastTask();

     PWR_BackupAccessCmd(DISABLE);

 

    }

And what exactly happens with sloppy code like this when the CPU happens be asleep over the Midnight event? Or asleep for a couple of days/weeks?

Seem also to remember that 00:00:00 is equivalent to 24:00:00 not 23:59:59, or perhaps you have some leap second event you are handling.

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

 

And what exactly happens with sloppy code like this when the CPU happens be asleep over the Midnight event? Or asleep for a couple of days/weeks?

 

 

Seem also to remember that 00:00:00 is equivalent to 24:00:00 not 23:59:59, or perhaps you have some leap second event you are handling.

I'm sorry,

I thought that he has problem with RTC_SetCounter. For first time when I tried write code for RTC Interrupt, I used example from Std_Periph_Lib. It not worked for me. 

The RTC reset counter part of his code look like ST's example. 

And yes, you're right. This solution is very bad. It's better to calculate date and time from seconds without resetting rtc counter.

yohan
Associate
Posted on May 17, 2011 at 13:52

hi :),

I just have a question about the 24 hours in stop time.

Does the RTC still up to date if the STM still in stop mode more than 24hours ?

Or does the counter stop when he reaches 86399 ?

In my case i want to know if i put a battery on Vbat and if i put the processor in stop mode for more than 24hours, will the RTC be ok when i'll wake up again the processor? or will it be stuck at 86399.

It it will be stuck is there a way to keep the rtc up to date anyway? by counting how long the processor have stayed in stop mode for exemple.

Thanks

Posted on May 17, 2011 at 13:52

It's a 32-bit counter, it does not stop at arbitrary values, when it gets to 0xFFFFFFFF it then wraps to 0x00000000. If the RTC prescaler is in seconds, this occurs in just over 136 years.

Thus my point about sloppy code, and missing the increment across the 24 hour threshold, should you only be interested in Time-Of-Day. If you do an equality check, and you miss the exact second you are checking, it will be 136 years before the check will match again.

If you want to confine it to 24 hours, you should always check >= 86400, in which case you should then subtract 86400 from the RTC. If it was out for several days, you might have to repeat the check/subtraction until the number is in scope. You can enumerate the days.

Generally it would be better just to use the 32-bit value to record the time and date, from some epoch date, like the one used by UNIX, or based from 2000 or 2010. You would then be able to do simple math on the RTC counter and figure how many seconds (hours, days, weeks, or get a tad more complicated for years, decades, centuries) had elapsed while asleep.

The leap year math also gets significantly simpler if your supported epoch is from 1-Jan-2000 to 31-Dec-2099. (hint every 4 years, but 2100 is NOT a leap year)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
yohan
Associate
Posted on May 17, 2011 at 13:52

hi,

thanks for your answer. it seems to be ok but i'll explain my case again to be sure it's ok.

I'm going to use an STM32 for an application where the processor will be put in stop mode for long periods (from 1day to 3weeks). The RTC will be powered by an external battery on Vbat. But i really need to have the right date/hour when i start up the processor again.

What worries me is that i read on AN2821 this :

'' Caution: In the case of a device in low-power mode or whose external supply is off when the counter reaches 86399, the counter cannot be reset and so the date is not updated. This is why, just after power reset, it is necessary to check the counter value and update the date as many times as the number of days during which the device remained in low-power mode or had its external main supply switched off.''

If the RTC counter do not reset at 86399 (24 hours). When i wake up the processor (for exemple counter at 180000) i just need to substract 86400 to 180000 untill i had a number <= 86400. Add the number of times i substracted 86400 to the day counter and the rest will be for the current time.

Right ? (just to be sure)

Thanks

Posted on May 17, 2011 at 13:52

The STM32's RTC is not a calendering device. It does not track days, weeks, or other earth/human representations. It counts seconds, or other units, depending on the oscillator and prescaler.

The caution is specifically for those who want to imagine the RTC as a Time-Of-Day counter. This model will break for them, if the part ticks past the 24-hour threshold overnight, or is left asleep for long periods. Such overflows must be specifically handled manually, by pulling the value into scope. If left unchecked, an alarm will NOT fire everyday, but once every 136 years.

Personally, I find this model to be particularly stupid, and prone to breakage or poor implementation.

Time is linear, and with a 32-bit counter you can model a 136 year period, and determine with little effort the date, day of week, month of year, and year. You can certainly make the STM32 report time and date exactly like you can on a PC. If you set the RTC correctly, or periodically sync it with an external source, you'll be fine.

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