src/hello.c
changeset 3 87dd3b72b024
parent 2 2687fbd14fd9
--- a/src/hello.c	Wed Sep 24 23:49:49 2014 +0300
+++ b/src/hello.c	Thu Sep 25 00:56:54 2014 +0300
@@ -1,10 +1,13 @@
 #include <avr/interrupt.h>
 #include <avr/io.h>
 
+#include "stdlib.h"
+
 #define DEBUG_DDR DDRB
 #define DEBUG_PIN 5
 #define DEBUG_PORT PORTB
 
+/* Relay outputs */
 #define RELAY_DDR DDRC
 #define RELAY_PORT PORTC
 #define RELAY_PIN PINC
@@ -15,9 +18,27 @@
 #define RELAY_LEFT  2
 #define RELAY_RIGHT 3
 
+/* Switch inputs */
+static ioport_t *const SWITCH_DDR = &DDRD;
+static ioport_t *const SWITCH_PORT = &PORTD;
+static ioport_t *const SWITCH_PIN = &PIND;
+static ioport_t *const SWITCH_PCMSK = &PCMSK2;
+static const byte SWITCH_PCIE = PCIE2;
+static const byte SWITCH_PCIF = PCIF2;
+
+enum switch_bits {
+    SWITCH_LEFT         = 0b00000100,
+    SWITCH_RIGHT        = 0b00001000,
+    SWITCH_HORN1        = 0b00010000,
+    SWITCH_HORN2        = 0b00100000,
+
+    SWITCH_MASK         = 0b00111100,
+};
+
 #include "debug.h"
 #include "relay.h"
 #include "serial.h"
+#include "switch.h"
 #include "timer.h"
 
 int main (void)
@@ -25,10 +46,12 @@
     debug_init();
     relay_init(RELAY_PINS);
     serial_init(SERIAL_BAUD_9600, SERIAL_PARITY_N, SERIAL_STOPBITS_1);
+    switch_init();
     timer_init();
 
     // init
     char c = '.';
+    byte s;
     unsigned short timeout = 8000;
 
     debug_set();
@@ -36,39 +59,53 @@
 
     // start
     while (true) {
+        c = s = 0;
+
         if (timer_sleep(timeout)) {
             c = '.';
         } else if ((c = serial_read())) {
+            switch (c) {
+                case 'L':       relay_open(RELAY_LEFT); break;
+                case 'R':       relay_open(RELAY_RIGHT); break;
+                case 'B':
+                                relay_open(RELAY_DOWN1);
+                                relay_open(RELAY_DOWN2);
+                                break;
+
+                case 'l':       relay_toggle(RELAY_LEFT); break;
+                case 'r':       relay_toggle(RELAY_RIGHT); break;
+                case 'b':
+                                relay_close(RELAY_DOWN1);
+                                relay_close(RELAY_DOWN2);
+                                break;
+
+                default:
+                    c = '!';
+                    break;
+            }
+        } else if (switch_read(&s)) {
+            c = '*';
+
+            if (s & SWITCH_LEFT)
+                c = 'l';
+
+            if (s & SWITCH_RIGHT)
+                c = 'r';
+
+            if (s & SWITCH_HORN1)
+                c = 'h';
+
+            if (s & SWITCH_HORN2)
+                c = 'h';
 
         } else {
+            // XXX: for some reason this occasionally gets stuck in an interrupt loop here after some switch events..
             c = '?';
         }
 
-        switch (c) {
-            case '.':       break;
-
-            case 'L':       relay_open(RELAY_LEFT); break;
-            case 'R':       relay_open(RELAY_RIGHT); break;
-            case 'B':
-                            relay_open(RELAY_DOWN1);
-                            relay_open(RELAY_DOWN2);
-                            break;
-
-            case 'l':       relay_toggle(RELAY_LEFT); break;
-            case 'r':       relay_toggle(RELAY_RIGHT); break;
-            case 'b':
-                            relay_close(RELAY_DOWN1);
-                            relay_close(RELAY_DOWN2);
-                            break;
-
-            default:
-                c = '!';
-                break;
-        }
-
+        // out
         debug_toggle();
 
-        // out
         serial_write(c);
     }
 }