HW2 implemented using protothread
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Mon Jul 18 2022 01:33:11 by
1.7.2