00001
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 #include "spi.h"
00051
00052 int getBaudDiv(struct spi_options_t * options, int cpuHz);
00053
00054
00059 void spi_reset(volatile avr32_spi_t * spi)
00060 {
00061 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00062 }
00063
00064
00075 int spi_initSlave(volatile avr32_spi_t * spi,
00076 unsigned char bits,
00077 unsigned char spi_mode)
00078 {
00079
00080 spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET);
00081
00082
00083
00084 if (bits > 16 || bits < 8) {
00085 return SPI_ERROR_ARGUMENT;
00086 }
00087
00088 spi->csr0 = (bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET;
00089
00090 switch(spi_mode) {
00091 case 0:
00092 spi->csr0 |= (1 << AVR32_SPI_CSR0_NCPHA_OFFSET);
00093 case 1:
00094 break;
00095 case 2:
00096 spi->csr0 |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00097 case 3:
00098 spi->csr0 |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
00099 break;
00100 default:
00101 return SPI_ERROR_ARGUMENT;
00102 }
00103
00104 return SPI_OK;
00105 }
00106
00107
00116 int spi_initTest(volatile avr32_spi_t * spi)
00117 {
00118
00119 spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET);
00120
00121 spi->mr |= (1<<AVR32_SPI_MR_MSTR_OFFSET);
00122
00123 spi->mr |= (1<<AVR32_SPI_MR_LLB_OFFSET);
00124
00125 return SPI_OK;
00126 }
00127
00128
00138 int spi_initMaster(volatile avr32_spi_t * spi, struct spi_options_t * options)
00139 {
00140 if (options->modfdis > 1) {
00141 return SPI_ERROR_ARGUMENT;
00142 }
00143
00144 if (options->fdiv > 1) {
00145 return SPI_ERROR_ARGUMENT;
00146 }
00147
00148
00149 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00150
00151
00152 spi->mr = AVR32_SPI_MR_MSTR_MASK|
00153 (options->fdiv<<AVR32_SPI_MR_FDIV_OFFSET)|
00154 (options->modfdis<<AVR32_SPI_MR_MODFDIS_OFFSET);
00155
00156 return SPI_OK;
00157 }
00158
00159
00173 int spi_selectionMode(volatile avr32_spi_t * spi,
00174 unsigned char variable_ps,
00175 unsigned char pcs_decode,
00176 unsigned char delay)
00177 {
00178 if (variable_ps > 1) {
00179 return SPI_ERROR_ARGUMENT;
00180 }
00181
00182 if (pcs_decode > 1) {
00183 return SPI_ERROR_ARGUMENT;
00184 }
00185
00186 spi->mr |=
00187 (variable_ps<<AVR32_SPI_MR_PS_OFFSET)|
00188 (pcs_decode<<AVR32_SPI_MR_PCSDEC_OFFSET)|
00189 (delay<<AVR32_SPI_MR_DLYBCS_OFFSET);
00190
00191 return SPI_OK;
00192 }
00193
00194
00205 int spi_selectChip(volatile avr32_spi_t * spi, unsigned char chip)
00206 {
00207
00208 spi->mr |= (0xF << AVR32_SPI_MR_PCS_OFFSET);
00209
00210 if ((spi->mr & (1<<AVR32_SPI_MR_PCSDEC_OFFSET)) != 0) {
00211
00212 if (chip > 15) {
00213 return SPI_ERROR_ARGUMENT;
00214 }
00215
00216 spi->mr |= chip << AVR32_SPI_MR_PCS_OFFSET;
00217 } else {
00218 if (chip > 3) {
00219 return SPI_ERROR_ARGUMENT;
00220 }
00221
00222 spi->mr &= ~(1<<(AVR32_SPI_MR_PCS_OFFSET + chip));
00223 }
00224
00225 return SPI_OK;
00226 }
00227
00228
00243 int spi_setupChipReg(volatile avr32_spi_t * spi,
00244 struct spi_options_t * options,
00245 unsigned int cpuHz)
00246 {
00247 unsigned long csr;
00248
00249 if (options->bits > 16 || options->bits < 8) {
00250 return SPI_ERROR_ARGUMENT;
00251 }
00252
00253 if (options->stay_act > 1) {
00254 return SPI_ERROR_ARGUMENT;
00255 }
00256
00257 int baudDiv = getBaudDiv(options, cpuHz);
00258
00259 if (baudDiv < 0) {
00260 return -baudDiv;
00261 }
00262
00263
00264 csr = ((options->bits - 8)<<AVR32_SPI_CSR0_BITS_OFFSET)|
00265 (baudDiv<<AVR32_SPI_CSR0_SCBR_OFFSET)|
00266 (options->spck_delay<<AVR32_SPI_CSR0_DLYBS_OFFSET)|
00267 (options->trans_delay<<AVR32_SPI_CSR0_DLYBCT_OFFSET)|
00268 (options->stay_act<<AVR32_SPI_CSR0_CSAAT_OFFSET);
00269
00270 switch(options->spi_mode) {
00271 case 0:
00272 csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00273 case 1:
00274 break;
00275 case 2:
00276 csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
00277 case 3:
00278 csr |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
00279 break;
00280 default:
00281 return SPI_ERROR_ARGUMENT;
00282 }
00283
00284 switch(options->reg) {
00285 case 0:
00286 spi->csr0 = csr;
00287 break;
00288 case 1:
00289 spi->csr1 = csr;
00290 break;
00291 case 2:
00292 spi->csr2 = csr;
00293 break;
00294 case 3:
00295 spi->csr3 = csr;
00296 break;
00297 default:
00298 return SPI_ERROR_ARGUMENT;
00299 }
00300
00301 return SPI_OK;
00302 }
00303
00304
00311 void spi_enable(volatile avr32_spi_t * spi)
00312 {
00313 spi->cr = (1<<AVR32_SPI_CR_SPIEN_OFFSET);
00314 }
00315
00316
00324 void spi_disable(volatile avr32_spi_t * spi)
00325 {
00326 spi->cr = (1<<AVR32_SPI_CR_SPIDIS_OFFSET);
00327 }
00328
00329
00340 int spi_write(volatile avr32_spi_t * spi, unsigned short data)
00341 {
00342 unsigned int timeout = SPI_TIMEOUT;
00343
00344 while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && timeout > 0) {
00345 --timeout;
00346 }
00347
00348 if (timeout == 0) {
00349 return SPI_ERROR_TIMEOUT;
00350 }
00351
00352 spi->tdr = data & 0x0000FFFF;
00353
00354 return SPI_OK;
00355 }
00356
00357
00375 int spi_variableSlaveWrite(volatile avr32_spi_t * spi, unsigned short data,
00376 unsigned char pcs, unsigned char lastxfer)
00377 {
00378 unsigned int timeout = SPI_TIMEOUT;
00379
00380 if (pcs > 15 || lastxfer > 1)
00381 return SPI_ERROR_ARGUMENT;
00382
00383 while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && --timeout) {
00384 }
00385
00386 if (timeout == 0) {
00387 return SPI_ERROR_TIMEOUT;
00388 }
00389
00390 spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
00391 (pcs << AVR32_SPI_TDR_PCS_OFFSET) |
00392 (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
00393
00394 return SPI_OK;
00395 }
00396
00397
00406 unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t * spi)
00407 {
00408 if ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0) {
00409 return 1;
00410 } else {
00411 return 0;
00412 }
00413 }
00414
00415
00426 int spi_read(volatile avr32_spi_t * spi, unsigned short * data)
00427 {
00428 unsigned int timeout = SPI_TIMEOUT;
00429
00430 do {
00431 --timeout;
00432 } while ((spi->sr & AVR32_SPI_SR_RDRF_MASK) == 0 && timeout > 0);
00433
00434 if (timeout == 0) {
00435 return SPI_ERROR_TIMEOUT;
00436 }
00437
00438 *data = spi->rdr & 0x0000FFFF;
00439
00440 return SPI_OK;
00441 }
00442
00443
00456 unsigned char spi_getStatus(volatile avr32_spi_t * spi)
00457 {
00458 unsigned char ret = 0;
00459
00460 if ((spi->sr & (1<<AVR32_SPI_SR_OVRES_OFFSET)) != 0) {
00461 ret = SPI_ERROR_OVERRUN;
00462 }
00463
00464 if ((spi->sr & (1<<AVR32_SPI_SR_MODF_OFFSET)) != 0) {
00465 ret += SPI_ERROR_MODE_FAULT;
00466 }
00467
00468 if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
00469 return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
00470 }
00471 else if (ret > 0) {
00472 return ret;
00473 } else {
00474 return SPI_OK;
00475 }
00476 }
00477
00478
00488 int getBaudDiv(struct spi_options_t * options, int cpuHz) {
00489 int baudDiv = 0;
00490
00491 if (options->fdiv == 0) {
00492 baudDiv = cpuHz / (options->baudrate);
00493 } else {
00494 baudDiv = cpuHz / (32 * options->baudrate);
00495 }
00496
00497 if (baudDiv > 255 || baudDiv <= 0) {
00498 return -SPI_ERROR_ARGUMENT;
00499 }
00500
00501 return baudDiv;
00502 }
00503