-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathspi.c
63 lines (47 loc) · 1.74 KB
/
spi.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include "spi.h"
#include <avr/io.h>
#include <avr/interrupt.h>
// Mega
#define PORT_SPI PORTB
#define DDR_SPI DDRB
#define DD_MISO DDB3
#define DD_MOSI DDB2
#define DD_SCK DDB1
#define DD_SS DDB0
void spi_init()
// Initialize pins for spi communication
{
DDR_SPI &= ~((1<<DD_MOSI)|(1<<DD_MISO)|(1<<DD_SS)|(1<<DD_SCK));
// Define the following pins as output
DDR_SPI |= ((1<<DD_MOSI)|(1<<DD_SS)|(1<<DD_SCK));
SPCR = ((1<<SPE)| // SPI Enable
(0<<SPIE)| // SPI Interupt Enable
(0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
(1<<MSTR)| // Master/Slave select
(0<<SPR1)|(1<<SPR0)| // SPI Clock Rate ..... fosc/128
(1<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
(1<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
SPSR = (1<<SPI2X); // Double Clock Rate
}
uint8_t spi_fast_shift (uint8_t data)
// Clocks only one byte to target device and returns the received one
{
SPDR = data;
while((SPSR & (1<<SPIF))==0);
return SPDR;
}
// Send a 20 bit value via spi
unsigned long spi_send20bit(unsigned long datagram, volatile uint8_t *cs_port, uint8_t cs_bit)
{
unsigned long i_datagram; // this is the returned value
*cs_port &= ~(1<<cs_bit); // chip select
datagram &= 0xFFFFFul; // force to 20 bit
i_datagram = spi_fast_shift((datagram >> 16) & 0xff);
i_datagram <<= 8;
i_datagram |= spi_fast_shift((datagram >> 8) & 0xff);
i_datagram <<= 8;
i_datagram |= spi_fast_shift((datagram) & 0xff);
i_datagram >>= 4;
*cs_port |= (1<<cs_bit); // deselect chip
return i_datagram;
}