spi_example.c File Reference


Detailed Description

SPI bus example application.

This file gives an example of using the SPI bus driver for both slave and master mode. It sends a text string to a slave in master mode, and in slave mode it receives data and try to compare this data with an expected string.

LEDs on STK1000 is used to give feedback to the user. The switches on STK1000 is used to change mode and send text strings.

Author:
Atmel Corporation: http://www.atmel.com
Support email: avr32@atmel.com
Revision
508
Date
2007-05-21 20:06:51 +0200 (Mon, 21 May 2007)

Definition in file spi_example.c.

#include "settings.h"
#include "spi.h"

Include dependency graph for spi_example.c:

Go to the source code of this file.

Typedefs

typedef unsigned char avr32_piomap_t [][2]
 Map over PIO for setup of peripherals.

Functions

void init_spiMaster (volatile avr32_spi_t *spi, long cpuHz)
 initialise SPI in master mode
void init_spiSlave (volatile avr32_spi_t *spi, long cpuHz)
 initialise SPI in slave mode
int main (void)
 Main function, executing starts here.
int pio_enable_module (avr32_piomap_t piomap, unsigned int size)
 Set the pins under module control.
void rgb_blinkColor (volatile avr32_pio_t *pio, unsigned char color)
 Function which blinks the RGB leds in a given color.
void rgb_setColor (volatile avr32_pio_t *pio, unsigned char color)
 Function to set the color of the RGB LEDs.
void spi_masterSend (volatile avr32_spi_t *spi, char *string)
 Send a text string to the SPI.
void spi_slaveReceive_and_compare (volatile avr32_spi_t *spi, char *string)
void spi_slaveReceiveAndCompare (volatile avr32_spi_t *spi, char *string)
 Receive a text and compare it to excpected text.


Typedef Documentation

typedef unsigned char avr32_piomap_t[][2]

Map over PIO for setup of peripherals.

Definition at line 100 of file spi_example.c.


Function Documentation

void init_spiMaster ( volatile avr32_spi_t *  spi,
long  cpuHz 
)

initialise SPI in master mode

Parameters:
spi Pointer to the correct avr32_spi_t struct
cpuHz CPU clock frequency in Hz

Definition at line 116 of file spi_example.c.

References spi_options_t::baudrate, spi_options_t::bits, spi_options_t::fdiv, spi_options_t::modfdis, spi_options_t::reg, rgb_setColor(), spi_options_t::spck_delay, SPI_BITS, spi_enable(), spi_initMaster(), SPI_MASTER_SPEED, spi_options_t::spi_mode, spi_selectChip(), spi_selectionMode(), spi_setupChipReg(), spi_options_t::stay_act, and spi_options_t::trans_delay.

Referenced by main().

00117 {
00118     volatile avr32_pio_t *pioc = &AVR32_PIOC;
00119 
00120     struct spi_options_t spiOptions;
00121 
00122     spiOptions.reg = 0;
00123     spiOptions.baudrate = SPI_MASTER_SPEED;
00124     spiOptions.bits = SPI_BITS;
00125     spiOptions.spck_delay = 0;
00126     spiOptions.trans_delay = 4;
00127     spiOptions.stay_act = 0;
00128     spiOptions.spi_mode = 1;
00129     spiOptions.fdiv = 0;
00130     spiOptions.modfdis = 0;
00131 
00132     /* Initialize as master */
00133     spi_initMaster(spi, &spiOptions);
00134 
00135     /* Set master mode; variable_ps, pcs_decode, delay */
00136     spi_selectionMode(spi, 0, 0, 0);
00137 
00138     /* Select slave chip 0 (SPI_NPCS0) */
00139     spi_selectChip(spi, 0);
00140 
00141     spi_setupChipReg(spi, &spiOptions, cpuHz);
00142 
00143     spi_enable(spi);
00144 
00145     pioc->sodr = (1<<AVR32_PIO_P7)|(1<<AVR32_PIO_P0);
00146     pioc->codr = (1<<AVR32_PIO_P6)|(1<<AVR32_PIO_P1);
00147     rgb_setColor(pioc, 0);
00148 }

