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

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

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

Definition in file spi_example.c.

`#include <avr32/io.h>`
`#include "spi_at32ap7000.h"`
`#include "gpio.h"`

Go to the source code of this file.

## Defines
#define | BUFFERSIZE 64
| Number of bytes in the receive buffer when operating in slave mode.
#define | CPUHZ 20000000
| CPU core speed in Hz.
#define | SPI_BITS 8
| Number of bits in each SPI package.
#define | SPI_MASTER_SPEED 125000
| SPI master speed in Hz.
#define | SPI_SLAVE_SPEED 160000
| SPI slave speed in Hz.
#define | TIMEOUT CPUHZ/200
| A adjustable delay avoiding multiple requests on the switches.
## 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.
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.

## Define Documentation

#define BUFFERSIZE 64

Number of bytes in the receive buffer when operating in slave mode.

Definition at line 161 of file spi_example.c.

Referenced by spi_slaveReceiveAndCompare().

#define CPUHZ 20000000

CPU core speed in Hz.

Definition at line 159 of file spi_example.c.

Referenced by main().

#define SPI_BITS 8

Number of bits in each SPI package.

Definition at line 166 of file spi_example.c.

Referenced by init_spiMaster(), and init_spiSlave().

#define SPI_MASTER_SPEED 125000

SPI master speed in Hz.

Definition at line 170 of file spi_example.c.

Referenced by init_spiMaster().

#define SPI_SLAVE_SPEED 160000

SPI slave speed in Hz.

Definition at line 168 of file spi_example.c.

Referenced by init_spiSlave().

#define TIMEOUT CPUHZ/200

A adjustable delay avoiding multiple requests on the switches.

Definition at line 164 of file spi_example.c.

Referenced by main(), and rgb_blinkColor().

## Typedef Documentation

typedef unsigned char avr32_piomap_t[][2]

Map over PIO for setup of peripherals.

Definition at line 205 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 219 of file spi_example.c.

References spi_options_t::baudrate, spi_options_t::bits, 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().

    00220 {
    00221   volatile avr32_pio_t *pioc = &AVR32_PIOC;
    00222   spi_options_t spiOptions;
    00223
    00224   spiOptions.reg = 0;
    00225   spiOptions.baudrate = SPI_MASTER_SPEED;
    00226   spiOptions.bits = SPI_BITS;
    00227   spiOptions.spck_delay = 0;
    00228   spiOptions.trans_delay = 4;
    00229   spiOptions.stay_act = 0;
    00230   spiOptions.spi_mode = 1;
    00231   spiOptions.modfdis = 0;
    00232
    00233   /* Initialize as master */
    00234   spi_initMaster(spi, &spiOptions);
    00235
    00236   /* Set master mode; variable_ps, pcs_decode, delay */
    00237   spi_selectionMode(spi, 0, 0, 0);
    00238
    00239   /* Select slave chip 0 (SPI_NPCS0) */
    00240   spi_selectChip(spi, 0);
    00241
    00242   spi_setupChipReg(spi, &spiOptions, cpuHz);
    00243
    00244   spi_enable(spi);
    00245
    00246   pioc->sodr = (1<<AVR32_PIO_P7)|(1<<AVR32_PIO_P0);
    00247   pioc->codr = (1<<AVR32_PIO_P6)|(1<<AVR32_PIO_P1);
    00248   rgb_setColor(pioc, 0);
    00249 }

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 257 of file spi_example.c.

References spi_options_t::baudrate, spi_options_t::bits, 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().

    00258 {
    00259   volatile avr32_pio_t *pioc = &AVR32_PIOC;
    00260
    00261   spi_options_t spiOptions;
    00262
    00263   spiOptions.reg = 0;
    00264   spiOptions.baudrate = SPI_SLAVE_SPEED;
    00265   spiOptions.bits = SPI_BITS;
    00266   spiOptions.spck_delay = 0;
    00267   spiOptions.trans_delay = 4;
    00268   spiOptions.stay_act = 0;
    00269   spiOptions.spi_mode = 1;
    00270   spiOptions.modfdis = 0;
    00271
    00272   /* Initialize as slave; bits, spi_mode */
    00273   spi_initSlave(spi, 8, 1);
    00274
    00275   spi_setupChipReg(spi, &spiOptions, cpuHz);
    00276
    00277   spi_enable(spi);
    00278
    00279   pioc->sodr = (1<<AVR32_PIO_P6)|(1<<AVR32_PIO_P0);
    00280   pioc->codr = (1<<AVR32_PIO_P7)|(1<<AVR32_PIO_P1);
    00281   rgb_setColor(pioc, 0);
    00282 }

int main | ( | void |  | ) |

Main function, executing starts here.

Returns:
  0 on success

