# spi_at32ap7000.h File Reference

## Detailed Description

SPI bus example driver.

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.

- Compiler: IAR EWAVR32 and GNU GCC for AVR32
- Supported devices: All AVR32 devices with a SPI module can be used.
- AppNote: AVR32105 - Master and Slave SPI Driver

Author:
  Atmel Corporation: http://www.atmel.com
  Support email: avr32@atmel.com

Definition in file spi_at32ap7000.h.

`#include <avr32/io.h>`

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 struct 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)
void | spi_enable (volatile avr32_spi_t *spi)
| Enables a disabled SPI.
void | spi_enablePDC (volatile avr32_spi_t *spi)
unsigned short | spi_getRcr (volatile avr32_spi_t *spi)
unsigned char | spi_getStatus (volatile avr32_spi_t *spi)
| Get status information from the SPI.
unsigned short | spi_getTcr (volatile avr32_spi_t *spi)
int | spi_initMaster (volatile avr32_spi_t *spi, 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, 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)
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 Documentation

#define SPI_ENABLE_PDC 1

Enable PDC functions for SPI.

Definition at line 61 of file spi_at32ap7000.h.

#define SPI_TIMEOUT 10000

Timeout for spi read and write blocking functions.

Definition at line 59 of file spi_at32ap7000.h.

Referenced by spi_read(), spi_variableSlaveWrite(), and spi_write().

## Typedef Documentation

typedef struct spi_pdc spi_pdc_t

Definition at line 125 of file spi_at32ap7000.h.

## Enumeration Type Documentation

anonymous enum

Error codes used by SPI driver.

Enumerator:

  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 64 of file spi_at32ap7000.h.

    00064      {
    00065     SPI_ERROR = -1,
    00066     SPI_OK = 0,
    00067     SPI_ERROR_TIMEOUT = 1,
    00068     SPI_ERROR_ARGUMENT,
    00069     SPI_ERROR_OVERRUN,
    00070     SPI_ERROR_MODE_FAULT,
    00071     SPI_ERROR_OVERRUN_AND_MODE_FAULT
    00072 };

## Function Documentation

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).

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Returns:
  Nothing

Definition at line 321 of file spi_at32ap7000.c.

    00322 {
    00323     spi->cr = (1<<AVR32_SPI_CR_SPIDIS_OFFSET);
    00324 }

void spi_disablePDC | ( | volatile avr32_spi_t * | spi | ) |

void spi_enable | ( | volatile avr32_spi_t * | spi | ) |

Enables a disabled SPI.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Returns:
  Nothing

Definition at line 308 of file spi_at32ap7000.c.

Referenced by init_spiMaster(), and init_spiSlave().

    00309 {
    00310     spi->cr = (1<<AVR32_SPI_CR_SPIEN_OFFSET);
    00311 }

void spi_enablePDC | ( | volatile avr32_spi_t * | spi | ) |

unsigned short spi_getRcr | ( | volatile avr32_spi_t * | spi | ) |

unsigned char spi_getStatus | ( | volatile avr32_spi_t * | spi | ) |

Get status information from the SPI.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Returns:
  Status

Return values:

  | 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 453 of file spi_at32ap7000.c.

References SPI_ERROR_MODE_FAULT, SPI_ERROR_OVERRUN, SPI_ERROR_OVERRUN_AND_MODE_FAULT, and SPI_OK.

    00454 {
    00455     unsigned char ret = 0;
    00456
    00457     if ((spi->sr & (1<<AVR32_SPI_SR_OVRES_OFFSET)) != 0) {
    00458         ret = SPI_ERROR_OVERRUN;
    00459     }
    00460
    00461     if ((spi->sr & (1<<AVR32_SPI_SR_MODF_OFFSET)) != 0) {
    00462         ret += SPI_ERROR_MODE_FAULT;
    00463     }
    00464
    00465     if (ret == (SPI_ERROR_OVERRUN + SPI_ERROR_MODE_FAULT)) {
    00466         return SPI_ERROR_OVERRUN_AND_MODE_FAULT;
    00467     }
    00468     else if (ret > 0) {
    00469         return ret;
    00470     } else {
    00471         return SPI_OK;
    00472     }
    00473 }

