HW2 implemented using protothread

Dependencies:   mbed

main.cpp

Committer:
the729
Date:
2010-12-01
Revision:
0:e2cc8ae74a24

File content as of revision 0:e2cc8ae74a24:

#include "mbed.h"
#include "pt.h"

Serial pc(USBTX, USBRX);

#define BTN0 p15
#define BTN1 p20
#define MAX_LENGTH 32

typedef unsigned int uint32_t;
typedef unsigned char uint8_t;

uint8_t key;
static struct pt pt_prot, pt_key;

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);
}

static PT_THREAD(protocol(struct pt *pt)) 
{
    static uint32_t data = 0;
    static uint8_t datalength = 0;
    PT_BEGIN(pt);

    datalength = 0;
    while (1) {
        PT_WAIT_UNTIL(pt, pc.readable());
        uint8_t c = pc.getc();
        pc.putc(c);
        if (c=='S') break;
        block_output("HOST ERROR. You are supposed to input S. Try again. \r\n");
    }
    while (1) {
        PT_WAIT_UNTIL(pt, pc.readable());
        uint8_t c = pc.getc();
        pc.putc(c);
        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");
            data <<= (32-datalength);
            break;
        } else {
            block_output("\r\nHOST ERROR. Continue input.\r\n");
        }
    }
    key = 0;
    while (datalength > 0) {
        PT_WAIT_UNTIL(pt, key>0);
        if (key >= 3) block_output("TOUCH ERROR\n");
        uint8_t c = key - 1;
        key = 0;
        pc.putc(c + '0');
        if (c == (data >> 31)) {
            datalength--;
            data <<= 1;
        } else {
            block_output("\r\nTOUCH ERROR. Continue touching.\r\n");
        }
    }
    pc.printf("\r\nMATCH! \r\n");
    PT_END(pt);
}

static PT_THREAD(getkey(struct pt *pt)) 
{
    static uint8_t c;
    PT_BEGIN(pt);

    while (1) {
        PT_WAIT_UNTIL(pt, c = read_cap());
        wait_ms(10);
        if (c == read_cap()) {
            PT_WAIT_WHILE(pt, read_cap());
            key = c;
            PT_WAIT_WHILE(pt, key);
        }
    }
    PT_END(pt);
}

int main() 
{
    key = 0;
    PT_INIT(&pt_prot);
    PT_INIT(&pt_key);
    while (1) {
        PT_SCHEDULE(protocol(&pt_prot));
        PT_SCHEDULE(getkey(&pt_key));
    }
}