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

Last change on this file since 12892 was 11787, checked in by neise, 13 years ago
set W5300 SPI clock freq to F_CPU/128. Since sometimes the W5300 interface seems not to work, when the Programming adapter is connected to the camere, this *might* help.
File size: 8.2 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
17void spi_setup_w5100() {
18 spi_clock_index = 0; //
19 spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices
20 spi_cpol = 0; spi_cpha = 0; // SPI mode=0 good for ethernet.
21 spi_setup(); // Setup SPI bits and clock speed
22}
23
24void spi_setup_ad7719() {
25 spi_clock_index = 6; // since AD7719 is not connected via level shifters .. we can go up to 4Mbps
26
27 spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices
28 spi_cpol = 1; spi_cpha = 1; // SPI mode=3 good for AD7719.
29 spi_setup(); // Setup SPI bits and clock speed
30}
31
32
33
34
35
36void spi_init(void)
37{
38 // there are a total of 4 devices on the SPI bus:
39 // 1.) Ethernet Modul WIZ812MJ
40 // 2.) AD7719 24bit ADC
41 // 3.) LIS3LV accelerometer <---- not used yet.
42 // 4.) MAX6662 temp sensor <---- not assembled!
43
44 // We check if they all can live with the same SPI settings:
45 // 1.) Ethernet modul:
46 // supports spi mode=0 or mode=3 --> eighther cpol=cpha=0 or cpol=cpha=1
47 // THAT IS NOT TRUE!!!!
48 // only mode 0 !!!!!!!!!!!!!!!!!!!!!!!!!!!1
49 // MSB first
50 // SCLK time 70ns minimum --> 14.2MHz maximum
51 //
52 // 2.) AD7719
53 // supports mode=3 --> cpol=cpha=1
54 // MSB first
55 // SCLK time 200ns minimum --> 5MHz maximum
56 //
57 // 3.) LIS3LV
58 // SPI CLK idles high --> cpol=1
59 // data valid at rising edge. --> cpha=1 as well
60 // ==> mode 3 is supported only.
61 // MSB first, but take take at multi byte transfers. LSbyte first
62 // SCLK time - is not mentioned in the datasheet
63 //
64 // 4.) MAX6662 Tempsensor
65 // since it is not assembled, this information is not necessary.
66
67 // fastes SPI CLK frequency can be --> F_CPU/2 = 4MHz
68 // slowest can be --> F_CPU/128 = 62.5KHz
69
70 // Lets try with the fastest!
71 spi_clock_index = 4; // this is reasonable for W5100 because of slow level shifters on the FSC.
72
73 spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices
74 spi_cpol = 0; spi_cpha = 0; // SPI mode=0 good for ethernet.
75 spi_setup(); // Setup SPI bits and clock speed
76
77}
78//-----------------------------------------------------------------------------
79void spi_setup(void)
80{
81 // Disable SPI, clear all flags
82 SPCR = 0;
83
84 // Set/Clear bits DORD, CPOL and CPHA in SPI Control Register
85 spi_dord & 0x01 ? (SPCR |= (1 << DORD)) : (SPCR &= ~(1 << DORD));
86 spi_cpol & 0x01 ? (SPCR |= (1 << CPOL)) : (SPCR &= ~(1 << CPOL));
87 spi_cpha & 0x01 ? (SPCR |= (1 << CPHA)) : (SPCR &= ~(1 << CPHA));
88
89 switch (spi_clock_index)
90 {
91 case 0:{ // F_CPU / 128
92 SPCR |= (1 << SPR1) | (1 << SPR0);
93 SPSR &= ~(1 <<SPI2X);
94 }
95 break;
96
97 case 1:{ // F_CPU / 64
98 SPCR |= (1 << SPR1);
99 SPSR &= ~(1 << SPI2X);
100 }
101 break;
102
103 case 2:{ // F_CPU / 32
104 SPCR |= (1 << SPR1);
105 SPSR |= (1 << SPI2X);
106 }
107 break;
108
109 case 3:{ // F_CPU / 16
110 SPCR |= (1 << SPR0);
111 SPSR &= ~(1 << SPI2X);
112 }
113 break;
114
115 case 4:{ // F_CPU / 8
116 SPCR |= (1 << SPR0);
117 SPSR |= (1 << SPI2X);
118 }
119 break;
120
121 case 5: // F_CPU / 4
122 SPSR &= ~(1 << SPI2X);
123 break;
124
125 case 6: // F_CPU / 2
126 SPSR |= (1 << SPI2X);
127 break;
128
129 default:{ // F_CPU / 128
130 SPCR |= (1 << SPR1) | (1 << SPR0);
131 SPSR &= ~(1 << SPI2X);
132 }
133 }
134
135 // Enable SPI in Master Mode
136 SPCR |= (1 << SPE) | (1 << MSTR);
137}
138
139//-----------------------------------------------------------------------------
140
141void spi_set_clock_index(U08 clock_index)
142{
143 if (clock_index > SPI_MAX_CLOCK_INDEX)
144 {
145 clock_index = SPI_MAX_CLOCK_INDEX;
146 }
147
148 spi_clock_index = clock_index;
149
150 spi_setup(); // Setup SPI bits and clock speed
151}
152//-----------------------------------------------------------------------------
153
154void spi_set_dord(U08 dord)
155{
156 if (dord > 1)
157 {
158 dord = 1;
159 }
160
161 spi_dord = dord;
162
163 spi_setup(); // Setup SPI bits and clock speed
164}
165//-----------------------------------------------------------------------------
166
167void spi_set_cpol(U08 cpol)
168{
169 if (cpol > 1)
170 {
171 cpol = 1;
172 }
173
174 spi_cpol = cpol;
175
176 spi_setup(); // Setup SPI bits and clock speed
177}
178//-----------------------------------------------------------------------------
179
180void spi_set_cpha(U08 cpha)
181{
182 if (cpha > 1)
183 {
184 cpha = 1;
185 }
186
187 spi_cpha = cpha;
188
189 spi_setup(); // Setup SPI bits and clock speed
190}
191
192//-----------------------------------------------------------------------------
193
194void spi_transfer(U08 bytes, U08 device)
195{
196/*
197#define SPI_E_CS PB4 //device 0
198#define SPI_AD_CS PD3 //device 1
199#define SPI_M_CS PD4 //device 2
200#define SPI_A_CS PD5 //device 3
201*/
202 U08 n;
203 // Transfer requested bytes
204 for (n = 0; n < bytes; n++)
205 {
206 PORTB |= 1<< PB3;
207 // Check for active slave select level
208 if (SPI_DEVICE_ACTIVE_HIGH[device])
209 {
210 if (device == 0) {
211 PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
212 } else {
213 PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
214 }
215 }
216 else
217 {
218 if (device == 0) {
219 PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
220 } else {
221 PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
222 }
223 }
224
225 PORTB &= ~(1<< PB3);
226 spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]);
227 PORTB |= 1<< PB3;
228
229 // Check for inactive slave select level
230 if (SPI_DEVICE_ACTIVE_HIGH[device])
231 {
232 if (device == 0) {
233 PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
234 } else {
235 PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
236 }
237 }
238 else
239 {
240 if (device == 0) {
241 PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
242 } else {
243 PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
244 }
245 }
246 PORTB &= ~(1<< PB3);
247 }
248}
249//-----------------------------------------------------------------------------
250
251U08 spi_transfer_byte(U08 data)
252{
253 // Start SPI Transfer
254 if (!(SPCR & (1<<MSTR)) )
255 SPCR |= 1<<MSTR;
256 SPDR = data;
257
258 // Wait for transfer completed
259
260 while (!(SPSR & (1 << SPIF)))
261 {
262 }
263
264
265 // Return result of transfer
266 return SPDR;
267}
268
269//-----------------------------------------------------------------------------
270void spi_transfer_string(U08 length, U08* addr, U08 device)
271{
272/*
273#define SPI_E_CS PB4 //device 0
274#define SPI_AD_CS PD3 //device 1
275#define SPI_M_CS PD4 //device 2
276#define SPI_A_CS PD5 //device 3
277*/
278 U08 n;
279
280 // I assume the CS line is in "not enable"-state;
281 if ( device == 0 ){
282 TGL_BIT(PORTB, SPI_DEVICE_SS[device]); // I toggle the line
283 } else {
284 TGL_BIT(PORTD, SPI_DEVICE_SS[device]); // I toggle the line
285 }
286 // now the line is in "enable"-state
287
288
289 // Transfer requested bytes
290 for (n = 0; n < length; n++)
291 {
292 spi_transfer_byte(addr[n]);
293 }
294
295 if ( device == 0 ){
296 TGL_BIT(PORTB, SPI_DEVICE_SS[device]); // I toggle the line
297 } else {
298 TGL_BIT(PORTD, SPI_DEVICE_SS[device]); // I toggle the line
299 }
300
301}
302//-----------------------------------------------------------------------------
303
304
305//-----------------------------------------------------------------------------
306
307void spi_transfer_w5100(U08 bytes)
308{
309
310 U08 n;
311 // Transfer requested bytes
312 SPCR |= 1<<MSTR; // make sure we are still SPI MASTER ... sometimes this bit is cleared by something ... dkw?
313 for (n = 0; n < bytes; n++)
314 {
315 PORTB &= ~(1<< PB4); // SS low
316
317 SPDR = spi_write_buffer[n];
318 while (!(SPSR & (1 << SPIF)))
319 spi_read_buffer[n] = SPDR ;
320
321 PORTB |= (1<< PB4); // SS HIGH
322 }
323
324
325}
326//-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.