Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@ Arduino library to support STM32 Low Power.

## Requirement
* [Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32) version >= 1.3.0
Comment thread
fpistm marked this conversation as resolved.
* [STM32RTC](https://github.com/stm32duino/STM32RTC)

## API

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

* **`void idle(uint32_t millis)`**: enter in idle mode
**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.
* **`void idle(uint32_t ms)`**: enter in idle mode
**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.

* **`void sleep(uint32_t millis)`**: enter in sleep mode
**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.
* **`void sleep(uint32_t ms)`**: enter in sleep mode
**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.

* **`void deepSleep(uint32_t millis)`**: enter in deepSleep mode
**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.
* **`void deepSleep(uint32_t ms)`**: enter in deepSleep mode
**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.

* **`void shutdown(uint32_t millis)`**: enter in shutdown mode
**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.
* **`void shutdown(uint32_t ms)`**: enter in shutdown mode
**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.

**Note: With [STM32RTC](https://github.com/stm32duino/STM32RTC) version lower than 1.1.0, the minimum number of milliseconds is 1000 ms.**

* **`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).
**param** pin: pin number
Expand Down
49 changes: 45 additions & 4 deletions examples/AlarmTimedWakeup/AlarmTimedWakeup.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@
/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();

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

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

Serial.begin(9600);
while(!Serial) {}
while (!Serial) {}

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

// Configure first alarm in 2 second then it will be done in the rtc callback
rtc.setAlarmEpoch( rtc.getEpoch() + 2 );
rtc.setAlarmEpoch( rtc.getEpoch() + 2);
}

void loop() {
Serial.print("Alarm Match: ");
Serial.print(alarmMatch_counter);
Serial.println(" times.");
delay(100);
Serial.flush();
digitalWrite(LED_BUILTIN, HIGH);
LowPower.deepSleep();
digitalWrite(LED_BUILTIN, LOW);
Expand All @@ -67,6 +73,41 @@ void alarmMatch(void* data)
// This function will be called once on device wakeup
// You can do some little operations here (like changing variables which will be used in the loop)
// Remember to avoid calling delay() and long running functions since this functions executes in interrupt context
#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000)
uint32_t epoc;
uint32_t epoc_ms;
uint32_t sec = 0;
uint32_t _millis = 1000;

if (data != NULL) {
_millis = *(uint32_t*)data;
// Minimum is 1 second
if (sec == 0) {
sec = 1;
}
}

sec = _millis / 1000;
#ifdef STM32F1xx
// Minimum is 1 second
if (sec == 0) {
sec = 1;
}
epoc = rtc.getEpoch(&epoc_ms);
#else
_millis = _millis % 1000;
epoc = rtc.getEpoch(&epoc_ms);

//Update epoch_ms - might need to add a second to epoch
epoc_ms += _millis;
if (epoc_ms >= 1000) {
sec ++;
epoc_ms -= 1000;
}
#endif
alarmMatch_counter++;
rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_SS, epoc_ms);
#else
uint32_t sec = 1;
if(data != NULL) {
sec = *(uint32_t*)data;
Expand All @@ -77,5 +118,5 @@ void alarmMatch(void* data)
}
alarmMatch_counter++;
rtc.setAlarmEpoch( rtc.getEpoch() + sec);
#endif
}

2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=STM32duino Low Power
version=1.0.3
version=1.1.0
author=Wi6Labs
maintainer=stm32duino
sentence=Power save primitives features for STM32 boards
Expand Down
66 changes: 40 additions & 26 deletions src/STM32LowPower.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
/**
******************************************************************************
* @file STM32LowPower.cpp
* @author WI6LABS
* @version V1.0.0
* @date 11-December-2017
* @author Frederic Pillon
* @brief Provides a STM32 Low Power interface with Arduino
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
* <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -62,55 +60,55 @@ void STM32LowPower::begin(void)
/**
* @brief Enable the idle low power mode (STM32 sleep). Exit this mode on
* interrupt or in n milliseconds.
* @param millis: optional delay before leave the idle mode (default: 0).
* @param ms: optional delay before leave the idle mode (default: 0).
* @retval None
*/
void STM32LowPower::idle(uint32_t millis)
void STM32LowPower::idle(uint32_t ms)
{
if ((millis > 0) || _rtc_wakeup) {
programRtcWakeUp(millis, IDLE_MODE);
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, IDLE_MODE);
}
LowPower_sleep(PWR_MAINREGULATOR_ON);
}

/**
* @brief Enable the sleep low power mode (STM32 sleep). Exit this mode on
* interrupt or in n milliseconds.
* @param millis: optional delay before leave the sleep mode (default: 0).
* @param ms: optional delay before leave the sleep mode (default: 0).
* @retval None
*/
void STM32LowPower::sleep(uint32_t millis)
void STM32LowPower::sleep(uint32_t ms)
{
if ((millis > 0) || _rtc_wakeup) {
programRtcWakeUp(millis, SLEEP_MODE);
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, SLEEP_MODE);
}
LowPower_sleep(PWR_LOWPOWERREGULATOR_ON);
}

/**
* @brief Enable the deepsleep low power mode (STM32 stop). Exit this mode on
* interrupt or in n milliseconds.
* @param millis: optional delay before leave the deepSleep mode (default: 0).
* @param ms: optional delay before leave the deepSleep mode (default: 0).
* @retval None
*/
void STM32LowPower::deepSleep(uint32_t millis)
void STM32LowPower::deepSleep(uint32_t ms)
{
if ((millis > 0) || _rtc_wakeup) {
programRtcWakeUp(millis, DEEP_SLEEP_MODE);
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, DEEP_SLEEP_MODE);
}
LowPower_stop(_serial);
}

/**
* @brief Enable the shutdown low power mode (STM32 shutdown or standby mode).
* Exit this mode on interrupt or in n milliseconds.
* @param millis: optional delay before leave the shutdown mode (default: 0).
* @param ms: optional delay before leave the shutdown mode (default: 0).
* @retval None
*/
void STM32LowPower::shutdown(uint32_t millis)
void STM32LowPower::shutdown(uint32_t ms)
{
if ((millis > 0) || _rtc_wakeup) {
programRtcWakeUp(millis, SHUTDOWN_MODE);
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, SHUTDOWN_MODE);
}
LowPower_shutdown();
}
Expand Down Expand Up @@ -169,13 +167,13 @@ void STM32LowPower::enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback, void *

/**
* @brief Configure the RTC alarm
* @param millis: time of the alarm in milliseconds. At least 1000ms.
* @param ms: time of the alarm in milliseconds.
* @param lp_mode: low power mode targeted.
* @retval None
*/
void STM32LowPower::programRtcWakeUp(uint32_t millis, LP_Mode lp_mode)
void STM32LowPower::programRtcWakeUp(uint32_t ms, LP_Mode lp_mode)
{
int epoc;
uint32_t epoc;
uint32_t sec;
STM32RTC &rtc = STM32RTC::getInstance();
STM32RTC::Source_Clock clkSrc = rtc.getClockSource();
Expand All @@ -201,15 +199,31 @@ void STM32LowPower::programRtcWakeUp(uint32_t millis, LP_Mode lp_mode)
}
rtc.configForLowPower(clkSrc);

if (millis > 0) {
if (ms != 0) {
// Convert millisecond to second
sec = millis / 1000;
sec = ms / 1000;

#if defined(STM32_RTC_VERSION) && (STM32_RTC_VERSION >= 0x01010000)
uint32_t epoc_ms;
ms = ms % 1000;
epoc = rtc.getEpoch(&epoc_ms);

//Update epoch_ms - might need to add a second to epoch
epoc_ms += ms;
if (epoc_ms >= 1000) {
sec ++;
epoc_ms -= 1000;
}

rtc.setAlarmEpoch(epoc + sec, STM32RTC::MATCH_DHHMMSS, epoc_ms);
#else
// Minimum is 1 second
if (sec == 0) {
sec = 1;
}

epoc = rtc.getEpoch();

rtc.setAlarmEpoch(epoc + sec);
#endif
}
}
36 changes: 19 additions & 17 deletions src/STM32LowPower.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
/**
******************************************************************************
* @file STM32LowPower.h
* @author WI6LABS
* @version V1.0.0
* @date 11-December-2017
* @author Frederic Pillon
* @brief Provides a STM32 Low Power interface with Arduino
*
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
* <h2><center>&copy; COPYRIGHT(c) 2020 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
Expand Down Expand Up @@ -41,6 +39,10 @@

#include <Arduino.h>

#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01090000)
#include "low_power.h"
#endif

// Check if PWR HAL enable in variants/board_name/stm32yzxx_hal_conf.h
#ifndef HAL_PWR_MODULE_ENABLED
#error "PWR configuration is missing. Check flag HAL_PWR_MODULE_ENABLED in variants/board_name/stm32yzxx_hal_conf.h"
Expand All @@ -64,28 +66,28 @@ class STM32LowPower {

void begin(void);

void idle(uint32_t millis = 0);
void idle(int millis)
void idle(uint32_t ms = 0);
void idle(int ms)
{
idle((uint32_t)millis);
idle((uint32_t)ms);
}

void sleep(uint32_t millis = 0);
void sleep(int millis)
void sleep(uint32_t ms = 0);
void sleep(int ms)
{
sleep((uint32_t)millis);
sleep((uint32_t)ms);
}

void deepSleep(uint32_t millis = 0);
void deepSleep(int millis)
void deepSleep(uint32_t ms = 0);
void deepSleep(int ms)
{
deepSleep((uint32_t)millis);
deepSleep((uint32_t)ms);
}

void shutdown(uint32_t millis = 0);
void shutdown(int millis)
void shutdown(uint32_t ms = 0);
void shutdown(int ms)
{
shutdown((uint32_t)millis);
shutdown((uint32_t)ms);
}

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

extern STM32LowPower LowPower;
Expand Down
Loading