Definition at line 455 of file spi_example.c.

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

    00456 {
    00457   volatile avr32_pio_t *pioa = &AVR32_PIOA;
    00458   volatile avr32_pio_t *piob = &AVR32_PIOB;
    00459   volatile avr32_pio_t *pioc = &AVR32_PIOC;
    00460   volatile avr32_spi_t *spi = &AVR32_SPI0;
    00461   char masterMode = 0;
    00462
    00463   gpio_map_t spi_piomap = {          \
    00464     {AVR32_SPI0_SCK_0_PIN, AVR32_SPI0_SCK_0_FUNCTION},  \
    00465     {AVR32_SPI0_MISO_0_PIN, AVR32_SPI0_MISO_0_FUNCTION},  \
    00466     {AVR32_SPI0_MOSI_0_PIN, AVR32_SPI0_MOSI_0_FUNCTION},  \
    00467     {AVR32_SPI0_NPCS_0_PIN, AVR32_SPI0_NPCS_0_FUNCTION},  \
    00468     {AVR32_SPI0_NPCS_1_PIN, AVR32_SPI0_NPCS_1_FUNCTION},  \
    00469     {AVR32_SPI0_NPCS_2_PIN, AVR32_SPI0_NPCS_2_FUNCTION},  \
    00470     {AVR32_SPI0_NPCS_3_PIN, AVR32_SPI0_NPCS_3_FUNCTION},  \
    00471   };
    00472
    00473   /* Disable all interrupts on PIO */
    00474   pioa->idr = 0xFFFFffff;
    00475   piob->idr = 0xFFFFffff;
    00476   pioc->idr = 0xFFFFffff;
    00477
    00478   /* Enable PIO on PIOB and clear all bits
    00479    * This is used for status information on LEDS and signals from switches
    00480    *
    00481    * LED0 - system is on and ready
    00482    * LED1 - system is receiving/sending data on SPI
    00483    * LED3 - system is comparing received data from SPI with expected data
    00484    * LED6 - system is in slave mode
    00485    * LED7 - system is in master mode
    00486    *
    00487    * PIOB: P0 to P7 is used for switches
    00488    * PIOC: P0 to P7 is used for LEDs
    00489    * PIOC: P8 to P13 is used for RGB LEDs
    00490    */
    00491   piob->per = 0x000000FF;
    00492   piob->odr = 0x000000FF;
    00493   piob->puer = 0x000000FF;
    00494
    00495   pioc->per = 0x0000FFFF;
    00496   pioc->oer = 0x0000FFFF;
    00497   pioc->ower = 0x0000FFFF;
    00498   pioc->codr = 0x0000FFFF;
    00499
    00500   /* Init PIO */
    00501   gpio_enable_module(spi_piomap, 7);
    00502
    00503   pioc->codr = 0x000000FF;
    00504   pioc->sodr = 0x000000AA;
    00505   rgb_setColor(pioc, 1);
    00506
    00507   int buttonTimer = 0;
    00508   char *textString = "Atmel AVR32 SPI test application\r\n";
    00509   char *textStringAlt = "AVR32 SPI Atmel test application\r\n";
    00510   char *textStringToLong = "This string is far to long to be used " \
    00511       "in Atmel AVR32 SPI test application\r\n";
    00512
    00513   rgb_setColor(pioc, 0);
    00514   init_spiSlave(spi, CPUHZ);
    00515
    00516   for (;;) {
    00517     /* SW7 is used to switch between master and slave mode */
    00518     if ((piob->pdsr & AVR32_PIO_P7_MASK) == 0
    00519         && buttonTimer <= 0) {
    00520       buttonTimer = TIMEOUT;
    00521
    00522       if (masterMode == 1) {
    00523         init_spiSlave(spi, CPUHZ);
    00524         masterMode = 0;
    00525       } else {
    00526         init_spiMaster(spi, CPUHZ);
    00527         masterMode = 1;
    00528       }
    00529     }
    00530
    00531     /* Actions for master mode
    00532      * SW5 sends "Atmel AVR32 SPI test application\r\n" on SPI
    00533      * SW4 sends "AVR32 SPI Atmel test application\r\n" on SPI
    00534      * SW3 sends "This string is far to long to be used in Atmel AVR32 SPI test application\r\n"
    00535      */
    00536     if (masterMode == 1) {
    00537       if ((piob->pdsr & AVR32_PIO_P5_MASK) == 0
    00538             && buttonTimer <= 0) {
    00539         buttonTimer = TIMEOUT;
    00540         spi_masterSend(spi, textString);
    00541       } else if ((piob->pdsr & AVR32_PIO_P4_MASK) == 0
    00542           && buttonTimer <= 0) {
    00543         buttonTimer = TIMEOUT;
    00544         spi_masterSend(spi, textStringAlt);
    00545       } else if ((piob->pdsr & AVR32_PIO_P3_MASK) == 0
    00546             && buttonTimer <= 0) {
    00547         buttonTimer = TIMEOUT;
    00548         spi_masterSend(spi, textStringToLong);
    00549       }
    00550
    00551     /* Slave mode polls if there is an incoming message on SPI */
    00552     } else {
    00553       if (spi_readRegisterFullCheck(spi) == 1) {
    00554         spi_slaveReceiveAndCompare(spi, textString);
    00555       }
    00556     }
    00557
    00558     if (buttonTimer > 0) {
    00559       --buttonTimer;
    00560     }
    00561   }
    00562 }

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 335 of file spi_example.c.

