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