Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
arnoz
Date:
Fri Oct 01 08:19:46 2021 +0000
Revision:
116:7a67265d7c19
Parent:
87:8d35c74403af
- Correct information regarding your last merge

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 87:8d35c74403af 19 #define BBI2C_DEBUG 0
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 87:8d35c74403af 49 BitBangI2C::BitBangI2C(PinName sda, PinName scl, bool internalPullup) :
mjr 87:8d35c74403af 50 sdaPin(sda, internalPullup), sclPin(scl, internalPullup)
mjr 82:4f6209cb5c33 51 {
mjr 82:4f6209cb5c33 52 // set the default frequency to 100kHz
mjr 86:e30a1f60f783 53 frequency(100000);
mjr 87:8d35c74403af 54
mjr 87:8d35c74403af 55 // we're initially in a stop
mjr 87:8d35c74403af 56 inStop = true;
mjr 82:4f6209cb5c33 57 }
mjr 82:4f6209cb5c33 58
mjr 86:e30a1f60f783 59 void BitBangI2C::frequency(uint32_t freq)
mjr 82:4f6209cb5c33 60 {
mjr 86:e30a1f60f783 61 // figure the clock time per cycle
mjr 86:e30a1f60f783 62 clkPeriod_us = 1000000/freq;
mjr 86:e30a1f60f783 63
mjr 86:e30a1f60f783 64 // Figure wait times according to frequency
mjr 86:e30a1f60f783 65 if (freq <= 100000)
mjr 86:e30a1f60f783 66 {
mjr 86:e30a1f60f783 67 // standard mode I2C bus - up to 100kHz
mjr 87:8d35c74403af 68
mjr 87:8d35c74403af 69 // nanosecond parameters
mjr 86:e30a1f60f783 70 tLow = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 71 tHigh = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 72 tHdSta = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 73 tSuSta = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 74 tSuSto = calcHiResWaitTime(4000);
mjr 86:e30a1f60f783 75 tAck = calcHiResWaitTime(300);
mjr 86:e30a1f60f783 76 tSuDat = calcHiResWaitTime(250);
mjr 87:8d35c74403af 77 tBuf = calcHiResWaitTime(4700);
mjr 86:e30a1f60f783 78 }
mjr 86:e30a1f60f783 79 else if (freq <= 400000)
mjr 86:e30a1f60f783 80 {
mjr 86:e30a1f60f783 81 // fast mode I2C - up to 400kHz
mjr 87:8d35c74403af 82
mjr 87:8d35c74403af 83 // nanosecond parameters
mjr 86:e30a1f60f783 84 tLow = calcHiResWaitTime(1300);
mjr 86:e30a1f60f783 85 tHigh = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 86 tHdSta = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 87 tSuSta = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 88 tSuSto = calcHiResWaitTime(600);
mjr 86:e30a1f60f783 89 tAck = calcHiResWaitTime(100);
mjr 86:e30a1f60f783 90 tSuDat = calcHiResWaitTime(100);
mjr 87:8d35c74403af 91 tBuf = calcHiResWaitTime(1300);
mjr 86:e30a1f60f783 92 }
mjr 86:e30a1f60f783 93 else
mjr 86:e30a1f60f783 94 {
mjr 86:e30a1f60f783 95 // fast mode plus - up to 1MHz
mjr 87:8d35c74403af 96
mjr 87:8d35c74403af 97 // nanosecond parameters
mjr 86:e30a1f60f783 98 tLow = calcHiResWaitTime(500);
mjr 86:e30a1f60f783 99 tHigh = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 100 tHdSta = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 101 tSuSta = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 102 tSuSto = calcHiResWaitTime(260);
mjr 86:e30a1f60f783 103 tAck = calcHiResWaitTime(50);
mjr 86:e30a1f60f783 104 tSuDat = calcHiResWaitTime(50);
mjr 87:8d35c74403af 105 tBuf = calcHiResWaitTime(500);
mjr 86:e30a1f60f783 106 }
mjr 82:4f6209cb5c33 107 }
mjr 82:4f6209cb5c33 108
mjr 82:4f6209cb5c33 109 void BitBangI2C::start()
mjr 82:4f6209cb5c33 110 {
mjr 87:8d35c74403af 111 // check to see if we're starting after a stop, or if this is a
mjr 87:8d35c74403af 112 // repeated start
mjr 87:8d35c74403af 113 if (inStop)
mjr 87:8d35c74403af 114 {
mjr 87:8d35c74403af 115 // in a stop - make sure we waited for the minimum hold time
mjr 87:8d35c74403af 116 hiResWait(tBuf);
mjr 87:8d35c74403af 117 }
mjr 87:8d35c74403af 118 else
mjr 87:8d35c74403af 119 {
mjr 87:8d35c74403af 120 // repeated start - take data high
mjr 87:8d35c74403af 121 sdaHi();
mjr 87:8d35c74403af 122 hiResWait(tSuDat);
mjr 87:8d35c74403af 123
mjr 87:8d35c74403af 124 // take clock high
mjr 87:8d35c74403af 125 sclHi();
mjr 87:8d35c74403af 126
mjr 87:8d35c74403af 127 // wait for the minimum setup period
mjr 87:8d35c74403af 128 hiResWait(tSuSta);
mjr 87:8d35c74403af 129 }
mjr 82:4f6209cb5c33 130
mjr 82:4f6209cb5c33 131 // take data low
mjr 86:e30a1f60f783 132 sdaLo();
mjr 82:4f6209cb5c33 133
mjr 87:8d35c74403af 134 // wait for the setup period and take clock low
mjr 87:8d35c74403af 135 hiResWait(tHdSta);
mjr 86:e30a1f60f783 136 sclLo();
mjr 87:8d35c74403af 137
mjr 87:8d35c74403af 138 // wait for the low period
mjr 87:8d35c74403af 139 hiResWait(tLow);
mjr 87:8d35c74403af 140
mjr 87:8d35c74403af 141 // no longer in a stop
mjr 87:8d35c74403af 142 inStop = false;
mjr 82:4f6209cb5c33 143 }
mjr 82:4f6209cb5c33 144
mjr 82:4f6209cb5c33 145 void BitBangI2C::stop()
mjr 82:4f6209cb5c33 146 {
mjr 87:8d35c74403af 147 // if we're not in a stop, enter one
mjr 87:8d35c74403af 148 if (!inStop)
mjr 87:8d35c74403af 149 {
mjr 87:8d35c74403af 150 // take SDA low
mjr 87:8d35c74403af 151 sdaLo();
mjr 86:e30a1f60f783 152
mjr 87:8d35c74403af 153 // take SCL high
mjr 87:8d35c74403af 154 sclHi();
mjr 87:8d35c74403af 155 hiResWait(tSuSto);
mjr 87:8d35c74403af 156
mjr 87:8d35c74403af 157 // take SDA high
mjr 87:8d35c74403af 158 sdaHi();
mjr 87:8d35c74403af 159
mjr 87:8d35c74403af 160 // we're in a stop
mjr 87:8d35c74403af 161 inStop = true;
mjr 87:8d35c74403af 162 }
mjr 82:4f6209cb5c33 163 }
mjr 82:4f6209cb5c33 164
mjr 82:4f6209cb5c33 165 bool BitBangI2C::wait(uint32_t timeout_us)
mjr 82:4f6209cb5c33 166 {
mjr 82:4f6209cb5c33 167 // set up a timer to monitor the timeout period
mjr 82:4f6209cb5c33 168 Timer t;
mjr 82:4f6209cb5c33 169 t.start();
mjr 82:4f6209cb5c33 170
mjr 82:4f6209cb5c33 171 // wait for an ACK
mjr 82:4f6209cb5c33 172 for (;;)
mjr 82:4f6209cb5c33 173 {
mjr 82:4f6209cb5c33 174 // if SDA is low, it's an ACK
mjr 82:4f6209cb5c33 175 if (!sdaPin.read())
mjr 82:4f6209cb5c33 176 return true;
mjr 82:4f6209cb5c33 177
mjr 82:4f6209cb5c33 178 // if we've reached the timeout, abort
mjr 82:4f6209cb5c33 179 if (t.read_us() > timeout_us)
mjr 82:4f6209cb5c33 180 return false;
mjr 82:4f6209cb5c33 181 }
mjr 82:4f6209cb5c33 182 }
mjr 82:4f6209cb5c33 183
mjr 82:4f6209cb5c33 184 void BitBangI2C::reset()
mjr 82:4f6209cb5c33 185 {
mjr 82:4f6209cb5c33 186 // write out 9 '1' bits
mjr 82:4f6209cb5c33 187 for (int i = 0 ; i < 9 ; ++i)
mjr 82:4f6209cb5c33 188 writeBit(1);
mjr 82:4f6209cb5c33 189
mjr 82:4f6209cb5c33 190 // issue a start sequence
mjr 82:4f6209cb5c33 191 start();
mjr 82:4f6209cb5c33 192
mjr 82:4f6209cb5c33 193 // take the clock high
mjr 86:e30a1f60f783 194 sclHi();
mjr 86:e30a1f60f783 195
mjr 86:e30a1f60f783 196 // wait for a few clock cycles
mjr 86:e30a1f60f783 197 wait_us(4*clkPeriod_us);
mjr 82:4f6209cb5c33 198 }
mjr 82:4f6209cb5c33 199
mjr 82:4f6209cb5c33 200 int BitBangI2C::write(uint8_t addr, const uint8_t *data, size_t len, bool repeated)
mjr 82:4f6209cb5c33 201 {
mjr 82:4f6209cb5c33 202 dprintf("i2c.write, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 203 addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 204
mjr 82:4f6209cb5c33 205 // send the start signal
mjr 82:4f6209cb5c33 206 start();
mjr 82:4f6209cb5c33 207
mjr 82:4f6209cb5c33 208 // send the address with the R/W bit set to WRITE (0)
mjr 82:4f6209cb5c33 209 if (write(addr))
mjr 82:4f6209cb5c33 210 {
mjr 82:4f6209cb5c33 211 eprintf(". i2c.write, address write failed, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 212 addr, dbgbytes(data, len), repeated ? "": "no ");
mjr 82:4f6209cb5c33 213 return -1;
mjr 82:4f6209cb5c33 214 }
mjr 82:4f6209cb5c33 215
mjr 82:4f6209cb5c33 216 // send the data bytes
mjr 82:4f6209cb5c33 217 for (int i = 0 ; i < len ; ++i)
mjr 82:4f6209cb5c33 218 {
mjr 82:4f6209cb5c33 219 if (write(data[i]))
mjr 82:4f6209cb5c33 220 {
mjr 82:4f6209cb5c33 221 eprintf(". i2c.write, write failed at byte %d, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 222 i, addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 223 return -2;
mjr 82:4f6209cb5c33 224 }
mjr 82:4f6209cb5c33 225 }
mjr 82:4f6209cb5c33 226
mjr 82:4f6209cb5c33 227 // send the stop, unless the start is to be repeated
mjr 82:4f6209cb5c33 228 if (!repeated)
mjr 82:4f6209cb5c33 229 stop();
mjr 82:4f6209cb5c33 230
mjr 82:4f6209cb5c33 231 // success
mjr 82:4f6209cb5c33 232 return 0;
mjr 82:4f6209cb5c33 233 }
mjr 82:4f6209cb5c33 234
mjr 82:4f6209cb5c33 235 int BitBangI2C::read(uint8_t addr, uint8_t *data, size_t len, bool repeated)
mjr 82:4f6209cb5c33 236 {
mjr 82:4f6209cb5c33 237 dprintf("i2c.read, addr=%02x\r\n", addr);
mjr 82:4f6209cb5c33 238
mjr 82:4f6209cb5c33 239 // send the start signal
mjr 82:4f6209cb5c33 240 start();
mjr 82:4f6209cb5c33 241
mjr 82:4f6209cb5c33 242 // send the address with the R/W bit set to READ (1)
mjr 82:4f6209cb5c33 243 if (write(addr | 0x01))
mjr 82:4f6209cb5c33 244 {
mjr 82:4f6209cb5c33 245 eprintf(". i2c.read, read addr write failed, addr=%02x [%s] %srepeat\r\n",
mjr 82:4f6209cb5c33 246 addr, dbgbytes(data, len), repeated ? "" : "no ");
mjr 82:4f6209cb5c33 247 return -1;
mjr 82:4f6209cb5c33 248 }
mjr 82:4f6209cb5c33 249
mjr 82:4f6209cb5c33 250 // Read the data. Send an ACK after each byte except the last,
mjr 82:4f6209cb5c33 251 // where we send a NAK.
mjr 82:4f6209cb5c33 252 for ( ; len != 0 ; --len, ++data)
mjr 82:4f6209cb5c33 253 *data = read(len > 1);
mjr 82:4f6209cb5c33 254
mjr 82:4f6209cb5c33 255 // send the stop signal, unless a repeated start is indicated
mjr 82:4f6209cb5c33 256 if (!repeated)
mjr 82:4f6209cb5c33 257 stop();
mjr 82:4f6209cb5c33 258
mjr 82:4f6209cb5c33 259 // success
mjr 82:4f6209cb5c33 260 return 0;
mjr 82:4f6209cb5c33 261 }
mjr 82:4f6209cb5c33 262
mjr 82:4f6209cb5c33 263 int BitBangI2C::write(uint8_t data)
mjr 82:4f6209cb5c33 264 {
mjr 82:4f6209cb5c33 265 // write the bits, most significant first
mjr 82:4f6209cb5c33 266 for (int i = 0 ; i < 8 ; ++i, data <<= 1)
mjr 82:4f6209cb5c33 267 writeBit(data & 0x80);
mjr 87:8d35c74403af 268
mjr 87:8d35c74403af 269 // release SDA so the device can control it
mjr 87:8d35c74403af 270 sdaHi();
mjr 87:8d35c74403af 271
mjr 87:8d35c74403af 272 // read the ACK bit
mjr 87:8d35c74403af 273 int ack = readBit();
mjr 87:8d35c74403af 274
mjr 87:8d35c74403af 275 // take SDA low again
mjr 87:8d35c74403af 276 sdaLo();
mjr 87:8d35c74403af 277
mjr 87:8d35c74403af 278 // return success if ACK was 0
mjr 87:8d35c74403af 279 return ack;
mjr 82:4f6209cb5c33 280 }
mjr 82:4f6209cb5c33 281
mjr 82:4f6209cb5c33 282 int BitBangI2C::read(bool ack)
mjr 82:4f6209cb5c33 283 {
mjr 87:8d35c74403af 284 // take SDA high before reading
mjr 87:8d35c74403af 285 sdaHi();
mjr 87:8d35c74403af 286
mjr 82:4f6209cb5c33 287 // read 8 bits, most significant first
mjr 82:4f6209cb5c33 288 uint8_t data = 0;
mjr 82:4f6209cb5c33 289 for (int i = 0 ; i < 8 ; ++i)
mjr 82:4f6209cb5c33 290 data = (data << 1) | readBit();
mjr 82:4f6209cb5c33 291
mjr 82:4f6209cb5c33 292 // switch to output mode and send the ACK bit
mjr 82:4f6209cb5c33 293 writeBit(!ack);
mjr 82:4f6209cb5c33 294
mjr 87:8d35c74403af 295 // release SDA
mjr 87:8d35c74403af 296 sdaHi();
mjr 87:8d35c74403af 297
mjr 82:4f6209cb5c33 298 // return the data byte we read
mjr 82:4f6209cb5c33 299 return data;
mjr 82:4f6209cb5c33 300 }
mjr 82:4f6209cb5c33 301
mjr 82:4f6209cb5c33 302 int BitBangI2C::readBit()
mjr 82:4f6209cb5c33 303 {
mjr 82:4f6209cb5c33 304 // take the clock high (actually, release it to the pull-up)
mjr 86:e30a1f60f783 305 sclHi();
mjr 82:4f6209cb5c33 306
mjr 82:4f6209cb5c33 307 // Wait (within reason) for it to actually read as high. The device
mjr 82:4f6209cb5c33 308 // can intentionally pull the clock line low to tell us to wait while
mjr 82:4f6209cb5c33 309 // it's working on preparing the data for us.
mjr 87:8d35c74403af 310 int t = 0;
mjr 87:8d35c74403af 311 do
mjr 82:4f6209cb5c33 312 {
mjr 87:8d35c74403af 313 // if the clock is high, we're ready to go
mjr 87:8d35c74403af 314 if (sclPin.read())
mjr 87:8d35c74403af 315 {
mjr 87:8d35c74403af 316 // wait for the data setup time
mjr 87:8d35c74403af 317 hiResWait(tSuDat);
mjr 87:8d35c74403af 318
mjr 87:8d35c74403af 319 // read the bit
mjr 87:8d35c74403af 320 bool bit = sdaPin.read();
mjr 87:8d35c74403af 321
mjr 87:8d35c74403af 322 // take the clock low again
mjr 87:8d35c74403af 323 sclLo();
mjr 87:8d35c74403af 324 hiResWait(tLow);
mjr 87:8d35c74403af 325
mjr 87:8d35c74403af 326 // return the bit
mjr 87:8d35c74403af 327 return bit;
mjr 87:8d35c74403af 328 }
mjr 82:4f6209cb5c33 329 }
mjr 87:8d35c74403af 330 while (t++ < 100000);
mjr 87:8d35c74403af 331
mjr 87:8d35c74403af 332 // we timed out
mjr 87:8d35c74403af 333 eprintf("i2c.readBit, clock stretching timeout\r\n");
mjr 87:8d35c74403af 334 return 0;
mjr 82:4f6209cb5c33 335 }