blob: c8552bf4cfe49b22c874a86946daafe4c907c0ec [file] [log] [blame]
Brian Silverman5f17a972016-02-28 01:49:32 -05001#ifndef FRC971_WPILIB_ADIS16448_H_
2#define FRC971_WPILIB_ADIS16448_H_
3
4#include <stdint.h>
5
6#include <memory>
7#include <atomic>
8
9#include "SPI.h"
10#include "DigitalInput.h"
11#undef ERROR
12
13#include "aos/common/logging/logging.h"
14
15namespace frc971 {
16namespace wpilib {
17
18// Handles interfacing with an Analog Devices ADIS16448 Inertial Sensor over
19// SPI and sending values out on a queue.
20//
21// The sensor is configured to generate samples at 204.8 Hz, and the values are
22// sent out as each sample is received.
23//
24// This is designed to be passed into ::std::thread's constructor so it will run
25// as a separate thread.
26class ADIS16448 {
27 public:
28 // port is where to find the sensor over SPI.
29 // dio1 must be connected to DIO1 on the sensor.
30 ADIS16448(SPI::Port port, DigitalInput *dio1);
31
32 // For ::std::thread to call.
33 //
34 // Initializes the sensor and then loops until Quit() is called taking
35 // readings.
36 void operator()();
37
38 void Quit() { run_ = false; }
39
Philipp Schrader29d54f22016-04-02 22:14:48 +000040 double gyro_x_zeroed_offset() const { return gyro_x_zeroed_offset_; }
41 double gyro_y_zeroed_offset() const { return gyro_y_zeroed_offset_; }
42 double gyro_z_zeroed_offset() const { return gyro_z_zeroed_offset_; }
43
Brian Silverman5f17a972016-02-28 01:49:32 -050044 private:
45 // Converts a 16-bit value at data to a scaled output value where a value of 1
46 // corresponds to lsb_per_output.
47 float ConvertValue(uint8_t *data, double lsb_per_output, bool sign = true);
48
49 // Performs an SPI transaction.
50 // Returns true if it succeeds.
51 template <uint8_t size>
52 bool DoTransaction(uint8_t to_send[size], uint8_t to_receive[size]);
53
54 // Reads one of the gyro's registers and returns the value in value.
55 // next_address is the address of the *next* register to read.
56 // Not sure what gets stored in value for the first read, but it should be
57 // ignored. Passing nullptr for value is allowed to completely ignore it.
58 // Returns true if it succeeds.
59 bool ReadRegister(uint8_t next_address, uint16_t *value);
60
61 // Writes a value to one of the registers.
62 // Returns true if it succeeds.
63 bool WriteRegister(uint8_t address, uint16_t value);
64
65 // Checks the given value of the DIAG_STAT register and logs any errors.
66 // Returns true if there are no errors we care about.
67 bool CheckDiagStatValue(uint16_t value) const;
68
69 // Starts everything up and runs a self test.
70 // Returns true if it succeeds.
71 bool Initialize();
72
73 const ::std::unique_ptr<SPI> spi_;
74 DigitalInput *const dio1_;
75
76 ::std::atomic<bool> run_{true};
Philipp Schrader29d54f22016-04-02 22:14:48 +000077
78 // The averaged values of the gyro over 6 seconds after power up.
Austin Schuh943fcbd2016-04-03 21:35:41 -070079 bool gyros_are_zeroed_ = false;
Philipp Schrader29d54f22016-04-02 22:14:48 +000080 double gyro_x_zeroed_offset_ = 0.0;
81 double gyro_y_zeroed_offset_ = 0.0;
82 double gyro_z_zeroed_offset_ = 0.0;
Brian Silverman5f17a972016-02-28 01:49:32 -050083};
84
85} // namespace wpilib
86} // namespace frc971
87
88#endif // FRC971_WPILIB_ADIS16448_H_