Here is the call graph for this function:

void init_spiSlave ( volatile avr32_spi_t *  spi,
long  cpuHz 
)

initialise SPI in slave mode

Parameters:
spi Pointer to the correct avr32_spi_t struct
cpuHz CPU clock frequency in Hz

Definition at line 156 of file spi_example.c.

References spi_options_t::baudrate, spi_options_t::bits, spi_options_t::fdiv, spi_options_t::modfdis, spi_options_t::reg, rgb_setColor(), spi_options_t::spck_delay, SPI_BITS, spi_enable(), spi_initSlave(), spi_options_t::spi_mode, spi_setupChipReg(), SPI_SLAVE_SPEED, spi_options_t::stay_act, and spi_options_t::trans_delay.

Referenced by main().

00157 {
00158     volatile avr32_pio_t *pioc = &AVR32_PIOC;
00159 
00160     struct spi_options_t spiOptions;
00161 
00162     spiOptions.reg = 0;
00163     spiOptions.baudrate = SPI_SLAVE_SPEED;
00164     spiOptions.bits = SPI_BITS;
00165     spiOptions.spck_delay = 0;
00166     spiOptions.trans_delay = 4;
00167     spiOptions.stay_act = 0;
00168     spiOptions.spi_mode = 1;
00169     spiOptions.fdiv = 0;
00170     spiOptions.modfdis = 0;
00171 
00172     /* Initialize as slave; bits, spi_mode */
00173     spi_initSlave(spi, 8, 1);
00174 
00175     spi_setupChipReg(spi, &spiOptions, cpuHz);
00176 
00177     spi_enable(spi);
00178 
00179     pioc->sodr = (1<<AVR32_PIO_P6)|(1<<AVR32_PIO_P0);
00180     pioc->codr = (1<<AVR32_PIO_P7)|(1<<AVR32_PIO_P1);
00181     rgb_setColor(pioc, 0);
00182 }

Here is the call graph for this function:

int main ( void   ) 

Main function, executing starts here.

Returns:
0 on success

Definition at line 355 of file spi_example.c.

References CPUHZ, init_spiMaster(), init_spiSlave(), pio_enable_module(), rgb_setColor(), spi_masterSend(), SPI_OK, spi_readRegisterFullCheck(), spi_slaveReceiveAndCompare(), and TIMEOUT.

