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

Last change on this file since 10667 was 10667, checked in by neise, 9 years ago
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        //      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 = 0; spi_cpha = 0;                                   // SPI mode=0 good for ethernet.
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.