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