source: firmware/FSC/src/spi_master.c@ 10204

Last change on this file since 10204 was 10109, checked in by lutz, 14 years ago
niculin & dom debugged quite some stuff
File size: 6.9 KB
Line 
1//-----------------------------------------------------------------------------
2#include "spi_master.h"
3
4//-----------------------------------------------------------------------------
5volatile U08 spi_clock_index;
6volatile U08 spi_cpol;
7volatile U08 spi_cpha;
8volatile U08 spi_dord;
9volatile BOOL spi_ss_active_high;
10volatile U08 spi_read_buffer[SPI_READ_BUFFER_SIZE];
11volatile U08 spi_write_buffer[SPI_WRITE_BUFFER_SIZE];
12
13volatile U08 SPI_DEVICE_SS[4]={SPI_E_CS ,SPI_AD_CS ,SPI_M_CS ,SPI_A_CS };
14volatile BOOL SPI_DEVICE_ACTIVE_HIGH[4]={false ,false ,false ,false };
15//-----------------------------------------------------------------------------
16
17
18
19
20void spi_init(void)
21{
22 // there are a total of 4 devices on the SPI bus:
23 // 1.) Ethernet Modul WIZ812MJ
24 // 2.) AD7719 24bit ADC
25 // 3.) LIS3LV accelerometer
26 // 4.) MAX6662 temp sensor <---- not assembled!
27
28 // We check if they all can live with the same SPI settings:
29 // 1.) Ethernet modul:
30 // supports spi mode=0 or mode=3 --> eighther cpol=cpha=0 or cpol=cpha=1
31 // MSB first
32 // SCLK time 70ns minimum --> 14.2MHz maximum
33 //
34 // 2.) AD7719
35 // supports mode=3 --> cpol=cpha=1
36 // MSB first
37 // SCLK time 200ns minimum --> 5MHz maximum
38 //
39 // 3.) LIS3LV
40 // SPI CLK idles high --> cpol=1
41 // data valid at rising edge. --> cpha=1 as well
42 // ==> mode 3 is supported only.
43 // MSB first, but take take at multi byte transfers. LSbyte first
44 // SCLK time - is not mentioned in the datasheet
45 //
46 // 4.) MAX6662 Tempsensor
47 // since it is not assembled, this information is not necessary.
48
49 // fastes SPI CLK frequency can be --> F_CPU/2 = 4MHz
50 // slowest can be --> F_CPU/128 = 62.5KHz
51
52 // Lets try with the fastest!
53 spi_clock_index = 0; // Set Clockindex for lowest clock speed (F_CPU / 128)
54
55 spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices
56 spi_cpol = 1; spi_cpha = 1; // SPI mode=3 --> good for all devices
57 spi_setup(); // Setup SPI bits and clock speed
58
59}
60//-----------------------------------------------------------------------------
61void spi_setup(void)
62{
63 // Disable SPI, clear all flags
64 SPCR = 0;
65
66 // Set/Clear bits DORD, CPOL and CPHA in SPI Control Register
67 spi_dord & 0x01 ? (SPCR |= (1 << DORD)) : (SPCR &= ~(1 << DORD));
68 spi_cpol & 0x01 ? (SPCR |= (1 << CPOL)) : (SPCR &= ~(1 << CPOL));
69 spi_cpha & 0x01 ? (SPCR |= (1 << CPHA)) : (SPCR &= ~(1 << CPHA));
70
71 switch (spi_clock_index)
72 {
73 case 0:{ // F_CPU / 128
74 SPCR |= (1 << SPR1) | (1 << SPR0);
75 SPSR &= ~(1 <<SPI2X);
76 }
77 break;
78
79 case 1:{ // F_CPU / 64
80 SPCR |= (1 << SPR1);
81 SPSR &= ~(1 << SPI2X);
82 }
83 break;
84
85 case 2:{ // F_CPU / 32
86 SPCR |= (1 << SPR1);
87 SPSR |= (1 << SPI2X);
88 }
89 break;
90
91 case 3:{ // F_CPU / 16
92 SPCR |= (1 << SPR0);
93 SPSR &= ~(1 << SPI2X);
94 }
95 break;
96
97 case 4:{ // F_CPU / 8
98 SPCR |= (1 << SPR0);
99 SPSR |= (1 << SPI2X);
100 }
101 break;
102
103 case 5: // F_CPU / 4
104 SPSR &= ~(1 << SPI2X);
105 break;
106
107 case 6: // F_CPU / 2
108 SPSR |= (1 << SPI2X);
109 break;
110
111 default:{ // F_CPU / 128
112 SPCR |= (1 << SPR1) | (1 << SPR0);
113 SPSR &= ~(1 << SPI2X);
114 }
115 }
116
117 // Enable SPI in Master Mode
118 SPCR |= (1 << SPE) | (1 << MSTR);
119}
120
121//-----------------------------------------------------------------------------
122
123void spi_set_clock_index(U08 clock_index)
124{
125 if (clock_index > SPI_MAX_CLOCK_INDEX)
126 {
127 clock_index = SPI_MAX_CLOCK_INDEX;
128 }
129
130 spi_clock_index = clock_index;
131
132 spi_setup(); // Setup SPI bits and clock speed
133}
134//-----------------------------------------------------------------------------
135
136void spi_set_dord(U08 dord)
137{
138 if (dord > 1)
139 {
140 dord = 1;
141 }
142
143 spi_dord = dord;
144
145 spi_setup(); // Setup SPI bits and clock speed
146}
147//-----------------------------------------------------------------------------
148
149void spi_set_cpol(U08 cpol)
150{
151 if (cpol > 1)
152 {
153 cpol = 1;
154 }
155
156 spi_cpol = cpol;
157
158 spi_setup(); // Setup SPI bits and clock speed
159}
160//-----------------------------------------------------------------------------
161
162void spi_set_cpha(U08 cpha)
163{
164 if (cpha > 1)
165 {
166 cpha = 1;
167 }
168
169 spi_cpha = cpha;
170
171 spi_setup(); // Setup SPI bits and clock speed
172}
173
174//-----------------------------------------------------------------------------
175
176void spi_transfer(U08 bytes, U08 device)
177{
178/*
179#define SPI_E_CS PB4 //device 0
180#define SPI_AD_CS PD3 //device 1
181#define SPI_M_CS PD4 //device 2
182#define SPI_A_CS PD5 //device 3
183*/
184 U08 n;
185
186 // Check for active slave select level
187 if (SPI_DEVICE_ACTIVE_HIGH[device])
188 {
189 if (device == 0) {
190 PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
191 } else {
192 PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
193 }
194 }
195 else
196 {
197 if (device == 0) {
198 PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
199 } else {
200 PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
201 }
202 }
203
204 // Transfer requested bytes
205 for (n = 0; n < bytes; n++)
206 {
207 spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]);
208 }
209
210 // Check for inactive slave select level
211 if (SPI_DEVICE_ACTIVE_HIGH[device])
212 {
213 if (device == 0) {
214 PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
215 } else {
216 PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
217 }
218 }
219 else
220 {
221 if (device == 0) {
222 PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
223 } else {
224 PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
225 }
226 }
227}
228//-----------------------------------------------------------------------------
229
230U08 spi_transfer_byte(U08 data)
231{
232 // Start SPI Transfer
233 if (!(SPCR & (1<<MSTR)) )
234 SPCR |= 1<<MSTR;
235 SPDR = data;
236
237 // Wait for transfer completed
238 while (!(SPSR & (1 << SPIF)))
239 {
240 }
241
242 // Return result of transfer
243 return SPDR;
244}
245
246//-----------------------------------------------------------------------------
247void spi_transfer_string(U08 length, U08* addr, U08 device)
248{
249/*
250#define SPI_E_CS PB4 //device 0
251#define SPI_AD_CS PD3 //device 1
252#define SPI_M_CS PD4 //device 2
253#define SPI_A_CS PD5 //device 3
254*/
255 U08 n;
256
257 // I assume the CS line is in "not enable"-state;
258 if ( device == 0 ){
259 TGL_BIT(PORTB, SPI_DEVICE_SS[device]); // I toggle the line
260 } else {
261 TGL_BIT(PORTD, SPI_DEVICE_SS[device]); // I toggle the line
262 }
263 // now the line is in "enable"-state
264
265
266 // Transfer requested bytes
267 for (n = 0; n < length; n++)
268 {
269 spi_transfer_byte(addr[n]);
270 }
271
272 if ( device == 0 ){
273 TGL_BIT(PORTB, SPI_DEVICE_SS[device]); // I toggle the line
274 } else {
275 TGL_BIT(PORTD, SPI_DEVICE_SS[device]); // I toggle the line
276 }
277
278}
279//-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.