00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00082 #include <cfg/os.h>
00083 #include <cfg/twi.h>
00084 #include <cfg/arch/gpio.h>
00085
00086 #include <dev/twif.h>
00087
00088 #if defined(__arm__)
00089
00090 #include <arch/arm.h>
00091
00097 #if !defined(TWI_PIO_ID)
00098 #if defined(MCU_AT91SAM7X256) || defined(MCU_AT91SAM7S256)
00099 #define TWI_PIO_ID PIOA_ID
00100 #elif defined(MCU_AT91SAM9260)
00101 #define TWI_PIO_ID PIOB_ID
00102 #else
00103 #define TWI_PIO_ID PIO_ID
00104 #endif
00105 #endif
00106
00112 #ifndef TWI_SDA_BIT
00113 #if defined(MCU_AT91SAM9260)
00114 #define TWI_SDA_BIT 12
00115 #else
00116 #define TWI_SDA_BIT 10
00117 #endif
00118 #endif
00119
00123 #ifndef TWI_DELAY
00124 #if defined(MCU_AT91SAM9260)
00125 #define TWI_DELAY 16
00126 #else
00127 #define TWI_DELAY 8
00128 #endif
00129 #endif
00130
00136 #ifndef TWI_SCL_BIT
00137 #if defined(MCU_AT91SAM9260)
00138 #define TWI_SCL_BIT 13
00139 #else
00140 #define TWI_SCL_BIT 11
00141 #endif
00142 #endif
00143
00149 #if TWI_PIO_ID == PIOA_ID
00150
00151 #ifndef TWI_SDA_PE_REG
00152 #define TWI_SDA_PE_REG PIOA_PER
00153 #endif
00154 #ifndef TWI_SDA_OE_REG
00155 #define TWI_SDA_OE_REG PIOA_OER
00156 #endif
00157 #ifndef TWI_SDA_OD_REG
00158 #define TWI_SDA_OD_REG PIOA_ODR
00159 #endif
00160 #ifndef TWI_SDA_COD_REG
00161 #define TWI_SDA_COD_REG PIOA_CODR
00162 #endif
00163 #ifndef TWI_SDA_SOD_REG
00164 #define TWI_SDA_SOD_REG PIOA_SODR
00165 #endif
00166 #ifndef TWI_SDA_PDS_REG
00167 #define TWI_SDA_PDS_REG PIOA_PDSR
00168 #endif
00169
00170 #ifndef TWI_SCL_PE_REG
00171 #define TWI_SCL_PE_REG PIOA_PER
00172 #endif
00173 #ifndef TWI_SCL_OE_REG
00174 #define TWI_SCL_OE_REG PIOA_OER
00175 #endif
00176 #ifndef TWI_SCL_OD_REG
00177 #define TWI_SCL_OD_REG PIOA_ODR
00178 #endif
00179 #ifndef TWI_SCL_COD_REG
00180 #define TWI_SCL_COD_REG PIOA_CODR
00181 #endif
00182 #ifndef TWI_SCL_SOD_REG
00183 #define TWI_SCL_SOD_REG PIOA_SODR
00184 #endif
00185 #ifndef TWI_SCL_PDS_REG
00186 #define TWI_SCL_PDS_REG PIOA_PDSR
00187 #endif
00188
00189 #elif TWI_PIO_ID == PIOB_ID
00190
00191 #ifndef TWI_SDA_PE_REG
00192 #define TWI_SDA_PE_REG PIOB_PER
00193 #endif
00194 #ifndef TWI_SDA_OE_REG
00195 #define TWI_SDA_OE_REG PIOB_OER
00196 #endif
00197 #ifndef TWI_SDA_OD_REG
00198 #define TWI_SDA_OD_REG PIOB_ODR
00199 #endif
00200 #ifndef TWI_SDA_COD_REG
00201 #define TWI_SDA_COD_REG PIOB_CODR
00202 #endif
00203 #ifndef TWI_SDA_SOD_REG
00204 #define TWI_SDA_SOD_REG PIOB_SODR
00205 #endif
00206 #ifndef TWI_SDA_PDS_REG
00207 #define TWI_SDA_PDS_REG PIOB_PDSR
00208 #endif
00209
00210 #ifndef TWI_SCL_PE_REG
00211 #define TWI_SCL_PE_REG PIOB_PER
00212 #endif
00213 #ifndef TWI_SCL_OE_REG
00214 #define TWI_SCL_OE_REG PIOB_OER
00215 #endif
00216 #ifndef TWI_SCL_OD_REG
00217 #define TWI_SCL_OD_REG PIOB_ODR
00218 #endif
00219 #ifndef TWI_SCL_COD_REG
00220 #define TWI_SCL_COD_REG PIOB_CODR
00221 #endif
00222 #ifndef TWI_SCL_SOD_REG
00223 #define TWI_SCL_SOD_REG PIOB_SODR
00224 #endif
00225 #ifndef TWI_SCL_PDS_REG
00226 #define TWI_SCL_PDS_REG PIOB_PDSR
00227 #endif
00228
00229 #elif TWI_PIO_ID == PIOC_ID
00230
00231 #ifndef TWI_SDA_PE_REG
00232 #define TWI_SDA_PE_REG PIOC_PER
00233 #endif
00234 #ifndef TWI_SDA_OE_REG
00235 #define TWI_SDA_OE_REG PIOC_OER
00236 #endif
00237 #ifndef TWI_SDA_OD_REG
00238 #define TWI_SDA_OD_REG PIOC_ODR
00239 #endif
00240 #ifndef TWI_SDA_COD_REG
00241 #define TWI_SDA_COD_REG PIOC_CODR
00242 #endif
00243 #ifndef TWI_SDA_SOD_REG
00244 #define TWI_SDA_SOD_REG PIOC_SODR
00245 #endif
00246 #ifndef TWI_SDA_PDS_REG
00247 #define TWI_SDA_PDS_REG PIOC_PDSR
00248 #endif
00249
00250 #ifndef TWI_SCL_PE_REG
00251 #define TWI_SCL_PE_REG PIOC_PER
00252 #endif
00253 #ifndef TWI_SCL_OE_REG
00254 #define TWI_SCL_OE_REG PIOC_OER
00255 #endif
00256 #ifndef TWI_SCL_OD_REG
00257 #define TWI_SCL_OD_REG PIOC_ODR
00258 #endif
00259 #ifndef TWI_SCL_COD_REG
00260 #define TWI_SCL_COD_REG PIOC_CODR
00261 #endif
00262 #ifndef TWI_SCL_SOD_REG
00263 #define TWI_SCL_SOD_REG PIOC_SODR
00264 #endif
00265 #ifndef TWI_SCL_PDS_REG
00266 #define TWI_SCL_PDS_REG PIOC_PDSR
00267 #endif
00268
00269 #else
00270
00271 #ifndef TWI_SDA_PE_REG
00272 #define TWI_SDA_PE_REG PIO_PER
00273 #endif
00274 #ifndef TWI_SDA_OE_REG
00275 #define TWI_SDA_OE_REG PIO_OER
00276 #endif
00277 #ifndef TWI_SDA_OD_REG
00278 #define TWI_SDA_OD_REG PIO_ODR
00279 #endif
00280 #ifndef TWI_SDA_COD_REG
00281 #define TWI_SDA_COD_REG PIO_CODR
00282 #endif
00283 #ifndef TWI_SDA_SOD_REG
00284 #define TWI_SDA_SOD_REG PIO_SODR
00285 #endif
00286 #ifndef TWI_SDA_PDS_REG
00287 #define TWI_SDA_PDS_REG PIO_PDSR
00288 #endif
00289
00290 #ifndef TWI_SCL_PE_REG
00291 #define TWI_SCL_PE_REG PIO_PER
00292 #endif
00293 #ifndef TWI_SCL_OE_REG
00294 #define TWI_SCL_OE_REG PIO_OER
00295 #endif
00296 #ifndef TWI_SCL_OD_REG
00297 #define TWI_SCL_OD_REG PIO_ODR
00298 #endif
00299 #ifndef TWI_SCL_COD_REG
00300 #define TWI_SCL_COD_REG PIO_CODR
00301 #endif
00302 #ifndef TWI_SCL_SOD_REG
00303 #define TWI_SCL_SOD_REG PIO_SODR
00304 #endif
00305 #ifndef TWI_SCL_PDS_REG
00306 #define TWI_SCL_PDS_REG PIO_PDSR
00307 #endif
00308
00309 #endif
00310
00311 #define TWI_ENABLE() { \
00312 outr(TWI_SDA_COD_REG, _BV(TWI_SDA_BIT)); \
00313 outr(TWI_SCL_COD_REG, _BV(TWI_SCL_BIT)); \
00314 outr(TWI_SDA_PE_REG, _BV(TWI_SDA_BIT)); \
00315 outr(TWI_SCL_PE_REG, _BV(TWI_SCL_BIT)); \
00316 }
00317
00318 #define SDA_LOW() { \
00319 outr(TWI_SDA_COD_REG, _BV(TWI_SDA_BIT)); \
00320 outr(TWI_SDA_OE_REG, _BV(TWI_SDA_BIT)); \
00321 }
00322
00323 #define SDA_HIGH() { \
00324 outr(TWI_SDA_SOD_REG, _BV(TWI_SDA_BIT)); \
00325 outr(TWI_SDA_OD_REG, _BV(TWI_SDA_BIT)); \
00326 }
00327
00328 #define SDA_STAT() (inr(TWI_SDA_PDS_REG) & _BV(TWI_SDA_BIT))
00329
00330 #define SCL_LOW() { \
00331 outr(TWI_SCL_COD_REG, _BV(TWI_SCL_BIT)); \
00332 outr(TWI_SCL_OE_REG, _BV(TWI_SCL_BIT)); \
00333 }
00334
00335 #define SCL_HIGH() { \
00336 outr(TWI_SCL_SOD_REG, _BV(TWI_SCL_BIT)); \
00337 outr(TWI_SCL_OD_REG, _BV(TWI_SCL_BIT)); \
00338 }
00339
00340 #elif defined(__AVR__)
00341
00342
00343
00344
00345 #include <cfg/arch/avr.h>
00346
00347 #ifndef TWI_SDA_BIT
00348 #define TWI_SDA_BIT 0
00349 #endif
00350
00351 #if (TWI_SDA_AVRPORT == AVRPORTD)
00352 #define TWI_SDA_PORT PORTD
00353 #define TWI_SDA_PIN PIND
00354 #define TWI_SDA_DDR DDRD
00355 #elif (TWI_SDA_AVRPORT == AVRPORTE)
00356 #define TWI_SDA_PORT PORTE
00357 #define TWI_SDA_PIN PINE
00358 #define TWI_SDA_DDR DDRE
00359 #elif (TWI_SDA_AVRPORT == AVRPORTF)
00360 #define TWI_SDA_PORT PORTF
00361 #define TWI_SDA_PIN PINF
00362 #define TWI_SDA_DDR DDRF
00363 #else
00364 #define TWI_SDA_PORT PORTB
00365 #define TWI_SDA_PIN PINB
00366 #define TWI_SDA_DDR DDRB
00367 #endif
00368
00369 #ifndef TWI_SCL_BIT
00370 #define TWI_SCL_BIT 1
00371 #endif
00372
00373 #if (TWI_SCL_AVRPORT == AVRPORTD)
00374 #define TWI_SCL_PORT PORTD
00375 #define TWI_SCL_DDR DDRD
00376 #elif (TWI_SCL_AVRPORT == AVRPORTE)
00377 #define TWI_SCL_PORT PORTE
00378 #define TWI_SCL_DDR DDRE
00379 #elif (TWI_SCL_AVRPORT == AVRPORTF)
00380 #define TWI_SCL_PORT PORTF
00381 #define TWI_SCL_DDR DDRF
00382 #else
00383 #define TWI_SCL_PORT PORTB
00384 #define TWI_SCL_DDR DDRB
00385 #endif
00386
00387 #define TWI_ENABLE() { \
00388 cbi(TWI_SDA_PORT, TWI_SDA_BIT); \
00389 cbi(TWI_SCL_PORT, TWI_SCL_BIT); \
00390 }
00391
00392 #define SDA_LOW() sbi(TWI_SDA_DDR, TWI_SDA_BIT)
00393 #define SDA_HIGH() cbi(TWI_SDA_DDR, TWI_SDA_BIT)
00394 #define SDA_STAT() bit_is_set(TWI_SDA_PIN, TWI_SDA_BIT)
00395
00396 #define SCL_LOW() sbi(TWI_SCL_DDR, TWI_SCL_BIT)
00397 #define SCL_HIGH() cbi(TWI_SCL_DDR, TWI_SCL_BIT)
00398
00399 #ifndef TWI_DELAY
00400 #define TWI_DELAY 8
00401 #endif
00402
00403 #endif
00404
00405
00406 static u_char tw_mm_error;
00407 static int twibb_initialized;
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 static void TwDelay(int nops)
00418 {
00419 while (nops--) {
00420 _NOP();
00421 }
00422 }
00423
00424
00425
00426
00427
00428
00429
00430
00431 static void TwStart(void)
00432 {
00433 SDA_HIGH();
00434 TwDelay(TWI_DELAY);
00435 SCL_HIGH();
00436 TwDelay(TWI_DELAY);
00437 SDA_LOW();
00438 TwDelay(TWI_DELAY);
00439 SCL_LOW();
00440 TwDelay(TWI_DELAY);
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450 static void TwStop(void)
00451 {
00452 SDA_LOW();
00453 TwDelay(TWI_DELAY);
00454 SCL_HIGH();
00455 TwDelay(2 * TWI_DELAY);
00456 SDA_HIGH();
00457 TwDelay(8 * TWI_DELAY);
00458 }
00459
00460
00461
00462
00463
00464
00465
00466 static int TwPut(u_char octet)
00467 {
00468 int i;
00469
00470 for (i = 0x80; i; i >>= 1) {
00471
00472 if (octet & i) {
00473 SDA_HIGH();
00474 } else {
00475 SDA_LOW();
00476 }
00477
00478 TwDelay(TWI_DELAY);
00479
00480 SCL_HIGH();
00481 TwDelay(2 * TWI_DELAY);
00482 SCL_LOW();
00483 TwDelay(TWI_DELAY);
00484 }
00485
00486
00487 SDA_HIGH();
00488
00489
00490 SCL_HIGH();
00491 TwDelay(2 * TWI_DELAY);
00492 if (SDA_STAT()) {
00493 i = -1;
00494 } else {
00495 i = 0;
00496 }
00497 SCL_LOW();
00498
00499 return i;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 static u_char TwGet(void)
00509 {
00510 u_char rc = 0;
00511 int i;
00512
00513
00514 SDA_HIGH();
00515 TwDelay(TWI_DELAY);
00516 for (i = 0x80; i; i >>= 1) {
00517 TwDelay(TWI_DELAY);
00518
00519 SCL_HIGH();
00520 TwDelay(2 * TWI_DELAY);
00521
00522 if (SDA_STAT()) {
00523 rc |= i;
00524 }
00525 SCL_LOW();
00526 }
00527 return rc;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536 static void TwAck(void)
00537 {
00538 SDA_LOW();
00539 TwDelay(TWI_DELAY);
00540 SCL_HIGH();
00541 TwDelay(2 * TWI_DELAY);
00542 SCL_LOW();
00543 TwDelay(TWI_DELAY);
00544 SDA_HIGH();
00545 }
00546
00574 int TwMasterTransact(u_char sla, CONST void *txdata, u_short txlen, void *rxdata, u_short rxsiz, u_long tmo)
00575 {
00576 int rc = 0;
00577 u_char *cp;
00578
00579 if (!twibb_initialized) {
00580 TwInit(0);
00581 }
00582
00583 if (txlen) {
00584 TwStart();
00585
00586 if ((rc = TwPut(sla << 1)) == 0) {
00587 for (cp = (u_char *)txdata; txlen--; cp++) {
00588 if ((rc = TwPut(*cp)) != 0) {
00589 break;
00590 }
00591 }
00592 }
00593 }
00594 if (rc == 0 && rxsiz) {
00595 TwStart();
00596
00597 if ((rc = TwPut((sla << 1) | 1)) == 0) {
00598 for (cp = rxdata;; cp++) {
00599 *cp = TwGet();
00600 if (++rc >= rxsiz) {
00601 break;
00602 }
00603 TwAck();
00604 }
00605 }
00606 }
00607 TwStop();
00608
00609 if (rc == -1) {
00610 tw_mm_error = TWERR_SLA_NACK;
00611 }
00612 return rc;
00613 }
00614
00623 int TwMasterError(void)
00624 {
00625 int rc = (int) tw_mm_error;
00626 tw_mm_error = 0;
00627
00628 return rc;
00629 }
00630
00654 int TwSlaveListen(u_char * sla, void *rxdata, u_short rxsiz, u_long tmo)
00655 {
00656 return -1;
00657 }
00658
00677 int TwSlaveRespond(void *txdata, u_short txlen, u_long tmo)
00678 {
00679 return -1;
00680 }
00681
00693 int TwSlaveError(void)
00694 {
00695 return TWERR_BUS;
00696 }
00697
00710 int TwIOCtl(int req, void *conf)
00711 {
00712 return 0;
00713 }
00714
00730 int TwInit(u_char sla)
00731 {
00732 SDA_HIGH();
00733 SCL_HIGH();
00734 TWI_ENABLE();
00735 twibb_initialized = 1;
00736
00737 return 0;
00738 }