Pathompong Puengrostham / Mbed 2 deprecated mbedPirate

Dependencies:   mbed

binwire.cpp

Committer:
iamjay
Date:
2010-12-23
Revision:
0:e0a44db7e925

File content as of revision 0:e0a44db7e925:

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