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