--- /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;
+}