References rgb_setColor(), and TIMEOUT.

Referenced by spi_slaveReceiveAndCompare().

    00336 {
    00337   volatile int pauseTimer = TIMEOUT/4;
    00338   volatile int pauseRepeat = 10;
    00339
    00340   do{
    00341     do{
    00342       --pauseTimer;
    00343     } while (pauseTimer > 0);
    00344
    00345     pauseTimer = TIMEOUT/4;
    00346
    00347     if ((pauseRepeat % 2) == 1) {
    00348       rgb_setColor(pio, 0);
    00349     } else {
    00350       rgb_setColor(pio, color);
    00351     }
    00352
    00353     --pauseRepeat;
    00354   } while (pauseRepeat > 0);
    00355 }

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 296 of file spi_example.c.

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

    00297 {
    00298   pio->codr = 0x00003F00;
    00299
    00300   switch(color) {
    00301     case 0:
    00302       break;
    00303     case 1:
    00304       pio->sodr = 0x00000300;
    00305       break;
    00306     case 2:
    00307       pio->sodr = 0x00000C00;
    00308       break;
    00309     case 3:
    00310       pio->sodr = 0x00003000;
    00311       break;
    00312     case 4:
    00313       pio->sodr = 0x00000F00;
    00314       break;
    00315     case 5:
    00316       pio->sodr = 0x00003F00;
    00317       break;
    00318     default:
    00319       break;
    00320   }
    00321 }

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 363 of file spi_example.c.

References SPI_OK, and spi_write().

Referenced by main().

    00364 {
    00365   volatile avr32_pio_t *pioc = &AVR32_PIOC;
    00366   int error;
    00367   char *textStringPtr = string;
    00368
    00369   pioc->codr = (1<<AVR32_PIO_P0);
    00370   pioc->sodr = (1<<AVR32_PIO_P1);
    00371
    00372   do {
    00373     error = spi_write(spi, (unsigned short) *textStringPtr);
    00374   } while (*textStringPtr++ != '\n');
    00375
    00376   pioc->codr = (1<<AVR32_PIO_P1);
    00377   pioc->sodr = (1<<AVR32_PIO_P0);
    00378
    00379   if (error != SPI_OK) {
    00380   }
    00381 }

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 390 of file spi_example.c.

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

Referenced by main().

    00391 {
    00392   int error = 0;
    00393   int index = 0;
    00394   int receivedChars = 0;
    00395   char *textStringPtr = string;
    00396   unsigned short receiveBuffer[BUFFERSIZE];
    00397   volatile avr32_pio_t *pioc = &AVR32_PIOC;
    00398
    00399   pioc->sodr = AVR32_PIO_P1_MASK|AVR32_PIO_P3_MASK;
    00400   rgb_setColor(pioc, 4);
    00401
    00402   do {
    00403     int errVal = SPI_OK;
    00404
    00405     errVal = spi_read(spi, &receiveBuffer[index]);
    00406
    00407     if (errVal == SPI_OK) {
    00408       ++index;
    00409       ++receivedChars;
    00410     }
    00411
    00412     /* break on buffer overflow */
    00413     if (receivedChars > BUFFERSIZE) {
    00414       error = BUFFERSIZE + 1;
    00415       break;
    00416     }
    00417
    00418   } while (receiveBuffer[index - 1] != '\n');
    00419
    00420   index = 0;
    00421   pioc->codr = AVR32_PIO_P1_MASK;
    00422   rgb_blinkColor(pioc, 4);
    00423
    00424   /* compare received buffer with expected text string */
    00425   do {
    00426     if ((receiveBuffer[index++] & 0x00FF)
    00427         != ((*textStringPtr++) & 0x00FF)) {
    00428       ++error;
    00429     }
    00430   } while (*textStringPtr != '\n');
    00431
    00432   /* print result on RGB LEDs
    00433    * error > BUFFERSIZE - buffer overflow
    00434    * error > 0 - string mismatch
    00435    * error = 0 - no error
    00436    */
    00437   if (error > BUFFERSIZE) {
    00438     rgb_blinkColor(pioc, 1);
    00439     rgb_setColor(pioc, 1);
    00440   }
    00441   else if (error > 0) {
    00442     rgb_setColor(pioc, 1);
    00443   } else {
    00444     rgb_setColor(pioc, 2);
    00445   }
    00446
    00447   pioc->codr = (1<<AVR32_PIO_P3);
    00448 }