HW2 implemented using protothread

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

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