Pathompong Puengrostham / Mbed 2 deprecated mbedPirate

Dependencies:   mbed

bitbang.cpp

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

File content as of revision 0:e0a44db7e925:

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