//----------------------------------------------------------------------------- #include "spi_master.h" //----------------------------------------------------------------------------- volatile U08 spi_clock_index; volatile U08 spi_cpol; volatile U08 spi_cpha; volatile U08 spi_dord; volatile BOOL spi_ss_active_high; volatile U08 spi_read_buffer[SPI_READ_BUFFER_SIZE]; volatile U08 spi_write_buffer[SPI_WRITE_BUFFER_SIZE]; volatile U08 SPI_DEVICE_SS[4]={SPI_E_CS ,SPI_AD_CS ,SPI_M_CS ,SPI_A_CS }; volatile BOOL SPI_DEVICE_ACTIVE_HIGH[4]={false ,false ,false ,false }; //----------------------------------------------------------------------------- void spi_setup_w5100() { spi_clock_index = 0; // spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices spi_cpol = 0; spi_cpha = 0; // SPI mode=0 good for ethernet. spi_setup(); // Setup SPI bits and clock speed } void spi_setup_ad7719() { spi_clock_index = 6; // since AD7719 is not connected via level shifters .. we can go up to 4Mbps spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices spi_cpol = 1; spi_cpha = 1; // SPI mode=3 good for AD7719. spi_setup(); // Setup SPI bits and clock speed } void spi_init(void) { // there are a total of 4 devices on the SPI bus: // 1.) Ethernet Modul WIZ812MJ // 2.) AD7719 24bit ADC // 3.) LIS3LV accelerometer <---- not used yet. // 4.) MAX6662 temp sensor <---- not assembled! // We check if they all can live with the same SPI settings: // 1.) Ethernet modul: // supports spi mode=0 or mode=3 --> eighther cpol=cpha=0 or cpol=cpha=1 // THAT IS NOT TRUE!!!! // only mode 0 !!!!!!!!!!!!!!!!!!!!!!!!!!!1 // MSB first // SCLK time 70ns minimum --> 14.2MHz maximum // // 2.) AD7719 // supports mode=3 --> cpol=cpha=1 // MSB first // SCLK time 200ns minimum --> 5MHz maximum // // 3.) LIS3LV // SPI CLK idles high --> cpol=1 // data valid at rising edge. --> cpha=1 as well // ==> mode 3 is supported only. // MSB first, but take take at multi byte transfers. LSbyte first // SCLK time - is not mentioned in the datasheet // // 4.) MAX6662 Tempsensor // since it is not assembled, this information is not necessary. // fastes SPI CLK frequency can be --> F_CPU/2 = 4MHz // slowest can be --> F_CPU/128 = 62.5KHz // Lets try with the fastest! spi_clock_index = 4; // this is reasonable for W5100 because of slow level shifters on the FSC. spi_dord = 0; // Data Order MSB first dord = 0 --> good for all devices spi_cpol = 0; spi_cpha = 0; // SPI mode=0 good for ethernet. spi_setup(); // Setup SPI bits and clock speed } //----------------------------------------------------------------------------- void spi_setup(void) { // Disable SPI, clear all flags SPCR = 0; // Set/Clear bits DORD, CPOL and CPHA in SPI Control Register spi_dord & 0x01 ? (SPCR |= (1 << DORD)) : (SPCR &= ~(1 << DORD)); spi_cpol & 0x01 ? (SPCR |= (1 << CPOL)) : (SPCR &= ~(1 << CPOL)); spi_cpha & 0x01 ? (SPCR |= (1 << CPHA)) : (SPCR &= ~(1 << CPHA)); switch (spi_clock_index) { case 0:{ // F_CPU / 128 SPCR |= (1 << SPR1) | (1 << SPR0); SPSR &= ~(1 < SPI_MAX_CLOCK_INDEX) { clock_index = SPI_MAX_CLOCK_INDEX; } spi_clock_index = clock_index; spi_setup(); // Setup SPI bits and clock speed } //----------------------------------------------------------------------------- void spi_set_dord(U08 dord) { if (dord > 1) { dord = 1; } spi_dord = dord; spi_setup(); // Setup SPI bits and clock speed } //----------------------------------------------------------------------------- void spi_set_cpol(U08 cpol) { if (cpol > 1) { cpol = 1; } spi_cpol = cpol; spi_setup(); // Setup SPI bits and clock speed } //----------------------------------------------------------------------------- void spi_set_cpha(U08 cpha) { if (cpha > 1) { cpha = 1; } spi_cpha = cpha; spi_setup(); // Setup SPI bits and clock speed } //----------------------------------------------------------------------------- void spi_transfer(U08 bytes, U08 device) { /* #define SPI_E_CS PB4 //device 0 #define SPI_AD_CS PD3 //device 1 #define SPI_M_CS PD4 //device 2 #define SPI_A_CS PD5 //device 3 */ U08 n; // Transfer requested bytes for (n = 0; n < bytes; n++) { PORTB |= 1<< PB3; // Check for active slave select level if (SPI_DEVICE_ACTIVE_HIGH[device]) { if (device == 0) { PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high } else { PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high } } else { if (device == 0) { PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low } else { PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low } } PORTB &= ~(1<< PB3); spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]); PORTB |= 1<< PB3; // Check for inactive slave select level if (SPI_DEVICE_ACTIVE_HIGH[device]) { if (device == 0) { PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low } else { PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low } } else { if (device == 0) { PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high } else { PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high } } PORTB &= ~(1<< PB3); } } //----------------------------------------------------------------------------- U08 spi_transfer_byte(U08 data) { // Start SPI Transfer if (!(SPCR & (1<