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