# HG changeset patch # User Tero Marttila # Date 1412799619 -10800 # Node ID d485c5b3ab4d393b44e3c49b20c64f3f7e129a32 # Parent 49643ef9d3d2599666430fa508b026d41c9b4bd1 spi: mixture of old spi_update and new spi_readwrite interfaces, using spi mode3 for adxl345 diff -r 49643ef9d3d2 -r d485c5b3ab4d include/spi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/spi.h Wed Oct 08 23:20:19 2014 +0300 @@ -0,0 +1,65 @@ +#ifndef QMSK_SPI_H +#define QMSK_SPI_H + +#include "stdlib.h" +#include "port.h" + +static ioport_t *const SPI_DDR = &DDRB; +static ioport_t *const SPI_PORT = &PORTB; + +static const byte SPI_SCK = PORTB5; +static const byte SPI_MISO = PORTB4; +static const byte SPI_MOSI = PORTB3; +static const byte SPI_SS = PORTB2; + +enum spi_dord { + SPI_DORD_MSB = 0b0, + + SPI_DORD = SPI_DORD_MSB +}; + +enum spi_cpol { + SPI_CPOL_0 = 0b0, + SPI_CPOL_1 = 0b1, + + SPI_CPOL = SPI_CPOL_1 // mode 3 +}; + +enum spi_cpha { + SPI_CPHA_0 = 0b0, + SPI_CPHA_1 = 0b1, + + SPI_CPHA = SPI_CPHA_1 // mode 3 +}; + +enum spi_clock { + SPI_CLOCK_4 = 0b000, + SPI_CLOCK_16 = 0b001, + SPI_CLOCK_64 = 0b010, + SPI_CLOCK_128 = 0b011, + + SPI_CLOCK = SPI_CLOCK_16 +}; + +#define SPI_COUNT 2 + +/* + * Initialize in SPI master mode. + */ +void spi_init (); + +/* + * Write out value, and return read value. + */ +byte spi_readwrite (byte value); + +/* + * Perform an SPI bus update. + */ +void spi_update (); + +void spi_set (byte index, byte value); + +byte spi_get (byte index); + +#endif diff -r 49643ef9d3d2 -r d485c5b3ab4d src/spi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/spi.c Wed Oct 08 23:20:19 2014 +0300 @@ -0,0 +1,88 @@ +#include "spi.h" + +static char spi_rx[SPI_COUNT], spi_tx[SPI_COUNT]; + +static const enum spi_dord spi_dord = SPI_DORD; +static const enum spi_cpol spi_cpol = SPI_CPOL; +static const enum spi_cpha spi_cpha = SPI_CPHA; +static const enum spi_clock spi_clock = SPI_CLOCK; + +void spi_init () +{ + // set output modes + sbi(SPI_DDR, SPI_SCK); // out + cbi(SPI_DDR, SPI_MISO); // in + sbi(SPI_DDR, SPI_MOSI); // out + sbi(SPI_DDR, SPI_SS); // out + + // initialize bus + sbi(SPI_PORT, SPI_SS); // high (off) + + // set mode + SPCR = ( + // SPI Interrupt Enable + (0b0 << SPIE) // disable + + // SPI Enable + | (0b1 << SPE) // enable + + // Data Order + | (spi_dord << DORD) + + // Master/Slave Select + | (0b1 << MSTR) // master + + // Clock Polarity + | (spi_cpol << CPOL) + + // Clock Phase + | (spi_cpha << CPHA) + + // SPI Clock Rate Select + | ((spi_clock & 0b11) << SPR0) + ); + SPSR = ( + (((spi_clock & 0b100) >> 2) << SPI2X) + ); +} + +byte spi_readwrite (byte value) +{ + // out + SPDR = value; + + // sync + while (!tbi(&SPSR, SPIF)) + ; + + return SPDR; +} +/* + * Perform an SPI bus update. + */ +void spi_update () +{ + char i; + char *rx = spi_rx + SPI_COUNT, *tx = spi_tx + SPI_COUNT; + + // start of packet + cbi(SPI_PORT, SPI_SS); // low + + for (i = SPI_COUNT; i > 0; i--) { + *--rx = spi_readwrite(*--tx); + } + + // end of packet + sbi(SPI_PORT, SPI_SS); // high +} + +void spi_set (byte index, byte value) +{ + spi_tx[index] = value; +} + +byte spi_get (byte index) +{ + return spi_rx[index]; +} +