HW2 implemented by interrupts

Dependencies:   mbed

Revision:
0:64a910e4a0d5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Dec 01 02:48:22 2010 +0000
@@ -0,0 +1,111 @@
+#include "mbed.h"
+
+//DigitalOut led1(LED1);
+//DigitalOut led2(LED2);
+
+Serial pc(USBTX, USBRX);
+
+#define BTN0 p15
+#define BTN1 p20
+#define MAX_LENGTH 32
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+enum {
+    IDLE=0, 
+    HOST_INPUT,
+    USER_INPUT
+} state;
+uint32_t data = 0;
+uint8_t datalength = 0;
+
+void precharge(PinName p) 
+{
+    DigitalIn prec(p);
+    prec.mode(PullUp);
+    prec.mode(PullNone);
+}
+
+uint8_t read_cap() 
+{
+    precharge(BTN0);
+    precharge(BTN1);
+    wait_ms(5);
+    float s0 = AnalogIn(BTN0);
+    float s1 = AnalogIn(BTN1);
+    return ((s0>0.5)?0:1) + ((s1>0.5)?0:2);
+}
+
+void block_output(const char * str)
+{
+    pc.printf("%s", str);
+}
+
+void uart_event()
+{
+    uint8_t c;
+    if (state == IDLE) {
+        pc.putc(c = pc.getc());
+        if (c == 'S') {
+            datalength = 0;
+            state = HOST_INPUT;
+        } else {
+            block_output("HOST ERROR. You are supposed to input S. Try again. \r\n");
+        }
+    }else if (state == HOST_INPUT) {
+        pc.putc(c = pc.getc());
+        if (c == '0' || c == '1') {
+            datalength ++;
+            if (datalength > MAX_LENGTH) {
+                block_output("\r\nLength execeeds maximum. \r\n");
+            } else {
+                data = (data << 1) | (c-'0');
+            }
+        } else if (c == 'E') {
+            block_output("\r\nInput End. Tap the caps now. \r\n");
+            if (!datalength) {
+                block_output("Zero length. Try again. \r\n");
+                state = IDLE;
+            } else {
+                data <<= (32-datalength);
+                state = USER_INPUT;
+            }
+        } else {
+            block_output("\r\nHOST ERROR. Continue input.\r\n");
+        }
+    }
+}
+
+void key_event(uint8_t c)
+{
+    if (state != USER_INPUT) return;
+    if (c >= 3) block_output("TOUCH ERROR\n");
+    c -= 1;
+    pc.putc(c + '0');
+    if (c == (data >> 31)) {
+        datalength--;
+        if (!datalength) {
+            pc.printf("\r\nMATCH! \r\n");
+            state = IDLE;
+        }
+        data <<= 1;
+    } else {
+        block_output("\r\nTOUCH ERROR. Continue touching.\r\n");
+    }
+}
+
+int main() {
+    uint8_t c;
+    state = IDLE;
+    pc.attach(&uart_event, Serial::RxIrq);
+    while(1) {
+        c = read_cap();
+        if (!c) continue;
+        wait_ms(10);
+        if (c == read_cap()) {
+            while(read_cap());
+            key_event(c);
+        }
+    }
+}