55 lines
1.4 KiB
C++

#pragma once
#include "Arduino.h"
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
// Utility macros
#define adc_disable() (ADCSRA &= ~_BV(ADEN)) // disable ADC (before power-off)
#define adc_enable() (ADCSRA |= _BV(ADEN)) // re-enable ADC
#define enable_pin_interrupts() (GIMSK |= _BV(PCIE)) // Enable Pin Change Interrupts
class TinyPower {
public:
static void setup() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
enable_pin_interrupts();
}
static void sleep(byte pin = -1) {
if (pin >= 0) PCMSK |= _BV(pin); // Use PB0 as interrupt pin
adc_disable();
sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
sleep_bod_disable();
sei(); // Enable interrupts
sleep_cpu(); // sleep
sleep_disable(); // Clear SE bit
cli(); // Disable interrupts
if (pin >= 0) PCMSK &= ~_BV(pin); // Turn off PB0 as interrupt pin
adc_enable();
sei(); // Enable interrupts
}
static void enableWdt(byte time) {
cli();
MCUSR = 0x00;
WDTCR |= _BV(WDCE) | _BV(WDE);
WDTCR = _BV(WDIE) | (time & 0x08 ? _WD_PS3_MASK : 0x00) | (time & 0x07);
sei();
}
static void disableWdt() {
cli();
MCUSR = 0x00;
WDTCR |= _BV(WDCE) | _BV(WDE);
WDTCR = 0x00;
sei();
}
};