Skip to content

Commit b388d85

Browse files
committed
Enhance RTC usage across LP mode
Previously RTC was configured to use LSE source clock. Some boards do not have LSE by default (ex Nucleo-L152RE). Moreover depending of the mode, clock could be LSI or HSE. Signed-off-by: Frederic.Pillon <[email protected]>
1 parent 6fc60e0 commit b388d85

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

Diff for: src/STM32LowPower.cpp

+36-15
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ STM32LowPower::STM32LowPower()
4545
{
4646
_configured = false;
4747
_serial = NULL;
48+
_rtc_wakeup = false;
4849
}
4950

5051
/**
@@ -66,8 +67,8 @@ void STM32LowPower::begin(void)
6667
*/
6768
void STM32LowPower::idle(uint32_t millis)
6869
{
69-
if(millis > 0) {
70-
programRtcWakeUp(millis);
70+
if((millis > 0) || _rtc_wakeup) {
71+
programRtcWakeUp(millis, IDLE_MODE);
7172
}
7273
LowPower_sleep(PWR_MAINREGULATOR_ON);
7374
}
@@ -80,8 +81,8 @@ void STM32LowPower::idle(uint32_t millis)
8081
*/
8182
void STM32LowPower::sleep(uint32_t millis)
8283
{
83-
if(millis > 0) {
84-
programRtcWakeUp(millis);
84+
if((millis > 0) || _rtc_wakeup) {
85+
programRtcWakeUp(millis, SLEEP_MODE);
8586
}
8687
LowPower_sleep(PWR_LOWPOWERREGULATOR_ON);
8788
}
@@ -94,8 +95,8 @@ void STM32LowPower::sleep(uint32_t millis)
9495
*/
9596
void STM32LowPower::deepSleep(uint32_t millis)
9697
{
97-
if(millis > 0) {
98-
programRtcWakeUp(millis);
98+
if((millis > 0) || _rtc_wakeup) {
99+
programRtcWakeUp(millis, DEEP_SLEEP_MODE);
99100
}
100101
LowPower_stop(_serial);
101102
}
@@ -108,8 +109,8 @@ void STM32LowPower::deepSleep(uint32_t millis)
108109
*/
109110
void STM32LowPower::shutdown(uint32_t millis)
110111
{
111-
if(millis > 0) {
112-
programRtcWakeUp(millis);
112+
if((millis > 0) || _rtc_wakeup) {
113+
programRtcWakeUp(millis, SHUTDOWN_MODE);
113114
}
114115
LowPower_shutdown();
115116
}
@@ -150,36 +151,56 @@ void STM32LowPower::enableWakeupFrom(HardwareSerial *serial, voidFuncPtrVoid cal
150151

151152
/**
152153
* @brief Attach a callback to a RTC alarm.
153-
* @param rtc: pointer to a STM32RTC
154+
* @param rtc: pointer to a STM32RTC. Can be NULL as RTC is a Singleton.
154155
* @param callback: pointer to callback function called when leave the low power
155156
* mode.
156-
* @param data: optional pointer to callaback data parameters (default NULL).
157+
* @param data: optional pointer to callback data parameters (default NULL).
157158
* @retval None
158159
*/
159160
void STM32LowPower::enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *data)
160161
{
161162
if(rtc == NULL) {
162163
rtc = &(STM32RTC::getInstance());
163164
}
164-
// Reconfigure rtc for low power mode (using LSE as clock source)
165-
rtc->configForLowPower();
165+
_rtc_wakeup = true;
166166
rtc->attachInterrupt(callback, data);
167167
}
168168

169169
/**
170170
* @brief Configure the RTC alarm
171171
* @param millis: time of the alarm in milliseconds. At least 1000ms.
172+
* @param lp_mode: low power mode targeted.
172173
* @retval None
173174
*/
174-
void STM32LowPower::programRtcWakeUp(uint32_t millis)
175+
void STM32LowPower::programRtcWakeUp(uint32_t millis, LP_Mode lp_mode)
175176
{
176177
int epoc;
177178
uint32_t sec;
178179
STM32RTC& rtc = STM32RTC::getInstance();
180+
STM32RTC::RTC_Source_Clock clkSrc = rtc.getClockSource();
181+
182+
switch(lp_mode) {
183+
case IDLE_MODE:
184+
case SLEEP_MODE:
185+
break;
186+
// LSI or LSE must be selected as clock source to wakeup the device.
187+
case DEEP_SLEEP_MODE:
188+
clkSrc = (clkSrc == STM32RTC::RTC_HSE_CLOCK) ? STM32RTC::RTC_LSI_CLOCK : clkSrc;
189+
break;
190+
default:
191+
case SHUTDOWN_MODE:
192+
#ifdef STM32L4xx
193+
// For shutdown mode LSE have to be used (STM32L4 series only)
194+
clkSrc = STM32RTC::RTC_LSE_CLOCK;
195+
#else
196+
// LSE or LSI
197+
clkSrc = (clkSrc == STM32RTC::RTC_HSE_CLOCK) ? STM32RTC::RTC_LSI_CLOCK : clkSrc;
198+
#endif
199+
break;
200+
}
201+
rtc.configForLowPower(clkSrc);
179202

180203
if(millis > 0) {
181-
// LSE must be selected as clock source to wakeup the device from shutdown mode
182-
rtc.configForLowPower();
183204
// Convert millisecond to second
184205
sec = millis / 1000;
185206
// Minimum is 1 second

Diff for: src/STM32LowPower.h

+12-3
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,18 @@ class STM32LowPower {
8383
void enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *data = NULL);
8484

8585
private:
86-
bool _configured; /* Low Power mode initialization status */
87-
serial_t *_serial; /* Serial for wakeup from deep sleep */
88-
void programRtcWakeUp(uint32_t millis);
86+
enum LP_Mode: uint8_t
87+
{
88+
IDLE_MODE,
89+
SLEEP_MODE,
90+
DEEP_SLEEP_MODE,
91+
SHUTDOWN_MODE
92+
};
93+
94+
bool _configured; // Low Power mode initialization status
95+
serial_t *_serial; // Serial for wakeup from deep sleep
96+
bool _rtc_wakeup; // Is RTC wakeup?
97+
void programRtcWakeUp(uint32_t millis, LP_Mode lp_mode);
8998
};
9099

91100
extern STM32LowPower LowPower;

0 commit comments

Comments
 (0)