0,0 → 1,157 |
#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); |
} |