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