This file defines a usefull set of functions for the SPI interface on AVR32 devices. The driver handles normal polled usage and direct memory access (PDC) usage.
Definition in file spi.c.
#include "spi.h"
Go to the source code of this file.
Functions | |
| int | getBaudDiv (struct spi_options_t *options, int cpuHz) |
| Calculate the baudrate division. | |
| void | spi_disable (volatile avr32_spi_t *spi) |
| Disables the SPI, ensures that nothing is transferred while setting up buffers. (Data loss is risked when used on a slave). | |
| void | spi_enable (volatile avr32_spi_t *spi) |
| Enables a disabled SPI. | |
| unsigned char | spi_getStatus (volatile avr32_spi_t *spi) |
| Get status information from the SPI. | |
| int | spi_initMaster (volatile avr32_spi_t *spi, struct spi_options_t *options) |
| Setup the SPI module in master mode. | |
| int | spi_initSlave (volatile avr32_spi_t *spi, unsigned char bits, unsigned char spi_mode) |
| Initialize the SPI in slave mode. | |
| int | spi_initTest (volatile avr32_spi_t *spi) |
| Setup the SPI in a test mode where the transmitter is connected to the receiver. | |
| int | spi_read (volatile avr32_spi_t *spi, unsigned short *data) |
| Read one block from the selected (fixed select) slave, will block program execution until timeout occurs if no data is received. | |
| unsigned char | spi_readRegisterFullCheck (volatile avr32_spi_t *spi) |
| Check if there is data in the receive register. | |
| void | spi_reset (volatile avr32_spi_t *spi) |
| Resets the SPI controller. | |
| int | spi_selectChip (volatile avr32_spi_t *spi, unsigned char chip) |
| Select slave chip. | |
| int | spi_selectionMode (volatile avr32_spi_t *spi, unsigned char variable_ps, unsigned char pcs_decode, unsigned char delay) |
| How and when are the slave chip selected (master mode only). | |
| int | spi_setupChipReg (volatile avr32_spi_t *spi, struct spi_options_t *options, unsigned int cpuHz) |
| Set options for a specific slave chip. The baudrate field has to be written before transfer in master mode. Four similar registers exist, one for each slave. When using encoded slave addressing, reg=0 sets options for slave 0-3, reg=1 for slave 4-7 and so on. | |
| int | spi_variableSlaveWrite (volatile avr32_spi_t *spi, unsigned short data, unsigned char pcs, unsigned char lastxfer) |
| Selects a slave and writes one block of data to this, will block program execution until timeout occurs if transmitter is busy. | |
| int | spi_write (volatile avr32_spi_t *spi, unsigned short data) |
| Writes one block of data to the selected (fixed select) slave, will block program execution until timeout occurs if transmitter is busy. | |
| int getBaudDiv | ( | struct spi_options_t * | options, | |
| int | cpuHz | |||
| ) |
Calculate the baudrate division.
| options | Pointer to a spi_options_t struct | |
| cpuHz | the clock frequency in Hz for the peripheral bus |
| >= | 0 on success | |
| < | 0 on error |
Definition at line 488 of file spi.c.
References spi_options_t::baudrate, spi_options_t::fdiv, and SPI_ERROR_ARGUMENT.
Referenced by spi_setupChipReg().
00488 { 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 }
| void spi_disable | ( | volatile avr32_spi_t * | spi | ) |
| void spi_enable | ( | volatile avr32_spi_t * | spi | ) |
Enables a disabled SPI.
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 311 of file spi.c.
Referenced by init_spiMaster().
| unsigned char spi_getStatus | ( | volatile avr32_spi_t * | spi | ) |
Get status information from the SPI.
| spi | Pointer to the correct avr32_spi_t struct |
| SPI_OK | on success | |
| SPI_ERROR_OVERRUN | Overrun error has occurred | |
| SPI_ERROR_MODE_FAULT | Mode fault (has been addressed as slave while in master mode) | |
| SPI_ERROR_OVERRUN_AND_MODE_FAULT | Overrun error and mode fault error has occurred |
Definition at line 456 of file spi.c.
References SPI_ERROR_MODE_FAULT, SPI_ERROR_OVERRUN, SPI_ERROR_OVERRUN_AND_MODE_FAULT, and SPI_OK.
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 }
| int spi_initMaster | ( | volatile avr32_spi_t * | spi, | |
| struct spi_options_t * | options | |||
| ) |
Setup the SPI module in master mode.
| spi | Pointer to the correct avr32_spi_t struct | |
| options | Pointer struct containing setup for a chip register |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 138 of file spi.c.
References spi_options_t::fdiv, spi_options_t::modfdis, SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster().
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 /* Reset */ 00149 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00150 00151 /* Master Mode */ 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 }
| int spi_initSlave | ( | volatile avr32_spi_t * | spi, | |
| unsigned char | bits, | |||
| unsigned char | spi_mode | |||
| ) |
Initialize the SPI in slave mode.
| spi | Pointer to the correct avr32_spi_t struct | |
| bits | Number of bits in each transmitted character (8 - 16) | |
| spi_mode | When the read and write bits; Clock polarity and phase |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 75 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
00078 { 00079 /* Reset */ 00080 spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET); 00081 00082 /* The number of bits and clock polarity/phase have to be set in 00083 csr0 for the SPI to communcate in slave mode */ 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: /* Not in legal range */ 00101 return SPI_ERROR_ARGUMENT; 00102 } 00103 00104 return SPI_OK; 00105 }
| int spi_initTest | ( | volatile avr32_spi_t * | spi | ) |
Setup the SPI in a test mode where the transmitter is connected to the receiver.
| spi | Pointer to the correct avr32_spi_t struct |
| SPI_OK | on success |
Definition at line 116 of file spi.c.
References SPI_OK.
00117 { 00118 /* Reset */ 00119 spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET); 00120 /* Master Mode */ 00121 spi->mr |= (1<<AVR32_SPI_MR_MSTR_OFFSET); 00122 /* Local Loopback */ 00123 spi->mr |= (1<<AVR32_SPI_MR_LLB_OFFSET); 00124 00125 return SPI_OK; 00126 }
| int spi_read | ( | volatile avr32_spi_t * | spi, | |
| unsigned short * | data | |||
| ) |
Read one block from the selected (fixed select) slave, will block program execution until timeout occurs if no data is received.
| spi | pointer to the correct avr32_spi_t struct | |
| data | the received block of data (8 to 16 bits) |
| SPI_OK | on success | |
| SPI_ERROR_TIMEOUT | on timeout waiting for data |
Definition at line 426 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
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 }
| unsigned char spi_readRegisterFullCheck | ( | volatile avr32_spi_t * | spi | ) |
Check if there is data in the receive register.
| spi | Pointer to the correct avr32_spi_t struct |
| 1 | when there is data in RDR | |
| 0 | when there is not data in RDR |
Definition at line 406 of file spi.c.
00407 { 00408 if ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0) { 00409 return 1; 00410 } else { 00411 return 0; 00412 } 00413 }
| void spi_reset | ( | volatile avr32_spi_t * | spi | ) |
| int spi_selectChip | ( | volatile avr32_spi_t * | spi, | |
| unsigned char | chip | |||
| ) |
Select slave chip.
| spi | Pointer to the correct avr32_spi_t struct | |
| chip | Slave chip number (normal: 0-3, \ extarnaly decoded signal: 0-15) |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 205 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster(), ltv350qv_power_off(), and ltv350qv_power_on().
00206 { 00207 /* Assert all lines; no peripheral is selected */ 00208 spi->mr |= (0xF << AVR32_SPI_MR_PCS_OFFSET); 00209 00210 if ((spi->mr & (1<<AVR32_SPI_MR_PCSDEC_OFFSET)) != 0) { 00211 /* The signal is decoded; allow up to 16 chips */ 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 }
| int spi_selectionMode | ( | volatile avr32_spi_t * | spi, | |
| unsigned char | variable_ps, | |||
| unsigned char | pcs_decode, | |||
| unsigned char | delay | |||
| ) |
How and when are the slave chip selected (master mode only).
| spi | Pointer to the correct avr32_spi_t struct | |
| variable_ps | Target slave is selected in transfer register \ for every character to transmit | |
| pcs_decode | The four chip select lines are decoded externaly; \ values 0 to 15 can be given to select_chip() | |
| delay | Delay in MCK cyles (or NxMCK with FDIV) between chip selects |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 173 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster().
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 }
| int spi_setupChipReg | ( | volatile avr32_spi_t * | spi, | |
| struct spi_options_t * | options, | |||
| unsigned int | cpuHz | |||
| ) |
Set options for a specific slave chip. The baudrate field has to be written before transfer in master mode. Four similar registers exist, one for each slave. When using encoded slave addressing, reg=0 sets options for slave 0-3, reg=1 for slave 4-7 and so on.
| spi | Pointer to the correct avr32_spi_t struct | |
| options | Pointer struct containing setup for a chip register | |
| cpuHz | clock speed in Hz for the peripheral bus |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 243 of file spi.c.
References spi_options_t::bits, getBaudDiv(), spi_options_t::reg, spi_options_t::spck_delay, SPI_ERROR_ARGUMENT, spi_options_t::spi_mode, SPI_OK, spi_options_t::stay_act, and spi_options_t::trans_delay.
Referenced by init_spiMaster().
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 /* Will use CSR0 offsets; these are the same for CSR0 - CSR3 */ 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: /* Not in legal range */ 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 }
| int spi_variableSlaveWrite | ( | volatile avr32_spi_t * | spi, | |
| unsigned short | data, | |||
| unsigned char | pcs, | |||
| unsigned char | lastxfer | |||
| ) |
Selects a slave and writes one block of data to this, will block program execution until timeout occurs if transmitter is busy.
| spi | Pointer to the correct avr32_spi_t struct | |
| data | The block to write | |
| pcs | Slave select (bit0 -> ncs_line0, bit1 -> ncs_line1, ...)
| |
| lastxfer | Last transfer to slave
|
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 375 of file spi.c.
References SPI_ERROR_ARGUMENT, SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by ltv350qv_write_reg().
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 }
| int spi_write | ( | volatile avr32_spi_t * | spi, | |
| unsigned short | data | |||
| ) |
Writes one block of data to the selected (fixed select) slave, will block program execution until timeout occurs if transmitter is busy.
| spi | Pointer to the correct avr32_spi_t struct | |
| data | The block to write |
| SPI_OK | on success | |
| SPI_TIMEOUT | on timeout |
Definition at line 340 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
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 }
1.5.3-20071008