HW2 implemented by interrupts

Dependencies:   mbed

main.cpp

Committer:
the729
Date:
2010-12-01
Revision:
0:64a910e4a0d5

File content as of revision 0:64a910e4a0d5:

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