Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri Apr 21 18:50:37 2017 +0000
Revision:
86:e30a1f60f783
Parent:
82:4f6209cb5c33
Child:
87:8d35c74403af
Capture a bunch of alternative bar code decoder tests, mostly unsuccessful

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 86:e30a1f60f783 1 // Bit Bang BitBangI2C implementation for KL25Z
mjr 82:4f6209cb5c33 2 //
mjr 82:4f6209cb5c33 3
mjr 82:4f6209cb5c33 4 #include "mbed.h"
mjr 82:4f6209cb5c33 5 #include "BitBangI2C.h"
mjr 82:4f6209cb5c33 6
mjr 86:e30a1f60f783 7
mjr 82:4f6209cb5c33 8 // --------------------------------------------------------------------------
mjr 82:4f6209cb5c33 9 //
mjr 82:4f6209cb5c33 10 // Debugging:
mjr 82:4f6209cb5c33 11 //
mjr 82:4f6209cb5c33 12 // 0 -> no debugging
mjr 82:4f6209cb5c33 13 // 1 -> print (on console) error messages only
mjr 82:4f6209cb5c33 14 // 2 -> print full diagnostics
mjr 82:4f6209cb5c33 15 //
mjr 82:4f6209cb5c33 16 // dprintf() = general debug diagnostics (printed only in case 2)
mjr 82:4f6209cb5c33 17 // eprintf() = error diagnostics (printed in case 1 and above)
mjr 82:4f6209cb5c33 18 //
mjr 82:4f6209cb5c33 19 #define BBI2C_DEBUG 1
mjr 82:4f6209cb5c33 20 #if BBI2C_DEBUG
mjr 82:4f6209cb5c33 21 # define eprintf(...) printf(__VA_ARGS__)
mjr 82:4f6209cb5c33 22 # if BBI2C_DEBUG >= 2
mjr 82:4f6209cb5c33 23 # define dprintf(...) printf(__VA_ARGS__)
mjr 82:4f6209cb5c33 24 # else
mjr 82:4f6209cb5c33 25 # define dprintf(...)
mjr 82:4f6209cb5c33 26 # endif
mjr 82:4f6209cb5c33 27 static const char *dbgbytes(const uint8_t *bytes, size_t len)
mjr 82:4f6209cb5c33 28 {
mjr 82:4f6209cb5c33 29 static char buf[128];
mjr 82:4f6209cb5c33 30 char *p = buf;
mjr 82:4f6209cb5c33 31 for (int i = 0 ; i < len && p + 4 < buf + sizeof(buf) ; ++i)
mjr 82:4f6209cb5c33 32 {
mjr 82:4f6209cb5c33 33 if (i > 0) *p++ = ',';
mjr 82:4f6209cb5c33 34 sprintf(p, "%02x", bytes[i]);
mjr 82:4f6209cb5c33 35 p += 2;
mjr 82:4f6209cb5c33 36 }
mjr 82:4f6209cb5c33 37 *p = '\0';
mjr 82:4f6209cb5c33 38 return buf;
mjr 82:4f6209cb5c33 39 }
mjr 82:4f6209cb5c33 40 #else
mjr 82:4f6209cb5c33 41 # define dprintf(...)
mjr 86:e30a1f60f783 42 # define eprintf(...)
mjr 82:4f6209cb5c33 43 #endif
mjr 82:4f6209cb5c33 44
mjr 82:4f6209cb5c33 45 // --------------------------------------------------------------------------
mjr 82:4f6209cb5c33 46 //
mjr 82:4f6209cb5c33 47 // Bit-bang I2C implementation
mjr 82:4f6209cb5c33 48 //
mjr 82:4f6209cb5c33 49 BitBangI2C::BitBangI2C(PinName sda, PinName scl) :
mjr 82:4f6209cb5c33 50 sclPin(scl), sdaPin(sda)
mjr 82:4f6209cb5c33 51 {
mjr 82:4f6209cb5c33 52 // set the default frequency to 100kHz
mjr 86:e30a1f60f783 53 frequency(100000);
mjr 82:4f6209cb5c33 54 }
mjr 82:4f6209cb5c33 55
mjr 86:e30a1f60f783 56 void BitBangI2C::frequency(uint32_t freq)
mjr 82:4f6209cb5c33 57 {
mjr 86:e30a1f60f783 58 // figure the clock time per cycle
mjr 86:e30a1f60f783 59 clkPeriod_us = 1000000/freq;
mjr 86:e30a1f60f783 60
mjr 86:e30a1f60f783 61 // Figure wait times according to frequency
mjr 86:e30a1f60f783 62 if (freq <= 100000)
mjr 86:e30a1f60f783 63 {
mjr 86:e30a1f60f783 64 // standard mode I2C bus - up to 100kHz
mjr 86:e30a1f60f783 65 tLow = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 66 tHigh = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 67 tBuf = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 68 tHdSta = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 69 tSuSta = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 70 tSuSto = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 71 tAck = calcHiResWaitTime(300);
mjr 86:e30a1f60f783 72 tData = calcHiResWaitTime(300);
mjr 86:e30a1f60f783 73 tSuDat = calcHiResWaitTime(250);
mjr 86:e30a1f60f783 74 }
mjr 86:e30a1f60f783 75 else if (freq <= 400000)
mjr 86:e30a1f60f783 76 {
mjr 86:e30a1f60f783 77 // fast mode I2C - up to 400kHz
mjr 86:e30a1f60f783 78 tLow = calcHiResWaitTime(1300);
mjr 86:e30a1f60f783 79 tHigh = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 80 tBuf = calcHiResWaitTime(1300);
mjr 86:e30a1f60f783 81 tHdSta = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 82 tSuSta = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 83 tSuSto = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 84 tAck = calcHiResWaitTime(100);
mjr 86:e30a1f60f783 85 tData = calcHiResWaitTime(100);
mjr 86:e30a1f60f783 86 tSuDat = calcHiResWaitTime(100);
mjr 86:e30a1f60f783 87 }
mjr 86:e30a1f60f783 88 else
mjr 86:e30a1f60f783 89 {
mjr 86:e30a1f60f783 90 // fast mode plus - up to 1MHz
mjr 86:e30a1f60f783 91 tLow = calcHiResWaitTime(500);
mjr 86:e30a1f60f783 92 tHigh = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 93 tBuf = calcHiResWaitTime(500);
mjr 86:e30a1f60f783 94 tHdSta = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 95 tSuSta = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 96 tSuSto = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 97 tAck = calcHiResWaitTime(50);
mjr 86:e30a1f60f783 98 tData = calcHiResWaitTime(50);
mjr 86:e30a1f60f783 99 tSuDat = calcHiResWaitTime(50);
mjr 86:e30a1f60f783 100 }
mjr 82:4f6209cb5c33 101 }
mjr 82:4f6209cb5c33 102
mjr 82:4f6209cb5c33 103 void BitBangI2C::start()
mjr 82:4f6209cb5c33 104 {
mjr 86:e30a1f60f783 105 // take clock and data high
mjr 86:e30a1f60f783 106 sclHi();
mjr 86:e30a1f60f783 107 sdaHi();
mjr 86:e30a1f60f783 108 hiResWait(tBuf);
mjr 82:4f6209cb5c33 109
mjr 82:4f6209cb5c33 110 // take data low
mjr 86:e30a1f60f783 111 sdaLo();
mjr 86:e30a1f60f783 112 hiResWait(tHdSta);
mjr 82:4f6209cb5c33 113
mjr 82:4f6209cb5c33 114 // take clock low
mjr 86:e30a1f60f783 115 sclLo();
mjr 86:e30a1f60f783 116 hiResWait(tLow);
mjr 82:4f6209cb5c33 117 }
mjr 82:4f6209cb5c33 118
mjr 82:4f6209cb5c33 119 void BitBangI2C::stop()
mjr 82:4f6209cb5c33 120 {
mjr 86:e30a1f60f783 121 // take SDA low
mjr 86:e30a1f60f783 122 sdaLo();
mjr 86:e30a1f60f783 123
mjr 82:4f6209cb5c33 124 // take SCL high
mjr 86:e30a1f60f783 125 sclHi();
mjr 86:e30a1f60f783 126 hiResWait(tSuSto);
mjr 82:4f6209cb5c33 127
mjr 82:4f6209cb5c33 128 // take SDA high
mjr 86:e30a1f60f783 129 sdaHi();
mjr 86:e30a1f60f783 130 hiResWait(tBuf);
mjr 82:4f6209cb5c33 131 }
mjr 82:4f6209cb5c33 132
mjr 82:4f6209cb5c33 133 bool BitBangI2C::wait(uint32_t timeout_us)
mjr 82:4f6209cb5c33 134 {
mjr 82:4f6209cb5c33 135 // set up a timer to monitor the timeout period
mjr 82:4f6209cb5c33 136 Timer t;
mjr 82:4f6209cb5c33 137 t.start();
mjr 82:4f6209cb5c33 138
mjr 82:4f6209cb5c33 139 // wait for an ACK
mjr 82:4f6209cb5c33 140 for (;;)
mjr 82:4f6209cb5c33 141 {
mjr 82:4f6209cb5c33 142 // if SDA is low, it's an ACK
mjr 82:4f6209cb5c33 143 if (!sdaPin.read())
mjr 82:4f6209cb5c33 144 return true;
mjr 82:4f6209cb5c33 145
mjr 82:4f6209cb5c33 146 // if we've reached the timeout, abort
mjr 82:4f6209cb5c33 147 if (t.read_us() > timeout_us)
mjr 82:4f6209cb5c33 148 return false;
mjr 82:4f6209cb5c33 149 }
mjr 82:4f6209cb5c33 150 }
mjr 82:4f6209cb5c33 151
mjr 82:4f6209cb5c33 152 void BitBangI2C::reset()
mjr 82:4f6209cb5c33 153 {
mjr 82:4f6209cb5c33 154 // write out 9 '1' bits
mjr 82:4f6209cb5c33 155 for (int i = 0 ; i < 9 ; ++i)
mjr 82:4f6209cb5c33 156 writeBit(1);
mjr 82:4f6209cb5c33 157
mjr 82:4f6209cb5c33 158 // issue a start sequence
mjr 82:4f6209cb5c33 159 start();
mjr 82:4f6209cb5c33 160
mjr 82:4f6209cb5c33 161 // take the clock high
mjr 86:e30a1f60f783 162 sclHi();
mjr 86:e30a1f60f783 163
mjr 86:e30a1f60f783 164 // wait for a few clock cycles
mjr 86:e30a1f60f783 165 wait_us(4*clkPeriod_us);
mjr 82:4f6209cb5c33 166 }
mjr 82:4f6209cb5c33 167
mjr 82:4f6209cb5c33 168 int BitBangI2C::write(uint8_t addr, const uint8_t *data, size_t len, bool repeated)
mjr 82:4f6209cb5c33 169 {
mjr 82:4f6209cb5c33 170 dprintf("i2c.write, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 171 addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 172
mjr 82:4f6209cb5c33 173 // send the start signal
mjr 82:4f6209cb5c33 174 start();
mjr 82:4f6209cb5c33 175
mjr 82:4f6209cb5c33 176 // send the address with the R/W bit set to WRITE (0)
mjr 82:4f6209cb5c33 177 if (write(addr))
mjr 82:4f6209cb5c33 178 {
mjr 82:4f6209cb5c33 179 eprintf(". i2c.write, address write failed, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 180 addr, dbgbytes(data, len), repeated ? "": "no ");
mjr 82:4f6209cb5c33 181 return -1;
mjr 82:4f6209cb5c33 182 }
mjr 82:4f6209cb5c33 183
mjr 82:4f6209cb5c33 184 // send the data bytes
mjr 82:4f6209cb5c33 185 for (int i = 0 ; i < len ; ++i)
mjr 82:4f6209cb5c33 186 {
mjr 82:4f6209cb5c33 187 if (write(data[i]))
mjr 82:4f6209cb5c33 188 {
mjr 82:4f6209cb5c33 189 eprintf(". i2c.write, write failed at byte %d, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 190 i, addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 191 return -2;
mjr 82:4f6209cb5c33 192 }
mjr 82:4f6209cb5c33 193 }
mjr 82:4f6209cb5c33 194
mjr 82:4f6209cb5c33 195 // send the stop, unless the start is to be repeated
mjr 82:4f6209cb5c33 196 if (!repeated)
mjr 82:4f6209cb5c33 197 stop();
mjr 82:4f6209cb5c33 198
mjr 82:4f6209cb5c33 199 // success
mjr 82:4f6209cb5c33 200 return 0;
mjr 82:4f6209cb5c33 201 }
mjr 82:4f6209cb5c33 202
mjr 82:4f6209cb5c33 203 int BitBangI2C::read(uint8_t addr, uint8_t *data, size_t len, bool repeated)
mjr 82:4f6209cb5c33 204 {
mjr 82:4f6209cb5c33 205 dprintf("i2c.read, addr=%02x\r\n", addr);
mjr 82:4f6209cb5c33 206
mjr 82:4f6209cb5c33 207 // send the start signal
mjr 82:4f6209cb5c33 208 start();
mjr 82:4f6209cb5c33 209
mjr 82:4f6209cb5c33 210 // send the address with the R/W bit set to READ (1)
mjr 82:4f6209cb5c33 211 if (write(addr | 0x01))
mjr 82:4f6209cb5c33 212 {
mjr 82:4f6209cb5c33 213 eprintf(". i2c.read, read addr write failed, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 214 addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 215 return -1;
mjr 82:4f6209cb5c33 216 }
mjr 82:4f6209cb5c33 217
mjr 82:4f6209cb5c33 218 // Read the data. Send an ACK after each byte except the last,
mjr 82:4f6209cb5c33 219 // where we send a NAK.
mjr 82:4f6209cb5c33 220 for ( ; len != 0 ; --len, ++data)
mjr 82:4f6209cb5c33 221 *data = read(len > 1);
mjr 82:4f6209cb5c33 222
mjr 82:4f6209cb5c33 223 // send the stop signal, unless a repeated start is indicated
mjr 82:4f6209cb5c33 224 if (!repeated)
mjr 82:4f6209cb5c33 225 stop();
mjr 82:4f6209cb5c33 226
mjr 82:4f6209cb5c33 227 // success
mjr 82:4f6209cb5c33 228 return 0;
mjr 82:4f6209cb5c33 229 }
mjr 82:4f6209cb5c33 230
mjr 82:4f6209cb5c33 231 int BitBangI2C::write(uint8_t data)
mjr 82:4f6209cb5c33 232 {
mjr 82:4f6209cb5c33 233 // write the bits, most significant first
mjr 82:4f6209cb5c33 234 for (int i = 0 ; i < 8 ; ++i, data <<= 1)
mjr 82:4f6209cb5c33 235 writeBit(data & 0x80);
mjr 82:4f6209cb5c33 236
mjr 82:4f6209cb5c33 237 // read and return the ACK bit
mjr 82:4f6209cb5c33 238 return readBit();
mjr 82:4f6209cb5c33 239 }
mjr 82:4f6209cb5c33 240
mjr 82:4f6209cb5c33 241 int BitBangI2C::read(bool ack)
mjr 82:4f6209cb5c33 242 {
mjr 82:4f6209cb5c33 243 // read 8 bits, most significant first
mjr 82:4f6209cb5c33 244 uint8_t data = 0;
mjr 82:4f6209cb5c33 245 for (int i = 0 ; i < 8 ; ++i)
mjr 82:4f6209cb5c33 246 data = (data << 1) | readBit();
mjr 82:4f6209cb5c33 247
mjr 82:4f6209cb5c33 248 // switch to output mode and send the ACK bit
mjr 82:4f6209cb5c33 249 writeBit(!ack);
mjr 82:4f6209cb5c33 250
mjr 82:4f6209cb5c33 251 // return the data byte we read
mjr 82:4f6209cb5c33 252 return data;
mjr 82:4f6209cb5c33 253 }
mjr 82:4f6209cb5c33 254
mjr 82:4f6209cb5c33 255 int BitBangI2C::readBit()
mjr 82:4f6209cb5c33 256 {
mjr 82:4f6209cb5c33 257 // take the clock high (actually, release it to the pull-up)
mjr 86:e30a1f60f783 258 sclHi();
mjr 82:4f6209cb5c33 259
mjr 82:4f6209cb5c33 260 // Wait (within reason) for it to actually read as high. The device
mjr 82:4f6209cb5c33 261 // can intentionally pull the clock line low to tell us to wait while
mjr 82:4f6209cb5c33 262 // it's working on preparing the data for us.
mjr 82:4f6209cb5c33 263 Timer t;
mjr 82:4f6209cb5c33 264 t.start();
mjr 82:4f6209cb5c33 265 while (sclPin.read() == 0 && t.read_us() < 500000) ;
mjr 82:4f6209cb5c33 266
mjr 82:4f6209cb5c33 267 // if the clock isn't high, we timed out
mjr 82:4f6209cb5c33 268 if (sclPin.read() == 0)
mjr 82:4f6209cb5c33 269 {
mjr 82:4f6209cb5c33 270 eprintf("i2c.readBit, clock stretching timeout\r\n");
mjr 82:4f6209cb5c33 271 return 0;
mjr 82:4f6209cb5c33 272 }
mjr 82:4f6209cb5c33 273
mjr 82:4f6209cb5c33 274 // wait until the clock interval is up
mjr 82:4f6209cb5c33 275 while (t.read_us() < clkPeriod_us);
mjr 82:4f6209cb5c33 276
mjr 82:4f6209cb5c33 277 // read the bit
mjr 82:4f6209cb5c33 278 bool bit = sdaPin.read();
mjr 82:4f6209cb5c33 279
mjr 82:4f6209cb5c33 280 // take the clock low again
mjr 86:e30a1f60f783 281 sclLo();
mjr 86:e30a1f60f783 282 hiResWait(tLow);
mjr 82:4f6209cb5c33 283
mjr 82:4f6209cb5c33 284 // return the bit
mjr 82:4f6209cb5c33 285 return bit;
mjr 82:4f6209cb5c33 286 }