Xmega Application Note | |||||
#include "avr_compiler.h"
Go to the source code of this file.
Data Structures | |
struct | SPI_DataPacket |
SPI data packet struct. More... | |
struct | SPI_Master |
SPI master struct. Holds pointer to SPI module, buffers and necessary varibles. More... | |
struct | SPI_Slave |
SPI slave struct. Holds pointers to SPI module and used port. More... | |
Defines | |
#define | SPI_BUSY 2 |
The SPI module is busy with another transmission. | |
#define | SPI_INTERRUPTED 1 |
The transmission was interrupted by another master. | |
#define | SPI_MasterInterruptTransmissionComplete(_spi) ( (_spi)->dataPacket->complete ) |
Checks if transmission is complete. | |
#define | SPI_MasterSSHigh(_port, _pinBM) ( (_port)->OUTSET = (_pinBM) ) |
Releases SPI SS line(s). | |
#define | SPI_MasterSSLow(_port, _pinBM) ( (_port)->OUTCLR = (_pinBM) ) |
Pulls SPI SS line(s) low in order to address the slave devices. | |
#define | SPI_MISO_bm 0x40 |
Bit mask for the MISO pin. | |
#define | SPI_MOSI_bm 0x20 |
Bit mask for the MOSI pin. | |
#define | SPI_OK 0 |
The transmission completed successfully. | |
#define | SPI_SCK_bm 0x80 |
Bit mask for the SCK pin. | |
#define | SPI_SlaveDataAvailable(_spi) ( (_spi)->module->STATUS & SPI_IF_bm ) |
Check if new data is available. | |
#define | SPI_SlaveReadByte(_spi) ( (_spi)->module->DATA ) |
Read received data byte. | |
#define | SPI_SlaveWriteByte(_spi, _data) ( (_spi)->module->DATA = (_data) ) |
Write data byte to the SPI shift register. | |
#define | SPI_SS_bm 0x10 |
Bit mask for the SS pin. | |
Typedefs | |
typedef struct SPI_DataPacket | SPI_DataPacket_t |
SPI data packet struct. | |
typedef struct SPI_Master | SPI_Master_t |
SPI master struct. Holds pointer to SPI module, buffers and necessary varibles. | |
typedef struct SPI_Slave | SPI_Slave_t |
SPI slave struct. Holds pointers to SPI module and used port. | |
Functions | |
void | SPI_MasterCreateDataPacket (SPI_DataPacket_t *dataPacket, const uint8_t *transmitData, uint8_t *receiveData, uint8_t bytesToTransceive, PORT_t *ssPort, uint8_t ssPinMask) |
Create data packet. | |
void | SPI_MasterInit (SPI_Master_t *spi, SPI_t *module, PORT_t *port, bool lsbFirst, SPI_MODE_t mode, SPI_INTLVL_t intLevel, bool clk2x, SPI_PRESCALER_t clockDivision) |
Initialize SPI module as master. | |
void | SPI_MasterInterruptHandler (SPI_Master_t *spi) |
Common SPI master interrupt service routine. | |
uint8_t | SPI_MasterInterruptTransceivePacket (SPI_Master_t *spi, SPI_DataPacket_t *dataPacket) |
Start transmission. | |
uint8_t | SPI_MasterTransceiveByte (SPI_Master_t *spi, uint8_t TXdata) |
SPI mastertransceive byte. | |
bool | SPI_MasterTransceivePacket (SPI_Master_t *spi, SPI_DataPacket_t *dataPacket) |
SPI transceive data packet. | |
void | SPI_SlaveInit (SPI_Slave_t *spi, SPI_t *module, PORT_t *port, bool lsbFirst, SPI_MODE_t mode, SPI_INTLVL_t intLevel) |
Initialize SPI module as slave. |
This file contains the function prototypes and enumerator definitions for various configuration parameters for the XMEGA SPI driver.
The driver is not intended for size and/or speed critical code, since most functions are just a few lines of code, and the function call overhead would decrease code performance. The driver is intended for rapid prototyping and documentation purposes for getting started with the XMEGA SPI module.
For size and/or speed critical code, it is recommended to copy the function contents directly into your application instead of making a function call.
Copyright (c) 2008, Atmel Corporation All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. The name of ATMEL may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Definition in file spi_driver.h.
#define SPI_BUSY 2 |
The SPI module is busy with another transmission.
Definition at line 75 of file spi_driver.h.
Referenced by SPI_MasterInterruptTransceivePacket().
#define SPI_INTERRUPTED 1 |
The transmission was interrupted by another master.
Definition at line 74 of file spi_driver.h.
Referenced by SPI_MasterInterruptTransceivePacket().
#define SPI_MasterInterruptTransmissionComplete | ( | _spi | ) | ( (_spi)->dataPacket->complete ) |
Checks if transmission is complete.
_spi | Pointer to SPI_Master_t struct instance. |
true | The transmission is complete. | |
false | The transmission is in progress. |
Definition at line 120 of file spi_driver.h.
#define SPI_MasterSSHigh | ( | _port, | |||
_pinBM | ) | ( (_port)->OUTSET = (_pinBM) ) |
Releases SPI SS line(s).
_port | Pointer to the I/O port where the SS pins are located. | |
_pinBM | A bitmask selecting the pins to release. |
NA |
Definition at line 142 of file spi_driver.h.
Referenced by main(), SPI_MasterInterruptHandler(), and SPI_MasterTransceivePacket().
#define SPI_MasterSSLow | ( | _port, | |||
_pinBM | ) | ( (_port)->OUTCLR = (_pinBM) ) |
Pulls SPI SS line(s) low in order to address the slave devices.
_port | Pointer to the I/O port where the SS pins are located. | |
_pinBM | A bitmask selecting the pins to pull low. |
NA |
Definition at line 131 of file spi_driver.h.
Referenced by main(), SPI_MasterInterruptTransceivePacket(), and SPI_MasterTransceivePacket().
#define SPI_MISO_bm 0x40 |
Bit mask for the MISO pin.
Definition at line 68 of file spi_driver.h.
Referenced by SPI_SlaveInit().
#define SPI_MOSI_bm 0x20 |
Bit mask for the MOSI pin.
Definition at line 67 of file spi_driver.h.
Referenced by SPI_MasterInit().
#define SPI_OK 0 |
The transmission completed successfully.
Definition at line 73 of file spi_driver.h.
Referenced by main(), and SPI_MasterInterruptTransceivePacket().
#define SPI_SCK_bm 0x80 |
Bit mask for the SCK pin.
Definition at line 69 of file spi_driver.h.
Referenced by SPI_MasterInit().
#define SPI_SlaveDataAvailable | ( | _spi | ) | ( (_spi)->module->STATUS & SPI_IF_bm ) |
Check if new data is available.
_spi | Pointer to SPI_Slave_t struct instance. |
Definition at line 171 of file spi_driver.h.
Referenced by main().
#define SPI_SlaveReadByte | ( | _spi | ) | ( (_spi)->module->DATA ) |
Read received data byte.
_spi | Pointer to SPI_Slave_t struct instance. |
Definition at line 161 of file spi_driver.h.
#define SPI_SlaveWriteByte | ( | _spi, | |||
_data | ) | ( (_spi)->module->DATA = (_data) ) |
Write data byte to the SPI shift register.
_spi | Pointer to SPI_Slave_t struct instance. | |
_data | The data to write to the shift register. |
Definition at line 151 of file spi_driver.h.
#define SPI_SS_bm 0x10 |
Bit mask for the SS pin.
Definition at line 66 of file spi_driver.h.
Referenced by SPI_MasterInterruptTransceivePacket().
typedef struct SPI_DataPacket SPI_DataPacket_t |
SPI data packet struct.
typedef struct SPI_Master SPI_Master_t |
SPI master struct. Holds pointer to SPI module, buffers and necessary varibles.
typedef struct SPI_Slave SPI_Slave_t |
SPI slave struct. Holds pointers to SPI module and used port.
void SPI_MasterCreateDataPacket | ( | SPI_DataPacket_t * | dataPacket, | |
const uint8_t * | transmitData, | |||
uint8_t * | receiveData, | |||
uint8_t | bytesToTransceive, | |||
PORT_t * | ssPort, | |||
uint8_t | ssPinMask | |||
) |
Create data packet.
This function prepares a data packet for transmission. Note that memory for dataPacket, transmitData and receiveData must be allocated outside this function.
dataPacket | Pointer to data packet used for this transmission. | |
transmitData | Pointer to data to transmit. | |
receiveData | Pointer to receive buffer. | |
bytesToTransceive | The number of bytes to transmit/receive. | |
ssPort | Pointer to I/O port where the SS pin used for this transmission is located. | |
ssPinMask | Pin mask selecting the SS pin in ssPort. |
Definition at line 173 of file spi_driver.c.
References SPI_DataPacket::bytesToTransceive, SPI_DataPacket::bytesTransceived, SPI_DataPacket::complete, SPI_DataPacket::receiveData, SPI_DataPacket::ssPinMask, SPI_DataPacket::ssPort, and SPI_DataPacket::transmitData.
Referenced by main().
00179 { 00180 dataPacket->ssPort = ssPort; 00181 dataPacket->ssPinMask = ssPinMask; 00182 dataPacket->transmitData = transmitData; 00183 dataPacket->receiveData = receiveData; 00184 dataPacket->bytesToTransceive = bytesToTransceive; 00185 dataPacket->bytesTransceived = 0; 00186 dataPacket->complete = false; 00187 }
void SPI_MasterInit | ( | SPI_Master_t * | spi, | |
SPI_t * | module, | |||
PORT_t * | port, | |||
bool | lsbFirst, | |||
SPI_MODE_t | mode, | |||
SPI_INTLVL_t | intLevel, | |||
bool | clk2x, | |||
SPI_PRESCALER_t | clockDivision | |||
) |
Initialize SPI module as master.
This function initializes a SPI module as master. The CTRL and INTCTRL registers for the SPI module is set according to the inputs to the function. In addition, data direction for the MOSI and SCK pins is set to output.
spi | The SPI_Master_t struct instance. | |
module | The SPI module. | |
port | The I/O port where the SPI module is connected. | |
lsbFirst | Data order will be LSB first if this is set to a non-zero value. | |
mode | SPI mode (Clock polarity and phase). | |
intLevel | SPI interrupt level. | |
clk2x | SPI double speed mode | |
clockDivision | SPI clock prescaler divison factor. |
Definition at line 87 of file spi_driver.c.
References SPI_Master::dataPacket, SPI_Master::interrupted, SPI_Master::module, SPI_Master::port, SPI_MOSI_bm, and SPI_SCK_bm.
Referenced by main().
00095 { 00096 spi->module = module; 00097 spi->port = port; 00098 spi->interrupted = false; 00099 00100 spi->module->CTRL = clockDivision | /* SPI prescaler. */ 00101 (clk2x ? SPI_CLK2X_bm : 0) | /* SPI Clock double. */ 00102 SPI_ENABLE_bm | /* Enable SPI module. */ 00103 (lsbFirst ? SPI_DORD_bm : 0) | /* Data order. */ 00104 SPI_MASTER_bm | /* SPI master. */ 00105 mode; /* SPI mode. */ 00106 00107 /* Interrupt level. */ 00108 spi->module->INTCTRL = intLevel; 00109 00110 /* No assigned data packet. */ 00111 spi->dataPacket = NULL; 00112 00113 /* MOSI and SCK as output. */ 00114 spi->port->DIRSET = SPI_MOSI_bm | SPI_SCK_bm; 00115 }
void SPI_MasterInterruptHandler | ( | SPI_Master_t * | spi | ) |
Common SPI master interrupt service routine.
This function is called by the SPI interrupt service handlers. For each SPI module that uses this driver, the ISR should call this function with a pointer to the related SPI_Master_t struct as argument.
spi | Pointer to the modules own SPI_Master_t struct. |
Definition at line 199 of file spi_driver.c.
References SPI_DataPacket::bytesToTransceive, SPI_DataPacket::bytesTransceived, SPI_DataPacket::complete, dataPacket, SPI_Master::dataPacket, SPI_Master::interrupted, SPI_Master::module, SPI_DataPacket::receiveData, SPI_MasterSSHigh, SPI_DataPacket::ssPinMask, SPI_DataPacket::ssPort, and SPI_DataPacket::transmitData.
Referenced by ISR().
00200 { 00201 uint8_t data; 00202 uint8_t bytesTransceived = spi->dataPacket->bytesTransceived; 00203 00204 /* If SS pin interrupt (SS used and pulled low). 00205 * No data received at this point. */ 00206 if ( !(spi->module->CTRL & SPI_MASTER_bm) ) { 00207 spi->interrupted = true; 00208 } 00209 00210 else { /* Data interrupt. */ 00211 00212 /* Store received data. */ 00213 data = spi->module->DATA; 00214 spi->dataPacket->receiveData[bytesTransceived] = data; 00215 00216 /* Next byte. */ 00217 bytesTransceived++; 00218 00219 /* If more data. */ 00220 if (bytesTransceived < spi->dataPacket->bytesToTransceive) { 00221 /* Put data byte in transmit data register. */ 00222 data = spi->dataPacket->transmitData[bytesTransceived]; 00223 spi->module->DATA = data; 00224 } 00225 00226 /* Transmission complete. */ 00227 else { 00228 00229 /* Release SS to slave(s). */ 00230 uint8_t ssPinMask = spi->dataPacket->ssPinMask; 00231 SPI_MasterSSHigh(spi->dataPacket->ssPort, ssPinMask); 00232 00233 spi->dataPacket->complete = true; 00234 } 00235 } 00236 /* Write back bytesTransceived to data packet. */ 00237 spi->dataPacket->bytesTransceived = bytesTransceived; 00238 }
uint8_t SPI_MasterInterruptTransceivePacket | ( | SPI_Master_t * | spi, | |
SPI_DataPacket_t * | dataPacket | |||
) |
Start transmission.
This function starts a SPI transmission. A data packet must be prepared for transmission first.
spi | The SPI_Master_t struct instance. | |
dataPacket | The SPI_dataPacket_t struct instance. |
SPI_OK | The transmission was completed successfully. | |
SPI_BUSY | The SPI module is busy. | |
SPI_INTERRUPTED | The transmission was interrupted by another master. |
Definition at line 255 of file spi_driver.c.
References SPI_DataPacket::bytesTransceived, SPI_DataPacket::complete, SPI_Master::dataPacket, SPI_Master::interrupted, SPI_Master::module, SPI_Master::port, SPI_BUSY, SPI_INTERRUPTED, SPI_MasterSSLow, SPI_OK, SPI_SS_bm, SPI_DataPacket::ssPinMask, SPI_DataPacket::ssPort, and SPI_DataPacket::transmitData.
Referenced by main().
00257 { 00258 uint8_t data; 00259 bool interrupted = spi->interrupted; 00260 00261 /* If no packets sent so far. */ 00262 if (spi->dataPacket == NULL) { 00263 spi->dataPacket = dataPacket; 00264 } 00265 00266 /* If ongoing transmission. */ 00267 else if (spi->dataPacket->complete == false) { 00268 return (SPI_BUSY); 00269 } 00270 00271 /* If interrupted by other master. */ 00272 else if (interrupted) { 00273 /* If SS released. */ 00274 if (spi->port->OUT & SPI_SS_bm) { 00275 /* No longer interrupted. */ 00276 interrupted = false; 00277 } 00278 else { 00279 return (SPI_INTERRUPTED); 00280 } 00281 } 00282 00283 /* NOT interrupted by other master. 00284 * Start transmission. */ 00285 spi->dataPacket = dataPacket; 00286 spi->dataPacket->complete = false; 00287 spi->interrupted = false; 00288 00289 /* SS to slave(s) low.*/ 00290 uint8_t ssPinMask = spi->dataPacket->ssPinMask; 00291 SPI_MasterSSLow(spi->dataPacket->ssPort, ssPinMask); 00292 00293 spi->dataPacket->bytesTransceived = 0; 00294 00295 /* Start sending data. */ 00296 data = spi->dataPacket->transmitData[0]; 00297 spi->module->DATA = data; 00298 00299 /* Successs */ 00300 return (SPI_OK); 00301 }
uint8_t SPI_MasterTransceiveByte | ( | SPI_Master_t * | spi, | |
uint8_t | TXdata | |||
) |
SPI mastertransceive byte.
This function clocks data in the DATA register to the slave, while data from the slave is clocked into the DATA register. The function does not check for ongoing access from other masters before initiating a transfer. For multimaster systems, checkers should be added to avoid bus contention.
SS line(s) must be pulled low before calling this function and released when finished.
spi | The SPI_Master_t struct instance. | |
TXdata | Data to transmit to slave. |
Definition at line 324 of file spi_driver.c.
References SPI_Master::module.
Referenced by main().
00325 { 00326 /* Send pattern. */ 00327 spi->module->DATA = TXdata; 00328 00329 /* Wait for transmission complete. */ 00330 while(!(spi->module->STATUS & SPI_IF_bm)) { 00331 00332 } 00333 /* Read received data. */ 00334 uint8_t result = spi->module->DATA; 00335 00336 return(result); 00337 }
bool SPI_MasterTransceivePacket | ( | SPI_Master_t * | spi, | |
SPI_DataPacket_t * | dataPacket | |||
) |
SPI transceive data packet.
This function transceives a number of bytes contained in a data packet struct. The SS line is kept low until all bytes are transceived. The received bytes are stored in the data packet struct.
spi | The SPI_Master_t struct instance. | |
dataPacket | The SPI_dataPacket_t struct instance. |
true | Success | |
false | Failure |
Definition at line 354 of file spi_driver.c.
References SPI_DataPacket::bytesToTransceive, SPI_DataPacket::bytesTransceived, SPI_DataPacket::complete, SPI_Master::dataPacket, SPI_Master::module, SPI_DataPacket::receiveData, SPI_MasterSSHigh, SPI_MasterSSLow, SPI_DataPacket::ssPinMask, SPI_DataPacket::ssPort, and SPI_DataPacket::transmitData.
Referenced by main().
00356 { 00357 /* Check if data packet has been created. */ 00358 if(dataPacket == NULL) { 00359 return false; 00360 } 00361 00362 /* Assign datapacket to SPI module. */ 00363 spi->dataPacket = dataPacket; 00364 00365 uint8_t ssPinMask = spi->dataPacket->ssPinMask; 00366 00367 /* If SS signal to slave(s). */ 00368 if (spi->dataPacket->ssPort != NULL) { 00369 /* SS to slave(s) low. */ 00370 SPI_MasterSSLow(spi->dataPacket->ssPort, ssPinMask); 00371 } 00372 00373 /* Transceive bytes. */ 00374 uint8_t bytesTransceived = 0; 00375 uint8_t bytesToTransceive = dataPacket->bytesToTransceive; 00376 while (bytesTransceived < bytesToTransceive) { 00377 00378 /* Send pattern. */ 00379 uint8_t data = spi->dataPacket->transmitData[bytesTransceived]; 00380 spi->module->DATA = data; 00381 00382 /* Wait for transmission complete. */ 00383 while(!(spi->module->STATUS & SPI_IF_bm)) { 00384 00385 } 00386 /* Read received data. */ 00387 data = spi->module->DATA; 00388 spi->dataPacket->receiveData[bytesTransceived] = data; 00389 00390 bytesTransceived++; 00391 } 00392 00393 /* If SS signal to slave(s). */ 00394 if (spi->dataPacket->ssPort != NULL) { 00395 /* Release SS to slave(s). */ 00396 SPI_MasterSSHigh(spi->dataPacket->ssPort, ssPinMask); 00397 } 00398 00399 /* Set variables to indicate that transmission is complete. */ 00400 spi->dataPacket->bytesTransceived = bytesTransceived; 00401 spi->dataPacket->complete = true; 00402 00403 /* Report success. */ 00404 return true; 00405 }
void SPI_SlaveInit | ( | SPI_Slave_t * | spi, | |
SPI_t * | module, | |||
PORT_t * | port, | |||
bool | lsbFirst, | |||
SPI_MODE_t | mode, | |||
SPI_INTLVL_t | intLevel | |||
) |
Initialize SPI module as slave.
This function initializes a SPI module as slave. The CTRL and INTCTRL registers for the SPI module is set according to the inputs to the function. In addition, data direction for the MISO pin is set to output.
spi | The SPI_Slave_t instance. | |
module | Pointer to the SPI module. | |
port | The I/O port where the SPI module is connected. | |
lsbFirst | Data order will be LSB first if this is set to true. | |
mode | SPI mode (Clock polarity and phase). | |
intLevel | SPI interrupt level. |
Definition at line 132 of file spi_driver.c.
References SPI_Slave::module, SPI_Slave::port, and SPI_MISO_bm.
Referenced by main().
00138 { 00139 /* SPI module. */ 00140 spi->module = module; 00141 spi->port = port; 00142 00143 spi->module->CTRL = SPI_ENABLE_bm | /* Enable SPI module. */ 00144 (lsbFirst ? SPI_DORD_bm : 0) | /* Data order. */ 00145 mode; /* SPI mode. */ 00146 00147 /* Interrupt level. */ 00148 spi->module->INTCTRL = intLevel; 00149 00150 /* MISO as output. */ 00151 spi->port->DIRSET = SPI_MISO_bm; 00152 }
Generated on Mon Nov 2 13:52:27 2009 for AVR1309 Using the XMEGA SPI by ![]() |