summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-05-31 10:56:17 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-05-31 10:56:17 +0200
commitd040ed5eecb104c201b330c468df3b6d8c59b7f1 (patch)
tree7ea3bf6e09734f742af1814487dd8a53a62388af /src
Initial commit. Working static light, but no rgbfade yet
Diffstat (limited to 'src')
-rw-r--r--src/main.cc15
-rw-r--r--src/system.cc185
-rw-r--r--src/system.h52
3 files changed, 252 insertions, 0 deletions
diff --git a/src/main.cc b/src/main.cc
new file mode 100644
index 0000000..39a3e38
--- /dev/null
+++ b/src/main.cc
@@ -0,0 +1,15 @@
+#include <avr/io.h>
+#include <stdlib.h>
+
+#include "system.h"
+
+int main (void)
+{
+ blinkencat.initialize();
+
+ while (1) {
+ blinkencat.loop();
+ }
+
+ return 0;
+}
diff --git a/src/system.cc b/src/system.cc
new file mode 100644
index 0000000..9b04f69
--- /dev/null
+++ b/src/system.cc
@@ -0,0 +1,185 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+#include <stdlib.h>
+
+// Debian's avr-libc lacks the ATTiny2313A WDTCSR definition
+#define WDTCSR _SFR_IO8(0x21)
+
+#include "system.h"
+
+/*
+ * Charge Status IN -> PD3 (PCINT14)
+ * Piezo IN -X
+ * Charge Status LED OUT -> PD1
+ * Vcc -> VCC
+ * GND -> GND
+ * Warm White OUT -> PD5 (OC0B)
+ * Blue OUT -> PB2 (OC0A)
+ * Button IN -> PD2 (PCINT13)
+ * Red OUT -> PB3 (OC1A)
+ * Green OUT -> PB4 (OC1B)
+ *
+ */
+
+System blinkencat;
+
+void System::initialize()
+{
+
+ // disable analog comparator
+ ACSR |= _BV(ACD);
+
+ // disable unused modules
+ PRR |= _BV(PRUSI) | _BV(PRUSART);
+
+ wdt_disable();
+
+ DDRA = 0;
+ DDRB = _BV(DDB2) | _BV(DDB3) | _BV(DDB4);
+ DDRD = _BV(DDD1) | _BV(DDD5);
+ PORTD = _BV(PD2);
+
+ /*
+ * Pin change interrupts on PD2 and PD3.
+ * They are also used to wake the chip from sleep, hence we can't use
+ * INT0/INT1 directly. For those, only a level interrupt is detected
+ * asynchronously.
+ */
+
+ PCMSK2 = _BV(PCINT13) | _BV(PCINT14);
+ GIMSK = _BV(PCIE2);
+
+ sei();
+}
+
+void System::idle()
+{
+ MCUCR &= ~_BV(SM0);
+ MCUCR |= _BV(SE);
+ asm("sleep");
+ MCUCR &= ~_BV(SE);
+}
+
+void System::sleep()
+{
+ MCUCR |= _BV(SM0) | _BV(SE);
+ asm("sleep");
+ MCUCR &= ~_BV(SE);
+}
+
+void System::set_outputs()
+{
+ if (warmwhite) {
+ PORTD |= _BV(PD5);
+ } else {
+ PORTD &= ~_BV(PD5);
+ }
+ if (red) {
+ PORTB |= _BV(PB3);
+ } else {
+ PORTB &= ~_BV(PB3);
+ }
+ if (green) {
+ PORTB |= _BV(PB4);
+ } else {
+ PORTB &= ~_BV(PB4);
+ }
+ if (blue) {
+ PORTB |= _BV(PB2);
+ } else {
+ PORTB &= ~_BV(PB2);
+ }
+}
+
+void System::loop()
+{
+ switch (mode) {
+ case OFF:
+ warmwhite = red = green = blue = 0;
+ break;
+ case WARMWHITE:
+ warmwhite = 255;
+ red = green = blue = 0;
+ break;
+ case RED:
+ red = 255;
+ warmwhite = green = blue = 0;
+ break;
+ case GREEN:
+ green = 255;
+ warmwhite = red = blue = 0;
+ break;
+ case BLUE:
+ blue = 255;
+ warmwhite = red = green = 0;
+ break;
+ case YELLOW:
+ red = green = 255;
+ warmwhite = blue = 0;
+ break;
+ case MAGENTA:
+ red = blue = 255;
+ warmwhite = green = 0;
+ break;
+ case CYAN:
+ green = blue = 255;
+ warmwhite = red = 0;
+ break;
+ case SUN:
+ warmwhite = red = green = blue = 255;
+ break;
+ default:
+ break;
+ }
+ set_outputs();
+
+ if (mode == OFF && !btn_debounce) {
+ sleep();
+ } else {
+ idle();
+ }
+}
+
+void System::next_mode(void)
+{
+ if (!btn_debounce) {
+ mode = (BCMode)((mode + 1) % MODE_ENUM_MAX);
+ }
+}
+
+void System::debounce_start(void)
+{
+ btn_debounce = 1;
+ wdt_reset();
+ WDTCSR = _BV(WDE) | _BV(WDCE);
+ WDTCSR = _BV(WDIE) | _BV(WDP1) | _BV(WDP0);
+}
+
+void System::debounce_done(void)
+{
+ btn_debounce = 0;
+ wdt_disable();
+}
+
+ISR(WDT_OVERFLOW_vect)
+{
+ blinkencat.debounce_done();
+}
+
+ISR(PCINT2_vect)
+{
+ if (!(PIND & _BV(PD2))) {
+ blinkencat.next_mode();
+ }
+ if (PIND & _BV(PD3)) {
+ blinkencat.is_charging = 1;
+ PORTD |= _BV(PD1);
+ } else {
+ blinkencat.is_charging = 0;
+ PORTD &= ~_BV(PD1);
+ }
+ blinkencat.debounce_start();
+}
diff --git a/src/system.h b/src/system.h
new file mode 100644
index 0000000..35c7172
--- /dev/null
+++ b/src/system.h
@@ -0,0 +1,52 @@
+#ifndef __SYSTEM_H__
+#define __SYSTEM_H__
+
+class System {
+ private:
+ uint8_t btn_debounce;
+
+ void idle(void);
+ void sleep(void);
+
+ uint8_t warmwhite;
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+
+ void set_outputs();
+
+ public:
+
+ void initialize(void);
+
+ void loop(void);
+
+ uint8_t is_charging;
+
+ enum BCMode : uint8_t {
+ OFF = 0,
+ WARMWHITE,
+ RED,
+ GREEN,
+ BLUE,
+ YELLOW,
+ MAGENTA,
+ CYAN,
+ SUN,
+ MODE_ENUM_MAX,
+ };
+
+ BCMode mode;
+
+ void next_mode(void);
+
+ void debounce_done(void);
+
+ void debounce_start(void);
+
+ System() { btn_debounce = 0; mode = OFF; is_charging = 0; };
+};
+
+extern System blinkencat;
+
+#endif