308 lines
7.6 KiB
C
308 lines
7.6 KiB
C
/*================================================================================================
|
|
|
|
spi.c SiWiCom copyright 2006 v1.0 (2006-05-11)
|
|
|
|
Name: Joakim Nilsson E-mail: mail@jopin.se
|
|
Name: Christoffer Martinsson E-mail: cm@cmtec.se
|
|
|
|
Description: Routines for SPI interface. Basic design by CM. Modifyed and extended by JN
|
|
for project SiWiCom 2006
|
|
|
|
SPI configuration is done by hardware.h witch must contain definitions for:
|
|
(X=letter i.e PORTX=PORTB, n=number i.e PXn=PB4)
|
|
|
|
SPI_PORT PORTX (Example: #define SPI_PORT PORTB) // PORTB as SPI-port
|
|
SPI_DDR DDRX (Example: #define SPI_DDR DDRB) // DDRB as direction for SPI pindirection
|
|
|
|
MOSI PXn (Example: #define MOSI PB3) // Master Out - Slave In
|
|
MISO PXn (Example: #define MISO PB4) // Master In - Slave Out
|
|
SCK PXn (Example: #define SCK PB5 // Serial Clock
|
|
|
|
Processor as SPI-master or SPI-slave, example:
|
|
#define _SPI_MASTER_
|
|
//#define _SPI_SLAVE_
|
|
|
|
If processor is defined as _SPI_MASTER_, Chip select port(s) (at least one, max 8) must be asigned as:
|
|
#define SPI_CS0_PORT PORTX
|
|
.
|
|
.
|
|
.
|
|
#define SPI_CS7_PORT PORTX
|
|
|
|
|
|
and SPI direction for the above asigned port(s) as:
|
|
#define SPI_CS0_DDR DDRX
|
|
.
|
|
.
|
|
.
|
|
#define SPI_CS7_DDR DDRX
|
|
|
|
and SPI pin(s) used for chip select as:
|
|
|
|
#define SPI_CS0 PXn
|
|
.
|
|
.
|
|
.
|
|
#define SPI_CS7 PXn
|
|
|
|
================================================================================================*/
|
|
#include "hardware.h"
|
|
#include <inttypes.h>
|
|
#include <avr/io.h>
|
|
#include "spi.h"
|
|
|
|
/*================================================================================================
|
|
Functions
|
|
================================================================================================*/
|
|
/*================================================================================================
|
|
spiWrite
|
|
|
|
Description: Write data to SPI.
|
|
|
|
Input: data to send
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiWrite(uint8_t data)
|
|
{
|
|
SPDR = data;
|
|
while(!(SPSR & (1<<SPIF)));
|
|
}
|
|
|
|
/*================================================================================================
|
|
spiRead
|
|
|
|
Description: Read data from SPI buffer.
|
|
|
|
Input: -
|
|
Return: SPI-value
|
|
------------------------------------------------------------------------------------------------*/
|
|
uint8_t spiRead(void)
|
|
{
|
|
return SPDR;
|
|
}
|
|
/*================================================================================================
|
|
spiSetHighSpeed
|
|
|
|
Description: Set datatrasfer to fc/4.
|
|
|
|
Input: -
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiSetHighSpeed(void)
|
|
{
|
|
SPCR &= ~(1<<SPR0);
|
|
SPCR &= ~(1<<SPR1);
|
|
}
|
|
/*================================================================================================
|
|
spiSetLowSpeed
|
|
|
|
Description: Set datatrasfer to fc/64.
|
|
|
|
Input: -
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiSetLowSpeed(void)
|
|
{
|
|
SPCR &= ~(1<<SPR0);
|
|
SPCR |= (1<<SPR1);
|
|
}
|
|
|
|
/*================================================================================================
|
|
spiInit
|
|
|
|
Description: Init SPI interface as master or slave depending on the "hardware.h" configuration.
|
|
|
|
Input: -
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiInit(void)
|
|
{
|
|
#ifdef _SPI_MASTER_ //If defined as master in hardware.h
|
|
|
|
#ifdef SPI_CS0
|
|
SPI_CS0_DDR |= (1<<SPI_CS0);
|
|
SPI_CS0_PORT |= (1<<SPI_CS0);
|
|
#endif
|
|
|
|
#ifdef SPI_CS1
|
|
SPI_CS1_DDR |=(1<<SPI_CS1);
|
|
SPI_CS1_PORT |= (1<<SPI_CS1);
|
|
#endif
|
|
|
|
#ifdef SPI_CS2
|
|
SPI_CS2_DDR |=(1<<SPI_CS2);
|
|
SPI_CS2_PORT |= (1<<SPI_CS2);
|
|
#endif
|
|
|
|
#ifdef SPI_CS3
|
|
SPI_CS3_DDR |=(1<<SPI_CS3);
|
|
SPI_CS3_PORT |= (1<<SPI_CS3);
|
|
#endif
|
|
|
|
#ifdef SPI_CS4
|
|
SPI_CS4_DDR |=(1<<SPI_CS4);
|
|
SPI_CS4_PORT |= (1<<SPI_CS4);
|
|
#endif
|
|
|
|
#ifdef SPI_CS5
|
|
SPI_CS5_DDR |=(1<<SPI_CS5);
|
|
SPI_CS5_PORT |= (1<<SPI_CS5);
|
|
#endif
|
|
|
|
#ifdef SPI_CS6
|
|
SPI_CS6_DDR |=(1<<SPI_CS6);
|
|
SPI_CS6_PORT |= (1<<SPI_CS6);
|
|
#endif
|
|
|
|
#ifdef SPI_CS7
|
|
SPI_CS7_DDR |=(1<<SPI_CS7);
|
|
SPI_CS7_PORT |= (1<<SPI_CS7);
|
|
#endif
|
|
|
|
SPI_DDR |= (1<<MOSI)|(1<<SCK); // MOSI and SCLK as output
|
|
SPI_PORT |= (1<<MISO) ; // Pullup on SO (slave out)
|
|
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPI2X); // SPI enable, SPI-Master, SC = fc/2
|
|
|
|
#elif _SPI_SLAVE_ //If defined as slave in hardware.h
|
|
|
|
SPI_DDR |= (1<<MISO); // MOSI and SCLK as output
|
|
SPI_PORT |=(1<<SS); // Pull-Up on SS
|
|
SPCR |= (1<<SPE); // SPI enable, SPI-Slave
|
|
|
|
#endif
|
|
}
|
|
|
|
/*================================================================================================
|
|
spiChipSelect
|
|
|
|
Description: Select device for communication via SPI. Protects chipselect on two devices at the
|
|
same time and secure that chosen chipselect is an initialised legal channel.
|
|
|
|
Input: uint8_t (The number of the desired chipselect. (Between 0 and 7) )
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiChipSelect(uint8_t chipselect){
|
|
|
|
/*All chipselectports disabled (high state)*/
|
|
#ifdef SPI_CS0
|
|
SPI_CS0_PORT |=(1<<SPI_CS0);
|
|
#endif
|
|
|
|
#ifdef SPI_CS1
|
|
SPI_CS1_PORT |=(1<<SPI_CS1);
|
|
#endif
|
|
|
|
#ifdef SPI_CS2
|
|
SPI_CS2_PORT |=(1<<SPI_CS2);
|
|
#endif
|
|
|
|
#ifdef SPI_CS3
|
|
SPI_CS3_PORT |=(1<<SPI_CS3);
|
|
#endif
|
|
|
|
#ifdef SPI_CS4
|
|
SPI_CS4_PORT |=(1<<SPI_CS4);
|
|
#endif
|
|
|
|
#ifdef SPI_CS5
|
|
SPI_CS5_PORT |=(1<<SPI_CS5);
|
|
#endif
|
|
|
|
#ifdef SPI_CS6
|
|
SPI_CS6_PORT |=(1<<SPI_CS6);
|
|
#endif
|
|
|
|
#ifdef SPI_CS7
|
|
SPI_CS7_PORT |=(1<<SPI_CS7);
|
|
#endif
|
|
|
|
/*Selected port as chipselect*/
|
|
#ifdef SPI_CS0
|
|
if(chipselect==0)
|
|
SPI_CS0_PORT &=~(1<<SPI_CS0);
|
|
#endif
|
|
|
|
#ifdef SPI_CS1
|
|
if(chipselect==1)
|
|
SPI_CS1_PORT &=~(1<<SPI_CS1);
|
|
#endif
|
|
|
|
#ifdef SPI_CS2
|
|
if(chipselect==2)
|
|
SPI_CS2_PORT &=~(1<<SPI_CS2);
|
|
#endif
|
|
|
|
#ifdef SPI_CS3
|
|
if(chipselect==3)
|
|
SPI_CS3_PORT &=~(1<<SPI_CS3);
|
|
#endif
|
|
|
|
#ifdef SPI_CS4
|
|
if(chipselect==4)
|
|
SPI_CS4_PORT &=~(1<<SPI_CS4);
|
|
#endif
|
|
|
|
#ifdef SPI_CS5
|
|
if(chipselect==5)
|
|
SPI_CS5_PORT &=~(1<<SPI_CS5);
|
|
#endif
|
|
|
|
#ifdef SPI_CS6
|
|
if(chipselect==6)
|
|
SPI_CS6_PORT &=~(1<<SPI_CS6);
|
|
#endif
|
|
|
|
#ifdef SPI_CS7
|
|
if(chipselect==7)
|
|
SPI_CS7_PORT &=~(1<<SPI_CS7);
|
|
#endif
|
|
}
|
|
|
|
/*================================================================================================
|
|
spiChipDeSelect
|
|
|
|
Description: Deselect all SPI channels
|
|
Input: -
|
|
Return: -
|
|
------------------------------------------------------------------------------------------------*/
|
|
void spiChipDeSelect(void)
|
|
{
|
|
/*All chipselectports disabled (high state)*/
|
|
#ifdef SPI_CS0
|
|
SPI_CS0_PORT |=(1<<SPI_CS0);
|
|
#endif
|
|
|
|
#ifdef SPI_CS1
|
|
SPI_CS1_PORT |=(1<<SPI_CS1);
|
|
#endif
|
|
|
|
#ifdef SPI_CS2
|
|
SPI_CS2_PORT |=(1<<SPI_CS2);
|
|
#endif
|
|
|
|
#ifdef SPI_CS3
|
|
SPI_CS3_PORT |=(1<<SPI_CS3);
|
|
#endif
|
|
|
|
#ifdef SPI_CS4
|
|
SPI_CS4_PORT |=(1<<SPI_CS4);
|
|
#endif
|
|
|
|
#ifdef SPI_CS5
|
|
SPI_CS5_PORT |=(1<<SPI_CS5);
|
|
#endif
|
|
|
|
#ifdef SPI_CS6
|
|
SPI_CS6_PORT |=(1<<SPI_CS6);
|
|
#endif
|
|
|
|
#ifdef SPI_CS7
|
|
SPI_CS7_PORT |=(1<<SPI_CS7);
|
|
#endif
|
|
|
|
}
|
|
/*================================================================================================
|
|
End
|
|
================================================================================================*/
|
|
|