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 | }
|