SPI.c


1
/*
2
    Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
3
*/
4
5
#include "spi.h"
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
10
#define PORT_SPI    PORTB
11
#define DDR_SPI     DDRB
12
#define DD_MISO     DDB4
13
#define DD_MOSI     DDB3
14
#define DD_SS       DDB2
15
#define DD_SCK      DDB5
16
17
18
void spi_init()
19
// Initialize pins for spi communication
20
{
21
    DDR_SPI &= ~((1<<DD_MOSI)|(1<<DD_MISO)|(1<<DD_SS)|(1<<DD_SCK));
22
    // Define the following pins as output
23
    DDR_SPI |= ((1<<DD_MOSI)|(1<<DD_SS)|(1<<DD_SCK));
24
25
    
26
    SPCR = ((1<<SPE)|               // SPI Enable
27
            (0<<SPIE)|              // SPI Interupt Enable
28
            (0<<DORD)|              // Data Order (0:MSB first / 1:LSB first)
29
            (1<<MSTR)|              // Master/Slave select   
30
            (0<<SPR1)|(1<<SPR0)|    // SPI Clock Rate
31
            (0<<CPOL)|              // Clock Polarity (0:SCK low / 1:SCK hi when idle)
32
            (0<<CPHA));             // Clock Phase (0:leading / 1:trailing edge sampling)
33
34
    SPSR = (0<<SPI2X);              // Double Clock Rate "1" @8MHz    
35
}
36
37
void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)
38
// Shift full array through target device
39
{
40
       uint8_t i;      
41
       for (i = 0; i < len; i++) {
42
             SPDR = dataout[i];
43
             while((SPSR & (1<<SPIF))==0);
44
             datain[i] = SPDR;
45
       }
46
}
47
48
void spi_transmit_sync (uint8_t * dataout, uint8_t len)
49
// Shift full array to target device without receiving any byte
50
{
51
       uint8_t i;      
52
       for (i = 0; i < len; i++) {
53
             SPDR = dataout[i];
54
             while((SPSR & (1<<SPIF))==0);
55
       }
56
}
57
58
uint8_t spi_fast_shift (uint8_t data)
59
// Clocks only one byte to target device and returns the received one
60
{
61
    SPDR = data;
62
    while((SPSR & (1<<SPIF))==0);
63
    return SPDR;
64
}