terom@55: #define SPI_DDR DDRB terom@55: #define SPI_PORT PORTB terom@55: terom@55: #define SPI_SCK PORTB5 terom@55: #define SPI_MISO PORTB4 terom@55: #define SPI_MOSI PORTB3 terom@55: #define SPI_SS PORTB2 terom@55: terom@55: /* State */ terom@55: #define SPI_COUNT 1 terom@55: terom@55: static char spi_rx[SPI_COUNT], spi_tx[SPI_COUNT]; terom@55: terom@55: enum { terom@55: SPI_DORD_MSB = 0b0, terom@55: terom@55: SPI_DORD = SPI_DORD_MSB terom@55: }; terom@55: terom@55: enum { terom@55: SPI_CPOL_RISING = 0b0, terom@55: terom@55: SPI_CPOL = SPI_CPOL_RISING terom@55: }; terom@55: terom@55: enum { terom@55: SPI_CPHA_SAMPLE = 0b0, terom@55: terom@55: SPI_CPHA = SPI_CPHA_SAMPLE terom@55: }; terom@55: terom@55: enum { terom@55: SPI_CLOCK_4 = 0b000, terom@55: SPI_CLOCK_16 = 0b001, terom@55: SPI_CLOCK_64 = 0b010, terom@55: SPI_CLOCK_128 = 0b011, terom@55: terom@55: SPI_CLOCK = SPI_CLOCK_16 terom@55: }; terom@55: terom@55: /* terom@55: * Initialize in SPI master mode. terom@55: */ terom@55: void spi_init () terom@55: { terom@55: // set output modes terom@55: sbi(&SPI_DDR, SPI_SCK); // out terom@55: sbi(&SPI_DDR, SPI_MOSI); // out terom@55: sbi(&SPI_DDR, SPI_SS); // out terom@55: terom@55: // initialize bus terom@55: sbi(&SPI_PORT, SPI_SS); // high (off) terom@55: terom@55: // set mode terom@55: SPCR = ( terom@55: // SPI Interrupt Enable terom@55: (0b0 << SPIE) // disable terom@55: terom@55: // SPI Enable terom@55: | (0b1 << SPE) // enable terom@55: terom@55: // Data Order terom@55: | (SPI_DORD << DORD) terom@55: terom@55: // Master/Slave Select terom@55: | (0b1 << MSTR) // master terom@55: terom@55: // Clock Polarity terom@55: | (SPI_CPOL << CPOL) terom@55: terom@55: // Clock Phase terom@55: | (SPI_CPHA << CPHA) terom@55: terom@55: // SPI Clock Rate Select terom@55: | ((SPI_CLOCK & 0b11) << SPR0) terom@55: ); terom@55: SPSR = ( terom@55: (((SPI_CLOCK & 0b100) >> 2) << SPI2X) terom@55: ); terom@55: } terom@55: terom@55: /* terom@55: * Perform an SPI bus update. terom@55: */ terom@55: void spi_update () terom@55: { terom@55: char i; terom@55: char *rx = spi_rx + SPI_COUNT, *tx = spi_tx + SPI_COUNT; terom@55: terom@55: // start of packet terom@55: cbi(&SPI_PORT, SPI_SS); // low terom@55: terom@55: for (i = SPI_COUNT; i > 0; i--) { terom@55: // out terom@55: SPDR = *--tx; terom@55: terom@55: // sync terom@55: while (!tbi(&SPSR, SPIF)) terom@55: ; terom@55: terom@55: *--rx = SPDR; terom@55: } terom@55: terom@55: // end of packet terom@55: sbi(&SPI_PORT, SPI_SS); // high terom@55: }