Pathompong Puengrostham / Mbed 2 deprecated mbedPirate

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
iamjay
Date:
Thu Dec 23 15:03:51 2010 +0000
Commit message:

Changed in this revision

SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
binwire.cpp Show annotated file Show diff for this revision Revisions of this file
binwire.h Show annotated file Show diff for this revision Revisions of this file
bitbang.cpp Show annotated file Show diff for this revision Revisions of this file
bitbang.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
util.cpp Show annotated file Show diff for this revision Revisions of this file
util.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,106 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+ 
+SerialBuffered::SerialBuffered( size_t bufferSize, PinName tx, PinName rx ) : Serial(  tx,  rx ) 
+{
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = 1.0;
+   
+    
+    attach( this, &SerialBuffered::handleInterrupt );
+    
+    m_buff = (uint8_t *) malloc( bufferSize );
+    if( m_buff == NULL )
+    {
+        //loggerSerial.printf("SerialBuffered - failed to alloc buffer size %d\r\n", (int) bufferSize );
+    }
+    else
+    {
+        m_buffSize = bufferSize;
+    }
+}
+
+
+SerialBuffered::~SerialBuffered()
+{
+    if( m_buff )
+        free( m_buff );
+}
+
+void SerialBuffered::setTimeout( float seconds )
+{
+    m_timeout = seconds;
+}
+    
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested )
+{
+    int i = 0;
+
+    for( ; i < requested; )
+    {
+        int c = getc();
+        if( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+    
+    return i;
+        
+}
+
+
+int SerialBuffered::getc()
+{
+    m_timer.reset();
+    m_timer.start();
+    while( m_contentStart == m_contentEnd )
+    {
+      
+
+        wait_ms( 1 );
+        if( m_timeout > 0 &&  m_timer.read() > m_timeout )
+            return EOF;
+    }
+
+    m_timer.stop();
+   
+    uint8_t result = m_buff[m_contentStart++];
+    m_contentStart =  m_contentStart % m_buffSize;
+
+   
+    return result;    
+}
+
+
+int SerialBuffered::readable()
+{
+    return m_contentStart != m_contentEnd ;
+}
+
+void SerialBuffered::handleInterrupt()
+{
+    
+    while( Serial::readable())
+    {
+        if( m_contentStart == (m_contentEnd +1) % m_buffSize)
+        {
+           //loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
+           Serial::getc();
+
+        }
+        else
+        {
+          
+            m_buff[ m_contentEnd ++ ] = Serial::getc();
+            m_contentEnd = m_contentEnd % m_buffSize;
+            
+           
+           
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,39 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you 
+// expect your program to receive in one go.
+
+class SerialBuffered : public Serial
+{
+public:
+    SerialBuffered( size_t bufferSize, PinName tx, PinName rx );
+    virtual ~SerialBuffered();
+    
+    int getc();     // will block till the next character turns up, or return -1 if there is a timeout
+    
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+    
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block 
+                                         // while waiting for a character
+                                         // Pass -1 to disable the timeout.
+    
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer, 
+                                                             // return number actually read, 
+                                                             // which may be less than requested if there has been a timeout
+    
+
+private:
+    
+    void handleInterrupt();
+    
+   
+    uint8_t *m_buff;            // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+    uint16_t  m_contentStart;   // index of first bytes of content
+    uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/binwire.cpp	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,366 @@
+#include "mbed.h"
+
+#include "binwire.h"
+
+#include "bitbang.h"
+#include "main.h"
+#include "util.h"
+
+enum {
+    PIC614 = 0,
+    PIC416,
+    PIC424
+};
+
+static void bin_io_peripheral_set(unsigned char c)
+{
+    if (c & 0x01) {
+        if (mode_config.HiZ == 0)
+            bp_cs.mode(PullNone);
+        else
+            bp_cs.mode(OpenDrain);
+    }
+    bp_cs.write(c & 0x01);
+    bp_cs.output();
+}
+
+static void PIC416_write(unsigned char cmd, unsigned char datl, unsigned char dath)
+{
+    unsigned char i, delay;
+
+    delay = cmd >> 6;
+    for (i = 0; i < 4; i++) {
+        if (i == 3 && delay > 0) {
+            bb_clk(1);
+            wait_ms(delay);
+            bb_clk(0);
+            continue;
+        }
+
+        if (cmd & 1)
+            bb_write_bit(1);
+        else
+            bb_write_bit(0);
+        cmd >>= 1;
+    }
+
+    bb_write_byte(datl);
+    bb_write_byte(dath);
+}
+
+static void PIC24_nop()
+{
+    bb_write_bit(0);
+    bb_write_bit(0);
+    bb_write_bit(0);
+    bb_write_bit(0);
+
+    bb_write_byte(0);
+    bb_write_byte(0);
+    bb_write_byte(0);
+}
+
+static void PIC424_write(unsigned long cmd, unsigned char pn)
+{
+    unsigned char i;
+
+    bb_write_bit(0);
+    bb_write_bit(0);
+    bb_write_bit(0);
+    bb_write_bit(0);
+
+    bb_write_byte(rev_byte(cmd));
+    bb_write_byte(rev_byte(cmd >> 8));
+    bb_write_byte(rev_byte(cmd >> 16));
+
+    pn &= 0x0F;
+    for (i = 0; i < pn; i++)
+        PIC24_nop();
+}
+
+static void PIC424_read()
+{
+    bb_write_bit(1);
+    bb_write_bit(0);
+    bb_write_bit(0);
+    bb_write_bit(0);
+
+    bb_write_byte(0);
+
+    bp.putc(bb_read_byte());
+    bp.putc(bb_read_byte());
+
+    PIC24_nop();
+    PIC24_nop();
+}
+
+void bin_wire_handler()
+{
+    unsigned char raw_cmd, wires, i;
+    unsigned char in_byte, pic_mode = PIC614;;
+    unsigned int cmds, j;
+    bool done = false;
+    int c = 0x01;
+
+    mode_config.HiZ = 1;
+    mode_config.lsbEN = 0;
+    mode_config.speed = 1;
+    mode_config.numbits = 8;
+
+    wires = 2;
+
+    bp_mosi.write(0);   bp_mosi.output();
+    bp_clk.write(0);    bp_clk.output();
+    bp_miso.input();
+    bb_cs(1);
+
+    bb_setup(2, 0xff);
+
+    while (1) {
+        raw_cmd = (c>>4);
+
+        switch (raw_cmd) {
+        case 0:
+            switch (c) {
+            case 0:
+                // Exit RAW wire mode
+                mode = BITBANG_MODE;
+                done = true;
+                break;
+            case 1:
+                bp.printf("RAW1");
+                break;
+            case 2:
+                bb_i2c_start();
+                bp.putc(1);
+                break;
+            case 3:
+                bb_i2c_stop();
+                bp.putc(1);
+                break;
+            case 4:
+                bb_cs(0);
+                bp.putc(1);
+                break;
+            case 5:
+                bb_cs(1);
+                bp.putc(1);
+                break;
+            case 6:
+                if (wires == 2)
+                    i = bb_read_byte();
+                else
+                    i = bb_read_write_byte(0xff);
+                if (mode_config.lsbEN == 1)
+                    i = rev_byte(i);
+                bp.putc(i);
+                break;
+            case 7:
+                bp.putc(bb_read_bit());
+                break;
+            case 8:
+                bp.putc(bb_miso());
+                break;
+            case 9:
+                bb_clock_ticks(1);
+                bp.putc(1);
+                break;
+            case 10:
+                bb_clk(0);
+                bp.putc(1);
+                break;
+            case 11:
+                bb_clk(1);
+                bp.putc(1);
+                break;
+            case 12:
+                bb_mosi(0);
+                bp.putc(1);
+                break;
+            case 13:
+                bb_mosi(1);
+                bp.putc(1);
+                break;
+            default:
+                bp.putc(0);
+                break;
+            }
+            break;
+
+        case 0x01:
+            in_byte = c & 0x0F;
+            in_byte++;
+            bp.putc(1);
+
+            for (i = 0; i < in_byte; i++) {
+                c = bp.getc();
+                if (mode_config.lsbEN == 1)
+                    c = rev_byte(c);
+                if (wires == 2) {
+                    bb_write_byte(c);
+                    bp.putc(1);
+                } else {
+                    c = bb_read_write_byte(c);
+                    if (mode_config.lsbEN == 1)
+                        c = rev_byte(c);
+                    bp.putc(c);
+                }
+            }
+            break;
+
+        case 0x02:
+            in_byte = c & 0x0F;
+            in_byte++;
+            bb_clock_ticks(in_byte);
+            bp.putc(1);
+            break;
+
+        case 0x03:
+            in_byte = c & 0x0F;
+            in_byte++;
+            bp.putc(1);
+            raw_cmd = bp.getc();
+            for (i = 0; i < in_byte; i++) {
+                if (raw_cmd & 0x80)
+                    bb_write_bit(1);
+                else
+                    bb_write_bit(0);
+                raw_cmd = raw_cmd << 1;
+            }
+            bp.putc(1);
+            break;
+
+        case 0x0A:
+            switch (c) {
+            case 0xA0:
+                pic_mode = bp.getc();
+                bp.putc(1);
+                break;
+
+            case 0xA4:
+                switch (pic_mode) {
+                case PIC416:
+                    cmds = bp.getc();
+                    cmds *= 3;
+                    for (j = 0; j < cmds; j++)
+                        bp_config.terminal_input[j] = bp.getc();
+
+                    for (j = 0; j < cmds; j += 3)
+                        PIC416_write(bp_config.terminal_input[j],
+                                bp_config.terminal_input[j + 1],
+                                bp_config.terminal_input[j + 2]);
+                    bp.putc(1);
+                    break;
+                case PIC424:
+                    cmds = bp.getc();
+                    cmds *= 4;
+                    for (j = 0; j < cmds; j++) {
+                        bp_config.terminal_input[j] = bp.getc();
+                    }
+                    for (j = 0; j < cmds; j += 4) {
+                        bb_write_bit(0);
+                        bb_write_bit(0);
+                        bb_write_bit(0);
+                        bb_write_bit(0);
+
+                        bb_write_byte(bp_config.terminal_input[j]);
+                        bb_write_byte(bp_config.terminal_input[j + 1]);
+                        bb_write_byte(bp_config.terminal_input[j + 2]);
+
+                        bp_config.terminal_input[j + 3] &= 0x0F;
+                        for (i = 0; i < bp_config.terminal_input[j + 3]; i++)
+                            PIC24_nop();
+                    }
+                    bp.putc(1);
+                    break;
+                default:
+                    bp.putc(0);
+                    break;
+                }
+                break;
+
+            case 0xA5:
+                switch (pic_mode) {
+                case PIC416:
+                    cmds = bp.getc();
+                    raw_cmd = bp.getc();
+                    for ( j = 0; j < cmds; j++) {
+                        c = raw_cmd;
+                        for (i = 0; i < 4; i++) {
+                            if (c & 1)
+                                bb_write_bit(1);
+                            else
+                                bb_write_bit(0);
+                            c >>= 1;
+                        }
+                        bb_read_byte();
+                        bp.putc(bb_read_byte());
+                    }
+                    break;
+                case PIC424:
+                    cmds = bp.getc();
+                    for (j = 0; j < cmds; j++) {
+                        PIC424_write(0xBA0B96, 2);
+                        PIC424_read();
+                        PIC424_write(0xBADBB6, 2);
+                        PIC424_write(0xBAD3D6, 2);
+                        PIC424_read();
+                        PIC424_write(0xBA0BB6, 2);
+                        PIC424_read();
+                    }
+                    break;
+                default:
+                    break;
+                }
+                break;
+
+            default:
+                bp.putc(0);
+                break;
+            }
+            break;
+
+        case 0x04:
+            bin_io_peripheral_set(c);
+            bp.putc(1);
+            break;
+
+        case 0x06:
+            c &= 0x03;
+            mode_config.speed = c;
+            bb_setup(wires, mode_config.speed);
+            bb_cs(1);
+            bp.putc(1);
+            break;
+
+        case 0x08:
+            if (c & 0x08)
+                mode_config.HiZ = 0;
+            else
+                mode_config.HiZ = 1;
+
+            if (c & 0x04)
+                wires = 3;
+            else
+                wires = 2;
+
+            if (c & 0x02)
+                mode_config.lsbEN = 1;
+            else
+                mode_config.lsbEN = 0;
+
+            bb_setup(wires, mode_config.speed);
+            bb_cs(1);
+            bp.putc(1);
+            break;
+
+        default:
+            bp.putc(0);
+            break;
+        }
+
+        if (done)
+            break;
+        c = bp.getc();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/binwire.h	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,6 @@
+#ifndef BINWIRE_H
+#define BINWIRE_H
+
+void bin_wire_handler();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bitbang.cpp	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,238 @@
+#include "mbed.h"
+
+#include "bitbang.h"
+
+#include "main.h"
+
+#define	BB_5KHZSPEED_SETTLE         20 //~5KHz
+#define	BB_5KHZSPEED_CLOCK          100
+#define	BB_5KHZSPEED_HALFCLOCK      BB_5KHZSPEED_CLOCK/2
+
+#define	BB_50KHZSPEED_SETTLE        2 //~50KHz
+#define	BB_50KHZSPEED_CLOCK         10
+#define	BB_50KHZSPEED_HALFCLOCK     BB_50KHZSPEED_CLOCK/2
+
+#define	BB_100KHZSPEED_SETTLE       1 //~100KHz
+#define	BB_100KHZSPEED_CLOCK        5
+#define	BB_100KHZSPEED_HALFCLOCK    2
+
+#define	BB_MAXSPEED_SETTLE          0 //~400KHz
+#define	BB_MAXSPEED_CLOCK           0
+#define	BB_MAXSPEED_HALFCLOCK       0
+
+struct {
+    int pins;
+    DigitalInOut *mo;
+    DigitalInOut *mi;
+    int delay_settle;
+    int delay_clock;
+    int delay_half_clock;
+} bitbang;
+
+void bb_setup(int pins, int speed)
+{
+    bitbang.pins = pins;
+
+    if (pins == 3) {
+        bitbang.mo = &bp_mosi;
+        bitbang.mi = &bp_miso;
+    } else {
+        bitbang.mo = &bp_mosi;
+        bitbang.mi = &bp_mosi;
+    }
+
+    switch (speed) {
+    case 0:
+        bitbang.delay_settle = BB_5KHZSPEED_SETTLE;
+        bitbang.delay_clock = BB_5KHZSPEED_CLOCK;
+        bitbang.delay_half_clock = BB_5KHZSPEED_HALFCLOCK;
+        break;
+    case 1:
+        bitbang.delay_settle = BB_50KHZSPEED_SETTLE;
+        bitbang.delay_clock = BB_50KHZSPEED_CLOCK;
+        bitbang.delay_half_clock = BB_50KHZSPEED_HALFCLOCK;
+        break;
+    case 2:
+        bitbang.delay_settle = BB_100KHZSPEED_SETTLE;
+        bitbang.delay_clock = BB_100KHZSPEED_CLOCK;
+        bitbang.delay_half_clock = BB_100KHZSPEED_HALFCLOCK;
+        break;
+    default:
+        bitbang.delay_settle = BB_MAXSPEED_SETTLE;
+        bitbang.delay_clock = BB_MAXSPEED_CLOCK;
+        bitbang.delay_half_clock = BB_MAXSPEED_HALFCLOCK;
+        break;
+    }
+}
+
+void bb_h(DigitalInOut *pin, int delay)
+{
+    if (mode_config.HiZ == 0)
+        pin->mode(PullNone);
+    else
+        pin->mode(OpenDrain);
+    pin->write(1);
+    pin->output();
+    wait_us(delay);
+}
+
+void bb_l(DigitalInOut *pin, int delay)
+{
+    pin->write(0);
+    pin->output();
+    wait_us(delay);
+}
+
+void bb_pin(DigitalInOut *pin, int dir, int delay)
+{
+    pin->write(dir);
+    if (dir) {
+        if (mode_config.HiZ == 0)
+            pin->mode(PullNone);
+        else
+            pin->mode(OpenDrain);
+    }
+    pin->output();
+    wait_us(delay);
+}
+
+unsigned char bb_r(DigitalInOut *pin)
+{
+    pin->input();
+    return pin->read();
+}
+
+void bb_cs(int dir)
+{
+    bb_pin(&bp_cs, dir, bitbang.delay_settle);
+}
+
+int bb_i2c_start()
+{
+    int error = 0;
+
+    bb_h(&bp_mosi, bitbang.delay_clock);
+    bb_h(&bp_clk, bitbang.delay_clock);
+
+    if (bp_clk.read() == 0 || bp_mosi.read() == 0)
+        error = 1;
+
+    bb_l(&bp_mosi, bitbang.delay_clock);
+
+    bb_l(&bp_clk, bitbang.delay_clock);
+
+    bb_h(&bp_mosi, bitbang.delay_clock);
+
+    return error;
+}
+
+int bb_i2c_stop()
+{
+    bb_l(&bp_mosi, bitbang.delay_clock);
+    bb_l(&bp_clk, bitbang.delay_clock);
+
+    bb_h(&bp_clk, bitbang.delay_clock);
+
+    bb_h(&bp_mosi, bitbang.delay_clock);
+
+    return 0;
+}
+
+unsigned int bb_read_write_byte(unsigned int c)
+{
+    unsigned int i, bt, tem, di, dat = 0;
+
+    bt = 1 << (mode_config.numbits - 1);
+
+    tem = c;
+    for (i = 0; i < mode_config.numbits; i++) {
+        bb_pin(&bp_mosi, (tem & bt), bitbang.delay_settle);
+        bb_h(&bp_clk, bitbang.delay_clock);
+        di = bb_r(&bp_miso);
+        bb_l(&bp_clk, bitbang.delay_clock);
+
+        tem = tem << 1;
+        dat = dat << 1;
+        if (di)
+            dat++;
+    }
+    return dat;
+}
+
+void bb_write_byte(unsigned int c)
+{
+    unsigned int i, bt, tem;
+
+    bt = 1 << (mode_config.numbits - 1);
+
+    tem = c;
+    for (i = 0; i < mode_config.numbits; i++) {
+        bb_pin(&bp_mosi, tem & bt, bitbang.delay_settle);
+        bb_h(&bp_clk, bitbang.delay_clock);
+        bb_l(&bp_clk, bitbang.delay_clock);
+
+        tem = tem << 1;
+    }
+}
+unsigned int bb_read_byte()
+{
+    int i, di, dat = 0;
+
+    bb_r(&bp_mosi);
+
+    for (i = 0; i < mode_config.numbits; i++) {
+        bb_h(&bp_clk, bitbang.delay_clock);
+        di = bb_r(&bp_mosi);
+        bb_l(&bp_clk, bitbang.delay_clock);
+
+        dat = dat << 1;
+        if (di)
+            dat++;
+    }
+
+    return dat;
+}
+
+unsigned char bb_read_bit()
+{
+    unsigned char c;
+
+    bb_r(bitbang.mi);
+    bb_h(&bp_clk, bitbang.delay_clock);
+    c = bb_r(bitbang.mi);
+    bb_l(&bp_clk, bitbang.delay_clock);
+
+    return c;
+}
+
+void bb_write_bit(unsigned char c)
+{
+    bb_pin(bitbang.mo, c, bitbang.delay_settle);
+    bb_h(&bp_clk, bitbang.delay_clock);
+    bb_l(&bp_clk, bitbang.delay_clock);
+}
+
+void bb_clock_ticks(unsigned char c)
+{
+    unsigned char i;
+
+    for (i = 0; i < c; i++) {
+        bb_h(&bp_clk, bitbang.delay_clock);
+        bb_l(&bp_clk, bitbang.delay_clock);
+    }
+}
+
+void bb_mosi(unsigned char dir)
+{
+    bb_pin(bitbang.mo, dir, bitbang.delay_settle);
+}
+
+void bb_clk(unsigned char dir)
+{
+    bb_pin(&bp_clk, dir, bitbang.delay_settle);
+}
+
+unsigned char bb_miso()
+{
+    return bb_r(bitbang.mi);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bitbang.h	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,20 @@
+#ifndef BITBANG_H
+#define BITBANG_H
+
+void bb_setup(int pins, int speed);
+void bb_h(DigitalInOut *pin, int delay);
+void bb_pin(DigitalInOut *pin, int dir, int delay);
+void bb_cs(int dir);
+int bb_i2c_start();
+int bb_i2c_stop();
+unsigned int bb_read_write_byte(unsigned int c);
+void bb_write_byte(unsigned int c);
+unsigned int bb_read_byte();
+unsigned char bb_read_bit(void);
+void bb_write_bit(unsigned char c);
+void bb_clock_ticks(unsigned char c);
+void bb_mosi(unsigned char dir);
+void bb_clk(unsigned char dir);
+unsigned char bb_miso();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,103 @@
+#include "mbed.h"
+
+#include "main.h"
+
+#include <stdint.h>
+
+#include "binwire.h"
+#include "bitbang.h"
+#include "util.h"
+
+Serial debug(USBTX, USBRX);
+SerialBuffered bp(4096, p13, p14);
+
+struct _bp_config bp_config;
+struct _mode_config mode_config;
+
+DigitalInOut bp_mosi(p5);
+DigitalInOut bp_miso(p6);
+DigitalInOut bp_clk(p7);
+DigitalInOut bp_cs(p8);
+DigitalInOut bp_aux(p9);
+DigitalInOut bp_adc(p15);
+
+unsigned char mode = BUSPIRATE_MODE;
+
+static void buspirate_handler()
+{
+    bool done = false;
+    int c;
+    int count = 0;
+
+    while (!done) {
+        c = bp.getc();
+        if (c == 0x00) {
+            if (++count >= 20) {
+                // Enter bitbang mode
+                mode = BITBANG_MODE;
+                done = true;
+            }
+        } else {
+            debug.printf("unsupported command: %x\n", c);
+            count = 0;
+        }
+    }
+}
+
+static void bitbang_handler()
+{
+    bool done = false;
+    int c = 0x00;
+
+    while (1) {
+        switch (c) {
+        case 0x00:
+            bp.printf("BBIO1");
+            break;
+        case 0x0F:
+            // Exit bitbang mode
+            mode = BUSPIRATE_MODE;
+            done = true;
+            break;
+        case 0x05:
+            // Enter RAW wire mode
+            mode = RAW_WIRE_MODE;
+            done = true;
+            break;
+        default:
+            debug.printf("unsupported bitbang command: %x\n", c);
+            break;
+        }
+        if (done)
+            break;
+        c = bp.getc();
+    }
+}
+
+int main()
+{
+    debug.baud(115200);
+    bp.baud(9600);
+
+    debug.printf("mbedPirate started\n");
+
+    while (1) {
+        switch (mode) {
+        case BUSPIRATE_MODE:
+            debug.printf("enter buspirate mode\n");
+            buspirate_handler();
+            break;
+        case BITBANG_MODE:
+            debug.printf("enter bitbang mode\n");
+            bitbang_handler();
+            break;
+        case RAW_WIRE_MODE:
+            debug.printf("enter rawwire mode\n");
+            bin_wire_handler();
+            break;
+        default:
+            debug.printf("unsupported mode: %d\n", mode);
+            break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.h	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,42 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#include "SerialBuffered.h"
+
+enum {
+    BUSPIRATE_MODE = 0,
+    BITBANG_MODE,
+    RAW_WIRE_MODE,
+};
+
+struct _bp_config {
+    unsigned char terminal_input[4096];
+};
+
+struct _mode_config {
+    unsigned char speed; 
+    unsigned char numbits;
+    unsigned char buf[16];
+    unsigned char altAUX:1;
+    unsigned char periodicService:1;
+    unsigned char lsbEN:1;
+    unsigned char HiZ:1;
+    unsigned char int16:1;
+};
+
+extern Serial debug;
+extern SerialBuffered bp;
+
+extern struct _bp_config bp_config;
+extern struct _mode_config mode_config;
+
+extern DigitalInOut bp_mosi;
+extern DigitalInOut bp_miso;
+extern DigitalInOut bp_clk;
+extern DigitalInOut bp_cs;
+extern DigitalInOut bp_aux;
+extern DigitalInOut bp_adc;
+
+extern unsigned char mode;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e2ac27c8e93e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util.cpp	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,21 @@
+#include "mbed.h"
+
+#include "util.h"
+
+#include "main.h"
+
+unsigned char rev_byte(unsigned char c)
+{
+    unsigned char r = 0, i;
+
+    for (i = 1; i != 0; i = i<<1) {
+        r = r << 1;	
+        if (c & i)
+            r |= 1;
+    }
+
+    if (mode_config.numbits != 8)
+        r >>= (8 - mode_config.numbits);
+
+    return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util.h	Thu Dec 23 15:03:51 2010 +0000
@@ -0,0 +1,6 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+unsigned char rev_byte(unsigned char c);
+
+#endif