Skip to content

Commit 3f3cd07

Browse files
authored
Merge pull request #31 from fpistm/subseconds
Manage subseconds sleep
2 parents 0ee07d1 + 609a43c commit 3f3cd07

File tree

7 files changed

+548
-57
lines changed

7 files changed

+548
-57
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,24 @@ Arduino library to support STM32 Low Power.
33

44
## Requirement
55
* [Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32) version >= 1.3.0
6-
* [STM32RTC](https://github.com/stm32duino/STM32RTC)
76

87
## API
98

109
* **`void begin()`**: configure the Low Power
1110

12-
* **`void idle(uint32_t millis)`**: enter in idle mode
13-
**param** millis (optional): number of milliseconds before to exit the mode. At least 1000 ms. The RTC is used in alarm mode to wakeup the chip in millis milliseconds.
11+
* **`void idle(uint32_t ms)`**: enter in idle mode
12+
**param** ms (optional): number of milliseconds before to exit the mode. The RTC is used in alarm mode to wakeup the chip in ms milliseconds.
1413

15-
* **`void sleep(uint32_t millis)`**: enter in sleep mode
16-
**param** millis (optional): number of milliseconds before to exit the mode. At least 1000 ms. The RTC is used in alarm mode to wakeup the chip in millis milliseconds.
14+
* **`void sleep(uint32_t ms)`**: enter in sleep mode
15+
**param** ms (optional): number of milliseconds before to exit the mode. he RTC is used in alarm mode to wakeup the chip in ms milliseconds.
1716

18-
* **`void deepSleep(uint32_t millis)`**: enter in deepSleep mode
19-
**param** millis (optional): number of milliseconds before to exit the mode. At least 1000 ms. The RTC is used in alarm mode to wakeup the chip in millis milliseconds.
17+
* **`void deepSleep(uint32_t ms)`**: enter in deepSleep mode
18+
**param** ms (optional): number of milliseconds before to exit the mode. The RTC is used in alarm mode to wakeup the chip in ms milliseconds.
2019

21-
* **`void shutdown(uint32_t millis)`**: enter in shutdown mode
22-
**param** millis (optional): number of milliseconds before to exit the mode. At least 1000 ms. The RTC is used in alarm mode to wakeup the board in millis milliseconds.
20+
* **`void shutdown(uint32_t ms)`**: enter in shutdown mode
21+
**param** ms (optional): number of milliseconds before to exit the mode. The RTC is used in alarm mode to wakeup the board in ms milliseconds.
22+
23+
**Note: With [STM32RTC](https://github.com/stm32duino/STM32RTC) version lower than 1.1.0, the minimum number of milliseconds is 1000 ms.**
2324

2425
* **`void attachInterruptWakeup(uint32_t pin, voidFuncPtrVoid callback, uint32_t mode)`**: Enable GPIO pin in interrupt mode. If the pin is a wakeup pin, it is configured as wakeup source (see board documentation).
2526
**param** pin: pin number

examples/AlarmTimedWakeup/AlarmTimedWakeup.ino

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
/* Get the rtc object */
1818
STM32RTC& rtc = STM32RTC::getInstance();
1919

20+
#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000)
21+
/* Change this value to set alarm match offset in millisecond */
22+
/* Note that STM32F1xx does not manage subsecond only second */
23+
static uint32_t atime = 567;
24+
#else
2025
// Time in second between blink
2126
static uint32_t atime = 1;
27+
#endif
2228

2329
// Declare it volatile since it's incremented inside an interrupt
2430
volatile int alarmMatch_counter = 0;
@@ -41,21 +47,21 @@ void setup() {
4147
pinMode(LED_BUILTIN, OUTPUT);
4248

4349
Serial.begin(9600);
44-
while(!Serial) {}
50+
while (!Serial) {}
4551

4652
// Configure low power
4753
LowPower.begin();
4854
LowPower.enableWakeupFrom(&rtc, alarmMatch, &atime);
4955

5056
// Configure first alarm in 2 second then it will be done in the rtc callback
51-
rtc.setAlarmEpoch( rtc.getEpoch() + 2 );
57+
rtc.setAlarmEpoch( rtc.getEpoch() + 2);
5258
}
5359

5460
void loop() {
5561
Serial.print("Alarm Match: ");
5662
Serial.print(alarmMatch_counter);
5763
Serial.println(" times.");
58-
delay(100);
64+
Serial.flush();
5965
digitalWrite(LED_BUILTIN, HIGH);
6066
LowPower.deepSleep();
6167
digitalWrite(LED_BUILTIN, LOW);
@@ -67,6 +73,41 @@ void alarmMatch(void* data)
6773
// This function will be called once on device wakeup
6874
// You can do some little operations here (like changing variables which will be used in the loop)
6975
// Remember to avoid calling delay() and long running functions since this functions executes in interrupt context
76+
#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000)
77+
uint32_t epoc;
78+
uint32_t epoc_ms;
79+
uint32_t sec = 0;
80+
uint32_t _millis = 1000;
81+
82+
if (data != NULL) {
83+
_millis = *(uint32_t*)data;
84+
// Minimum is 1 second
85+
if (sec == 0) {
86+
sec = 1;
87+
}
88+
}
89+
90+
sec = _millis / 1000;
91+
#ifdef STM32F1xx
92+
// Minimum is 1 second
93+
if (sec == 0) {
94+
sec = 1;
95+
}
96+
epoc = rtc.getEpoch(&epoc_ms);
97+
#else
98+
_millis = _millis % 1000;
99+
epoc = rtc.getEpoch(&epoc_ms);
100+
101+
//Update epoch_ms - might need to add a second to epoch
102+
epoc_ms += _millis;
103+
if (epoc_ms >= 1000) {
104+
sec ++;
105+
epoc_ms -= 1000;
106+
}
107+
#endif
108+
alarmMatch_counter++;
109+
rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_SS, epoc_ms);
110+
#else
70111
uint32_t sec = 1;
71112
if(data != NULL) {
72113
sec = *(uint32_t*)data;
@@ -77,5 +118,5 @@ void alarmMatch(void* data)
77118
}
78119
alarmMatch_counter++;
79120
rtc.setAlarmEpoch( rtc.getEpoch() + sec);
121+
#endif
80122
}
81-

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=STM32duino Low Power
2-
version=1.0.3
2+
version=1.1.0
33
author=Wi6Labs
44
maintainer=stm32duino
55
sentence=Power save primitives features for STM32 boards

src/STM32LowPower.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
/**
22
******************************************************************************
33
* @file STM32LowPower.cpp
4-
* @author WI6LABS
5-
* @version V1.0.0
6-
* @date 11-December-2017
4+
* @author Frederic Pillon
75
* @brief Provides a STM32 Low Power interface with Arduino
86
*
97
******************************************************************************
108
* @attention
119
*
12-
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
10+
* <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
1311
*
1412
* Redistribution and use in source and binary forms, with or without modification,
1513
* are permitted provided that the following conditions are met:
@@ -62,55 +60,55 @@ void STM32LowPower::begin(void)
6260
/**
6361
* @brief Enable the idle low power mode (STM32 sleep). Exit this mode on
6462
* interrupt or in n milliseconds.
65-
* @param millis: optional delay before leave the idle mode (default: 0).
63+
* @param ms: optional delay before leave the idle mode (default: 0).
6664
* @retval None
6765
*/
68-
void STM32LowPower::idle(uint32_t millis)
66+
void STM32LowPower::idle(uint32_t ms)
6967
{
70-
if ((millis > 0) || _rtc_wakeup) {
71-
programRtcWakeUp(millis, IDLE_MODE);
68+
if ((ms != 0) || _rtc_wakeup) {
69+
programRtcWakeUp(ms, IDLE_MODE);
7270
}
7371
LowPower_sleep(PWR_MAINREGULATOR_ON);
7472
}
7573

7674
/**
7775
* @brief Enable the sleep low power mode (STM32 sleep). Exit this mode on
7876
* interrupt or in n milliseconds.
79-
* @param millis: optional delay before leave the sleep mode (default: 0).
77+
* @param ms: optional delay before leave the sleep mode (default: 0).
8078
* @retval None
8179
*/
82-
void STM32LowPower::sleep(uint32_t millis)
80+
void STM32LowPower::sleep(uint32_t ms)
8381
{
84-
if ((millis > 0) || _rtc_wakeup) {
85-
programRtcWakeUp(millis, SLEEP_MODE);
82+
if ((ms != 0) || _rtc_wakeup) {
83+
programRtcWakeUp(ms, SLEEP_MODE);
8684
}
8785
LowPower_sleep(PWR_LOWPOWERREGULATOR_ON);
8886
}
8987

9088
/**
9189
* @brief Enable the deepsleep low power mode (STM32 stop). Exit this mode on
9290
* interrupt or in n milliseconds.
93-
* @param millis: optional delay before leave the deepSleep mode (default: 0).
91+
* @param ms: optional delay before leave the deepSleep mode (default: 0).
9492
* @retval None
9593
*/
96-
void STM32LowPower::deepSleep(uint32_t millis)
94+
void STM32LowPower::deepSleep(uint32_t ms)
9795
{
98-
if ((millis > 0) || _rtc_wakeup) {
99-
programRtcWakeUp(millis, DEEP_SLEEP_MODE);
96+
if ((ms != 0) || _rtc_wakeup) {
97+
programRtcWakeUp(ms, DEEP_SLEEP_MODE);
10098
}
10199
LowPower_stop(_serial);
102100
}
103101

104102
/**
105103
* @brief Enable the shutdown low power mode (STM32 shutdown or standby mode).
106104
* Exit this mode on interrupt or in n milliseconds.
107-
* @param millis: optional delay before leave the shutdown mode (default: 0).
105+
* @param ms: optional delay before leave the shutdown mode (default: 0).
108106
* @retval None
109107
*/
110-
void STM32LowPower::shutdown(uint32_t millis)
108+
void STM32LowPower::shutdown(uint32_t ms)
111109
{
112-
if ((millis > 0) || _rtc_wakeup) {
113-
programRtcWakeUp(millis, SHUTDOWN_MODE);
110+
if ((ms != 0) || _rtc_wakeup) {
111+
programRtcWakeUp(ms, SHUTDOWN_MODE);
114112
}
115113
LowPower_shutdown();
116114
}
@@ -169,13 +167,13 @@ void STM32LowPower::enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *
169167

170168
/**
171169
* @brief Configure the RTC alarm
172-
* @param millis: time of the alarm in milliseconds. At least 1000ms.
170+
* @param ms: time of the alarm in milliseconds.
173171
* @param lp_mode: low power mode targeted.
174172
* @retval None
175173
*/
176-
void STM32LowPower::programRtcWakeUp(uint32_t millis, LP_Mode lp_mode)
174+
void STM32LowPower::programRtcWakeUp(uint32_t ms, LP_Mode lp_mode)
177175
{
178-
int epoc;
176+
uint32_t epoc;
179177
uint32_t sec;
180178
STM32RTC &rtc = STM32RTC::getInstance();
181179
STM32RTC::Source_Clock clkSrc = rtc.getClockSource();
@@ -201,15 +199,31 @@ void STM32LowPower::programRtcWakeUp(uint32_t millis, LP_Mode lp_mode)
201199
}
202200
rtc.configForLowPower(clkSrc);
203201

204-
if (millis > 0) {
202+
if (ms != 0) {
205203
// Convert millisecond to second
206-
sec = millis / 1000;
204+
sec = ms / 1000;
205+
206+
#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000)
207+
uint32_t epoc_ms;
208+
ms = ms % 1000;
209+
epoc = rtc.getEpoch(&epoc_ms);
210+
211+
//Update epoch_ms - might need to add a second to epoch
212+
epoc_ms += ms;
213+
if (epoc_ms >= 1000) {
214+
sec ++;
215+
epoc_ms -= 1000;
216+
}
217+
218+
rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_DHHMMSS, epoc_ms);
219+
#else
207220
// Minimum is 1 second
208221
if (sec == 0) {
209222
sec = 1;
210223
}
211-
212224
epoc = rtc.getEpoch();
225+
213226
rtc.setAlarmEpoch(epoc + sec);
227+
#endif
214228
}
215229
}

src/STM32LowPower.h

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
/**
22
******************************************************************************
33
* @file STM32LowPower.h
4-
* @author WI6LABS
5-
* @version V1.0.0
6-
* @date 11-December-2017
4+
* @author Frederic Pillon
75
* @brief Provides a STM32 Low Power interface with Arduino
86
*
97
******************************************************************************
108
* @attention
119
*
12-
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
10+
* <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
1311
*
1412
* Redistribution and use in source and binary forms, with or without modification,
1513
* are permitted provided that the following conditions are met:
@@ -41,6 +39,10 @@
4139

4240
#include <Arduino.h>
4341

42+
#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01090000)
43+
#include "low_power.h"
44+
#endif
45+
4446
// Check if PWR HAL enable in variants/board_name/stm32yzxx_hal_conf.h
4547
#ifndef HAL_PWR_MODULE_ENABLED
4648
#error "PWR configuration is missing. Check flag HAL_PWR_MODULE_ENABLED in variants/board_name/stm32yzxx_hal_conf.h"
@@ -64,28 +66,28 @@ class STM32LowPower {
6466

6567
void begin(void);
6668

67-
void idle(uint32_t millis = 0);
68-
void idle(int millis)
69+
void idle(uint32_t ms = 0);
70+
void idle(int ms)
6971
{
70-
idle((uint32_t)millis);
72+
idle((uint32_t)ms);
7173
}
7274

73-
void sleep(uint32_t millis = 0);
74-
void sleep(int millis)
75+
void sleep(uint32_t ms = 0);
76+
void sleep(int ms)
7577
{
76-
sleep((uint32_t)millis);
78+
sleep((uint32_t)ms);
7779
}
7880

79-
void deepSleep(uint32_t millis = 0);
80-
void deepSleep(int millis)
81+
void deepSleep(uint32_t ms = 0);
82+
void deepSleep(int ms)
8183
{
82-
deepSleep((uint32_t)millis);
84+
deepSleep((uint32_t)ms);
8385
}
8486

85-
void shutdown(uint32_t millis = 0);
86-
void shutdown(int millis)
87+
void shutdown(uint32_t ms = 0);
88+
void shutdown(int ms)
8789
{
88-
shutdown((uint32_t)millis);
90+
shutdown((uint32_t)ms);
8991
}
9092

9193
void attachInterruptWakeup(uint32_t pin, voidFuncPtrVoid callback, uint32_t mode, LP_Mode LowPowerMode = SHUTDOWN_MODE);
@@ -97,7 +99,7 @@ class STM32LowPower {
9799
bool _configured; // Low Power mode initialization status
98100
serial_t *_serial; // Serial for wakeup from deep sleep
99101
bool _rtc_wakeup; // Is RTC wakeup?
100-
void programRtcWakeUp(uint32_t millis, LP_Mode lp_mode);
102+
void programRtcWakeUp(uint32_t ms, LP_Mode lp_mode);
101103
};
102104

103105
extern STM32LowPower LowPower;

0 commit comments

Comments
 (0)