|
1 #include "spi.h" |
|
2 |
|
3 static char spi_rx[SPI_COUNT], spi_tx[SPI_COUNT]; |
|
4 |
|
5 static const enum spi_dord spi_dord = SPI_DORD; |
|
6 static const enum spi_cpol spi_cpol = SPI_CPOL; |
|
7 static const enum spi_cpha spi_cpha = SPI_CPHA; |
|
8 static const enum spi_clock spi_clock = SPI_CLOCK; |
|
9 |
|
10 void spi_init () |
|
11 { |
|
12 // set output modes |
|
13 sbi(SPI_DDR, SPI_SCK); // out |
|
14 cbi(SPI_DDR, SPI_MISO); // in |
|
15 sbi(SPI_DDR, SPI_MOSI); // out |
|
16 sbi(SPI_DDR, SPI_SS); // out |
|
17 |
|
18 // initialize bus |
|
19 sbi(SPI_PORT, SPI_SS); // high (off) |
|
20 |
|
21 // set mode |
|
22 SPCR = ( |
|
23 // SPI Interrupt Enable |
|
24 (0b0 << SPIE) // disable |
|
25 |
|
26 // SPI Enable |
|
27 | (0b1 << SPE) // enable |
|
28 |
|
29 // Data Order |
|
30 | (spi_dord << DORD) |
|
31 |
|
32 // Master/Slave Select |
|
33 | (0b1 << MSTR) // master |
|
34 |
|
35 // Clock Polarity |
|
36 | (spi_cpol << CPOL) |
|
37 |
|
38 // Clock Phase |
|
39 | (spi_cpha << CPHA) |
|
40 |
|
41 // SPI Clock Rate Select |
|
42 | ((spi_clock & 0b11) << SPR0) |
|
43 ); |
|
44 SPSR = ( |
|
45 (((spi_clock & 0b100) >> 2) << SPI2X) |
|
46 ); |
|
47 } |
|
48 |
|
49 byte spi_readwrite (byte value) |
|
50 { |
|
51 // out |
|
52 SPDR = value; |
|
53 |
|
54 // sync |
|
55 while (!tbi(&SPSR, SPIF)) |
|
56 ; |
|
57 |
|
58 return SPDR; |
|
59 } |
|
60 /* |
|
61 * Perform an SPI bus update. |
|
62 */ |
|
63 void spi_update () |
|
64 { |
|
65 char i; |
|
66 char *rx = spi_rx + SPI_COUNT, *tx = spi_tx + SPI_COUNT; |
|
67 |
|
68 // start of packet |
|
69 cbi(SPI_PORT, SPI_SS); // low |
|
70 |
|
71 for (i = SPI_COUNT; i > 0; i--) { |
|
72 *--rx = spi_readwrite(*--tx); |
|
73 } |
|
74 |
|
75 // end of packet |
|
76 sbi(SPI_PORT, SPI_SS); // high |
|
77 } |
|
78 |
|
79 void spi_set (byte index, byte value) |
|
80 { |
|
81 spi_tx[index] = value; |
|
82 } |
|
83 |
|
84 byte spi_get (byte index) |
|
85 { |
|
86 return spi_rx[index]; |
|
87 } |
|
88 |