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.h.
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Data Structures | |
| struct | spi_options_t |
| Parameters for setting options for slave chips. More... | |
| struct | spi_pdc |
Defines | |
| #define | SPI_ENABLE_PDC 1 |
| Enable PDC functions for SPI. | |
| #define | SPI_TIMEOUT 10000 |
| Timeout for spi read and write blocking functions. | |
Typedefs | |
| typedef spi_pdc | spi_pdc_t |
Enumerations | |
| enum | { SPI_ERROR = -1, SPI_OK = 0, SPI_ERROR_TIMEOUT = 1, SPI_ERROR_ARGUMENT, SPI_ERROR_OVERRUN, SPI_ERROR_MODE_FAULT, SPI_ERROR_OVERRUN_AND_MODE_FAULT } |
| Error codes used by SPI driver. More... | |
Functions | |
| 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_disablePDC (volatile avr32_spi_t *spi) |
| Disable the Periperal DMA Controller (PDC). | |
| void | spi_enable (volatile avr32_spi_t *spi) |
| Enables a disabled SPI. | |
| void | spi_enablePDC (volatile avr32_spi_t *spi) |
| Enable the Periperal DMA Controller (PDC). | |
| unsigned short | spi_getRcr (volatile avr32_spi_t *spi) |
| Check remaining size of current receive buffer. | |
| unsigned char | spi_getStatus (volatile avr32_spi_t *spi) |
| Get status information from the SPI. | |
| unsigned short | spi_getTcr (volatile avr32_spi_t *spi) |
| Check remaining size of current transmit buffer. | |
| 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_set_RxBuf (volatile avr32_spi_t *spi, void *rp, unsigned short rc, void *rnp, unsigned short rnc) |
| int | spi_set_TxBuf (volatile avr32_spi_t *spi, void *tp, unsigned short tc, void *tnp, unsigned short tnc) |
| 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_unselectChip (volatile avr32_spi_t *spi, unsigned char chip) |
| Unselect slave chip. | |
| 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. | |
| #define SPI_TIMEOUT 10000 |
Timeout for spi read and write blocking functions.
Definition at line 60 of file spi.h.
Referenced by spi_read(), spi_variableSlaveWrite(), and spi_write().
| anonymous enum |
Error codes used by SPI driver.
| SPI_ERROR | |
| SPI_OK | |
| SPI_ERROR_TIMEOUT | |
| SPI_ERROR_ARGUMENT | |
| SPI_ERROR_OVERRUN | |
| SPI_ERROR_MODE_FAULT | |
| SPI_ERROR_OVERRUN_AND_MODE_FAULT |
Definition at line 65 of file spi.h.
00065 { 00066 SPI_ERROR = -1, 00067 SPI_OK = 0, 00068 SPI_ERROR_TIMEOUT = 1, 00069 SPI_ERROR_ARGUMENT, 00070 SPI_ERROR_OVERRUN, 00071 SPI_ERROR_MODE_FAULT, 00072 SPI_ERROR_OVERRUN_AND_MODE_FAULT 00073 };
| void spi_disable | ( | volatile avr32_spi_t * | spi | ) |
| void spi_disablePDC | ( | volatile avr32_spi_t * | spi | ) |
Disable the Periperal DMA Controller (PDC).
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 463 of file spi.c.
References spi_pdc::ptcr.
00464 { 00465 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi; 00466 pdc->ptcr |= (1<<1); /* Disable RXT */ 00467 pdc->ptcr |= (1<<9); /* Disable TXT */ 00468 }
| void spi_enable | ( | volatile avr32_spi_t * | spi | ) |
Enables a disabled SPI.
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 326 of file spi.c.
Referenced by init_spiMaster(), and init_spiSlave().
| void spi_enablePDC | ( | volatile avr32_spi_t * | spi | ) |
Enable the Periperal DMA Controller (PDC).
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 475 of file spi.c.
References spi_pdc::ptcr.
00476 { 00477 volatile spi_pdc_t *pdc = (volatile spi_pdc_t *)spi; 00478 pdc->ptcr |= (1<<0); /* Enable RXT */ 00479 pdc->ptcr |= (1<<8); /* Enable TXT */ 00480 }
| unsigned short spi_getRcr | ( | volatile avr32_spi_t * | spi | ) |
Check remaining size of current receive buffer.
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 581 of file spi.c.
References spi_pdc::rcr.
| 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 614 of file spi.c.
References SPI_ERROR_MODE_FAULT, SPI_ERROR_OVERRUN, SPI_ERROR_OVERRUN_AND_MODE_FAULT, and SPI_OK.
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 }
| unsigned short spi_getTcr | ( | volatile avr32_spi_t * | spi | ) |
Check remaining size of current transmit buffer.
| spi | Pointer to the correct avr32_spi_t struct |
Definition at line 594 of file spi.c.
References spi_pdc::tcr.
| 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 136 of file spi.c.
References spi_options_t::fdiv, spi_options_t::modfdis, SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster().
00137 { 00138 if (options->modfdis > 1 || options->fdiv > 1) { 00139 return SPI_ERROR_ARGUMENT; 00140 } 00141 00142 /* Reset */ 00143 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00144 00145 /* Master Mode */ 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 }
| 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 73 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiSlave().
00076 { 00077 /* Reset */ 00078 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00079 00080 /* The number of bits and clock polarity/phase have to be set in 00081 csr0 for the SPI to communcate in slave mode */ 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: /* Not in legal range */ 00099 return SPI_ERROR_ARGUMENT; 00100 } 00101 00102 return SPI_OK; 00103 }
| 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 114 of file spi.c.
References SPI_OK.
00115 { 00116 /* Reset */ 00117 spi->cr = AVR32_SPI_CR_SWRST_MASK; 00118 /* Master Mode */ 00119 spi->mr |= AVR32_SPI_MR_MSTR_MASK; 00120 /* Local Loopback */ 00121 spi->mr |= AVR32_SPI_MR_LLB_MASK; 00122 00123 return SPI_OK; 00124 }
| 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 440 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by spi_slaveReceiveAndCompare().
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 }
| 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 420 of file spi.c.
Referenced by main().
00421 { 00422 if ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0) { 00423 return 1; 00424 } else { 00425 return 0; 00426 } 00427 }
| 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-14) |
| SPI_OK | on success | |
| SPI_ERROR_ARGUMENT | when invalid arguments are passed |
Definition at line 201 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster().
00202 { 00203 /* Assert all lines; no peripheral is selected */ 00204 spi->mr |= AVR32_SPI_MR_PCS_MASK; 00205 00206 if ((spi->mr & AVR32_SPI_MR_PCSDEC_MASK) != 0) { 00207 /* The signal is decoded; allow up to 15 chips */ 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 }
| 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 14 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 168 of file spi.c.
References SPI_ERROR_ARGUMENT, and SPI_OK.
Referenced by init_spiMaster().
00172 { 00173 if (variable_ps > 1 || pcs_decode > 1) { 00174 return SPI_ERROR_ARGUMENT; 00175 } 00176 00177 /* Unset bitfields */ 00178 spi->mr &= ~(AVR32_SPI_MR_PS_MASK| 00179 AVR32_SPI_MR_PCSDEC_MASK| 00180 AVR32_SPI_MR_DLYBCS_MASK); 00181 /* Set selction bits */ 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 }
| int spi_set_RxBuf | ( | volatile avr32_spi_t * | spi, | |
| void * | rp, | |||
| unsigned short | rc, | |||
| void * | rnp, | |||
| unsigned short | rnc | |||
| ) |
| int spi_set_TxBuf | ( | volatile avr32_spi_t * | spi, | |
| void * | tp, | |||
| unsigned short | tc, | |||
| void * | tnp, | |||
| unsigned short | tnc | |||
| ) |
| 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 261 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(), and init_spiSlave().
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 /* Will use CSR0 offsets; these are the same for CSR0 - CSR3 */ 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: /* Not in legal range */ 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 }
Here is the call graph for this function:

| int spi_unselectChip | ( | volatile avr32_spi_t * | spi, | |
| unsigned char | chip | |||
| ) |
Unselect slave chip.
| spi | Pointer to the correct avr32_spi_t struct | |
| chip | Slave chip number (normal: 0-3, \ extarnaly decoded signal: 0-14) |
| SPI_OK | on success |
Definition at line 235 of file spi.c.
References SPI_OK.
00236 { 00237 /* Assert all lines; no peripheral is selected */ 00238 spi->mr |= AVR32_SPI_MR_PCS_MASK; 00239 00240 /* Last transfer, so deassert the current NPCS if CSAAT is set */ 00241 spi->cr = AVR32_SPI_CR_LASTXFER_MASK; 00242 00243 return SPI_OK; 00244 }
| 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 390 of file spi.c.
References SPI_ERROR_ARGUMENT, SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
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 }
| 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 355 of file spi.c.
References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.
Referenced by spi_masterSend().
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 }
1.5.1