00356 {
00357     volatile avr32_pio_t *pioa = &AVR32_PIOA;
00358     volatile avr32_pio_t *piob = &AVR32_PIOB;
00359     volatile avr32_pio_t *pioc = &AVR32_PIOC;
00360     volatile avr32_spi_t *spi = &AVR32_SPI0;
00361     char masterMode = 0;
00362     int retval = SPI_OK;
00363 
00364     avr32_piomap_t spi_piomap = {                   \
00365         {AVR32_SPI0_SCK_0_PIN, AVR32_SPI0_SCK_0_FUNCTION},  \
00366         {AVR32_SPI0_MISO_0_PIN, AVR32_SPI0_MISO_0_FUNCTION},    \
00367         {AVR32_SPI0_MOSI_0_PIN, AVR32_SPI0_MOSI_0_FUNCTION},    \
00368         {AVR32_SPI0_NPCS_0_PIN, AVR32_SPI0_NPCS_0_FUNCTION},    \
00369         {AVR32_SPI0_NPCS_1_PIN, AVR32_SPI0_NPCS_1_FUNCTION},    \
00370         {AVR32_SPI0_NPCS_2_PIN, AVR32_SPI0_NPCS_2_FUNCTION},    \
00371         {AVR32_SPI0_NPCS_3_PIN, AVR32_SPI0_NPCS_3_FUNCTION},    \
00372     };
00373 
00374     /* Disable all interrupts on PIO */
00375     pioa->idr = 0xFFFFffff;
00376     piob->idr = 0xFFFFffff;
00377     pioc->idr = 0xFFFFffff;
00378 
00379     /* Enable PIO on PIOB and clear all bits
00380      * This is used for status information on LEDS and signals from switches
00381      *
00382      * LED0 - system is on and ready
00383      * LED1 - system is receiving/sending data on SPI
00384      * LED3 - system is comparing received data from SPI with expected data
00385      * LED6 - system is in slave mode
00386      * LED7 - system is in master mode
00387      *
00388      * PIOB: P0 to P7 is used for switches
00389      * PIOC: P0 to P7 is used for LEDs
00390      * PIOC: P8 to P13 is used for RGB LEDs
00391      */
00392     piob->per = 0x000000FF;
00393     piob->odr = 0x000000FF;
00394     piob->puer = 0x000000FF;
00395 
00396     pioc->per = 0x0000FFFF;
00397     pioc->oer = 0x0000FFFF;
00398     pioc->ower = 0x0000FFFF;
00399     pioc->codr = 0x0000FFFF;
00400 
00401     /* Init PIO */
00402     retval = pio_enable_module(spi_piomap, 7);
00403 
00404     if (retval != SPI_OK) {
00405         pioc->codr = 0x000000FF;
00406         pioc->sodr = 0x000000AA;
00407         rgb_setColor(pioc, 1);
00408         return -1;
00409     }
00410 
00411     int buttonTimer = 0;
00412     char *textString = "Atmel AVR32 SPI test application\r\n";
00413     char *textStringAlt = "AVR32 SPI Atmel test application\r\n";
00414     char *textStringToLong = "This string is far to long to be used " \
00415             "in Atmel AVR32 SPI test application\r\n";
00416 
00417     rgb_setColor(pioc, 0);
00418     init_spiSlave(spi, CPUHZ);
00419 
00420     for (;;) {
00421         /* SW7 is used to switch between master and slave mode */
00422         if ((piob->pdsr & AVR32_PIO_P7_MASK) == 0
00423                 && buttonTimer <= 0) {
00424             buttonTimer = TIMEOUT;
00425 
00426             if (masterMode == 1) {
00427                 init_spiSlave(spi, CPUHZ);
00428                 masterMode = 0;
00429             } else {
00430                 init_spiMaster(spi, CPUHZ);
00431                 masterMode = 1;
00432             }
00433         }
00434 
00435         /* Actions for master mode
00436          * SW5 sends "Atmel AVR32 SPI test application\r\n" on SPI
00437          * SW4 sends "AVR32 SPI Atmel test application\r\n" on SPI
00438          * SW3 sends "This string is far to long to be used in Atmel AVR32 SPI test application\r\n"
00439          */
00440         if (masterMode == 1) {
00441             if ((piob->pdsr & AVR32_PIO_P5_MASK) == 0
00442                         && buttonTimer <= 0) {
00443                 buttonTimer = TIMEOUT;
00444                 spi_masterSend(spi, textString);
00445             } else if ((piob->pdsr & AVR32_PIO_P4_MASK) == 0
00446                     && buttonTimer <= 0) {
00447                 buttonTimer = TIMEOUT;
00448                 spi_masterSend(spi, textStringAlt);
00449             } else if ((piob->pdsr & AVR32_PIO_P3_MASK) == 0
00450                         && buttonTimer <= 0) {
00451                 buttonTimer = TIMEOUT;
00452                 spi_masterSend(spi, textStringToLong);
00453             }
00454 
00455         /* Slave mode polls if there is an incoming message on SPI */
00456         } else {
00457             if (spi_readRegisterFullCheck(spi) == 1) {
00458                 spi_slaveReceiveAndCompare(spi, textString);
00459             }
00460         }
00461 
00462         if (buttonTimer > 0) {
00463             --buttonTimer;
00464         }
00465     }
00466 }

