Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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/interrupt.h>
00024 
00025 #include "spi.h"
00026 
00027 // Define the SPI_USEINT key if you want SPI bus operation to be
00028 // interrupt-driven.  The primary reason for not using SPI in
00029 // interrupt-driven mode is if the SPI send/transfer commands
00030 // will be used from within some other interrupt service routine
00031 // or if interrupts might be globally turned off due to of other
00032 // aspects of your program
00033 //
00034 // Comment-out or uncomment this line as necessary
00035 //#define SPI_USEINT
00036 
00037 // global variables
00038 volatile u08 spiTransferComplete;
00039 
00040 // SPI interrupt service handler
00041 #ifdef SPI_USEINT
00042 SIGNAL(SIG_SPI)
00043 {
00044     spiTransferComplete = TRUE;
00045 }
00046 #endif
00047 
00048 // access routines
00049 void spiInit()
00050 {
00051 #ifdef __AVR_ATmega128__
00052     // setup SPI I/O pins
00053     sbi(PORTB, 1);  // set SCK hi
00054     sbi(DDRB, 1);   // set SCK as output
00055     cbi(DDRB, 3);   // set MISO as input
00056     sbi(DDRB, 2);   // set MOSI as output
00057     sbi(DDRB, 0);   // SS must be output for Master mode to work
00058 #elif __AVR_ATmega8__
00059     // setup SPI I/O pins
00060     sbi(PORTB, 5);  // set SCK hi
00061     sbi(DDRB, 5);   // set SCK as output
00062     cbi(DDRB, 4);   // set MISO as input
00063     sbi(DDRB, 3);   // set MOSI as output
00064     sbi(DDRB, 2);   // SS must be output for Master mode to work
00065 #else
00066     // setup SPI I/O pins
00067     sbi(PORTB, 7);  // set SCK hi
00068     sbi(DDRB, 7);   // set SCK as output
00069     cbi(DDRB, 6);   // set MISO as input
00070     sbi(DDRB, 5);   // set MOSI as output
00071     sbi(DDRB, 4);   // SS must be output for Master mode to work
00072 #endif
00073     
00074     // setup SPI interface :
00075     // master mode
00076     sbi(SPCR, MSTR);
00077     // clock = f/4
00078 //  cbi(SPCR, SPR0);
00079 //  cbi(SPCR, SPR1);
00080     // clock = f/16
00081     cbi(SPCR, SPR0);
00082     sbi(SPCR, SPR1);
00083     // select clock phase positive-going in middle of data
00084     cbi(SPCR, CPOL);
00085     // Data order MSB first
00086     cbi(SPCR,DORD);
00087     // enable SPI
00088     sbi(SPCR, SPE);
00089         
00090     
00091     // some other possible configs
00092     //outp((1<<MSTR)|(1<<SPE)|(1<<SPR0), SPCR );
00093     //outp((1<<CPHA)|(1<<CPOL)|(1<<MSTR)|(1<<SPE)|(1<<SPR0)|(1<<SPR1), SPCR );
00094     //outp((1<<CPHA)|(1<<MSTR)|(1<<SPE)|(1<<SPR0), SPCR );
00095     
00096     // clear status
00097     inb(SPSR);
00098     spiTransferComplete = TRUE;
00099 
00100     // enable SPI interrupt
00101     #ifdef SPI_USEINT
00102     sbi(SPCR, SPIE);
00103     #endif
00104 }
00105 /*
00106 void spiSetBitrate(u08 spr)
00107 {
00108     outb(SPCR, (inb(SPCR) & ((1<<SPR0)|(1<<SPR1))) | (spr&((1<<SPR0)|(1<<SPR1)))));
00109 }
00110 */
00111 void spiSendByte(u08 data)
00112 {
00113     // send a byte over SPI and ignore reply
00114     #ifdef SPI_USEINT
00115         while(!spiTransferComplete);
00116         spiTransferComplete = FALSE;
00117     #else
00118         while(!(inb(SPSR) & (1<<SPIF)));
00119     #endif
00120 
00121     outb(SPDR, data);
00122 }
00123 
00124 u08 spiTransferByte(u08 data)
00125 {
00126     #ifdef SPI_USEINT
00127     // send the given data
00128     spiTransferComplete = FALSE;
00129     outb(SPDR, data);
00130     // wait for transfer to complete
00131     while(!spiTransferComplete);
00132     #else
00133     // send the given data
00134     outb(SPDR, data);
00135     // wait for transfer to complete
00136     while(!(inb(SPSR) & (1<<SPIF)));
00137     #endif
00138     // return the received data
00139     return inb(SPDR);
00140 }
00141 
00142 u16 spiTransferWord(u16 data)
00143 {
00144     u16 rxData = 0;
00145 
00146     // send MS byte of given data
00147     rxData = (spiTransferByte((data>>8) & 0x00FF))<<8;
00148     // send LS byte of given data
00149     rxData |= (spiTransferByte(data & 0x00FF));
00150 
00151     // return the received data
00152     return rxData;
00153 }

Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by  doxygen 1.4.2