unsigned short spi_getTcr | ( | volatile avr32_spi_t * | spi | ) |

int spi_initMaster | ( | volatile avr32_spi_t * | spi,
|  | spi_options_t * | options |
| ) |  |  |

Setup the SPI module in master mode.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct
  | options | Pointer struct containing setup for a chip register

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 135 of file spi_at32ap7000.c.

References spi_options_t::fdiv, spi_options_t::modfdis, SPI_ERROR_ARGUMENT, and SPI_OK.

Referenced by init_spiMaster().

    00136 {
    00137     if (options->modfdis > 1) {
    00138         return SPI_ERROR_ARGUMENT;
    00139     }
    00140
    00141     if (options->fdiv > 1) {
    00142         return SPI_ERROR_ARGUMENT;
    00143     }
    00144
    00145     /* Reset */
    00146     spi->cr = AVR32_SPI_CR_SWRST_MASK;
    00147
    00148     /* Master Mode */
    00149     spi->mr = AVR32_SPI_MR_MSTR_MASK|
    00150         (options->fdiv<<AVR32_SPI_MR_FDIV_OFFSET)|
    00151         (options->modfdis<<AVR32_SPI_MR_MODFDIS_OFFSET);
    00152
    00153     return SPI_OK;
    00154 }

int spi_initSlave | ( | volatile avr32_spi_t * | spi,
|  | unsigned char | bits,
|  | unsigned char | spi_mode |
| ) |  |  |

Initialize the SPI in slave mode.

Parameters:

  | 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

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 72 of file spi_at32ap7000.c.

References SPI_ERROR_ARGUMENT, and SPI_OK.

Referenced by init_spiSlave().

    00075 {
    00076     /* Reset */
    00077     spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET);
    00078
    00079     /* The number of bits and clock polarity/phase have to be set in
    00080        csr0 for the SPI to communcate in slave mode */
    00081     if (bits > 16 || bits < 8) {
    00082         return SPI_ERROR_ARGUMENT;
    00083     }
    00084
    00085     spi->csr0 = (bits - 8) << AVR32_SPI_CSR0_BITS_OFFSET;
    00086
    00087     switch(spi_mode) {
    00088         case 0:
    00089             spi->csr0 |= (1 << AVR32_SPI_CSR0_NCPHA_OFFSET);
    00090         case 1:
    00091             break;
    00092         case 2:
    00093             spi->csr0 |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
    00094         case 3:
    00095             spi->csr0 |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
    00096             break;
    00097         default: /* Not in legal range */
    00098             return SPI_ERROR_ARGUMENT;
    00099     }
    00100
    00101     return SPI_OK;
    00102 }

int spi_initTest | ( | volatile avr32_spi_t * | spi | ) |

Setup the SPI in a test mode where the transmitter is connected to the receiver.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Returns:
  Status

Return values:

  | SPI_OK | on success

Definition at line 113 of file spi_at32ap7000.c.

References SPI_OK.

    00114 {
    00115     /* Reset */
    00116     spi->cr = (1<<AVR32_SPI_CR_SWRST_OFFSET);
    00117     /* Master Mode */
    00118     spi->mr |= (1<<AVR32_SPI_MR_MSTR_OFFSET);
    00119     /* Local Loopback */
    00120     spi->mr |= (1<<AVR32_SPI_MR_LLB_OFFSET);
    00121
    00122     return SPI_OK;
    00123 }

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.

Parameters:

  | spi | pointer to the correct avr32_spi_t struct
  | data | the received block of data (8 to 16 bits)

Returns:
  status or error code

