00001
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 #include "spi.h"
00050
00051 #ifdef FREERTOS_USED
00052
00053 #include "FreeRTOS.h"
00054 #include "semphr.h"
00055
00056 #endif
00057
00058
00061
00062
00063 typedef union
00064 {
00065 unsigned long cr;
00066 avr32_spi_cr_t CR;
00067 } u_avr32_spi_cr_t;
00068
00069 typedef union
00070 {
00071 unsigned long mr;
00072 avr32_spi_mr_t MR;
00073 } u_avr32_spi_mr_t;
00074
00075 typedef union
00076 {
00077 unsigned long tdr;
00078 avr32_spi_tdr_t TDR;
00079 } u_avr32_spi_tdr_t;
00080
00081 typedef union
00082 {
00083 unsigned long ier;
00084 avr32_spi_ier_t IER;
00085 } u_avr32_spi_ier_t;
00086
00087 typedef union
00088 {
00089 unsigned long idr;
00090 avr32_spi_idr_t IDR;
00091 } u_avr32_spi_idr_t;
00092
00093 typedef union
00094 {
00095 unsigned long csr;
00096 avr32_spi_csr0_t CSR;
00097 } u_avr32_spi_csr_t;
00098
00100
00101
00102 #ifdef FREERTOS_USED
00103
00105 static xSemaphoreHandle xSPIMutex;
00106
00107 #endif
00108
00109
00120 static int getBaudDiv(const spi_options_t *options, unsigned int pba_hz)
00121 {
00122 int baudDiv = (pba_hz + options->baudrate / 2) / options->baudrate;
00123
00124 if (baudDiv <= 0 || baudDiv > 255) {
00125 return -1;
00126 }
00127
00128 return baudDiv;
00129 }
00130
00131
00132 void spi_reset(volatile avr32_spi_t *spi)
00133 {
00134 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00135 }
00136
00137
00138 spi_status_t spi_initSlave(volatile avr32_spi_t *spi,
00139 unsigned char bits,
00140 unsigned char spi_mode)
00141 {
00142 if (spi_mode > 3 ||
00143 bits < 8 || bits > 16) {
00144 return SPI_ERROR_ARGUMENT;
00145 }
00146
00147
00148 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00149
00150
00151 spi->csr0 = ((spi_mode >> 1) << AVR32_SPI_CSR0_CPOL_OFFSET) |
00152 (((spi_mode & 0x1) ^ 0x1) << AVR32_SPI_CSR0_NCPHA_OFFSET) |
00153 ((bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET);
00154
00155 return SPI_OK;
00156 }
00157
00158
00159 spi_status_t spi_initTest(volatile avr32_spi_t *spi)
00160 {
00161
00162 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00163 spi->mr |= AVR32_SPI_MR_MSTR_MASK |
00164 AVR32_SPI_MR_LLB_MASK;
00165
00166 return SPI_OK;
00167 }
00168
00169
00170 spi_status_t spi_initMaster(volatile avr32_spi_t *spi, const spi_options_t *options)
00171 {
00172 u_avr32_spi_mr_t u_avr32_spi_mr;
00173
00174 if (options->modfdis > 1) {
00175 return SPI_ERROR_ARGUMENT;
00176 }
00177
00178
00179 spi->cr = AVR32_SPI_CR_SWRST_MASK;
00180
00181
00182 u_avr32_spi_mr.mr = spi->mr;
00183 u_avr32_spi_mr.MR.mstr = 1;
00184 u_avr32_spi_mr.MR.modfdis = options->modfdis;
00185 u_avr32_spi_mr.MR.llb = 0;
00186 u_avr32_spi_mr.MR.pcs = (1 << AVR32_SPI_MR_PCS_SIZE) - 1;
00187 spi->mr = u_avr32_spi_mr.mr;
00188
00189 return SPI_OK;
00190 }
00191
00192
00193 spi_status_t spi_selectionMode(volatile avr32_spi_t *spi,
00194 unsigned char variable_ps,
00195 unsigned char pcs_decode,
00196 unsigned char delay)
00197 {
00198 u_avr32_spi_mr_t u_avr32_spi_mr;
00199
00200 if (variable_ps > 1 ||
00201 pcs_decode > 1) {
00202 return SPI_ERROR_ARGUMENT;
00203 }
00204
00205 u_avr32_spi_mr.mr = spi->mr;
00206 u_avr32_spi_mr.MR.ps = variable_ps;
00207 u_avr32_spi_mr.MR.pcsdec = pcs_decode;
00208 u_avr32_spi_mr.MR.dlybcs = delay;
00209 spi->mr = u_avr32_spi_mr.mr;
00210
00211 return SPI_OK;
00212 }
00213
00214
00215 spi_status_t spi_selectChip(volatile avr32_spi_t *spi, unsigned char chip)
00216 {
00217 #ifdef FREERTOS_USED
00218 while (pdFALSE == xSemaphoreTake(xSPIMutex, 20));
00219 #endif
00220
00221
00222 spi->mr |= AVR32_SPI_MR_PCS_MASK;
00223
00224 if (spi->mr & AVR32_SPI_MR_PCSDEC_MASK) {
00225
00226 if (chip > 14) {
00227 return SPI_ERROR_ARGUMENT;
00228 }
00229
00230 spi->mr &= ~AVR32_SPI_MR_PCS_MASK | (chip << AVR32_SPI_MR_PCS_OFFSET);
00231 } else {
00232 if (chip > 3) {
00233 return SPI_ERROR_ARGUMENT;
00234 }
00235
00236 spi->mr &= ~(1 << (AVR32_SPI_MR_PCS_OFFSET + chip));
00237 }
00238
00239 return SPI_OK;
00240 }
00241
00242
00243 spi_status_t spi_unselectChip(volatile avr32_spi_t *spi, unsigned char chip)
00244 {
00245 unsigned int timeout = SPI_TIMEOUT;
00246
00247 while (!(spi->sr & AVR32_SPI_SR_TXEMPTY_MASK)) {
00248 if (!timeout--) {
00249 return SPI_ERROR_TIMEOUT;
00250 }
00251 }
00252
00253
00254 spi->mr |= AVR32_SPI_MR_PCS_MASK;
00255
00256
00257 spi->cr = AVR32_SPI_CR_LASTXFER_MASK;
00258
00259 #ifdef FREERTOS_USED
00260 xSemaphoreGive(xSPIMutex);
00261 #endif
00262
00263 return SPI_OK;
00264 }
00265
00266
00267 spi_status_t spi_setupChipReg(volatile avr32_spi_t *spi,
00268 const spi_options_t *options,
00269 unsigned int pba_hz)
00270 {
00271 u_avr32_spi_csr_t u_avr32_spi_csr;
00272
00273 if (options->spi_mode > 3 ||
00274 options->stay_act > 1 ||
00275 options->bits < 8 || options->bits > 16) {
00276 return SPI_ERROR_ARGUMENT;
00277 }
00278
00279 int baudDiv = getBaudDiv(options, pba_hz);
00280
00281 if (baudDiv < 0) {
00282 return SPI_ERROR_ARGUMENT;
00283 }
00284
00285
00286 u_avr32_spi_csr.csr = 0;
00287 u_avr32_spi_csr.CSR.cpol = options->spi_mode >> 1;
00288 u_avr32_spi_csr.CSR.ncpha = (options->spi_mode & 0x1) ^ 0x1;
00289 u_avr32_spi_csr.CSR.csaat = options->stay_act;
00290 u_avr32_spi_csr.CSR.bits = options->bits - 8;
00291 u_avr32_spi_csr.CSR.scbr = baudDiv;
00292 u_avr32_spi_csr.CSR.dlybs = options->spck_delay;
00293 u_avr32_spi_csr.CSR.dlybct = options->trans_delay;
00294
00295 switch(options->reg) {
00296 case 0:
00297 spi->csr0 = u_avr32_spi_csr.csr;
00298 break;
00299 case 1:
00300 spi->csr1 = u_avr32_spi_csr.csr;
00301 break;
00302 case 2:
00303 spi->csr2 = u_avr32_spi_csr.csr;
00304 break;
00305 case 3:
00306 spi->csr3 = u_avr32_spi_csr.csr;
00307 break;
00308 default:
00309 return SPI_ERROR_ARGUMENT;
00310 }
00311
00312 #ifdef FREERTOS_USED
00313 if (!xSPIMutex)
00314 {
00315
00316 vSemaphoreCreateBinary(xSPIMutex);
00317 if (!xSPIMutex)
00318 {
00319 while(1);
00320 }
00321 }
00322 #endif
00323
00324 return SPI_OK;
00325 }
00326
00327
00328 void spi_enable(volatile avr32_spi_t *spi)
00329 {
00330 spi->cr = AVR32_SPI_CR_SPIEN_MASK;
00331 }
00332
00333
00334 void spi_disable(volatile avr32_spi_t *spi)
00335 {
00336 spi->cr = AVR32_SPI_CR_SPIDIS_MASK;
00337 }
00338
00339
00340 int spi_is_enabled(volatile avr32_spi_t *spi)
00341 {
00342 return (spi->sr & AVR32_SPI_SR_SPIENS_MASK) != 0;
00343 }
00344
00345
00346 unsigned char spi_writeRegisterEmptyCheck(volatile avr32_spi_t *spi)
00347 {
00348 return ((spi->sr & AVR32_SPI_SR_TDRE_MASK) != 0);
00349 }
00350
00351
00352 spi_status_t spi_write(volatile avr32_spi_t *spi, unsigned short data)
00353 {
00354 unsigned int timeout = SPI_TIMEOUT;
00355
00356 while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
00357 if (!timeout--) {
00358 return SPI_ERROR_TIMEOUT;
00359 }
00360 }
00361
00362 spi->tdr = data << AVR32_SPI_TDR_TD_OFFSET;
00363
00364 return SPI_OK;
00365 }
00366
00367
00368 spi_status_t spi_variableSlaveWrite(volatile avr32_spi_t *spi, unsigned short data,
00369 unsigned char pcs, unsigned char lastxfer)
00370 {
00371 unsigned int timeout = SPI_TIMEOUT;
00372
00373 if (pcs > 14 || lastxfer > 1) {
00374 return SPI_ERROR_ARGUMENT;
00375 }
00376
00377 while (!(spi->sr & AVR32_SPI_SR_TDRE_MASK)) {
00378 if (!timeout--) {
00379 return SPI_ERROR_TIMEOUT;
00380 }
00381 }
00382
00383 spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
00384 (pcs << AVR32_SPI_TDR_PCS_OFFSET) |
00385 (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
00386
00387 return SPI_OK;
00388 }
00389
00390
00391 unsigned char spi_writeEndCheck(volatile avr32_spi_t *spi)
00392 {
00393 return ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) != 0);
00394 }
00395
00396
00397 unsigned char spi_readRegisterFullCheck(volatile avr32_spi_t *spi)
00398 {
00399 return ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0);
00400 }
00401
00402
00403 spi_status_t spi_read(volatile avr32_spi_t *spi, unsigned short *data)
00404 {
00405 unsigned int timeout = SPI_TIMEOUT;
00406
00407 while ((spi->sr & (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) !=
00408 (AVR32_SPI_SR_RDRF_MASK | AVR32_SPI_SR_TXEMPTY_MASK)) {
00409 if (!timeout--) {
00410 return SPI_ERROR_TIMEOUT;
00411 }
00412 }
00413
00414 *data = spi->rdr >> AVR32_SPI_RDR_RD_OFFSET;
00415
00416 return SPI_OK;
00417 }
00418
00419
00420 unsigned char spi_getStatus(volatile avr32_spi_t *spi)
00421 {
00422 spi_status_t ret = SPI_OK;
00423 unsigned long sr = spi->sr;
00424
00425 if (sr & AVR32_SPI_SR_OVRES_MASK) {
00426 ret = SPI_ERROR_OVERRUN;
00427 }
00428
00429 if (sr & AVR32_SPI_SR_MODF_MASK) {
00430 ret += SPI_ERROR_MODE_FAULT;
00431 }
00432
00433 if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
00434 return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
00435 }
00436 else if (ret > 0) {
00437 return ret;
00438 } else {
00439 return SPI_OK;
00440 }
00441 }