adxl345: control/data registers read/write default tip
authorTero Marttila <terom@paivola.fi>
Wed, 08 Oct 2014 23:20:34 +0300
changeset 11 a383e22204f2
parent 10 d485c5b3ab4d
adxl345: control/data registers read/write
include/adxl345.h
src/adxl345.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/adxl345.h	Wed Oct 08 23:20:34 2014 +0300
@@ -0,0 +1,23 @@
+#ifndef QMSK_ADXL345_H
+#define QMSK_ADXL345_H
+
+#include "port.h"
+#include "stdlib.h"
+
+/*
+ * Setup ADXL345_CS as the chip-select pin.
+ */
+void adxl345_init ();
+
+byte adxl345_read_devid ();
+
+/*
+ * Setup for measurements.
+ */
+void adxl345_setup ();
+
+int16_t adxl345_read_x ();
+int16_t adxl345_read_y ();
+int16_t adxl345_read_z ();
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/adxl345.c	Wed Oct 08 23:20:34 2014 +0300
@@ -0,0 +1,170 @@
+#include "adxl345.h"
+
+#include "spi.h"
+
+#include <util/delay.h>
+
+/*
+ * SPI format
+ */
+enum adxl345_header_bits {
+    ADXL345_READ        = 0b10000000,
+    ADXL345_WRITE       = 0b00000000,
+
+    ADXL345_MULTI       = 0b01000000,
+};
+
+enum adxl345_reg {
+    ADXL345_DEVID       = 0x00,
+
+    ADXL345_POWER_CTL   = 0x2D,
+
+    ADXL345_DATA_FORMAT = 0x31,
+    ADXL345_DATAX0      = 0x32,
+    ADXL345_DATAX1      = 0x33,
+    ADXL345_DATAY0      = 0x34,
+    ADXL345_DATAY1      = 0x35,
+    ADXL345_DATAZ0      = 0x36,
+    ADXL345_DATAZ1      = 0x37,
+};
+
+enum adxl345_power_ctl {
+    ADXL345_POWER_CTL_LINK          = 0b00100000,
+    ADXL345_POWER_CTL_AUTO_SLEEP    = 0b00010000,
+    ADXL345_POWER_CTL_MEASURE       = 0b00001000,
+    ADXL345_POWER_CTL_SLEEP         = 0b00000100,
+    ADXL345_POWER_CTL_WAKEUP        = 0b00000011,
+};
+
+enum adxl345_power_ctl_wakeup {
+    ADXL345_POWER_CTL_WAKEUP_8      = 0b00000011,
+    ADXL345_POWER_CTL_WAKEUP_4      = 0b00000001,
+    ADXL345_POWER_CTL_WAKEUP_2      = 0b00000010,
+    ADXL345_POWER_CTL_WAKEUP_1      = 0b00000000,
+};
+
+enum adxl345_data_format {
+    ADXL345_DATA_FORMAT_SELF_TEST   = 0b10000000,
+    ADXL345_DATA_FORMAT_SPI         = 0b01000000,
+    ADXL345_DATA_FORMAT_INT_INVERT  = 0b00100000,
+    ADXL345_DATA_FORMAT_FULL_RES    = 0b00001000,
+    ADXL345_DATA_FORMAT_JUSTIFY     = 0b00000100,
+    ADXL345_DATA_FORMAT_RANGE       = 0b00000011,
+};
+
+enum adxl345_data_format_range {
+    ADXL345_DATA_FORMAT_RANGE_2G    = 0b00000000,
+    ADXL345_DATA_FORMAT_RANGE_4G    = 0b00000001,
+    ADXL345_DATA_FORMAT_RANGE_8G    = 0b00000010,
+    ADXL345_DATA_FORMAT_RANGE_16G   = 0b00000011,
+};
+
+#define ADXL345_DDR DDRB
+#define ADXL345_PORT PORTB
+#define ADXL345_CS PORTB2
+
+void adxl345_init ()
+{
+    // set CS pin
+    sbi(&ADXL345_DDR,    ADXL345_CS);   // out
+    sbi(&ADXL345_PORT,   ADXL345_CS);   // high (off)
+}
+
+static inline void adxl345_start ()
+{
+    cbi(&ADXL345_PORT,   ADXL345_CS);    // low (on)
+    _delay_us(1);
+}
+
+static inline void adxl345_stop ()
+{
+    sbi(&ADXL345_PORT,   ADXL345_CS);    // high (off)
+    _delay_us(100);
+}
+
+static void adxl345_write (enum adxl345_reg reg, byte value)
+{
+    adxl345_start();
+
+    spi_readwrite(ADXL345_WRITE | reg);
+    spi_readwrite(value);
+
+    adxl345_stop();
+}
+
+static byte adxl345_read (enum adxl345_reg reg)
+{
+    byte value;
+
+    adxl345_start();
+
+    spi_readwrite(ADXL345_READ | reg);
+    value = spi_readwrite(0);
+
+    adxl345_stop();
+
+    return value;
+}
+
+static int8_t adxl345_read_s8 (enum adxl345_reg reg)
+{
+    int8_t value = 0;
+
+    adxl345_start();
+
+    spi_readwrite(ADXL345_READ | ADXL345_MULTI | reg);
+    value = spi_readwrite(0);
+
+    adxl345_stop();
+
+    return value;
+}
+
+static int16_t adxl345_read_s16 (enum adxl345_reg reg)
+{
+    char v0, v1;
+
+    adxl345_start();
+
+    spi_readwrite(ADXL345_READ | ADXL345_MULTI | reg);
+    v0 = spi_readwrite(0);
+    v1 = spi_readwrite(0);
+    adxl345_stop();
+
+    return ((int) v1 << 8) | (int) v0;
+}
+
+byte adxl345_read_devid ()
+{
+    return adxl345_read(ADXL345_DEVID);
+}
+
+void adxl345_setup ()
+{
+    adxl345_write(ADXL345_POWER_CTL,
+            // enable measrurement mode
+            ADXL345_POWER_CTL_MEASURE
+    );
+
+    /*
+    adxl345_write(ADXL345_DATA_FORMAT,
+            // self-test
+            ADXL345_DATA_FORMAT_SELF_TEST
+    );
+    */
+}
+
+int16_t adxl345_read_x ()
+{
+    return adxl345_read_s16(ADXL345_DATAX0);
+}
+
+int16_t adxl345_read_y ()
+{
+    return adxl345_read_s16(ADXL345_DATAY0);
+}
+
+int16_t adxl345_read_z ()
+{
+    return adxl345_read_s16(ADXL345_DATAZ0);
+}