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@0:e0a44db7e925, 2010-12-23 (annotated)
- Committer:
- iamjay
- Date:
- Thu Dec 23 15:03:51 2010 +0000
- Revision:
- 0:e0a44db7e925
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| iamjay | 0:e0a44db7e925 | 1 | #include "mbed.h" | 
| iamjay | 0:e0a44db7e925 | 2 | |
| iamjay | 0:e0a44db7e925 | 3 | #include "bitbang.h" | 
| iamjay | 0:e0a44db7e925 | 4 | |
| iamjay | 0:e0a44db7e925 | 5 | #include "main.h" | 
| iamjay | 0:e0a44db7e925 | 6 | |
| iamjay | 0:e0a44db7e925 | 7 | #define BB_5KHZSPEED_SETTLE 20 //~5KHz | 
| iamjay | 0:e0a44db7e925 | 8 | #define BB_5KHZSPEED_CLOCK 100 | 
| iamjay | 0:e0a44db7e925 | 9 | #define BB_5KHZSPEED_HALFCLOCK BB_5KHZSPEED_CLOCK/2 | 
| iamjay | 0:e0a44db7e925 | 10 | |
| iamjay | 0:e0a44db7e925 | 11 | #define BB_50KHZSPEED_SETTLE 2 //~50KHz | 
| iamjay | 0:e0a44db7e925 | 12 | #define BB_50KHZSPEED_CLOCK 10 | 
| iamjay | 0:e0a44db7e925 | 13 | #define BB_50KHZSPEED_HALFCLOCK BB_50KHZSPEED_CLOCK/2 | 
| iamjay | 0:e0a44db7e925 | 14 | |
| iamjay | 0:e0a44db7e925 | 15 | #define BB_100KHZSPEED_SETTLE 1 //~100KHz | 
| iamjay | 0:e0a44db7e925 | 16 | #define BB_100KHZSPEED_CLOCK 5 | 
| iamjay | 0:e0a44db7e925 | 17 | #define BB_100KHZSPEED_HALFCLOCK 2 | 
| iamjay | 0:e0a44db7e925 | 18 | |
| iamjay | 0:e0a44db7e925 | 19 | #define BB_MAXSPEED_SETTLE 0 //~400KHz | 
| iamjay | 0:e0a44db7e925 | 20 | #define BB_MAXSPEED_CLOCK 0 | 
| iamjay | 0:e0a44db7e925 | 21 | #define BB_MAXSPEED_HALFCLOCK 0 | 
| iamjay | 0:e0a44db7e925 | 22 | |
| iamjay | 0:e0a44db7e925 | 23 | struct { | 
| iamjay | 0:e0a44db7e925 | 24 | int pins; | 
| iamjay | 0:e0a44db7e925 | 25 | DigitalInOut *mo; | 
| iamjay | 0:e0a44db7e925 | 26 | DigitalInOut *mi; | 
| iamjay | 0:e0a44db7e925 | 27 | int delay_settle; | 
| iamjay | 0:e0a44db7e925 | 28 | int delay_clock; | 
| iamjay | 0:e0a44db7e925 | 29 | int delay_half_clock; | 
| iamjay | 0:e0a44db7e925 | 30 | } bitbang; | 
| iamjay | 0:e0a44db7e925 | 31 | |
| iamjay | 0:e0a44db7e925 | 32 | void bb_setup(int pins, int speed) | 
| iamjay | 0:e0a44db7e925 | 33 | { | 
| iamjay | 0:e0a44db7e925 | 34 | bitbang.pins = pins; | 
| iamjay | 0:e0a44db7e925 | 35 | |
| iamjay | 0:e0a44db7e925 | 36 | if (pins == 3) { | 
| iamjay | 0:e0a44db7e925 | 37 | bitbang.mo = &bp_mosi; | 
| iamjay | 0:e0a44db7e925 | 38 | bitbang.mi = &bp_miso; | 
| iamjay | 0:e0a44db7e925 | 39 | } else { | 
| iamjay | 0:e0a44db7e925 | 40 | bitbang.mo = &bp_mosi; | 
| iamjay | 0:e0a44db7e925 | 41 | bitbang.mi = &bp_mosi; | 
| iamjay | 0:e0a44db7e925 | 42 | } | 
| iamjay | 0:e0a44db7e925 | 43 | |
| iamjay | 0:e0a44db7e925 | 44 | switch (speed) { | 
| iamjay | 0:e0a44db7e925 | 45 | case 0: | 
| iamjay | 0:e0a44db7e925 | 46 | bitbang.delay_settle = BB_5KHZSPEED_SETTLE; | 
| iamjay | 0:e0a44db7e925 | 47 | bitbang.delay_clock = BB_5KHZSPEED_CLOCK; | 
| iamjay | 0:e0a44db7e925 | 48 | bitbang.delay_half_clock = BB_5KHZSPEED_HALFCLOCK; | 
| iamjay | 0:e0a44db7e925 | 49 | break; | 
| iamjay | 0:e0a44db7e925 | 50 | case 1: | 
| iamjay | 0:e0a44db7e925 | 51 | bitbang.delay_settle = BB_50KHZSPEED_SETTLE; | 
| iamjay | 0:e0a44db7e925 | 52 | bitbang.delay_clock = BB_50KHZSPEED_CLOCK; | 
| iamjay | 0:e0a44db7e925 | 53 | bitbang.delay_half_clock = BB_50KHZSPEED_HALFCLOCK; | 
| iamjay | 0:e0a44db7e925 | 54 | break; | 
| iamjay | 0:e0a44db7e925 | 55 | case 2: | 
| iamjay | 0:e0a44db7e925 | 56 | bitbang.delay_settle = BB_100KHZSPEED_SETTLE; | 
| iamjay | 0:e0a44db7e925 | 57 | bitbang.delay_clock = BB_100KHZSPEED_CLOCK; | 
| iamjay | 0:e0a44db7e925 | 58 | bitbang.delay_half_clock = BB_100KHZSPEED_HALFCLOCK; | 
| iamjay | 0:e0a44db7e925 | 59 | break; | 
| iamjay | 0:e0a44db7e925 | 60 | default: | 
| iamjay | 0:e0a44db7e925 | 61 | bitbang.delay_settle = BB_MAXSPEED_SETTLE; | 
| iamjay | 0:e0a44db7e925 | 62 | bitbang.delay_clock = BB_MAXSPEED_CLOCK; | 
| iamjay | 0:e0a44db7e925 | 63 | bitbang.delay_half_clock = BB_MAXSPEED_HALFCLOCK; | 
| iamjay | 0:e0a44db7e925 | 64 | break; | 
| iamjay | 0:e0a44db7e925 | 65 | } | 
| iamjay | 0:e0a44db7e925 | 66 | } | 
| iamjay | 0:e0a44db7e925 | 67 | |
| iamjay | 0:e0a44db7e925 | 68 | void bb_h(DigitalInOut *pin, int delay) | 
| iamjay | 0:e0a44db7e925 | 69 | { | 
| iamjay | 0:e0a44db7e925 | 70 | if (mode_config.HiZ == 0) | 
| iamjay | 0:e0a44db7e925 | 71 | pin->mode(PullNone); | 
| iamjay | 0:e0a44db7e925 | 72 | else | 
| iamjay | 0:e0a44db7e925 | 73 | pin->mode(OpenDrain); | 
| iamjay | 0:e0a44db7e925 | 74 | pin->write(1); | 
| iamjay | 0:e0a44db7e925 | 75 | pin->output(); | 
| iamjay | 0:e0a44db7e925 | 76 | wait_us(delay); | 
| iamjay | 0:e0a44db7e925 | 77 | } | 
| iamjay | 0:e0a44db7e925 | 78 | |
| iamjay | 0:e0a44db7e925 | 79 | void bb_l(DigitalInOut *pin, int delay) | 
| iamjay | 0:e0a44db7e925 | 80 | { | 
| iamjay | 0:e0a44db7e925 | 81 | pin->write(0); | 
| iamjay | 0:e0a44db7e925 | 82 | pin->output(); | 
| iamjay | 0:e0a44db7e925 | 83 | wait_us(delay); | 
| iamjay | 0:e0a44db7e925 | 84 | } | 
| iamjay | 0:e0a44db7e925 | 85 | |
| iamjay | 0:e0a44db7e925 | 86 | void bb_pin(DigitalInOut *pin, int dir, int delay) | 
| iamjay | 0:e0a44db7e925 | 87 | { | 
| iamjay | 0:e0a44db7e925 | 88 | pin->write(dir); | 
| iamjay | 0:e0a44db7e925 | 89 | if (dir) { | 
| iamjay | 0:e0a44db7e925 | 90 | if (mode_config.HiZ == 0) | 
| iamjay | 0:e0a44db7e925 | 91 | pin->mode(PullNone); | 
| iamjay | 0:e0a44db7e925 | 92 | else | 
| iamjay | 0:e0a44db7e925 | 93 | pin->mode(OpenDrain); | 
| iamjay | 0:e0a44db7e925 | 94 | } | 
| iamjay | 0:e0a44db7e925 | 95 | pin->output(); | 
| iamjay | 0:e0a44db7e925 | 96 | wait_us(delay); | 
| iamjay | 0:e0a44db7e925 | 97 | } | 
| iamjay | 0:e0a44db7e925 | 98 | |
| iamjay | 0:e0a44db7e925 | 99 | unsigned char bb_r(DigitalInOut *pin) | 
| iamjay | 0:e0a44db7e925 | 100 | { | 
| iamjay | 0:e0a44db7e925 | 101 | pin->input(); | 
| iamjay | 0:e0a44db7e925 | 102 | return pin->read(); | 
| iamjay | 0:e0a44db7e925 | 103 | } | 
| iamjay | 0:e0a44db7e925 | 104 | |
| iamjay | 0:e0a44db7e925 | 105 | void bb_cs(int dir) | 
| iamjay | 0:e0a44db7e925 | 106 | { | 
| iamjay | 0:e0a44db7e925 | 107 | bb_pin(&bp_cs, dir, bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 108 | } | 
| iamjay | 0:e0a44db7e925 | 109 | |
| iamjay | 0:e0a44db7e925 | 110 | int bb_i2c_start() | 
| iamjay | 0:e0a44db7e925 | 111 | { | 
| iamjay | 0:e0a44db7e925 | 112 | int error = 0; | 
| iamjay | 0:e0a44db7e925 | 113 | |
| iamjay | 0:e0a44db7e925 | 114 | bb_h(&bp_mosi, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 115 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 116 | |
| iamjay | 0:e0a44db7e925 | 117 | if (bp_clk.read() == 0 || bp_mosi.read() == 0) | 
| iamjay | 0:e0a44db7e925 | 118 | error = 1; | 
| iamjay | 0:e0a44db7e925 | 119 | |
| iamjay | 0:e0a44db7e925 | 120 | bb_l(&bp_mosi, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 121 | |
| iamjay | 0:e0a44db7e925 | 122 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 123 | |
| iamjay | 0:e0a44db7e925 | 124 | bb_h(&bp_mosi, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 125 | |
| iamjay | 0:e0a44db7e925 | 126 | return error; | 
| iamjay | 0:e0a44db7e925 | 127 | } | 
| iamjay | 0:e0a44db7e925 | 128 | |
| iamjay | 0:e0a44db7e925 | 129 | int bb_i2c_stop() | 
| iamjay | 0:e0a44db7e925 | 130 | { | 
| iamjay | 0:e0a44db7e925 | 131 | bb_l(&bp_mosi, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 132 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 133 | |
| iamjay | 0:e0a44db7e925 | 134 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 135 | |
| iamjay | 0:e0a44db7e925 | 136 | bb_h(&bp_mosi, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 137 | |
| iamjay | 0:e0a44db7e925 | 138 | return 0; | 
| iamjay | 0:e0a44db7e925 | 139 | } | 
| iamjay | 0:e0a44db7e925 | 140 | |
| iamjay | 0:e0a44db7e925 | 141 | unsigned int bb_read_write_byte(unsigned int c) | 
| iamjay | 0:e0a44db7e925 | 142 | { | 
| iamjay | 0:e0a44db7e925 | 143 | unsigned int i, bt, tem, di, dat = 0; | 
| iamjay | 0:e0a44db7e925 | 144 | |
| iamjay | 0:e0a44db7e925 | 145 | bt = 1 << (mode_config.numbits - 1); | 
| iamjay | 0:e0a44db7e925 | 146 | |
| iamjay | 0:e0a44db7e925 | 147 | tem = c; | 
| iamjay | 0:e0a44db7e925 | 148 | for (i = 0; i < mode_config.numbits; i++) { | 
| iamjay | 0:e0a44db7e925 | 149 | bb_pin(&bp_mosi, (tem & bt), bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 150 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 151 | di = bb_r(&bp_miso); | 
| iamjay | 0:e0a44db7e925 | 152 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 153 | |
| iamjay | 0:e0a44db7e925 | 154 | tem = tem << 1; | 
| iamjay | 0:e0a44db7e925 | 155 | dat = dat << 1; | 
| iamjay | 0:e0a44db7e925 | 156 | if (di) | 
| iamjay | 0:e0a44db7e925 | 157 | dat++; | 
| iamjay | 0:e0a44db7e925 | 158 | } | 
| iamjay | 0:e0a44db7e925 | 159 | return dat; | 
| iamjay | 0:e0a44db7e925 | 160 | } | 
| iamjay | 0:e0a44db7e925 | 161 | |
| iamjay | 0:e0a44db7e925 | 162 | void bb_write_byte(unsigned int c) | 
| iamjay | 0:e0a44db7e925 | 163 | { | 
| iamjay | 0:e0a44db7e925 | 164 | unsigned int i, bt, tem; | 
| iamjay | 0:e0a44db7e925 | 165 | |
| iamjay | 0:e0a44db7e925 | 166 | bt = 1 << (mode_config.numbits - 1); | 
| iamjay | 0:e0a44db7e925 | 167 | |
| iamjay | 0:e0a44db7e925 | 168 | tem = c; | 
| iamjay | 0:e0a44db7e925 | 169 | for (i = 0; i < mode_config.numbits; i++) { | 
| iamjay | 0:e0a44db7e925 | 170 | bb_pin(&bp_mosi, tem & bt, bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 171 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 172 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 173 | |
| iamjay | 0:e0a44db7e925 | 174 | tem = tem << 1; | 
| iamjay | 0:e0a44db7e925 | 175 | } | 
| iamjay | 0:e0a44db7e925 | 176 | } | 
| iamjay | 0:e0a44db7e925 | 177 | unsigned int bb_read_byte() | 
| iamjay | 0:e0a44db7e925 | 178 | { | 
| iamjay | 0:e0a44db7e925 | 179 | int i, di, dat = 0; | 
| iamjay | 0:e0a44db7e925 | 180 | |
| iamjay | 0:e0a44db7e925 | 181 | bb_r(&bp_mosi); | 
| iamjay | 0:e0a44db7e925 | 182 | |
| iamjay | 0:e0a44db7e925 | 183 | for (i = 0; i < mode_config.numbits; i++) { | 
| iamjay | 0:e0a44db7e925 | 184 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 185 | di = bb_r(&bp_mosi); | 
| iamjay | 0:e0a44db7e925 | 186 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 187 | |
| iamjay | 0:e0a44db7e925 | 188 | dat = dat << 1; | 
| iamjay | 0:e0a44db7e925 | 189 | if (di) | 
| iamjay | 0:e0a44db7e925 | 190 | dat++; | 
| iamjay | 0:e0a44db7e925 | 191 | } | 
| iamjay | 0:e0a44db7e925 | 192 | |
| iamjay | 0:e0a44db7e925 | 193 | return dat; | 
| iamjay | 0:e0a44db7e925 | 194 | } | 
| iamjay | 0:e0a44db7e925 | 195 | |
| iamjay | 0:e0a44db7e925 | 196 | unsigned char bb_read_bit() | 
| iamjay | 0:e0a44db7e925 | 197 | { | 
| iamjay | 0:e0a44db7e925 | 198 | unsigned char c; | 
| iamjay | 0:e0a44db7e925 | 199 | |
| iamjay | 0:e0a44db7e925 | 200 | bb_r(bitbang.mi); | 
| iamjay | 0:e0a44db7e925 | 201 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 202 | c = bb_r(bitbang.mi); | 
| iamjay | 0:e0a44db7e925 | 203 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 204 | |
| iamjay | 0:e0a44db7e925 | 205 | return c; | 
| iamjay | 0:e0a44db7e925 | 206 | } | 
| iamjay | 0:e0a44db7e925 | 207 | |
| iamjay | 0:e0a44db7e925 | 208 | void bb_write_bit(unsigned char c) | 
| iamjay | 0:e0a44db7e925 | 209 | { | 
| iamjay | 0:e0a44db7e925 | 210 | bb_pin(bitbang.mo, c, bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 211 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 212 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 213 | } | 
| iamjay | 0:e0a44db7e925 | 214 | |
| iamjay | 0:e0a44db7e925 | 215 | void bb_clock_ticks(unsigned char c) | 
| iamjay | 0:e0a44db7e925 | 216 | { | 
| iamjay | 0:e0a44db7e925 | 217 | unsigned char i; | 
| iamjay | 0:e0a44db7e925 | 218 | |
| iamjay | 0:e0a44db7e925 | 219 | for (i = 0; i < c; i++) { | 
| iamjay | 0:e0a44db7e925 | 220 | bb_h(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 221 | bb_l(&bp_clk, bitbang.delay_clock); | 
| iamjay | 0:e0a44db7e925 | 222 | } | 
| iamjay | 0:e0a44db7e925 | 223 | } | 
| iamjay | 0:e0a44db7e925 | 224 | |
| iamjay | 0:e0a44db7e925 | 225 | void bb_mosi(unsigned char dir) | 
| iamjay | 0:e0a44db7e925 | 226 | { | 
| iamjay | 0:e0a44db7e925 | 227 | bb_pin(bitbang.mo, dir, bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 228 | } | 
| iamjay | 0:e0a44db7e925 | 229 | |
| iamjay | 0:e0a44db7e925 | 230 | void bb_clk(unsigned char dir) | 
| iamjay | 0:e0a44db7e925 | 231 | { | 
| iamjay | 0:e0a44db7e925 | 232 | bb_pin(&bp_clk, dir, bitbang.delay_settle); | 
| iamjay | 0:e0a44db7e925 | 233 | } | 
| iamjay | 0:e0a44db7e925 | 234 | |
| iamjay | 0:e0a44db7e925 | 235 | unsigned char bb_miso() | 
| iamjay | 0:e0a44db7e925 | 236 | { | 
| iamjay | 0:e0a44db7e925 | 237 | return bb_r(bitbang.mi); | 
| iamjay | 0:e0a44db7e925 | 238 | } |