spi: mixture of old spi_update and new spi_readwrite interfaces, using spi mode3 for adxl345
authorTero Marttila <terom@paivola.fi>
Wed, 08 Oct 2014 23:20:19 +0300
changeset 10 d485c5b3ab4d
parent 9 49643ef9d3d2
child 11 a383e22204f2
spi: mixture of old spi_update and new spi_readwrite interfaces, using spi mode3 for adxl345
include/spi.h
src/spi.c
--- /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
--- /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];
+}
+