spi.c 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.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr32@atmel.com
Name
RELEASE_1_0
Revision
1.9
RCSfile
spi.c,v
Date
2006/05/09 11:25:42

Definition in file spi.c.

#include "spi.h"

Include dependency graph for spi.c:

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.


Function Documentation

int getBaudDiv ( struct spi_options_t options,
int  cpuHz 
)

Calculate the baudrate division.

Parameters:
options Pointer to a spi_options_t struct
cpuHz the clock frequency in Hz for the peripheral bus
Returns:
division factor or error code
Return values:
>= 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  ) 

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 324 of file spi.c.

00325 {
00326         spi->cr = (1<<AVR32_SPI_CR_SPIDIS_OFFSET);
00327 }

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 311 of file spi.c.

Referenced by init_spiMaster().

00312 {
00313         spi->cr = (1<<AVR32_SPI_CR_SPIEN_OFFSET);
00314 }

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

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

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

Parameters:
spi Pointer to the correct avr32_spi_t struct
Returns:
Status
Return values:
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.

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

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

Resets the SPI controller.

Parameters:
spi Pointer to the correct avr32_spi_t struct

Definition at line 59 of file spi.c.

00060 {
00061         spi->cr = AVR32_SPI_CR_SWRST_MASK;
00062 }

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

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

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 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 }

Here is the call graph for this function:

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

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 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 }


Generated on Wed May 7 16:03:17 2008 for AVR32114 Using the AVR32 LCD Controller by  doxygen 1.5.3-20071008