Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
BitBangI2C/BitBangI2C.cpp@87:8d35c74403af, 2017-05-09 (annotated)
- Committer:
- mjr
- Date:
- Tue May 09 05:48:37 2017 +0000
- Revision:
- 87:8d35c74403af
- Parent:
- 86:e30a1f60f783
AEDR-8300, VL6180X, TLC59116; new plunger firing detection
Who changed what in which revision?
User | Revision | Line number | New 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 | } |