summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Schodet2011-09-26 19:35:24 +0200
committerNicolas Schodet2011-09-26 19:41:34 +0200
commit83f4265644321022cce13d0e4f5a5f5335a4d7a9 (patch)
tree85cfdaa03745a2ab6b301cc20c1a35e5a9ace998
parent38b4a4d5ca0f30a5e058de2a99436df187a46f52 (diff)
src/binwatch, src/common: add power reduction and sleep when waiting button
-rw-r--r--src/binwatch/Makefile4
-rw-r--r--src/binwatch/binwatch.c2
-rw-r--r--src/binwatch/counter.c2
-rw-r--r--src/common/button.c17
-rw-r--r--src/common/power.c55
-rw-r--r--src/common/power.h36
6 files changed, 112 insertions, 4 deletions
diff --git a/src/binwatch/Makefile b/src/binwatch/Makefile
index e123a2c..dd7404b 100644
--- a/src/binwatch/Makefile
+++ b/src/binwatch/Makefile
@@ -1,7 +1,7 @@
BASE = $b/digital/avr
AVR_PROGS = counter binwatch
-counter_SOURCES = counter.c led.c button.c
-binwatch_SOURCES = binwatch.c led.c rtc.c button.c
+counter_SOURCES = counter.c led.c button.c power.c
+binwatch_SOURCES = binwatch.c led.c rtc.c button.c power.c
MODULES = utils
binwatch_MODULES = utils twi
CONFIGFILE = avrconfig.h
diff --git a/src/binwatch/binwatch.c b/src/binwatch/binwatch.c
index de48181..99283f3 100644
--- a/src/binwatch/binwatch.c
+++ b/src/binwatch/binwatch.c
@@ -25,6 +25,7 @@
#include "common/led.h"
#include "common/rtc.h"
#include "common/button.h"
+#include "common/power.h"
/** Get time in leds format. */
static uint16_t
@@ -42,6 +43,7 @@ int
main (void)
{
/* Initialise hardware. */
+ power_init ();
led_init ();
button_init ();
/* Initialise RTC. */
diff --git a/src/binwatch/counter.c b/src/binwatch/counter.c
index 71f9ba5..ff72c0d 100644
--- a/src/binwatch/counter.c
+++ b/src/binwatch/counter.c
@@ -24,10 +24,12 @@
#include "common.h"
#include "common/led.h"
#include "common/button.h"
+#include "common/power.h"
int
main (void)
{
+ power_init ();
led_init ();
button_init ();
uint16_t i;
diff --git a/src/common/button.c b/src/common/button.c
index 1924f62..7209eff 100644
--- a/src/common/button.c
+++ b/src/common/button.c
@@ -26,6 +26,7 @@
#include "io.h"
#include "button.h"
#include "led.h"
+#include "power.h"
/** Delay for the button to be considered debounced. */
#define BUTTON_DEBOUNCE_MS 100
@@ -33,6 +34,9 @@
void
button_init (void)
{
+ /* Initialise pin change interrupt. */
+ GIMSK |= _BV (PCIE);
+ PCMSK = IO_BV (BUTTON_IO);
/* Button is shared with leds, no PORT init. */
}
@@ -40,8 +44,12 @@ void
button_wait (void)
{
/* Wait until button is pressed. */
- while (IO_GET (BUTTON_IO))
- ;
+ GIFR = _BV (PCIF); /* Clear previous interrupt. */
+ if (IO_GET (BUTTON_IO))
+ {
+ /* Sleep, the pin change interrupt will wake me up. */
+ power_sleep ();
+ }
/* Remove pull-up to save battery and shut off leds. */
led_no_pull_up ();
/* Wait until button is really released. */
@@ -62,3 +70,8 @@ button_pressed (void)
return !IO_GET (BUTTON_IO);
}
+SIGNAL (PCINT0_vect)
+{
+ /* Nothing to do, only wake up. */
+}
+
diff --git a/src/common/power.c b/src/common/power.c
new file mode 100644
index 0000000..c7a5aab
--- /dev/null
+++ b/src/common/power.c
@@ -0,0 +1,55 @@
+/* power.c */
+/* binwatch - Tiny binary wristwatch. {{{
+ *
+ * Copyright (C) 2011 Nicolas Schodet
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact :
+ * Web: http://ni.fr.eu.org/
+ * Email: <nico at ni.fr.eu.org>
+ * }}} */
+#include "common.h"
+#include "power.h"
+#include "io.h"
+
+#include <avr/sleep.h>
+
+void
+power_init (void)
+{
+ /* Shutdown unused peripherals. */
+ /* Analog comparator. */
+ ACSR = _BV (ACD);
+ /* Timers, USI and ADC. */
+ PRR = _BV (PRTIM1) | _BV (PRTIM0) | _BV (PRUSI) | _BV (PRADC);
+ /* B3, B4, B5 input values are never read. */
+ DIDR0 = 0b111000;
+}
+
+void
+power_sleep (void)
+{
+ /* Enable interrupts right before sleep instruction so that any pending
+ * interrupt will occur after the processor go to sleep and really wake
+ * the processor. See avr-libc documentation. */
+ set_sleep_mode (SLEEP_MODE_PWR_DOWN);
+ sleep_enable ();
+ sei ();
+ sleep_cpu ();
+ sleep_disable ();
+ cli ();
+}
+
diff --git a/src/common/power.h b/src/common/power.h
new file mode 100644
index 0000000..279a26e
--- /dev/null
+++ b/src/common/power.h
@@ -0,0 +1,36 @@
+#ifndef power_h
+#define power_h
+/* power.h - Power reduction mesures. */
+/* binwatch - Tiny binary wristwatch. {{{
+ *
+ * Copyright (C) 2011 Nicolas Schodet
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Contact :
+ * Web: http://ni.fr.eu.org/
+ * Email: <nico at ni.fr.eu.org>
+ * }}} */
+
+/** Initialise power reduction. */
+void
+power_init (void);
+
+/** Enter power down deep sleep mode, use an enabled interrupt to wake-up.
+ * Interrupts will be enabled only for the duration of the sleep. */
+void
+power_sleep (void);
+
+#endif /* power_h */