source: firmware/FSC/usb_src/spi_master.c

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