Main Page   Data Structures   File List   Data Fields   Globals  

/spi.c

Go to the documentation of this file.
00001 /*! \file spi.c \brief SPI interface driver. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'spi.c'
00005 // Title        : SPI interface driver
00006 // Author       : Pascal Stang - Copyright (C) 2000-2002
00007 // Created      : 11/22/2000
00008 // Revised      : 06/06/2002
00009 // Version      : 0.6
00010 // Target MCU   : Atmel AVR series
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 #include <avr/io.h>
00023 #include <avr/signal.h>
00024 #include <avr/interrupt.h>
00025 
00026 #include "spi.h"
00027 
00028 // Define the SPI_USEINT key if you want SPI bus operation to be
00029 // interrupt-driven.  The primary reason for not using SPI in
00030 // interrupt-driven mode is if the SPI send/transfer commands
00031 // will be used from within some other interrupt service routine
00032 // or if interrupts might be globally turned off due to of other
00033 // aspects of your program
00034 //
00035 // Comment-out or uncomment this line as necessary
00036 //#define SPI_USEINT
00037 
00038 // global variables
00039 volatile u08 spiTransferComplete;
00040 
00041 // SPI interrupt service handler
00042 #ifdef SPI_USEINT
00043 SIGNAL(SIG_SPI)
00044 {
00045     spiTransferComplete = TRUE;
00046 }
00047 #endif
00048 
00049 // access routines
00050 void spiInit()
00051 {
00052 #ifdef __AVR_ATmega128__
00053     // setup SPI I/O pins
00054     sbi(PORTB, 1);  // set SCK hi
00055     sbi(DDRB, 1);   // set SCK as output
00056     cbi(DDRB, 3);   // set MISO as input
00057     sbi(DDRB, 2);   // set MOSI as output
00058     sbi(DDRB, 0);   // SS must be output for Master mode to work
00059 #else
00060     // setup SPI I/O pins
00061     sbi(PORTB, 7);  // set SCK hi
00062     sbi(DDRB, 7);   // set SCK as output
00063     cbi(DDRB, 6);   // set MISO as input
00064     sbi(DDRB, 5);   // set MOSI as output
00065     sbi(DDRB, 4);   // SS must be output for Master mode to work
00066 #endif
00067     
00068     // setup SPI interface :
00069     // clock = f/16
00070     // select clock phase positive-going in middle of data
00071     // master mode
00072     // enable SPI
00073     outp((1<<MSTR)|(1<<SPE)|(1<<SPR0), SPCR );
00074     
00075     // some other possible configs
00076     //outp((1<<CPHA)|(1<<CPOL)|(1<<MSTR)|(1<<SPE)|(1<<SPR0)|(1<<SPR1), SPCR );
00077     //outp((1<<CPHA)|(1<<MSTR)|(1<<SPE)|(1<<SPR0), SPCR );
00078     
00079     // clear status
00080     inp(SPSR);
00081     spiTransferComplete = TRUE;
00082 
00083     // enable SPI interrupt
00084     #ifdef SPI_USEINT
00085     sbi(SPCR, SPIE);
00086     #endif
00087 }
00088 
00089 void spiSendByte(u08 data)
00090 {
00091     // send a byte over SPI and ignore reply
00092     if(spiTransferComplete)
00093     {
00094         spiTransferComplete = FALSE;
00095         outp(data, SPDR);
00096     }
00097 }
00098 
00099 u08 spiTransferByte(u08 data)
00100 {
00101     // send the given data
00102     if(spiTransferComplete)
00103     {
00104         spiTransferComplete = FALSE;
00105         outp(data, SPDR);
00106     }
00107     // wait for transfer to complete
00108     #ifdef SPI_USEINT
00109         while(!spiTransferComplete);
00110     #else
00111         while(!(inp(SPSR) & (1<<SPIF)));
00112         // *** reading of the SPSR and SPDR are crucial
00113         // *** to the clearing of the SPIF flag
00114         // *** in non-interrupt mode
00115         //inp(SPDR);
00116         // set flag
00117         spiTransferComplete = TRUE;
00118     #endif
00119     // return the received data
00120     return inp(SPDR);
00121 }
00122 
00123 u16 spiTransferWord(u16 data)
00124 {
00125     u16 rxData = 0;
00126 
00127     // send MS byte of given data
00128     rxData = (spiTransferByte((data>>8) & 0x00FF))<<8;
00129     // send LS byte of given data
00130     rxData |= (spiTransferByte(data & 0x00FF));
00131 
00132     // return the received data
00133     return rxData;
00134 }

Generated on Fri Aug 1 10:42:42 2003 for Procyon AVRlib by doxygen1.2.18