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
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include <stdio.h>
00056
00057 #include <cfg/arch.h>
00058 #include <dev/board.h>
00059 #include <dev/irqreg.h>
00060
00061 #include <sys/event.h>
00062 #include <sys/timer.h>
00063
00064 #include <dev/at91_spi.h>
00065
00066 static HANDLE spi0_que;
00067 #if defined (SPI1_BASE)
00068 static HANDLE spi1_que;
00069 #endif
00070
00076 static void At91Spi0Interrupt(void *arg)
00077 {
00078 NutEventPostFromIrq(&spi0_que);
00079 }
00080
00084 int At91Spi0Init(void)
00085 {
00086
00087 At91Spi0Enable();
00088
00089 outr(PMC_PCER, _BV(SPI0_ID));
00090
00091
00092 NutRegisterIrqHandler(&sig_SPI0, At91Spi0Interrupt, 0);
00093 NutIrqEnable(&sig_SPI0);
00094
00095 return At91SpiReset(SPI0_BASE);
00096 }
00097
00107 int At91Spi0InitChipSelects(u_int mask)
00108 {
00109 if (mask & _BV(0)) {
00110 #if defined(SPI0_CS0_PIN)
00111 outr(SPI0_CS0_PIO_BASE + SPI0_CS0_PSR_OFF, SPI0_CS0_PIN);
00112 outr(SPI0_CS0_PIO_BASE + PIO_PDR_OFF, SPI0_CS0_PIN);
00113 mask &= ~_BV(0);
00114 #endif
00115 }
00116 if (mask & _BV(1)) {
00117 #if defined(SPI0_CS1_PIN)
00118 outr(SPI0_CS1_PIO_BASE + SPI0_CS1_PSR_OFF, SPI0_CS1_PIN);
00119 outr(SPI0_CS1_PIO_BASE + PIO_PDR_OFF, SPI0_CS1_PIN);
00120 mask &= ~_BV(1);
00121 #endif
00122 }
00123 if (mask & _BV(2)) {
00124 #if defined(SPI0_CS2_PIN)
00125 outr(SPI0_CS2_PIO_BASE + SPI0_CS2_PSR_OFF, SPI0_CS2_PIN);
00126 outr(SPI0_CS2_PIO_BASE + PIO_PDR_OFF, SPI0_CS2_PIN);
00127 mask &= ~_BV(2);
00128 #endif
00129 }
00130 if (mask & _BV(3)) {
00131 #if defined(SPI0_CS3_PIN)
00132 outr(SPI0_CS3_PIO_BASE + SPI0_CS3_PSR_OFF, SPI0_CS3_PIN);
00133 outr(SPI0_CS3_PIO_BASE + PIO_PDR_OFF, SPI0_CS3_PIN);
00134 mask &= ~_BV(3);
00135 #endif
00136 }
00137 return mask ? -1 : 0;
00138 }
00139
00143 int At91Spi0Enable(void)
00144 {
00145
00146 outr(SPI0_PIO_BASE + SPI0_PSR_OFF, SPI0_PINS);
00147 outr(SPI0_PIO_BASE + PIO_PDR_OFF, SPI0_PINS);
00148
00149 return 0;
00150 }
00151
00152 #if defined(SPI1_BASE)
00153
00159 static void At91Spi1Interrupt(void *arg)
00160 {
00161 NutEventPostFromIrq(&spi1_que);
00162 }
00163
00167 int At91Spi1Init(void)
00168 {
00169
00170 At91Spi1Enable();
00171
00172 outr(PMC_PCER, _BV(SPI1_ID));
00173
00174
00175 NutRegisterIrqHandler(&sig_SPI1, At91Spi1Interrupt, 0);
00176 NutIrqEnable(&sig_SPI1);
00177
00178 return At91SpiReset(SPI1_BASE);
00179 }
00180
00190 int At91Spi1InitChipSelects(u_int mask)
00191 {
00192 #if defined(SPI1_CS0_PIN)
00193 if (mask & _BV(0)) {
00194 outr(SPI1_CS0_PIO_BASE + SPI1_CS0_PSR_OFF, SPI1_CS0_PIN);
00195 outr(SPI1_CS0_PIO_BASE + PIO_PDR_OFF, SPI1_CS0_PIN);
00196 mask &= ~_BV(0);
00197 }
00198 #endif
00199 #if defined(SPI1_CS1_PIN)
00200 if (mask & _BV(1)) {
00201 outr(SPI1_CS1_PIO_BASE + SPI1_CS1_PSR_OFF, SPI1_CS1_PIN);
00202 outr(SPI1_CS1_PIO_BASE + PIO_PDR_OFF, SPI1_CS1_PIN);
00203 mask &= ~_BV(1);
00204 }
00205 #endif
00206 #if defined(SPI1_CS2_PIN)
00207 if (mask & _BV(2)) {
00208 outr(SPI1_CS2_PIO_BASE + SPI1_CS2_PSR_OFF, SPI1_CS2_PIN);
00209 outr(SPI1_CS2_PIO_BASE + PIO_PDR_OFF, SPI1_CS2_PIN);
00210 mask &= ~_BV(2);
00211 }
00212 #endif
00213 #if defined(SPI1_CS3_PIN)
00214 if (mask & _BV(3)) {
00215 outr(SPI1_CS3_PIO_BASE + SPI1_CS3_PSR_OFF, SPI1_CS3_PIN);
00216 outr(SPI1_CS3_PIO_BASE + PIO_PDR_OFF, SPI1_CS3_PIN);
00217 mask &= ~_BV(3);
00218 }
00219 #endif
00220 return mask ? -1 : 0;
00221 }
00222
00226 int At91Spi1Enable(void)
00227 {
00228
00229 outr(SPI1_PIO_BASE + SPI1_PSR_OFF, SPI1_PINS);
00230 outr(SPI1_PIO_BASE + PIO_PDR_OFF, SPI1_PINS);
00231
00232 return 0;
00233 }
00234
00235 #endif
00236
00245 int At91SpiInit(u_int base)
00246 {
00247 int rc = -1;
00248
00249
00250
00251
00252 if (base == SPI0_BASE) {
00253 rc = At91Spi0Init();
00254 }
00255 #if defined(SPI1_BASE)
00256 if (base == SPI1_BASE) {
00257 rc = At91Spi1Init();
00258 }
00259 #endif
00260 return rc;
00261 }
00262
00263 int At91SpiEnable(u_int base)
00264 {
00265 outr(base + SPI_CR_OFF, SPI_SPIEN);
00266
00267 return 0;
00268 }
00269
00270 int At91SpiDisable(u_int base)
00271 {
00272 outr(base + SPI_CR_OFF, SPI_SPIDIS);
00273
00274 return 0;
00275 }
00276
00285 int At91SpiReset(u_int base)
00286 {
00287 int rc = -1;
00288
00289
00290 At91SpiDisable(base);
00291
00292
00293 outr(base + SPI_CR_OFF, SPI_SWRST);
00294
00295
00296 outr(base + SPI_MR_OFF, (90 << SPI_DLYBCS_LSB) | SPI_PCS | SPI_MODFDIS | SPI_MSTR);
00297
00298
00299 At91SpiEnable(base);
00300
00301 return rc;
00302 }
00303
00315 int At91SpiInitChipSelects(u_int base, u_int mask)
00316 {
00317 int rc = -1;
00318
00319
00320 if (base == SPI0_BASE) {
00321 rc = At91Spi0InitChipSelects(mask);
00322 }
00323
00324 #if defined(SPI1_BASE)
00325 if (base == SPI1_BASE) {
00326 rc = At91Spi1InitChipSelects(mask);
00327 }
00328 #endif
00329 return rc;
00330 }
00331
00341 int At91SpiSetRate(u_int base, u_int cs, uint32_t rate)
00342 {
00343 int rc = 0;
00344 u_int divider;
00345
00346
00347 divider = (u_int) At91GetMasterClock();
00348
00349 divider += (u_int) (rate / 2);
00350 divider /= rate;
00351
00352 if (divider < 1) {
00353 divider = 1;
00354 }
00355
00356 else if (divider > 255) {
00357 divider = 255;
00358 }
00359 switch (cs) {
00360 case 0:
00361 outr(base + SPI_CSR0_OFF, (inr(base + SPI_CSR0_OFF) & ~SPI_SCBR) | (divider << SPI_SCBR_LSB));
00362 break;
00363 case 1:
00364 outr(base + SPI_CSR1_OFF, (inr(base + SPI_CSR1_OFF) & ~SPI_SCBR) | (divider << SPI_SCBR_LSB));
00365 break;
00366 case 2:
00367 outr(base + SPI_CSR2_OFF, (inr(base + SPI_CSR2_OFF) & ~SPI_SCBR) | (divider << SPI_SCBR_LSB));
00368 break;
00369 case 3:
00370 outr(base + SPI_CSR3_OFF, (inr(base + SPI_CSR3_OFF) & ~SPI_SCBR) | (divider << SPI_SCBR_LSB));
00371 break;
00372 default:
00373 rc = -1;
00374 break;
00375 }
00376 return 0;
00377 }
00378
00379 uint32_t At91SpiGetModeFlags(u_int base, u_int cs)
00380 {
00381 uint32_t rc = SPIMF_MFDETECT;
00382 u_int mv = inr(base + SPI_MR_OFF);
00383
00384 if (mv & SPI_MSTR) {
00385 rc |= SPI_MSTR;
00386 }
00387 if (mv & SPI_PCSDEC) {
00388 rc |= SPIMF_MASTER;
00389 }
00390 if (mv & SPI_MODFDIS) {
00391 rc &= ~SPIMF_MFDETECT;
00392 }
00393 if (mv & SPI_LLB) {
00394 rc |= SPIMF_LOOPBACK;
00395 }
00396
00397 mv = inr(base + SPI_CSR0_OFF + cs * 4);
00398 if (mv & SPI_CPOL) {
00399 if (mv & SPI_NCPHA) {
00400 rc |= SPIMF_SCKIAHI;
00401 } else {
00402 rc |= SPIMF_SCKIAHI | SPIMF_CAPRISE;
00403 }
00404 } else if (mv & SPI_NCPHA) {
00405 rc |= SPIMF_CAPRISE;
00406 }
00407 return rc;
00408 }
00409
00424 int At91SpiSetModeFlags(u_int base, u_int cs, uint32_t mode)
00425 {
00426 u_int mv;
00427
00428 mv = inr(base + SPI_MR_OFF) & ~(SPI_MSTR | SPI_PCSDEC | SPI_MODFDIS | SPI_LLB);
00429 if (mode & SPIMF_MASTER) {
00430 mv |= SPI_MSTR;
00431 }
00432 if (mode & SPIMF_PCSDEC) {
00433 mv |= SPI_PCSDEC;
00434 }
00435 if (mode & SPIMF_MFDETECT) {
00436 mv &= ~SPI_MODFDIS;
00437 }
00438 if (mode & SPIMF_LOOPBACK) {
00439 mv |= SPI_LLB;
00440 }
00441 outr(base + SPI_MR_OFF, mv);
00442
00443 mv = inr(base + SPI_CSR0_OFF + cs * 4) & ~(SPI_CPOL | SPI_NCPHA | SPI_CSAAT);
00444 if (mode & SPIMF_SCKIAHI) {
00445 if (mode & SPIMF_CAPRISE) {
00446 mv |= SPI_CPOL;
00447 } else {
00448 mv |= SPI_CPOL | SPI_NCPHA;
00449 }
00450 } else {
00451 if (mode & SPIMF_CAPRISE) {
00452 mv |= SPI_NCPHA;
00453 }
00454 }
00455 if (mode & SPIMF_KEEPCS) {
00456 mv |= SPI_CSAAT;
00457 }
00458 outr(base + SPI_CSR0_OFF + cs * 4, mv);
00459
00460 if (At91SpiGetModeFlags(base, cs) != mode) {
00461 return -1;
00462 }
00463 return 0;
00464 }
00465
00466 u_int At91SpiGetBits(u_int base, u_int cs)
00467 {
00468 u_int rc;
00469
00470 switch (inr(base + SPI_CSR0_OFF + cs * 4) & SPI_BITS) {
00471 case SPI_BITS_9:
00472 rc = 9;
00473 break;
00474 case SPI_BITS_10:
00475 rc = 10;
00476 break;
00477 case SPI_BITS_11:
00478 rc = 11;
00479 break;
00480 case SPI_BITS_12:
00481 rc = 12;
00482 break;
00483 case SPI_BITS_13:
00484 rc = 13;
00485 break;
00486 case SPI_BITS_14:
00487 rc = 14;
00488 break;
00489 case SPI_BITS_15:
00490 rc = 15;
00491 break;
00492 case SPI_BITS_16:
00493 rc = 16;
00494 break;
00495 default:
00496 rc = 8;
00497 break;
00498 }
00499 return rc;
00500 }
00501
00502 int At91SpiSetBits(u_int base, u_int cs, u_int bits)
00503 {
00504 u_int mv;
00505
00506 mv = inr(base + SPI_CSR0_OFF + cs * 4) & ~SPI_BITS;
00507 switch (bits) {
00508 case 9:
00509 mv |= SPI_BITS_9;
00510 break;
00511 case 10:
00512 mv |= SPI_BITS_10;
00513 break;
00514 case 11:
00515 mv |= SPI_BITS_11;
00516 break;
00517 case 12:
00518 mv |= SPI_BITS_12;
00519 break;
00520 case 13:
00521 mv |= SPI_BITS_13;
00522 break;
00523 case 14:
00524 mv |= SPI_BITS_14;
00525 break;
00526 case 15:
00527 mv |= SPI_BITS_15;
00528 break;
00529 case 16:
00530 mv |= SPI_BITS_16;
00531 break;
00532 default:
00533 mv |= SPI_BITS_8;
00534 break;
00535 }
00536 outr(base + SPI_CSR0_OFF + cs * 4, mv);
00537
00538 if (At91SpiGetBits(base, cs) != bits) {
00539 return -1;
00540 }
00541 return 0;
00542 }
00543
00544 u_int At91SpiGetSckDelay(u_int base, u_int cs)
00545 {
00546 return (inr(base + SPI_CSR0_OFF + cs * 4) & ~SPI_DLYBS) >> SPI_DLYBS_LSB;
00547 }
00548
00549 int At91SpiSetSckDelay(u_int base, u_int cs, u_int dly)
00550 {
00551 u_int csr = base + SPI_CSR0_OFF + cs * 4;
00552
00553 outr(csr, (inr(csr) & ~SPI_DLYBS) | ((dly << SPI_DLYBS_LSB) & SPI_DLYBS));
00554
00555 if (At91SpiGetSckDelay(base, cs) != dly) {
00556 return -1;
00557 }
00558 return 0;
00559 }
00560
00561 u_int At91SpiGetTxDelay(u_int base, u_int cs)
00562 {
00563 return (inr(base + SPI_CSR0_OFF + cs * 4) & ~SPI_DLYBCT) >> SPI_DLYBCT_LSB;
00564 }
00565
00566 int At91SpiSetTxDelay(u_int base, u_int cs, u_int dly)
00567 {
00568 u_int csr = base + SPI_CSR0_OFF + cs * 4;
00569
00570 outr(csr, (inr(csr) & ~SPI_DLYBCT) | ((dly << SPI_DLYBCT_LSB) & SPI_DLYBCT));
00571
00572 if (At91SpiGetTxDelay(base, cs) != dly) {
00573 return -1;
00574 }
00575 return 0;
00576 }
00577
00578 u_int At91SpiGetCsDelay(u_int base)
00579 {
00580 return (inr(base + SPI_MR_OFF) & ~SPI_DLYBCS) >> SPI_DLYBCS_LSB;
00581 }
00582
00583 int At91SpiSetCsDelay(u_int base, u_int dly)
00584 {
00585 outr(base + SPI_MR_OFF, (inr(base + SPI_MR_OFF) & ~SPI_DLYBCS) | ((dly << SPI_DLYBCS_LSB) & SPI_DLYBCS));
00586
00587 if (At91SpiGetCsDelay(base) != dly) {
00588 return -1;
00589 }
00590 return 0;
00591 }
00592
00605 int At91SpiTransfer2(u_int base, u_int cs, CONST void *txbuf, void *rxbuf, int xlen, CONST void *txnbuf, void *rxnbuf, int xnlen)
00606 {
00607 int rc = -1;
00608 u_int flags;
00609 u_int sr;
00610
00611 outr(base + PERIPH_PTCR_OFF, PDC_TXTDIS | PDC_RXTDIS);
00612
00613 flags = inr(base + SPI_MR_OFF) & ~SPI_PCS;
00614 switch (cs) {
00615 case 0:
00616 flags |= SPI_PCS_0;
00617 break;
00618 case 1:
00619 flags |= SPI_PCS_1;
00620 break;
00621 case 2:
00622 flags |= SPI_PCS_2;
00623 break;
00624 case 3:
00625 flags |= SPI_PCS_3;
00626 break;
00627 }
00628 outr(base + SPI_MR_OFF, flags);
00629
00630
00631 outr(base + PERIPH_TPR_OFF, (u_int) txbuf);
00632 outr(base + PERIPH_TCR_OFF, (u_int) xlen);
00633
00634 outr(base + PERIPH_RPR_OFF, (u_int) rxbuf);
00635 outr(base + PERIPH_RCR_OFF, (u_int) xlen);
00636
00637
00638 outr(base + PERIPH_TNPR_OFF, (u_int) txnbuf);
00639 outr(base + PERIPH_TNCR_OFF, (u_int) xnlen);
00640
00641
00642 outr(base + PERIPH_RNPR_OFF, (u_int) rxnbuf);
00643 outr(base + PERIPH_RNCR_OFF, (u_int) xnlen);
00644
00645 outr(base + SPI_IDR_OFF, (u_int) - 1);
00646 outr(base + SPI_IER_OFF, SPI_RXBUFF);
00647 outr(base + PERIPH_PTCR_OFF, PDC_TXTEN | PDC_RXTEN);
00648
00649 while (((sr = inr(base + SPI_SR_OFF)) & SPI_RXBUFF) == 0) {
00650 if (base == SPI0_BASE) {
00651 if ((rc = NutEventWait(&spi0_que, 500)) != 0) {
00652 printf("[TO]");
00653 break;
00654 }
00655 }
00656 #if defined(SPI1_BASE)
00657 else if (base == SPI1_BASE) {
00658 if ((rc = NutEventWait(&spi1_que, 500)) != 0) {
00659 break;
00660 }
00661 }
00662 #endif
00663 }
00664 outr(base + PERIPH_PTCR_OFF, PDC_TXTDIS | PDC_RXTDIS);
00665
00666 return rc;
00667 }