Closed zokl closed 4 years ago
I don't see any issue with having longer time (I don't remind what is the RTC overflow period) You can also remove the RTC wakeup and only wakeup on interrupts. Don't forget to stop the watchdog in a such case. Some features like software timer, task or state machine needs regular wakeup, so you be able to use them.
Thank you for a tip to the watchdog. Watchdog makes a restart.
I have tried to measure the sleep and I am not able to sleep longer than approx 30 seconds.
log from project_loop in ms:
Wakeups : 4426 Wakeups : 32440 Wakeups : 60463 Wakeups : 88487 Wakeups : 116510 Wakeups : 144534 Wakeups : 172557 Wakeups : 200581
I am so sorry but I am not able to sleep longer than 28 s. I try to modify several parts of config files but without success. For now, I have set:
#define ITSDK_WITH_RTC __RTC_ENABLED // The Rtc is usd in the firmware
#define ITSDK_WITH_CLK_ADJUST __ENABLE // The RTC (and wtachdog) is calibrated
#define ITSDK_RTC_CLKFREQ 32768 // RTC clock source frequency
#define ITSDK_CLK_BEST_SOURCE __CLK_BEST_SRC_RTC // The RTC is the most accurate clk source to ADJUST Others
#define ITSDK_CLK_CORRECTION 1000 // correct clock with 1200 o/oo (+20%) of the ticks (used when clk_adjust = 0 or for RTC when CLK_BEST_SRC_RTC)
#define ITSDK_LOWPOWER_MINDUR_MS 5 // Under 5 ms sleep request, no need to sleep
#define ITSDK_LOWPOWER_RTC_MS 60000 // RTC wake up after 10s
I would like to wakeup after 60 s but the system wake up after 28s. WatchDog is disabled.
I made a wakeup measurement:
...
void project_loop() {
log_info("Wakeup after %d ms \r\n", (uint32_t)itsdk_time_get_ms() - timeDiff);
timeDiff = (uint32_t)itsdk_time_get_ms();
}
with the following result:
Wakeup after 27996 ms
Wakeup after 28005 ms
Wakeup after 28002 ms
Wakeup after 28001 ms
Wakeup after 28006 ms
Wakeup after 28001 ms
I try to find the problem point and maybe rtc.c and ticks calculation?
/**
* Configure the RTC source clock for running LowPower
*/
void rtc_configure4LowPower(uint16_t ms) {
rtc_prepareSleepTime();
if ( ms > 0 ) {
rtc_runRtcUntil(ms);
}
}
/**
* Deactivate the WakeUpTimer for not having the IRQ looping
*/
void rtc_disable4LowPower() {
rtc_disableWakeUp();
rtc_updateTimeAfterSleepTime();
}
/**
* Run Rtc for a given time in ticks
* Max is 16s
*/
void rtc_runRtcUntil(uint16_t ms) {
rtc_runRtcUntilTicks(rtc_getTicksFromDuration((uint32_t)ms));
}
/*
* Convert a duration in ticks (Wake-Up Clock only)
*/
uint32_t rtc_getTicksFromDuration(uint32_t ms) {
return (ms * (ITSDK_RTC_CLKFREQ/16)) / 1000;
}
/*
* Convert a tick duration in ms (Wake-Up Clock only)
*/
int32_t rtc_getMsFromTicks(uint32_t ticks) {
return (ticks * 1000) / (ITSDK_RTC_CLKFREQ/16);
}
/**
* Run the RTC for a given number of tics
*/
void rtc_runRtcUntilTicks(uint32_t ticks) {
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, ticks, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
}
I made several tests and I found the solution to my problem with long sleep duration. Long sleep is longer than 1s :-).
You use in rtc.c for wakeup HAL_RTCEx_SetWakeUpTimer_IT with wakeup clock RTC_WAKEUPCLOCK_RTCCLK_DIV16. This is a 16 bit counter. The maximum time is about 32 s.
If you use RTC_WAKEUPCLOCK_CK_SPRE_16BITS, this is the wakeup counter clock source that is set to CalendarCLK, then the WakeUpCounter is in seconds and you are able to sleep up to 48 days.
For my purposes will be good if I have a function like this:
void rtc_runRtcUntilSeconds(uint32_t s) {
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, ms, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
}
Is it possible to extend our SDK to this function?
Thank you for you proposal, I'm going to review that to ensure it will not have side effect. It make sense to be able to increase the RTC wake up over 32s.
I've just push a commit on the devel branch. Please test and let me know if this works and fixed your issue.
I've just push a commit on the devel branch. Please test and let me know if this works and fixed your issue.
I have tried it and it working.
There could be a potential problem with a watchdog. If you use a longer sleep period and you have activated watchdog (in common configuration) it makes a restart early. For now, I don't know how to resolve it in an easy way. Maybe note in the comment?
Hello, I apologize for thoroughly testing your patch. It does not work as expected. There is still a restriction in the form of uint16_t for the rtc_configure4LowPower and rtc_runRtcUntil function parameters. Can you please change the data type to uint32_t?
Thank you.
I'll take a look to it, the RTC is 16bits, so even if 32b is use, the time is limited to 16bits ticks.
I'll take a look to it, the RTC is 16bits, so even if 32b is use, the time is limited to 16bits ticks.
Yes, it is 16bit but it differ if you use tics or seconds ...
Fixed in commit #58 including the watchdog error reporting in the config.h.template file. Thank you for your issue submission.
Hello Paul,
is it possible to be in lowpower longer than hundreds of ms? Maybe hours or days? I try to increase ITSDK_LOWPOWER_RTC_MS to tens of seconds but MCU reboots after a few seconds. Is it a bug or common behavior?
In my other IoT applications based on HAL STM32, I used deep sleep mode and RTC woke up the system after hours and days without a problem.
Thank you, Zbynek Kocur