Here is the call graph for this function:

int pio_enable_module ( avr32_piomap_t  piomap,
unsigned int  size 
)

Set the pins under module control.

Parameters:
piomap a map describing how the setup of the PIO
size number of elements in the map
Returns:
Status or error code
Return values:
SPI_OK on success
SPI_ERROR_ARGUMENT on bad values in piomap

Definition at line 478 of file spi_example.c.

References SPI_ERROR_ARGUMENT.

Referenced by main().

00479 {
00480     int i;
00481     volatile struct avr32_pio_t *pio;
00482 
00483     /* get the base address for the port */
00484     switch(**piomap/32) {
00485 
00486         case 0:
00487             pio = &AVR32_PIOA;
00488             break;
00489         case 1:
00490             pio = &AVR32_PIOB;
00491             break;
00492         case 2:
00493             pio = &AVR32_PIOC;
00494             break;
00495         case 3:
00496             pio = &AVR32_PIOD;
00497             break;
00498         case 4:
00499             pio = &AVR32_PIOE;
00500             break;
00501         default :
00502             return SPI_ERROR_ARGUMENT;
00503 
00504     }
00505 
00506     for (i = 0; i < size; i++) {
00507 
00508         pio->pdr |= (1<<((**piomap) % 32));
00509         pio->pudr |= (1<<((**piomap) % 32));
00510 
00511         switch(*(*piomap+1)) {
00512             case 0:
00513                 pio->asr |= (1<<((**piomap) % 32));
00514                 break;
00515             case 1:
00516                 pio->bsr |= (1<<((**piomap) % 32));
00517                 break;
00518             default:
00519                 return SPI_ERROR_ARGUMENT;
00520         }
00521 
00522         ++piomap;
00523 
00524     }
00525 
00526     return SPI_OK;
00527 }

void rgb_blinkColor ( volatile avr32_pio_t *  pio,
unsigned char  color 
)

Function which blinks the RGB leds in a given color.

Parameters:
pio Pointer to an avr32_pio_t struct for RBG blinking
color The color of the LED when active
  • 0 Off
  • 1 red
  • 2 green
  • 3 blue
  • 4 orange
  • 5 white

Definition at line 235 of file spi_example.c.

References rgb_setColor(), and TIMEOUT.

Referenced by spi_slaveReceiveAndCompare().

00236 {
00237     volatile int pauseTimer = TIMEOUT/4;
00238     volatile int pauseRepeat = 10;
00239 
00240     do{
00241         do{
00242             --pauseTimer;
00243         } while (pauseTimer > 0);
00244 
00245         pauseTimer = TIMEOUT/4;
00246 
00247         if ((pauseRepeat % 2) == 1) {
00248             rgb_setColor(pio, 0);
00249         } else {
00250             rgb_setColor(pio, color);
00251         }
00252 
00253         --pauseRepeat;
00254     } while (pauseRepeat > 0);
00255 }

Here is the call graph for this function:

void rgb_setColor ( volatile avr32_pio_t *  pio,
unsigned char  color 
)

Function to set the color of the RGB LEDs.

Parameters:
pio Pointer to an avr32_pio_t struct for RGB blinking
color The color of the LED
  • 0 Off
  • 1 red
  • 2 green
  • 3 blue
  • 4 orange
  • 5 white

Definition at line 196 of file spi_example.c.

Referenced by init_spiMaster(), init_spiSlave(), main(), rgb_blinkColor(), and spi_slaveReceiveAndCompare().

00197 {
00198     pio->codr = 0x00003F00;
00199 
00200     switch(color) {
00201         case 0:
00202             break;
00203         case 1:
00204             pio->sodr = 0x00000300;
00205             break;
00206         case 2:
00207             pio->sodr = 0x00000C00;
00208             break;
00209         case 3:
00210             pio->sodr = 0x00003000;
00211             break;
00212         case 4:
00213             pio->sodr = 0x00000F00;
00214             break;
00215         case 5:
00216             pio->sodr = 0x00003F00;
00217             break;
00218         default:
00219             break;
00220     }
00221 }

