Tianji Wu
/
hw2_intr
HW2 implemented by interrupts
Diff: main.cpp
- 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); + } + } +}