From 562190f552ce3396432c043068e9836fed19b493 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 6 Dec 2016 18:43:05 +0100 Subject: [PATCH] Add APIs for boards with companion chip (eg. Tian) --- examples/TianStandby/TianStandby.ino | 51 ++++++++++++++++++++++++++++ src/ArduinoLowPower.h | 19 +++++++++++ 2 files changed, 70 insertions(+) create mode 100644 examples/TianStandby/TianStandby.ino diff --git a/examples/TianStandby/TianStandby.ino b/examples/TianStandby/TianStandby.ino new file mode 100644 index 0000000..e4f4d56 --- /dev/null +++ b/examples/TianStandby/TianStandby.ino @@ -0,0 +1,51 @@ +/* + TianStandby + + This sketch demonstrates the usage of SAMD chip to furtherly reduce the power usage of Tian + board. This method can be applied to any board with companion chips which expose a method + (via direct pin interrupt or via a command) to enter and exit standby. + 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, the internal RTC of SAMD chip will wake up the processor every 20 seconds. + Before going to sleep, the SAMD chip tells the MIPS CPU to standby too. + Please note that, if the processor is sleeping, a new sketch can't be uploaded. To overcome this, manually reset the board (usually with a single or double tap to the RESET button) + + This example code is in the public domain. +*/ + +#include "ArduinoLowPower.h" + +#define MIPS_PIN 32 + +void MIPS_PM(bool sleep) { + pinMode(MIPS_PIN, OUTPUT); + digitalWrite(MIPS_PIN, sleep ? LOW: HIGH); +} + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + LowPower.companionLowPowerCallback(MIPS_PM); + // Uncomment this function if you wish to attach function dummy when RTC wakes up the chip + LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, onWakeup, CHANGE); +} + +void loop() { + digitalWrite(LED_BUILTIN, HIGH); + delay(500); + digitalWrite(LED_BUILTIN, LOW); + delay(500); + // Triggers a 2000 ms sleep (the device will be woken up only by the registered wakeup sources and by internal RTC) + // The power consumption of the chip will drop consistently + // Send sleep command to MIPS CPU and then go to sleep + LowPower.companionSleep(); + LowPower.sleep(20000); +} + +void onWakeup() { + // 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 the companion chip, too + LowPower.companionWakeup(); +} diff --git a/src/ArduinoLowPower.h b/src/ArduinoLowPower.h index a338824..8e555ff 100644 --- a/src/ArduinoLowPower.h +++ b/src/ArduinoLowPower.h @@ -15,7 +15,13 @@ #include "RTCZero.h" #endif +#if defined(ARDUINO_SAMD_TIAN) +// add here any board with companion chip which can be woken up +#define BOARD_HAS_COMPANION_CHIP +#endif + //typedef void (*voidFuncPtr)( void ) ; +typedef void (*onOffFuncPtr)( bool ) ; class ArduinoLowPowerClass { public: @@ -39,6 +45,18 @@ class ArduinoLowPowerClass { void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode); + #ifdef BOARD_HAS_COMPANION_CHIP + void companionLowPowerCallback(onOffFuncPtr callback) { + companionSleepCB = callback; + } + void companionSleep() { + companionSleepCB(true); + } + void companionWakeup() { + companionSleepCB(false); + } + #endif + #ifdef __ARDUINO_ARC__ void wakeFromSleepCallback(void); void wakeFromDoze(void); @@ -74,6 +92,7 @@ class ArduinoLowPowerClass { #define RTC_ALARM_WAKEUP 0xFF #define RESET_BUTTON_WAKEUP 0xFE #endif + void (*companionSleepCB)(bool); }; extern ArduinoLowPowerClass LowPower;