Subversion Repositories Code-Repo

Rev

Blame | Last modification | View Log | RSS feed

#include "adxl345.h"
#include "hal_hardware_board.h"
#include "hal_SPI.h"

/*
 * Writes the given byte to the register at the address
 */
void WriteSPI(unsigned char addr, unsigned char data) {
        ADXL_CS_LOW();
        spiSendByte(addr & ~ADXL_BYTE_WRITE);
        spiSendByte(data);
        ADXL_CS_HIGH();
}

/*
 * Reads the value of the register at the address
 */
unsigned char ReadSPI(unsigned char addr) {
        unsigned char ret;
        ADXL_CS_LOW();
        spiSendByte(addr | ADXL_BYTE_READ);
        spiReadFrame(&ret, 1);
        ADXL_CS_HIGH();
        return ret;
}

/*
 * Reads a 16-bit value of the register at the address
 */
int Read16SPI(unsigned char addr) {
        unsigned char recv[2];
        int ret;
        ADXL_CS_LOW();
        spiSendByte(addr | ADXL_MULTI_BYTE_READ);
        spiReadFrame(recv, 2);
        ADXL_CS_HIGH();
        ret = recv[0];
        ret |= recv[1] << 8;
        return ret;
}

/*
 * ADXL345 Initialization Function
 */
unsigned char ADXLInit(void) {
        unsigned char deviceID;

        // Check if device exists
        deviceID = ReadSPI(ADXL345_REG_DEVID);
        if (deviceID != 0xE5)
                return 1;

        // Set FIFO to bypass mode
        WriteSPI(ADXL345_REG_FIFO_CTL, 0x00);

//      // Set the INT_INVERT bit in DATA_FORMAT register
        WriteSPI(ADXL345_REG_DATA_FORMAT, 0x20);

        ADXLSetRange(ADXL345_RANGE_16_G);

        ADXLSetDataRate(ADXL345_DATARATE_12_5_HZ);

        ADXLClearInterrupts();

        ADXLStandbyOff();

        return 0;
}

void ADXLStandbyOn(void) {
        // Turn off measurements
        WriteSPI(ADXL345_REG_POWER_CTL, 0x00);
}

void ADXLStandbyOff(void) {
        // Turn on measurements
        WriteSPI(ADXL345_REG_POWER_CTL, 0x08);
}

/*
 * Sets up and enables the tap interrupt
 */
void ADXLInitInterrupts(void) {
        // Set tap acceleration threshold  (62.5mg/LSB, 0xFF=16g)
        WriteSPI(ADXL345_REG_THRESH_TAP, 0x20);

        // Set maximum tap duration (625us/LSB)
        WriteSPI(ADXL345_REG_DUR, 0xFF);

        // Set minimum time for second tap (1.25ms/LSB)
        WriteSPI(ADXL345_REG_LATENT, 0xFF);

        // Set maximum time for second tap (1.25ms/LSB)
        WriteSPI(ADXL345_REG_WINDOW, 0xFF);

        // Bind single tap to INT1 and double tap to INT2
        WriteSPI(ADXL345_REG_INT_MAP, 0x20);

        // Enable all three axis for tap detection
        WriteSPI(ADXL345_REG_TAP_AXES, 0x07);

        // Enable single tap interrupts
        WriteSPI(ADXL345_REG_INT_ENABLE, 0x40);
}

/*
 * Clears any active interrupt flags
 */
void ADXLClearInterrupts(void) {
        ReadSPI(ADXL345_REG_INT_SOURCE);
}

/*
 * Returns sensor data
 */
void ADXLRead(int *x, int *y, int *z) {
        *x = Read16SPI(ADXL345_REG_DATAX0);
        *y = Read16SPI(ADXL345_REG_DATAY0);
        *z = Read16SPI(ADXL345_REG_DATAZ0);
}

/*
 * Sets the sensitivity range (2/4/8/16g)
 */
void ADXLSetRange(range_t range) {
        unsigned char data = ReadSPI(ADXL345_REG_DATA_FORMAT);

        // Set the new sensitivity range
        data &= ~0x0F;
        data |= range;

        // Set the FULL_RES bit
        data |= 0x08;

        WriteSPI(ADXL345_REG_DATA_FORMAT, data);
}

/*
 * Sets the data rate
 */
void ADXLSetDataRate(dataRate_t rate) {
        unsigned char data = rate;

#ifdef ADXL345_LOW_POWER_MODE
        // Set the low power mode bit
        data |= 0x10;
#endif

        WriteSPI(ADXL345_REG_BW_RATE, data);
}