1 | /*
|
2 | Copyright (c) 2007 Stefan Engelke <mbox@stefanengelke.de>
|
3 |
|
4 | Permission is hereby granted, free of charge, to any person
|
5 | obtaining a copy of this software and associated documentation
|
6 | files (the "Software"), to deal in the Software without
|
7 | restriction, including without limitation the rights to use, copy,
|
8 | modify, merge, publish, distribute, sublicense, and/or sell copies
|
9 | of the Software, and to permit persons to whom the Software is
|
10 | furnished to do so, subject to the following conditions:
|
11 |
|
12 | The above copyright notice and this permission notice shall be
|
13 | included in all copies or substantial portions of the Software.
|
14 |
|
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
22 | DEALINGS IN THE SOFTWARE.
|
23 |
|
24 | $Id$
|
25 | */
|
26 |
|
27 | #include "spi.h"
|
28 |
|
29 | #include <avr/io.h>
|
30 | #include <avr/interrupt.h>
|
31 |
|
32 | #define PORT_SPI PORTB
|
33 | #define DDR_SPI DDRB
|
34 | #define DD_MISO DDB4
|
35 | #define DD_MOSI DDB3
|
36 | #define DD_SS DDB2
|
37 | #define DD_SCK DDB5
|
38 |
|
39 |
|
40 | void spi_init()
|
41 | // Initialize pins for spi communication
|
42 | {
|
43 | DDR_SPI &= ~((1<<DD_MOSI)|(1<<DD_MISO)|(1<<DD_SS)|(1<<DD_SCK));
|
44 | // Define the following pins as output
|
45 | DDR_SPI |= ((1<<DD_MOSI)|(1<<DD_SS)|(1<<DD_SCK));
|
46 |
|
47 |
|
48 | SPCR = ((1<<SPE)| // SPI Enable
|
49 | (0<<SPIE)| // SPI Interupt Enable
|
50 | (0<<DORD)| // Data Order (0:MSB first / 1:LSB first)
|
51 | (1<<MSTR)| // Master/Slave select
|
52 | (0<<SPR1)|(1<<SPR0)| // SPI Clock Rate
|
53 | (0<<CPOL)| // Clock Polarity (0:SCK low / 1:SCK hi when idle)
|
54 | (0<<CPHA)); // Clock Phase (0:leading / 1:trailing edge sampling)
|
55 |
|
56 | SPSR = (1<<SPI2X); // Double Clock Rate
|
57 |
|
58 | }
|
59 |
|
60 | void spi_transfer_sync (uint8_t * dataout, uint8_t * datain, uint8_t len)
|
61 | // Shift full array through target device
|
62 | {
|
63 | uint8_t i;
|
64 | for (i = 0; i < len; i++) {
|
65 | SPDR = dataout[i];
|
66 | while((SPSR & (1<<SPIF))==0);
|
67 | datain[i] = SPDR;
|
68 | }
|
69 | }
|
70 |
|
71 | void spi_transmit_sync (uint8_t * dataout, uint8_t len)
|
72 | // Shift full array to target device without receiving any byte
|
73 | {
|
74 | uint8_t i;
|
75 | for (i = 0; i < len; i++) {
|
76 | SPDR = dataout[i];
|
77 | while((SPSR & (1<<SPIF))==0);
|
78 | }
|
79 | }
|
80 |
|
81 | uint8_t spi_fast_shift (uint8_t data)
|
82 | // Clocks only one byte to target device and returns the received one
|
83 | {
|
84 | SPDR = data;
|
85 | while((SPSR & (1<<SPIF))==0);
|
86 | return SPDR;
|
87 | }
|