1 /* 2 * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. 3 * Copyright 2003, Thomas Kurschel. All Rights Reserved. 4 * Distributed under the terms of the MIT License. 5 */ 6 7 /*! 8 I2C protocol 9 */ 10 11 #include "i2c.h" 12 13 #include <KernelExport.h> 14 #include <OS.h> 15 16 17 //#define TRACE_I2C 18 #ifdef TRACE_I2C 19 extern "C" void _sPrintf(const char *format, ...); 20 # define TRACE(x...) _sPrintf("I2C: " x) 21 #else 22 # define TRACE(x...) ; 23 #endif 24 25 26 //! Timining for 100kHz bus (fractional parts are rounded up) 27 const static i2c_timing kTiming100k = { 28 buf : 5, 29 hd_sta : 4, 30 low : 5, 31 high : 4, 32 su_sta : 5, 33 hd_dat : 0, 34 su_dat : 1, 35 r : 1, 36 f : 1, 37 su_sto : 4, 38 39 // as these are unspecified, we use half a clock cycle as a safe guess 40 start_timeout : 5, 41 byte_timeout : 5, 42 bit_timeout : 5, 43 ack_start_timeout : 5, 44 ack_timeout : 5 45 }; 46 47 // timing for 400 kHz bus 48 // (argh! heavy up-rounding here) 49 const static i2c_timing kTiming400k = { 50 buf : 2, 51 hd_sta : 1, 52 low : 2, 53 high : 1, 54 su_sta : 1, 55 hd_dat : 0, 56 su_dat : 1, 57 r : 1, 58 f : 1, 59 su_sto : 1, 60 61 // see kTiming100k 62 start_timeout : 2, 63 byte_timeout : 2, 64 bit_timeout : 2, 65 ack_start_timeout : 2, 66 ack_timeout : 2 67 }; 68 69 70 /*! 71 There's no spin in user space, but we need it to wait a couple 72 of microseconds only 73 (in this case, snooze has much too much overhead) 74 */ 75 void 76 spin(bigtime_t delay) 77 { 78 bigtime_t startTime = system_time(); 79 80 while (system_time() - startTime < delay) 81 ; 82 } 83 84 85 //! Wait until slave releases clock signal ("clock stretching") 86 static status_t 87 wait_for_clk(const i2c_bus *bus, bigtime_t timeout) 88 { 89 bigtime_t startTime; 90 91 // wait for clock signal to raise 92 spin(bus->timing.r); 93 94 startTime = system_time(); 95 96 while (true) { 97 int clk, data; 98 99 bus->get_signals(bus->cookie, &clk, &data); 100 if (clk != 0) 101 return B_OK; 102 103 if (system_time() - startTime > timeout) 104 return B_TIMEOUT; 105 106 spin(bus->timing.r); 107 } 108 } 109 110 111 //! Send start or repeated start condition 112 static status_t 113 send_start_condition(const i2c_bus *bus) 114 { 115 status_t status; 116 117 bus->set_signals(bus->cookie, 1, 1); 118 119 status = wait_for_clk(bus, bus->timing.start_timeout); 120 if (status != B_OK) { 121 TRACE("send_start_condition(): Timeout sending start condition\n"); 122 return status; 123 } 124 125 spin(bus->timing.su_sta); 126 bus->set_signals(bus->cookie, 1, 0); 127 spin(bus->timing.hd_sta); 128 bus->set_signals(bus->cookie, 0, 0); 129 spin(bus->timing.f); 130 131 return B_OK; 132 } 133 134 135 //! Send stop condition 136 static status_t 137 send_stop_condition(const i2c_bus *bus) 138 { 139 status_t status; 140 141 bus->set_signals(bus->cookie, 0, 0); 142 spin(bus->timing.r); 143 bus->set_signals(bus->cookie, 1, 0); 144 145 // a slave may wait for us, so let elapse the acknowledge timeout 146 // to make the slave release bus control 147 status = wait_for_clk(bus, bus->timing.ack_timeout); 148 if (status != B_OK) { 149 TRACE("send_stop_condition(): Timeout sending stop condition\n"); 150 return status; 151 } 152 153 spin(bus->timing.su_sto); 154 bus->set_signals(bus->cookie, 1, 1); 155 spin(bus->timing.buf); 156 157 return B_OK; 158 } 159 160 161 //! Send one bit 162 static status_t 163 send_bit(const i2c_bus *bus, bool bit, int timeout) 164 { 165 status_t status; 166 167 //TRACE("send_bit(bit = %d)\n", bit & 1); 168 169 bus->set_signals(bus->cookie, 0, bit & 1); 170 spin(bus->timing.su_dat); 171 bus->set_signals(bus->cookie, 1, bit & 1); 172 173 status = wait_for_clk(bus, timeout); 174 if (status != B_OK) { 175 TRACE("send_bit(): Timeout when sending next bit\n"); 176 return status; 177 } 178 179 spin(bus->timing.high); 180 bus->set_signals(bus->cookie, 0, bit & 1); 181 spin(bus->timing.f + bus->timing.low); 182 183 return B_OK; 184 } 185 186 187 //! Send acknowledge and wait for reply 188 static status_t 189 send_acknowledge(const i2c_bus *bus) 190 { 191 status_t status; 192 bigtime_t startTime; 193 194 // release data so slave can modify it 195 bus->set_signals(bus->cookie, 0, 1); 196 spin(bus->timing.su_dat); 197 bus->set_signals(bus->cookie, 1, 1); 198 199 status = wait_for_clk(bus, bus->timing.ack_start_timeout); 200 if (status != B_OK) { 201 TRACE("send_acknowledge(): Timeout when sending acknowledge\n"); 202 return status; 203 } 204 205 // data and clock is high, now wait for slave to pull data low 206 // (according to spec, this can happen any time once clock is high) 207 startTime = system_time(); 208 209 while (true) { 210 int clk, data; 211 212 bus->get_signals(bus->cookie, &clk, &data); 213 214 if (data == 0) 215 break; 216 217 if (system_time() - startTime > bus->timing.ack_timeout) { 218 TRACE("send_acknowledge(): Slave didn't acknowledge byte\n"); 219 return B_TIMEOUT; 220 } 221 222 spin(bus->timing.r); 223 } 224 225 TRACE("send_acknowledge(): Success!\n"); 226 227 // make sure we've waited at least t_high 228 spin(bus->timing.high); 229 230 bus->set_signals(bus->cookie, 0, 1); 231 spin(bus->timing.f + bus->timing.low); 232 233 return B_OK; 234 } 235 236 237 //! Send byte and wait for acknowledge if <ackowledge> is true 238 static status_t 239 send_byte(const i2c_bus *bus, uint8 byte, bool acknowledge) 240 { 241 int i; 242 243 //TRACE("send_byte(byte = %x)\n", byte); 244 245 for (i = 7; i >= 0; --i) { 246 status_t status = send_bit(bus, byte >> i, 247 i == 7 ? bus->timing.byte_timeout : bus->timing.bit_timeout); 248 if (status != B_OK) 249 return status; 250 } 251 252 if (acknowledge) 253 return send_acknowledge(bus); 254 255 return B_OK; 256 } 257 258 259 //! Send slave address, obeying 10-bit addresses and general call addresses 260 static status_t 261 send_slave_address(const i2c_bus *bus, int slaveAddress, bool isWrite) 262 { 263 status_t status; 264 265 status = send_byte(bus, (slaveAddress & 0xfe) | !isWrite, true); 266 if (status != B_OK) 267 return status; 268 269 // there are the following special cases if the first byte looks like: 270 // - 0000 0000 - general call address (second byte with address follows) 271 // - 0000 0001 - start byte 272 // - 0000 001x - CBus address 273 // - 0000 010x - address reserved for different bus format 274 // - 0000 011x | 275 // - 0000 1xxx |-> reserved 276 // - 1111 1xxx | 277 // - 1111 0xxx - 10 bit address (second byte contains remaining 8 bits) 278 279 // the lsb is 0 for write and 1 for read (except for general call address) 280 if ((slaveAddress & 0xff) != 0 && (slaveAddress & 0xf8) != 0xf0) 281 return B_OK; 282 283 return send_byte(bus, slaveAddress >> 8, true); 284 // send second byte if required 285 } 286 287 288 //! Receive one bit 289 static status_t 290 receive_bit(const i2c_bus *bus, bool *bit, int timeout) 291 { 292 status_t status; 293 int clk, data; 294 295 bus->set_signals(bus->cookie, 1, 1); 296 // release clock 297 298 // wait for slave to raise clock 299 status = wait_for_clk(bus, timeout); 300 if (status != B_OK) { 301 TRACE("receive_bit(): Timeout waiting for bit sent by slave\n"); 302 return status; 303 } 304 305 bus->get_signals(bus->cookie, &clk, &data); 306 // sample data 307 308 spin(bus->timing.high); 309 // leave clock high for minimal time 310 311 bus->set_signals(bus->cookie, 0, 1); 312 // pull clock low so slave waits for us before next bit 313 314 spin(bus->timing.f + bus->timing.low); 315 // let it settle and leave it low for minimal time 316 // to make sure slave has finished bit transmission too 317 318 *bit = data; 319 return B_OK; 320 } 321 322 323 /*! 324 Send positive acknowledge afterwards if <acknowledge> is true, 325 else send negative one 326 */ 327 static status_t 328 receive_byte(const i2c_bus *bus, uint8 *resultByte, bool acknowledge) 329 { 330 uint8 byte = 0; 331 int i; 332 333 // pull clock low to let slave wait for us 334 bus->set_signals(bus->cookie, 0, 1); 335 336 for (i = 7; i >= 0; i--) { 337 bool bit; 338 339 status_t status = receive_bit(bus, &bit, 340 i == 7 ? bus->timing.byte_timeout : bus->timing.bit_timeout); 341 if (status != B_OK) 342 return status; 343 344 byte = (byte << 1) | bit; 345 } 346 347 //SHOW_FLOW(3, "%x ", byte); 348 349 *resultByte = byte; 350 351 return send_bit(bus, acknowledge ? 0 : 1, bus->timing.bit_timeout); 352 } 353 354 355 //! Send multiple bytes 356 static status_t 357 send_bytes(const i2c_bus *bus, const uint8 *writeBuffer, ssize_t writeLength) 358 { 359 TRACE("send_bytes(length = %ld)\n", writeLength); 360 361 for (; writeLength > 0; --writeLength, ++writeBuffer) { 362 status_t status = send_byte(bus, *writeBuffer, true); 363 if (status != B_OK) 364 return status; 365 } 366 367 return B_OK; 368 } 369 370 371 //! Receive multiple bytes 372 static status_t 373 receive_bytes(const i2c_bus *bus, uint8 *readBuffer, ssize_t readLength) 374 { 375 TRACE("receive_bytes(length = %ld)\n", writeLength); 376 377 for (; readLength > 0; --readLength, ++readBuffer) { 378 status_t status = receive_byte(bus, readBuffer, readLength > 1); 379 if (status != B_OK) 380 return status; 381 } 382 383 return B_OK; 384 } 385 386 387 // #pragma mark - exported functions 388 389 390 //! Combined i2c send+receive format 391 status_t 392 i2c_send_receive(const i2c_bus *bus, int slaveAddress, const uint8 *writeBuffer, 393 size_t writeLength, uint8 *readBuffer, size_t readLength) 394 { 395 status_t status = send_start_condition(bus); 396 if (status != B_OK) 397 return status; 398 399 status = send_slave_address(bus, slaveAddress, true); 400 if (status != B_OK) 401 goto err; 402 403 status = send_bytes(bus, writeBuffer, writeLength); 404 if (status != B_OK) 405 goto err; 406 407 status = send_start_condition(bus); 408 if (status != B_OK) 409 return status; 410 411 status = send_slave_address(bus, slaveAddress, false); 412 if (status != B_OK) 413 goto err; 414 415 status = receive_bytes(bus, readBuffer, readLength); 416 if (status != B_OK) 417 goto err; 418 419 return send_stop_condition(bus); 420 421 err: 422 TRACE("i2c_send_receive(): Cancelling transmission\n"); 423 send_stop_condition(bus); 424 return status; 425 } 426 427 428 void 429 i2c_get100k_timing(i2c_timing *timing) 430 { 431 *timing = kTiming100k; 432 } 433 434 435 void 436 i2c_get400k_timing(i2c_timing *timing) 437 { 438 *timing = kTiming400k; 439 } 440