Created
May 7, 2014 19:43
-
-
Save matthijskooijman/ec46363bc6c7ed2598b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <avr/sleep.h> | |
#include <avr/interrupt.h> | |
#include <util/delay.h> | |
void setup(){ | |
Serial.begin(115200); | |
pinMode(LED_RED, OUTPUT); | |
pinMode(LED_GREEN, OUTPUT); | |
pinMode(LED_BLUE, OUTPUT); | |
pinMode(2, INPUT_PULLUP); | |
pinMode(3, INPUT_PULLUP); | |
pinMode(4, INPUT_PULLUP); | |
pinMode(5, INPUT_PULLUP); | |
pinMode(6, INPUT_PULLUP); | |
pinMode(7, INPUT_PULLUP); | |
pinMode(8, INPUT_PULLUP); | |
pinMode(A0, INPUT_PULLUP); | |
pinMode(A1, INPUT_PULLUP); | |
pinMode(A2, INPUT_PULLUP); | |
pinMode(A3, INPUT_PULLUP); | |
pinMode(A4, INPUT_PULLUP); | |
pinMode(A5, INPUT_PULLUP); | |
pinMode(A6, INPUT_PULLUP); | |
pinMode(A7, INPUT_PULLUP); | |
pinMode(MISO, INPUT_PULLUP); | |
pinMode(MOSI, INPUT_PULLUP); | |
pinMode(SCK, INPUT_PULLUP); | |
pinMode(BACKPACK_BUS, INPUT_PULLUP); | |
pinMode(13, INPUT_PULLUP); | |
pinMode(14, INPUT_PULLUP); | |
pinMode(SDA, INPUT_PULLUP); | |
pinMode(SCL, INPUT_PULLUP); | |
pinMode(VCC_ENABLE, OUTPUT); | |
Serial.write("DONE"); | |
} | |
ISR(TIMER2_COMPA_vect) { | |
// Do nothing, only used to trigger a wakeup | |
} | |
void loop() { | |
// Stop timer2 | |
TCCR2B = 0; | |
// Enable asynchronous mode for timer2 (uses external 32kHz | |
// crystal. This might corrupt the settings registers, so re-set | |
// TCCR2B. | |
ASSR |= (1 << AS2); | |
TCCR2B = 0; | |
// Outputs disconnected, Fast PWM mode (COMPA didn't seem to | |
// work properly in normal mode) | |
TCCR2A = (1 << WGM21) | (1 << WGM20); | |
// Reset timer | |
TCNT2 = 0; | |
// Interrupt at 5 seconds | |
OCR2A = 160; | |
// Clear any pending interrupt | |
TIFR2 = (1 << OCF2A); | |
TIMSK2 = (1 << OCIE2A); | |
// Put tranceiver to sleep | |
TRXPR |= (1 << SLPTR); | |
PRR2 |= (1 << PRTRX24); | |
// Disable Analag comparator | |
ACSR = (1 << ACD); | |
// Disable ADC | |
ADCSRA &= ~(1 << ADEN); | |
// TODO: When re-enabling the ADC, wait for the AVDDOK bit | |
// Disable the TX side of UART0. If the 16u2 it connects to is | |
// powered off, it offers a path to ground, so keeping the pin | |
// enabled and high (TTL idle) wastes around 1mA of current. | |
UCSR0B &= ~(1 << TXEN0); | |
UCSR0B &= ~(1 << RXEN0); | |
set_sleep_mode(SLEEP_MODE_PWR_SAVE); | |
cli(); | |
// Start timer, prescaler 1024, meaning a single timer increment | |
// is 1/32s | |
TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20); | |
// When the timer is in asynchronous mode, it takes up to one | |
// 32kHz clock cycle for register writes to take effect. Wait | |
// until that's done before sleeping. | |
while (ASSR & (1 << TCR2BUB)) /* nothing */; | |
sleep_enable(); | |
#ifdef sleep_bod_disable | |
// On 256rfr2, BOD is automatically disabled in deep sleep, but | |
// some other MCUs need explicit disabling. This should happen shortly | |
// before actually sleeping. It's always automatically re-enabled. | |
sleep_bod_disable(); | |
#endif | |
sei(); | |
// AVR guarantees that the instruction after sei is executed, so | |
// there is no race condition here | |
sleep_cpu(); | |
sleep_disable(); | |
// Disable interrupt again | |
TIMSK2 = 0; | |
digitalWrite(LED_GREEN, LOW); | |
delay(1000); | |
digitalWrite(LED_GREEN, HIGH); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment