blob: 7fb3b7152854bce1db3dc853c52754c897e2578f [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved.
3 */
4/* Open Source Software - may be modified and shared by FRC teams. The code */
5/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
6/*----------------------------------------------------------------------------*/
7
8#include "ADXL345_SPI.h"
9#include "DigitalInput.h"
10#include "DigitalOutput.h"
11#include "LiveWindow/LiveWindow.h"
12
13const uint8_t ADXL345_SPI::kPowerCtlRegister;
14const uint8_t ADXL345_SPI::kDataFormatRegister;
15const uint8_t ADXL345_SPI::kDataRegister;
16constexpr double ADXL345_SPI::kGsPerLSB;
17
18/**
19 * Constructor.
20 *
21 * @param port The SPI port the accelerometer is attached to
22 * @param range The range (+ or -) that the accelerometer will measure.
23 */
24ADXL345_SPI::ADXL345_SPI(SPI::Port port, ADXL345_SPI::Range range) : SPI(port) {
25 SetClockRate(500000);
26 SetMSBFirst();
27 SetSampleDataOnFalling();
28 SetClockActiveLow();
29 SetChipSelectActiveHigh();
30
31 uint8_t commands[2];
32 // Turn on the measurements
33 commands[0] = kPowerCtlRegister;
34 commands[1] = kPowerCtl_Measure;
35 Transaction(commands, commands, 2);
36
37 SetRange(range);
38
39 HALReport(HALUsageReporting::kResourceType_ADXL345,
40 HALUsageReporting::kADXL345_SPI);
41
42 LiveWindow::GetInstance()->AddSensor("ADXL345_SPI", port, this);
43}
44
45/** {@inheritdoc} */
46void ADXL345_SPI::SetRange(Range range) {
47 uint8_t commands[2];
48
49 // Specify the data format to read
50 commands[0] = kDataFormatRegister;
51 commands[1] = kDataFormat_FullRes | (uint8_t)(range & 0x03);
52 Transaction(commands, commands, 2);
53}
54
55/** {@inheritdoc} */
56double ADXL345_SPI::GetX() { return GetAcceleration(kAxis_X); }
57
58/** {@inheritdoc} */
59double ADXL345_SPI::GetY() { return GetAcceleration(kAxis_Y); }
60
61/** {@inheritdoc} */
62double ADXL345_SPI::GetZ() { return GetAcceleration(kAxis_Z); }
63
64/**
65 * Get the acceleration of one axis in Gs.
66 *
67 * @param axis The axis to read from.
68 * @return Acceleration of the ADXL345 in Gs.
69 */
70double ADXL345_SPI::GetAcceleration(ADXL345_SPI::Axes axis) {
71 uint8_t buffer[3];
72 uint8_t command[3] = {0, 0, 0};
73 command[0] =
74 (kAddress_Read | kAddress_MultiByte | kDataRegister) + (uint8_t)axis;
75 Transaction(command, buffer, 3);
76
77 // Sensor is little endian... swap bytes
78 int16_t rawAccel = buffer[2] << 8 | buffer[1];
79 return rawAccel * kGsPerLSB;
80}
81
82/**
83 * Get the acceleration of all axes in Gs.
84 *
85 * @return An object containing the acceleration measured on each axis of the
86 * ADXL345 in Gs.
87 */
88ADXL345_SPI::AllAxes ADXL345_SPI::GetAccelerations() {
89 AllAxes data = AllAxes();
90 uint8_t dataBuffer[7] = {0, 0, 0, 0, 0, 0, 0};
91 int16_t rawData[3];
92
93 // Select the data address.
94 dataBuffer[0] = (kAddress_Read | kAddress_MultiByte | kDataRegister);
95 Transaction(dataBuffer, dataBuffer, 7);
96
97 for (int32_t i = 0; i < 3; i++) {
98 // Sensor is little endian... swap bytes
99 rawData[i] = dataBuffer[i * 2 + 2] << 8 | dataBuffer[i * 2 + 1];
100 }
101
102 data.XAxis = rawData[0] * kGsPerLSB;
103 data.YAxis = rawData[1] * kGsPerLSB;
104 data.ZAxis = rawData[2] * kGsPerLSB;
105
106 return data;
107}
108
109std::string ADXL345_SPI::GetSmartDashboardType() const {
110 return "3AxisAccelerometer";
111}
112
113void ADXL345_SPI::InitTable(std::shared_ptr<ITable> subtable) {
114 m_table = subtable;
115 UpdateTable();
116}
117
118void ADXL345_SPI::UpdateTable() {
119 if (m_table != nullptr) {
120 m_table->PutNumber("X", GetX());
121 m_table->PutNumber("Y", GetY());
122 m_table->PutNumber("Z", GetZ());
123 }
124}
125
126std::shared_ptr<ITable> ADXL345_SPI::GetTable() const { return m_table; }