Return values:

  | SPI_OK | on success
  | SPI_ERROR_TIMEOUT | on timeout waiting for data

Definition at line 423 of file spi_at32ap7000.c.

References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.

Referenced by spi_slaveReceiveAndCompare().

    00424 {
    00425     unsigned int timeout = SPI_TIMEOUT;
    00426
    00427     do {
    00428         --timeout;
    00429     } while ((spi->sr & AVR32_SPI_SR_RDRF_MASK) == 0 && timeout > 0);
    00430
    00431     if (timeout == 0) {
    00432         return SPI_ERROR_TIMEOUT;
    00433     }
    00434
    00435     *data = spi->rdr & 0x0000FFFF;
    00436
    00437     return SPI_OK;
    00438 }

unsigned char spi_readRegisterFullCheck | ( | volatile avr32_spi_t * | spi | ) |

Check if there is data in the receive register.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Returns:
  Status

Return values:

  | 1 | when there is data in RDR
  | 0 | when there is not data in RDR

Definition at line 403 of file spi_at32ap7000.c.

Referenced by main().

    00404 {
    00405     if ((spi->sr & AVR32_SPI_SR_RDRF_MASK) != 0) {
    00406         return 1;
    00407     } else {
    00408         return 0;
    00409     }
    00410 }

void spi_reset | ( | volatile avr32_spi_t * | spi | ) |

Resets the SPI controller.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct

Definition at line 56 of file spi_at32ap7000.c.

    00057 {
    00058     spi->cr = AVR32_SPI_CR_SWRST_MASK;
    00059 }

int spi_selectChip | ( | volatile avr32_spi_t * | spi,
|  | unsigned char | chip |
| ) |  |  |

Select slave chip.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct
  | chip | Slave chip number (normal: 0-3, \ extarnaly decoded signal: 0-15)

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 202 of file spi_at32ap7000.c.

References SPI_ERROR_ARGUMENT, and SPI_OK.

