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.
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 unsigned char avr32_piomap_t[][2] |
| void init_spiMaster | ( | volatile avr32_spi_t * | spi, | |
| long | cpuHz | |||
| ) |
initialise SPI in master mode
| 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
| 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.
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.
| piomap | a map describing how the setup of the PIO | |
| size | number of elements in the map |
| 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.
| pio | Pointer to an avr32_pio_t struct for RBG blinking | |
| color | The color of the LED when active
|
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.
| pio | Pointer to an avr32_pio_t struct for RGB blinking | |
| color | The color of the LED
|
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.
| 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.
| 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:

1.5.1