switch
authorTero Marttila <terom@paivola.fi>
Thu, 25 Sep 2014 00:55:47 +0300
changeset 8 61eba9d55764
parent 7 5c37ed521807
child 9 49643ef9d3d2
switch
include/switch.h
src/switch.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/switch.h	Thu Sep 25 00:55:47 2014 +0300
@@ -0,0 +1,45 @@
+#ifndef QMSK_SWITCH_H
+#define QMSK_SWITCH_H
+
+#include "stdlib.h"
+
+extern byte switch_mask;
+
+/*
+ * Setup switch input triggering on SWITCH_DDR/PORT/PIN using SWITCH_PCMSK/PCIE/PCIF interrupts.
+ */
+void switch_init (void)
+{
+    switch_mask = SWITCH_MASK;
+
+    // input mode
+    byte bit = 1;
+
+    for (byte i = 0; i < 8; i++) {
+        if (SWITCH_MASK & bit) {
+            cbi(SWITCH_DDR, i);
+
+            // pull-up
+            sbi(SWITCH_PORT, i);
+        }
+
+        bit <<= 1;
+    }
+
+    // interrupt mask for port
+    *SWITCH_PCMSK = SWITCH_MASK;
+
+    // enable interrupts
+    sbi(&PCICR, SWITCH_PCIE);
+}
+
+/*
+ * Update switch state if changed.
+ *
+ * Returns 1 if changed, 0 if no changes.
+ *
+ * TODO: debouncing
+ */
+byte switch_read (byte *sp);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/switch.c	Thu Sep 25 00:55:47 2014 +0300
@@ -0,0 +1,39 @@
+#include "stdlib.h"
+//#include "switch.h"
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+byte switch_mask;
+byte switch_status;
+byte switch_state;
+
+ISR(PCINT0_vect)
+{
+    switch_status = 1;
+    switch_state = PINB;
+}
+
+ISR(PCINT1_vect)
+{
+    switch_status = 1;
+    switch_state = PINC;
+}
+
+ISR(PCINT2_vect)
+{
+    switch_status = 1;
+    switch_state = PIND;
+}
+
+byte switch_read (byte *sp)
+{
+    if (!switch_status)
+        return 0;
+
+    switch_status = 0;
+
+    *sp = ~switch_state & switch_mask;
+
+    return 1;
+}