• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

spi.h

Go to the documentation of this file.
00001 /* SPI interface header file */
00002 /* Copyright (C) 2009 Holger Dietze
00003  *
00004  *   This program is free software; you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation; either version 2 of the License, or
00007  *   (at your option) version 3.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License along
00015  *   with this program; if not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef SPI_H
00019 #define SPI_H
00020 
00021 #include <stdint.h>
00022 #include <avr/io.h>
00023 #include <util/delay.h>
00024 
00030 /* port and pin definitions */
00031 #if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1280__) \
00032   || defined(__AVR_ATmega2560__)
00033 
00034 #define DDR_SPI    DDRB
00035 
00036 #define DR_SPI_SS    DDB0
00037 
00038 #define DR_SPI_SCK   DDB1
00039 
00040 #define DR_SPI_MOSI  DDB2
00041 
00042 #define DR_SPI_MISO  DDB3
00043 
00045 #define PORT_SPI   PORTB
00046 
00047 #define PORT_SPI_SS   PB0
00048 
00049 #define PORT_SPI_SCK  PB1
00050 
00051 #define PORT_SPI_MOSI PB2
00052 
00053 #define PORT_SPI_MISO PB3
00054 #else
00055 #    warning "device type not defined"
00056 #endif
00057 
00058 
00062 void spi_init (uint8_t div);
00068 void spi_set_speed (uint8_t div);
00069 
00080 inline uint8_t spi_transfer (uint8_t b, uint8_t wait, uint8_t read)
00081 {
00082   uint8_t spsr;
00083 
00084   SPDR = b;
00085   if (wait && (spsr = SPSR) & _BV(WCOL)) {
00086     /* after write collision just wait for SPIF */
00087     while (!(spsr & _BV(SPIF))) spsr = SPSR;
00088     SPDR = b;
00089   }
00090   /* at this point, we started the transfer */
00091   if (read) {
00092     /* wait for completion */
00093     if (!wait) spsr = SPSR;
00094     while (!(spsr & _BV(SPIF))) spsr = SPSR;
00095     return SPDR;
00096   } else {
00097     /* we don't care when the transfer finishes */
00098     return 0xff;
00099   }
00100 }
00101 
00106 #define spi_write(b) spi_transfer ((b), 1, 0)
00107 
00111 #define spi_read(b)   spi_transfer (b, 1, 1)
00112 
00121 inline void spi_do_select (uint8_t ss_enable)
00122 {
00123   if (!ss_enable) /* when selecting, we expect the previous transmission to
00124                    * be complete (we already waited at de-select time) */
00125     while (0 && !(SPSR & _BV(SPIF)));
00126   if (ss_enable) {
00127     PORT_SPI &= ~_BV(PORT_SPI_SS);
00128   }
00129   else
00130     PORT_SPI |= _BV(PORT_SPI_SS);
00131 }
00132 
00134 #define spi_select() spi_do_select (1)
00135 
00136 #define spi_deselect() spi_do_select (0)
00137 
00138 #endif

Generated by  doxygen 1.7.1