Referenced by init_spiMaster().

    00203 {
    00204     /* Assert all lines; no peripheral is selected */
    00205     spi->mr |= (0xF << AVR32_SPI_MR_PCS_OFFSET);
    00206
    00207     if ((spi->mr & (1<<AVR32_SPI_MR_PCSDEC_OFFSET)) != 0) {
    00208         /* The signal is decoded; allow up to 16 chips */
    00209         if (chip > 15) {
    00210             return SPI_ERROR_ARGUMENT;
    00211         }
    00212
    00213         spi->mr |= 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).

Parameters:

  | 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

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 170 of file spi_at32ap7000.c.

References SPI_ERROR_ARGUMENT, and SPI_OK.

Referenced by init_spiMaster().

    00174 {
    00175     if (variable_ps > 1) {
    00176         return SPI_ERROR_ARGUMENT;
    00177     }
    00178
    00179     if (pcs_decode > 1) {
    00180         return SPI_ERROR_ARGUMENT;
    00181     }
    00182
    00183     spi->mr |=
    00184         (variable_ps<<AVR32_SPI_MR_PS_OFFSET)|
    00185         (pcs_decode<<AVR32_SPI_MR_PCSDEC_OFFSET)|
    00186         (delay<<AVR32_SPI_MR_DLYBCS_OFFSET);
    00187
    00188     return SPI_OK;
    00189 }

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,
|  | 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.

Parameters:

  | 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

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 240 of file spi_at32ap7000.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().

    00243 {
    00244     unsigned long csr;
    00245
    00246     if (options->bits > 16 || options->bits < 8) {
    00247         return SPI_ERROR_ARGUMENT;
    00248     }
    00249
    00250     if (options->stay_act > 1) {
    00251         return SPI_ERROR_ARGUMENT;
    00252     }
    00253
    00254     int baudDiv = getBaudDiv(options, cpuHz);
    00255
    00256     if (baudDiv < 0) {
    00257         return -baudDiv;
    00258     }
    00259
    00260     /* Will use CSR0 offsets; these are the same for CSR0 - CSR3 */
    00261     csr = ((options->bits - 8)<<AVR32_SPI_CSR0_BITS_OFFSET)|
    00262         (baudDiv<<AVR32_SPI_CSR0_SCBR_OFFSET)|
    00263         (options->spck_delay<<AVR32_SPI_CSR0_DLYBS_OFFSET)|
    00264         (options->trans_delay<<AVR32_SPI_CSR0_DLYBCT_OFFSET)|
    00265         (options->stay_act<<AVR32_SPI_CSR0_CSAAT_OFFSET);
    00266
    00267     switch(options->spi_mode) {
    00268         case 0:
    00269             csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
    00270         case 1:
    00271             break;
    00272         case 2:
    00273             csr |= (1<<AVR32_SPI_CSR0_NCPHA_OFFSET);
    00274         case 3:
    00275             csr |= (1<<AVR32_SPI_CSR0_CPOL_OFFSET);
    00276             break;
    00277         default: /* Not in legal range */
    00278             return SPI_ERROR_ARGUMENT;
    00279     }
    00280
    00281     switch(options->reg) {
    00282         case 0:
    00283             spi->csr0 = csr;
    00284             break;
    00285         case 1:
    00286             spi->csr1 = csr;
    00287             break;
    00288         case 2:
    00289             spi->csr2 = csr;
    00290             break;
    00291         case 3:
    00292             spi->csr3 = csr;
    00293             break;
    00294         default:
    00295             return SPI_ERROR_ARGUMENT;
    00296     }
    00297
    00298     return SPI_OK;
    00299 }

int spi_unselectChip | ( | volatile avr32_spi_t * | spi,
|  | unsigned char | 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.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct
  | data | The block to write
  | pcs | Slave select (bit0 -> ncs_line0, bit1 -> ncs_line1, ...) SPI_NPCS0 SPI_NPCS1 SPI_NPCS2 SPI_NPCS3
  | lastxfer | Last transfer to slave 0 when there is more transfers to the slave 1 when there is no more transfers to the slave

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_ERROR_ARGUMENT | when invalid arguments are passed

Definition at line 372 of file spi_at32ap7000.c.

References SPI_ERROR_ARGUMENT, SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.

    00374 {
    00375     unsigned int timeout = SPI_TIMEOUT;
    00376
    00377     if (pcs > 15 || lastxfer > 1)
    00378         return SPI_ERROR_ARGUMENT;
    00379
    00380     while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && --timeout) {
    00381     }
    00382
    00383     if (timeout == 0) {
    00384         return SPI_ERROR_TIMEOUT;
    00385     }
    00386
    00387     spi->tdr = (data << AVR32_SPI_TDR_TD_OFFSET) |
    00388         (pcs << AVR32_SPI_TDR_PCS_OFFSET) |
    00389         (lastxfer << AVR32_SPI_TDR_LASTXFER_OFFSET);
    00390
    00391     return SPI_OK;
    00392 }

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.

Parameters:

  | spi | Pointer to the correct avr32_spi_t struct
  | data | The block to write

Returns:
  Status

Return values:

  | SPI_OK | on success
  | SPI_TIMEOUT | on timeout

Definition at line 337 of file spi_at32ap7000.c.

References SPI_ERROR_TIMEOUT, SPI_OK, and SPI_TIMEOUT.

Referenced by spi_masterSend().

    00338 {
    00339     unsigned int timeout = SPI_TIMEOUT;
    00340
    00341     while ((spi->sr & AVR32_SPI_SR_TXEMPTY_MASK) == 0 && timeout > 0) {
    00342         --timeout;
    00343     }
    00344
    00345     if (timeout == 0) {
    00346         return SPI_ERROR_TIMEOUT;
    00347     }
    00348
    00349     spi->tdr = data & 0x0000FFFF;
    00350
    00351     return SPI_OK;
    00352 }