Skip to content

STM32 Low Power library (Rework of PR 1) #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 25, 2018
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
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,64 @@
# STM32LowPower
Arduino library to support Low Power

## 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 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 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 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 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
**param** callback: pointer to callback
**param** mode: interrupt mode (HIGH, LOW, RISING, FALLING or CHANGE)

* **`void enableWakeupFrom(HardwareSerial *serial, voidFuncPtrVoid callback)`**: enable a UART peripheral in low power mode. See board documentation for low power mode compatibility.
**param** serial: pointer to a UART
**param** callback: pointer to a callback to call when the board is waked up.

* **`void enableWakeupFrom(TwoWire *wire, voidFuncPtrVoid callback)`**:
enable an I2C peripheral in low power mode. See board documentation for low power mode compatibility.
**param** wire: pointer to I2C
**param** callback: pointer to a callback to call when the board is waked up.

* **`void enableWakeupFrom(STM32RTC *rtc, voidFuncPtr callback)`**
attach a callback to the RTC peripheral.
**param** rtc: pointer to RTC
**param** callback: pointer to a callback to call when the board is waked up.

`Begin()` function must be called at least once before `idle()`, `sleep()`, `deepSleep()` or `shutdown()` functions.

`attachInterruptWakeup()` or `enableWakeupFrom()` functions should be called before `idle()`, `sleep()`, `deepSleep()` or `shutdown()` functions.

The board will restart when exit the deepSleep or shutdown mode.

## Hardware state

* **Idle mode**: low wake-up latency (µs range) (e.g. ARM WFI). Memories and
voltage supplies are retained. Minimal power saving mainly on the core itself.

* **sleep mode**: low wake-up latency (µs range) (e.g. ARM WFI), Memories and
voltage supplies are retained. Minimal power saving mainly on the core itself but
higher than idle mode.

* **deep sleep mode**: medium latency (ms range), clocks are gated to reduced. Memories
and voltage supplies are retained. If supported, Peripherals wake-up is possible (UART, I2C ...).

* **shutdown mode**: high wake-up latency (posible hundereds of ms or second
timeframe), voltage supplies are cut except always-on domain, memory content
are lost and system basically reboots.

## Source

You can find the source files at
https://github.com/stm32duino/STM32LowPower
81 changes: 81 additions & 0 deletions examples/AlarmTimedWakup/AlarmTimedWakup.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
AdvancedTimedWakeup

This sketch demonstrates the usage of Internal Interrupts to wakeup a chip in deep sleep mode.

In this sketch:
- RTC date and time are configured.
- Alarm is set to wake up the processor each 'atime' and called a custom alarm callback
which increment a value and reload alarm with 'atime' offset.

This example code is in the public domain.
*/

#include "STM32LowPower.h"
#include <STM32RTC.h>

/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();

// Time in second between blink
static uint32_t atime = 1;

// Declare it volatile since it's incremented inside an interrupt
volatile int alarmMatch_counter = 0;

// Variables for RTC configurations
static byte seconds = 0;
static byte minutes = 0;
static byte hours = 0;

static byte weekDay = 1;
static byte day = 1;
static byte month = 1;
static byte year = 18;

void setup() {
rtc.begin();
rtc.setTime(hours, minutes, seconds);
rtc.setDate(weekDay, day, month, year);

pinMode(LED_BUILTIN, OUTPUT);

Serial.begin(9600);
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 );
}

void loop() {
Serial.print("Alarm Match: ");
Serial.print(alarmMatch_counter);
Serial.println(" times.");
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
LowPower.deepSleep();
digitalWrite(LED_BUILTIN, LOW);
LowPower.deepSleep();
}

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
uint32_t sec = 1;
if(data != NULL) {
sec = *(uint32_t*)data;
// Minimum is 1 second
if (sec == 0){
sec = 1;
}
}
alarmMatch_counter++;
rtc.setAlarmEpoch( rtc.getEpoch() + sec);
}

52 changes: 52 additions & 0 deletions examples/ExternalWakeup/ExternalWakeup.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
ExternalWakeup
This sketch demonstrates the usage of External Interrupts (on pins) to wakeup
a chip in sleep mode. Sleep modes allow a significant drop in the power usage
of a board while it does nothing waiting for an event to happen.
Battery powered application can take advantage of these modes to enhance
battery life significantly.
In this sketch, pressing a pushbutton attached to pin will wake up the board.
This example code is in the public domain.
*/

#include "STM32LowPower.h"

// Blink sequence number
// Declare it volatile since it's incremented inside an interrupt
volatile int repetitions = 1;

// Pin used to trigger a wakeup
const int pin = USER_BTN;

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
// Set pin as INPUT_PULLUP to avoid spurious wakeup
pinMode(pin, INPUT_PULLUP);

// Configure low power
LowPower.begin();
// Attach a wakeup interrupt on pin, calling repetitionsIncrease when the device is woken up
LowPower.attachInterruptWakeup(pin, repetitionsIncrease, RISING);
}

void loop() {
for (int i = 0; i < repetitions; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}
// Triggers an infinite sleep (the device will be woken up only by the registered wakeup sources)
// The power consumption of the chip will drop consistently
LowPower.sleep();
}

void repetitionsIncrease() {
// 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
repetitions ++;
}
57 changes: 57 additions & 0 deletions examples/SerialDeepSleep/SerialDeepSleep.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
SerialDeepSleep
This sketch demonstrates the usage of Serial Interrupts to wakeup a chip
in deep sleep mode.
This sketch is compatible only with board supporting uart peripheral in
stop mode.
This example code is in the public domain.
*/

#include "STM32LowPower.h"

// Declare it volatile since it's incremented inside an interrupt
volatile int wakeup_counter = 0;

void setup() {
Serial.begin(9600);
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
// Configure low power
LowPower.begin();
// Enable UART in Low Power mode wakeup source
LowPower.enableWakeupFrom(&Serial, SerialWakeup);
Serial.println("Start deep sleep wakeup from Serial");
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
// Triggers an infinite deep sleep
// (the device will be woken up only by the registered wakeup sources)
// The power consumption of the chip will drop consistently
LowPower.deepSleep();

Serial.print(wakeup_counter);
Serial.println(" wake up");

// Empty Serial Rx
while(Serial.available()) {
char c = Serial.read();
Serial.print(c);
}
Serial.println();
}

void SerialWakeup() {
// 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
wakeup_counter++;
}
25 changes: 25 additions & 0 deletions examples/TimedWakeup/TimedWakeup.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
TimedWakeup
This sketch demonstrates the usage of Internal Interrupts to wakeup a chip
in deep sleep mode.
In this sketch, the internal RTC will wake up the processor every second.
This example code is in the public domain.
*/

#include "STM32LowPower.h"

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
// Configure low power
LowPower.begin();
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH);
LowPower.deepSleep(1000);
digitalWrite(LED_BUILTIN, LOW);
LowPower.deepSleep(1000);
}
26 changes: 26 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#######################################
# Syntax Coloring Map For Energy Saving
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

ArduinoLowPower KEYWORD1
LowPower KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
idle KEYWORD2
sleep KEYWORD2
deepSleep KEYWORD2
shutdown KEYWORD2
attachInterruptWakeup KEYWORD2
enableWakeupFrom KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=STM32duino Low Power
version=1.0.0
author=Wi6Labs
maintainer=stm32duino
sentence=Power save primitives features for STM32 boards
paragraph=With this library you can manage the low power states of STM32 boards
category=Device Control
url=https://github.com/stm32duino/STM32LowPower
architectures=stm32
Loading