//----------------------------------------------------------------------------- #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_init(void) { // set all CS's: output DDRB |= (1 << SPI_E_CS); DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); // set all Chips selects HIGH PORTB |= (1 << SPI_E_CS); PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS); // set MOSI and SCK: output & // set MISO: input SPI_DDR |= (1 << SPI_MOSI); SPI_DDR |= (1 << SPI_SCLK); SPI_DDR &= ~(1 << SPI_MISO); // set MOSI, SCK: HIGH. MISO leave alone. SPI_PRT |= (1 << SPI_MOSI); SPI_PRT |= (1 << SPI_SCLK); SPI_PRT |= (1 << SPI_MISO); spi_clock_index = 4; // Set Clockindex for lowest clock speed (F_CPU / 128) spi_dord = 0; // Data Order MSB first dord = 0 spi_cpol = 1; spi_cpha = 1; // mode=3 needed by ADC ... lets see whats next. 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; // 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 } } // Transfer requested bytes for (n = 0; n < bytes; n++) { spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]); } // 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 } } } //----------------------------------------------------------------------------- U08 spi_transfer_byte(U08 data) { // Start SPI Transfer if (!(SPCR & (1<