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

Last change on this file since 10102 was 10102, checked in by neise, 9 years ago
- still testing - AD7719 and ATmega ADC work muxers as well output via USB
File size: 6.3 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
23// set all CS's: output
24DDRB |= (1 << SPI_E_CS);
25DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
26
27// set all Chips selects HIGH
28PORTB |= (1 << SPI_E_CS);
29PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
30
31// set MOSI and SCK: output & // set MISO: input
32SPI_DDR |= (1 << SPI_MOSI);
33SPI_DDR |= (1 << SPI_SCLK);
34SPI_DDR &= ~(1 << SPI_MISO);
35
36// set MOSI, SCK: HIGH. MISO leave alone.
37SPI_PRT |= (1 << SPI_MOSI);
38SPI_PRT |= (1 << SPI_SCLK);
39SPI_PRT |= (1 << SPI_MISO);
40
41
42
43  spi_clock_index = 4;  // Set Clockindex for lowest clock speed (F_CPU / 128)
44  spi_dord = 0;                                 // Data Order MSB first dord = 0
45  spi_cpol = 1;                 
46  spi_cpha = 1;                                 // mode=3 needed by ADC ... lets see whats next.
47  spi_setup();                                  // Setup SPI bits and clock speed
48
49}
50//-----------------------------------------------------------------------------
51void spi_setup(void)
52{
53  // Disable SPI, clear all flags
54  SPCR = 0;
55
56  // Set/Clear bits DORD, CPOL and CPHA in SPI Control Register
57  spi_dord & 0x01 ? (SPCR |= (1 << DORD)) : (SPCR &= ~(1 << DORD));
58  spi_cpol & 0x01 ? (SPCR |= (1 << CPOL)) : (SPCR &= ~(1 << CPOL));
59  spi_cpha & 0x01 ? (SPCR |= (1 << CPHA)) : (SPCR &= ~(1 << CPHA));
60
61  switch (spi_clock_index)
62  {
63    case 0:{ // F_CPU / 128
64      SPCR |= (1 << SPR1) | (1 << SPR0);
65      SPSR &= ~(1 <<SPI2X);
66          }
67    break;
68
69    case 1:{ // F_CPU / 64
70      SPCR |= (1 << SPR1);
71      SPSR &= ~(1 << SPI2X);
72          }
73    break;
74
75    case 2:{ // F_CPU / 32
76      SPCR |= (1 << SPR1);
77      SPSR |= (1 << SPI2X);
78          }
79    break;
80
81    case 3:{ // F_CPU / 16
82      SPCR |= (1 << SPR0);
83      SPSR &= ~(1 << SPI2X);
84          }
85    break;
86
87    case 4:{ // F_CPU / 8
88      SPCR |= (1 << SPR0);
89      SPSR |= (1 << SPI2X);
90          }
91    break;
92
93    case 5: // F_CPU / 4
94      SPSR &= ~(1 << SPI2X);
95    break;
96
97    case 6: // F_CPU / 2
98      SPSR |= (1 << SPI2X);
99    break;
100
101    default:{ // F_CPU / 128
102      SPCR |= (1 << SPR1) | (1 << SPR0);
103      SPSR &= ~(1 << SPI2X);
104          }
105  }
106
107  // Enable SPI in Master Mode
108  SPCR |= (1 << SPE) | (1 << MSTR);
109}
110
111//-----------------------------------------------------------------------------
112
113void spi_set_clock_index(U08 clock_index)
114{
115  if (clock_index > SPI_MAX_CLOCK_INDEX)
116  {
117    clock_index = SPI_MAX_CLOCK_INDEX;
118  }
119
120  spi_clock_index = clock_index;
121
122  spi_setup(); // Setup SPI bits and clock speed
123}
124//-----------------------------------------------------------------------------
125
126void spi_set_dord(U08 dord)
127{
128  if (dord > 1)
129  {
130    dord = 1;
131  }
132
133  spi_dord = dord;
134
135  spi_setup(); // Setup SPI bits and clock speed
136}
137//-----------------------------------------------------------------------------
138
139void spi_set_cpol(U08 cpol)
140{
141  if (cpol > 1)
142  {
143    cpol = 1;
144  }
145
146  spi_cpol = cpol;
147
148  spi_setup(); // Setup SPI bits and clock speed
149}
150//-----------------------------------------------------------------------------
151
152void spi_set_cpha(U08 cpha)
153{
154  if (cpha > 1)
155  {
156    cpha = 1;
157  }
158
159  spi_cpha = cpha;
160
161  spi_setup(); // Setup SPI bits and clock speed
162}
163
164//-----------------------------------------------------------------------------
165
166void spi_transfer(U08 bytes, U08 device)
167{
168/*
169#define SPI_E_CS PB4            //device 0
170#define SPI_AD_CS PD3           //device 1
171#define SPI_M_CS PD4            //device 2
172#define SPI_A_CS PD5            //device 3
173*/
174  U08 n;
175 
176  // Check for active slave select level
177  if (SPI_DEVICE_ACTIVE_HIGH[device])
178  {
179                if (device == 0) {
180        PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
181                } else {
182                        PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
183                }
184  }
185  else
186  {
187                if (device == 0) {
188        PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
189                } else {
190                        PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
191                }
192  }
193
194  // Transfer requested bytes
195  for (n = 0; n < bytes; n++)
196  {
197    spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]);
198  }
199
200  // Check for inactive slave select level
201  if (SPI_DEVICE_ACTIVE_HIGH[device])
202  {
203                if (device == 0) {
204        PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
205                } else {
206                        PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
207                }
208  }
209  else
210  {
211                if (device == 0) {
212        PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
213                } else {
214                        PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
215                }
216  }
217}
218//-----------------------------------------------------------------------------
219
220U08 spi_transfer_byte(U08 data)
221{
222  // Start SPI Transfer
223        if (!(SPCR & (1<<MSTR)) )
224                SPCR |= 1<<MSTR;
225  SPDR = data;
226
227  // Wait for transfer completed
228  while (!(SPSR & (1 << SPIF)))
229  {
230  }
231
232  // Return result of transfer
233  return SPDR;
234}
235
236//-----------------------------------------------------------------------------
237void spi_transfer_string(U08 length, U08* addr, U08 device)
238{
239/*
240#define SPI_E_CS PB4            //device 0
241#define SPI_AD_CS PD3   //device 1
242#define SPI_M_CS PD4            //device 2
243#define SPI_A_CS PD5            //device 3
244*/
245  U08 n;
246 
247  // I assume the CS line is in "not enable"-state;
248        if ( device == 0 ){
249        TGL_BIT(PORTB, SPI_DEVICE_SS[device]);  // I toggle the line
250        } else {
251                TGL_BIT(PORTD, SPI_DEVICE_SS[device]);  // I toggle the line
252        }
253  // now the line is in "enable"-state
254 
255
256  // Transfer requested bytes
257  for (n = 0; n < length; n++)
258  {
259    spi_transfer_byte(addr[n]);
260  }
261       
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
268}
269//-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.