From e159ecf46f978d49d3eaf4a8304e376cd2cd9d4a Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 28 Oct 2016 18:30:13 +0200 Subject: [PATCH] [WIP] initial API design samd basic functions ported --- keywords.txt | 22 ++++++++++ library.properties | 9 ++++ src/ArduinoLowPower.cpp | 95 +++++++++++++++++++++++++++++++++++++++++ src/ArduinoLowPower.h | 35 +++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 keywords.txt create mode 100644 library.properties create mode 100644 src/ArduinoLowPower.cpp create mode 100644 src/ArduinoLowPower.h diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..1867568 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,22 @@ +####################################### +# Syntax Coloring Map For Energy Saving +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +ArduinoLowPower KEYWORD1 +LowPower KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +idle KEYWORD2 +sleep KEYWORD2 +deepSleep KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..52d087d --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=Arduino Low Power +version=1.0.0 +author=Arduino +maintainer=Arduino LLC +sentence=Power save primitives features for 32 bit boards +paragraph=With this library you can manage the low power states of newer Arduino boards +category=Device Control +url=http://arduino.cc/libraries/ArduinoLowPower +architectures=samd,arc32 diff --git a/src/ArduinoLowPower.cpp b/src/ArduinoLowPower.cpp new file mode 100644 index 0000000..2cd07ac --- /dev/null +++ b/src/ArduinoLowPower.cpp @@ -0,0 +1,95 @@ +#include "ArduinoLowPower.h" + +#ifdef ARDUINO_ARCH_SAMD + +#include "WInterrupts.h" + +void ArduinoLowPowerClass::idle() { + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + PM->SLEEP.reg = 2; + __DSB(); + __WFI(); +} + +void ArduinoLowPowerClass::idle(uint32_t millis) { + setAlarmIn(millis); + idle(); +} + +void ArduinoLowPowerClass::sleep() { + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); +} + +void ArduinoLowPowerClass::sleep(uint32_t millis) { + setAlarmIn(millis); + sleep(); +} + +void ArduinoLowPowerClass::deepSleep() { + sleep(); +} + +void ArduinoLowPowerClass::deepSleep(uint32_t millis) { + sleep(millis); +} + +void ArduinoLowPowerClass::setAlarmIn(uint32_t millis) { + + if (!rtc.isConfigured()) { + attachInterruptWakeup(RTC_ALARM_WAKEUP, NULL, 0); + } + + uint32_t now = rtc.getEpoch(); + rtc.setAlarmEpoch(now + millis/1000); + rtc.enableAlarm(rtc.MATCH_YYMMDDHHMMSS); +} + +void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) { + + if (pin > PINS_COUNT) { + // check for external wakeup sources + // only enables the wakeup bit, no callback + // RTC library should call this API to enable the alarm subsystem + switch (pin) { + case RTC_ALARM_WAKEUP: + rtc.begin(); + rtc.attachInterrupt(callback); + /*case UART_WAKEUP:*/ + } + return; + } + + EExt_Interrupts in = g_APinDescription[pin].ulExtInt; + if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI) + return; + + attachInterrupt(pin, callback, mode); + +#if 0 + // enable EIC clock + GCLK->CLKCTRL.bit.CLKEN = 0; //disable GCLK module + while (GCLK->STATUS.bit.SYNCBUSY); + + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK6 | GCLK_CLKCTRL_ID( GCM_EIC )) ; //EIC clock switched on GCLK6 + while (GCLK->STATUS.bit.SYNCBUSY); + + GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(6)); //source for GCLK6 is OSCULP32K + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); + + GCLK->GENCTRL.bit.RUNSTDBY = 1; //GCLK6 run standby + while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); +#endif + + // Enable wakeup capability on pin in case being used during sleep + EIC->WAKEUP.reg |= (1 << in); + + /* Errata: Make sure that the Flash does not power all the way down + * when in sleep mode. */ + NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val; +} + +#endif + +ArduinoLowPowerClass LowPower; diff --git a/src/ArduinoLowPower.h b/src/ArduinoLowPower.h new file mode 100644 index 0000000..52a709a --- /dev/null +++ b/src/ArduinoLowPower.h @@ -0,0 +1,35 @@ +#ifndef _ARDUINO_LOW_POWER_H_ +#define _ARDUINO_LOW_POWER_H_ + +#include + +#ifdef ARDUINO_ARCH_SAMD +#include "RTCZero.h" +#endif + +//typedef void (*voidFuncPtr)( void ) ; + +class ArduinoLowPowerClass { + public: + void idle(void); + void idle(uint32_t millis); + + void sleep(void); + void sleep(uint32_t millis); + + void deepSleep(void); + void deepSleep(uint32_t millis); + + void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode); + + private: + #ifdef ARDUINO_ARCH_SAMD + void setAlarmIn(uint32_t millis); + RTCZero rtc; + #define RTC_ALARM_WAKEUP 0xFF + #endif +}; + +extern ArduinoLowPowerClass LowPower; + +#endif