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