void spi_masterSend ( volatile avr32_spi_t *  spi,
char *  string 
)

Send a text string to the SPI.

Parameters:
spi Pointer to the correct avr32_spi_t struct
string The text string to send on the SPI buss, terminated with a \n

Definition at line 263 of file spi_example.c.

References SPI_OK, and spi_write().

Referenced by main().

00264 {
00265     volatile avr32_pio_t *pioc = &AVR32_PIOC;
00266     int error;
00267     char *textStringPtr = string;
00268 
00269     pioc->codr = (1<<AVR32_PIO_P0);
00270     pioc->sodr = (1<<AVR32_PIO_P1);
00271 
00272     do {
00273         error = spi_write(spi, (unsigned short) *textStringPtr);
00274     } while (*textStringPtr++ != '\n');
00275 
00276     pioc->codr = (1<<AVR32_PIO_P1);
00277     pioc->sodr = (1<<AVR32_PIO_P0);
00278 
00279     if (error != SPI_OK) {
00280     }
00281 }

Here is the call graph for this function:

void spi_slaveReceive_and_compare ( volatile avr32_spi_t *  spi,
char *  string 
)

void spi_slaveReceiveAndCompare ( volatile avr32_spi_t *  spi,
char *  string 
)

Receive a text and compare it to excpected text.

Parameters:
spi Pointer to the correct avr32_spi_t struct
string The text string which the received data is compared with. String is terminated with a

Definition at line 290 of file spi_example.c.

References BUFFERSIZE, rgb_blinkColor(), rgb_setColor(), SPI_OK, and spi_read().

Referenced by main().

00291 {
00292     int error = 0;
00293     int index = 0;
00294     int receivedChars = 0;
00295     char *textStringPtr = string;
00296     unsigned short receiveBuffer[BUFFERSIZE];
00297     volatile avr32_pio_t *pioc = &AVR32_PIOC;
00298 
00299     pioc->sodr = AVR32_PIO_P1_MASK|AVR32_PIO_P3_MASK;
00300     rgb_setColor(pioc, 4);
00301 
00302     do {
00303         int errVal = SPI_OK;
00304 
00305         errVal = spi_read(spi, &receiveBuffer[index]);
00306 
00307         if (errVal == SPI_OK) {
00308             ++index;
00309             ++receivedChars;
00310         }
00311 
00312         /* break on buffer overflow */
00313         if (receivedChars > BUFFERSIZE) {
00314             error = BUFFERSIZE + 1;
00315             break;
00316         }
00317 
00318     } while (receiveBuffer[index - 1] != '\n');
00319 
00320     index = 0;
00321     pioc->codr = AVR32_PIO_P1_MASK;
00322     rgb_blinkColor(pioc, 4);
00323 
00324     /* compare received buffer with expected text string */
00325     do {
00326         if ((receiveBuffer[index++] & 0x00FF)
00327                 != ((*textStringPtr++) & 0x00FF)) {
00328             ++error;
00329         }
00330     } while (*textStringPtr != '\n');
00331 
00332     /* print result on RGB LEDs
00333      * error > BUFFERSIZE - buffer overflow
00334      * error > 0 - string mismatch
00335      * error = 0 - no error
00336      */
00337     if (error > BUFFERSIZE) {
00338         rgb_blinkColor(pioc, 1);
00339         rgb_setColor(pioc, 1);
00340     }
00341     else if (error > 0) {
00342         rgb_setColor(pioc, 1);
00343     } else {
00344         rgb_setColor(pioc, 2);
00345     }
00346 
00347     pioc->codr = (1<<AVR32_PIO_P3);
00348 }

Here is the call graph for this function:


Generated on Mon May 21 20:10:40 2007 for AVR32105 - Master and Slave SPI driver by  doxygen 1.5.1