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