Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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);
}