HW2 implemented by interrupts

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 //DigitalOut led1(LED1);
00004 //DigitalOut led2(LED2);
00005 
00006 Serial pc(USBTX, USBRX);
00007 
00008 #define BTN0 p15
00009 #define BTN1 p20
00010 #define MAX_LENGTH 32
00011 
00012 typedef unsigned int uint32_t;
00013 typedef unsigned char uint8_t;
00014 
00015 enum {
00016     IDLE=0, 
00017     HOST_INPUT,
00018     USER_INPUT
00019 } state;
00020 uint32_t data = 0;
00021 uint8_t datalength = 0;
00022 
00023 void precharge(PinName p) 
00024 {
00025     DigitalIn prec(p);
00026     prec.mode(PullUp);
00027     prec.mode(PullNone);
00028 }
00029 
00030 uint8_t read_cap() 
00031 {
00032     precharge(BTN0);
00033     precharge(BTN1);
00034     wait_ms(5);
00035     float s0 = AnalogIn(BTN0);
00036     float s1 = AnalogIn(BTN1);
00037     return ((s0>0.5)?0:1) + ((s1>0.5)?0:2);
00038 }
00039 
00040 void block_output(const char * str)
00041 {
00042     pc.printf("%s", str);
00043 }
00044 
00045 void uart_event()
00046 {
00047     uint8_t c;
00048     if (state == IDLE) {
00049         pc.putc(c = pc.getc());
00050         if (c == 'S') {
00051             datalength = 0;
00052             state = HOST_INPUT;
00053         } else {
00054             block_output("HOST ERROR. You are supposed to input S. Try again. \r\n");
00055         }
00056     }else if (state == HOST_INPUT) {
00057         pc.putc(c = pc.getc());
00058         if (c == '0' || c == '1') {
00059             datalength ++;
00060             if (datalength > MAX_LENGTH) {
00061                 block_output("\r\nLength execeeds maximum. \r\n");
00062             } else {
00063                 data = (data << 1) | (c-'0');
00064             }
00065         } else if (c == 'E') {
00066             block_output("\r\nInput End. Tap the caps now. \r\n");
00067             if (!datalength) {
00068                 block_output("Zero length. Try again. \r\n");
00069                 state = IDLE;
00070             } else {
00071                 data <<= (32-datalength);
00072                 state = USER_INPUT;
00073             }
00074         } else {
00075             block_output("\r\nHOST ERROR. Continue input.\r\n");
00076         }
00077     }
00078 }
00079 
00080 void key_event(uint8_t c)
00081 {
00082     if (state != USER_INPUT) return;
00083     if (c >= 3) block_output("TOUCH ERROR\n");
00084     c -= 1;
00085     pc.putc(c + '0');
00086     if (c == (data >> 31)) {
00087         datalength--;
00088         if (!datalength) {
00089             pc.printf("\r\nMATCH! \r\n");
00090             state = IDLE;
00091         }
00092         data <<= 1;
00093     } else {
00094         block_output("\r\nTOUCH ERROR. Continue touching.\r\n");
00095     }
00096 }
00097 
00098 int main() {
00099     uint8_t c;
00100     state = IDLE;
00101     pc.attach(&uart_event, Serial::RxIrq);
00102     while(1) {
00103         c = read_cap();
00104         if (!c) continue;
00105         wait_ms(10);
00106         if (c == read_cap()) {
00107             while(read_cap());
00108             key_event(c);
00109         }
00110     }
00111 }