#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);
}