Rev 248 | 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) {
halSPISetPolarityPhase(1,1); // ADXL345 operates in SPI(1,1)
ADXL_CS_LOW();
spiSendByte(addr & ~ADXL_BYTE_WRITE);
spiSendByte(data);
ADXL_CS_HIGH();
halSPISetPolarityPhase(0,0); // Revert back to SPI(0,0)
}
/*
* Reads the value of the register at the address
*/
unsigned char ReadSPI(unsigned char addr) {
unsigned char ret;
halSPISetPolarityPhase(1,1); // ADXL345 operates in SPI(1,1)
ADXL_CS_LOW();
spiSendByte(addr | ADXL_BYTE_READ);
spiReadFrame(&ret, 1);
ADXL_CS_HIGH();
halSPISetPolarityPhase(0,0); // Revert back to SPI(0,0)
return ret;
}
/*
* Reads a 16-bit value of the register at the address
*/
int Read16SPI(unsigned char addr) {
unsigned char recv[2];
int ret;
halSPISetPolarityPhase(1,1); // ADXL345 operates in SPI(1,1)
ADXL_CS_LOW();
spiSendByte(addr | ADXL_MULTI_BYTE_READ);
spiReadFrame(recv, 2);
ADXL_CS_HIGH();
halSPISetPolarityPhase(0,0); // Revert back to SPI(0,0)
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, 0x18);
// 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_ACT_TAP_STATUS);
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);
}