00001
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 #include "spi.h"
00049
00050 int getBaudDiv(struct spi_options_t * options, int cpuHz);
00051
00052
00057 void spi_reset(volatile avr32_spi_t *spi)
00058 {
00059 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00060 }
00061
00062
00073 int spi_initSlave(volatile avr32_spi_t *spi,
00074 unsigned char bits,
00075 unsigned char spi_mode)
00076 {
00077
00078 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00079
00080
00081
00082 if (bits > 16 || bits < 8) {
00083 return SPI_ERROR_ARGUMENT;
00084 }
00085
00086 spi->csr0 = (bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET;
00087
00088 switch (spi_mode) {
00089 case 0:
00090 spi->csr0 |= (1 << AVR32_SPI_CSR0_NCPHA_OFFSET);
00091 case 1:
00092 break;
00093 case 2:
00094 spi->csr0 |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00095 case 3:
00096 spi->csr0 |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
00097 break;
00098 default:
00099 return SPI_ERROR_ARGUMENT;
00100 }
00101
00102 return SPI_OK;
00103 }
00104
00105
00114 int spi_initTest(volatile avr32_spi_t *spi)
00115 {
00116
00117 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00118
00119 spi->mr |= AVR32_SPI_MR_MSTR_MASK;
00120
00121 spi->mr |= AVR32_SPI_MR_LLB_MASK;
00122
00123 return SPI_OK;
00124 }
00125
00126
00136 int spi_initMaster(volatile avr32_spi_t *spi, struct spi_options_t *options)
00137 {
00138 if (options->modfdis > 1 || options->fdiv > 1) {
00139 return SPI_ERROR_ARGUMENT;
00140 }
00141
00142
00143 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00144
00145
00146 spi->mr = AVR32_SPI_MR_MSTR_MASK|
00147 AVR32_SPI_MR_PCS_MASK|
00148 (options->fdiv<<AVR32_SPI_MR_FDIV_OFFSET)|
00149 (options->modfdis<<AVR32_SPI_MR_MODFDIS_OFFSET);
00150
00151 return SPI_OK;
00152 }
00153
00154
00168 int spi_selectionMode(volatile avr32_spi_t *spi,
00169 unsigned char variable_ps,
00170 unsigned char pcs_decode,
00171 unsigned char delay)
00172 {
00173 if (variable_ps > 1 || pcs_decode > 1) {
00174 return SPI_ERROR_ARGUMENT;
00175 }
00176
00177
00178 spi->mr &= ~(AVR32_SPI_MR_PS_MASK|
00179 AVR32_SPI_MR_PCSDEC_MASK|
00180 AVR32_SPI_MR_DLYBCS_MASK);
00181
00182 spi->mr |=
00183 (variable_ps<<AVR32_SPI_MR_PS_OFFSET)|
00184 (pcs_decode<<AVR32_SPI_MR_PCSDEC_OFFSET)|
00185 (delay<<AVR32_SPI_MR_DLYBCS_OFFSET);
00186
00187 return SPI_OK;
00188 }
00189
00190
00201 int spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip)
00202 {
00203
00204 spi->mr |= AVR32_SPI_MR_PCS_MASK;
00205
00206 if ((spi->mr & AVR32_SPI_MR_PCSDEC_MASK) != 0) {
00207
00208 if (chip > 14) {
00209 return SPI_ERROR_ARGUMENT;
00210 }
00211
00212 spi->mr = (spi->mr & ~AVR32_SPI_MR_PCS_MASK)|
00213 (chip << AVR32_SPI_MR_PCS_OFFSET);
00214 } else {
00215 if (chip > 3) {
00216 return SPI_ERROR_ARGUMENT;
00217 }
00218
00219 spi->mr &= ~(1<<(AVR32_SPI_MR_PCS_OFFSET + chip));
00220 }
00221
00222 return SPI_OK;
00223 }
00224
00225
00235 int spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip)
00236 {
00237
00238 spi->mr |= AVR32_SPI_MR_PCS_MASK;
00239
00240
00241 spi->cr = AVR32_SPI_CR_LASTXFER_MASK;
00242
00243 return SPI_OK;
00244 }
00245
00246
00261 int spi_setupChipReg(volatile avr32_spi_t *spi,
00262 struct spi_options_t *options,
00263 unsigned int cpuHz)
00264 {
00265 int baudDiv = -1;
00266 unsigned long csr = 0;
00267
00268 if (options->bits > 16 || options->bits < 8 || options->stay_act > 1) {
00269 return SPI_ERROR_ARGUMENT;
00270 }
00271
00272 baudDiv = getBaudDiv(options, cpuHz);
00273
00274 if (baudDiv < 0) {
00275 return -baudDiv;
00276 }
00277
00278
00279 csr = ((options->bits - 8)<<AVR32_SPI_CSR0_BITS_OFFSET)|
00280 (baudDiv<<AVR32_SPI_CSR0_SCBR_OFFSET)|
00281 (options->spck_delay<<AVR32_SPI_CSR0_DLYBS_OFFSET)|
00282 (options->trans_delay<<AVR32_SPI_CSR0_DLYBCT_OFFSET)|
00283 (options->stay_act<<AVR32_SPI_CSR0_CSAAT_OFFSET);
00284
00285 switch (options->spi_mode) {
00286 case 0:
00287 csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00288 case 1:
00289 break;
00290 case 2:
00291 csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00292 case 3:
00293 csr |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
00294 break;
00295 default:
00296 return SPI_ERROR_ARGUMENT;
00297 }
00298
00299 switch (options->reg) {
00300 case 0:
00301 spi->csr0 = csr;
00302 break;
00303 case 1:
00304 spi->csr1 = csr;
00305 break;
00306 case 2:
00307 spi->csr2 = csr;
00308 break;
00309 case 3:
00310 spi->csr3 = csr;
00311 break;
00312 default:
00313 return SPI_ERROR_ARGUMENT;
00314 }
00315
00316 return SPI_OK;
00317 }
00318
00319
00326 void spi_enable(volatile avr32_spi_t *spi)
00327 {
00328 spi->cr = AVR32_SPI_CR_SPIEN_MASK;
00329 }
00330
00331
00339 void spi_disable(volatile avr32_spi_t *spi)
00340 {
00341 spi->cr = AVR32_SPI_CR_SPIDIS_MASK;
00342 }
00343
00344
00355 int spi_write(volatile avr32_spi_t *spi, unsigned short data)
00356 {
00357 unsigned int timeout = SPI_TIMEOUT;
00358
00359 while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && timeout > 0) {
00360 --timeout;
00361 }
00362
00363 if (timeout == 0) {
00364 return SPI_ERROR_TIMEOUT;
00365 }
00366
00367 spi->tdr = data & 0x0000FFFF;
00368
00369 return SPI_OK;
00370 }
00371
00372
00390 int spi_variableSlaveWrite(volatile avr32_spi_t *spi, unsigned short data,
00391 unsigned char pcs, unsigned char lastxfer)
00392 {
00393 unsigned int timeout = SPI_TIMEOUT;
00394
00395 if (pcs > 14 || lastxfer > 1)
00396 return SPI_ERROR_ARGUMENT;
00397
00398 while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && --timeout) {
00399 }
00400
00401 if (timeout == 0) {
00402 return SPI_ERROR_TIMEOUT;
00403 }
00404
00405 spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
00406 (pcs << AVR32_SPI_TDR_PCS_OFFSET) |
00407 (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
00408
00409 return SPI_OK;
00410 }
00411
00420 unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t * spi)
00421 {
00422 if ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0) {
00423 return 1;
00424 } else {
00425 return 0;
00426 }
00427 }
00428
00429
00440 int spi_read(volatile avr32_spi_t *spi, unsigned short *data)
00441 {
00442 unsigned int timeout = SPI_TIMEOUT;
00443
00444 do {
00445 --timeout;
00446 } while ((spi->sr & AVR32_SPI_SR_RDRF_MASK) == 0 && timeout > 0);
00447
00448 if (timeout == 0) {
00449 return SPI_ERROR_TIMEOUT;
00450 }
00451
00452 *data = spi->rdr & 0x0000FFFF;
00453
00454 return SPI_OK;
00455 }
00456
00457
00458 #ifdef SPI_ENABLE_PDC
00459
00463 void spi_disablePDC(volatile avr32_spi_t * spi)
00464 {
00465 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00466 pdc->ptcr |= (1<<1);
00467 pdc->ptcr |= (1<<9);
00468 }
00469
00470
00475 void spi_enablePDC(volatile avr32_spi_t * spi)
00476 {
00477 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00478 pdc->ptcr |= (1<<0);
00479 pdc->ptcr |= (1<<8);
00480 }
00481
00482
00497 int spi_setRxBuf(volatile avr32_spi_t * spi,
00498 void * rp,
00499 unsigned short rc,
00500 void * rnp,
00501 unsigned short rnc)
00502 {
00503 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00504
00505
00506 pdc->ptcr |= (1<<1);
00507
00508 if (rnp != 0) {
00509 pdc->rnpr = (long) rnp;
00510 pdc->rncr = rnc;
00511 } else {
00512 return SPI_ERROR_ARGUMENT;
00513 }
00514
00515 if (rp != 0) {
00516 pdc->rpr = (long) rp;
00517 pdc->rcr = rc;
00518 } else {
00519 return SPI_ERROR_ARGUMENT;
00520 }
00521
00522
00523 pdc->ptcr |= (1<<0);
00524
00525 return SPI_OK;
00526 }
00527
00528
00543 int spi_setTxBuf(volatile avr32_spi_t * spi,
00544 void * tp,
00545 unsigned short tc,
00546 void * tnp,
00547 unsigned short tnc)
00548 {
00549 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00550
00551
00552 pdc->ptcr |= (1<<9);
00553
00554 if (tnp != 0) {
00555 pdc->tnpr = (long) tnp;
00556 pdc->tncr = tnc;
00557 } else {
00558 return SPI_ERROR_ARGUMENT;
00559 }
00560
00561 if (tp != 0) {
00562 pdc->tpr = (long) tp;
00563 pdc->tcr = tc;
00564 } else {
00565 return SPI_ERROR_ARGUMENT;
00566 }
00567
00568
00569 pdc->ptcr |= (1<<8);
00570
00571 return SPI_OK;
00572 }
00573
00574
00581 unsigned short spi_getRcr(volatile avr32_spi_t * spi)
00582 {
00583 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00584 return pdc->rcr;
00585 }
00586
00587
00594 unsigned short spi_getTcr(volatile avr32_spi_t * spi)
00595 {
00596 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi;
00597 return pdc->tcr;
00598 }
00599 #endif
00600
00601
00614 unsigned char spi_getStatus(volatile avr32_spi_t *spi)
00615 {
00616 unsigned char ret = 0;
00617
00618 if ((spi->sr & AVR32_SPI_SR_OVRES_MASK) != 0) {
00619 ret = SPI_ERROR_OVERRUN;
00620 }
00621
00622 if ((spi->sr & AVR32_SPI_SR_MODF_MASK) != 0) {
00623 ret += SPI_ERROR_MODE_FAULT;
00624 }
00625
00626 if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
00627 return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
00628 }
00629 else if (ret > 0) {
00630 return ret;
00631 } else {
00632 return SPI_OK;
00633 }
00634 }
00635
00636
00646 int getBaudDiv(struct spi_options_t * options, int cpuHz) {
00647 int baudDiv = 0;
00648
00649 if (options->fdiv == 0) {
00650 baudDiv = cpuHz / (options->baudrate);
00651 } else {
00652 baudDiv = cpuHz / (32 * options->baudrate);
00653 }
00654
00655 if (baudDiv > (AVR32_SPI_CSR0_SCBR_MASK<<AVR32_SPI_CSR0_SCBR_OFFSET)
00656 || baudDiv <= 0) {
00657 return -SPI_ERROR_ARGUMENT;
00658 }
00659
00660 return baudDiv;
00661 }
00662