--- /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);
+}