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