blob: 4f2aaa02e7fbd86f4eb68eb5514c435401afd56d [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"
Brian Silvermana70994f2017-03-16 22:32:55 -070011#include "DigitalOutput.h"
Brian Silverman5f17a972016-02-28 01:49:32 -050012#undef ERROR
13
14#include "aos/common/logging/logging.h"
15
16namespace frc971 {
17namespace wpilib {
18
19// Handles interfacing with an Analog Devices ADIS16448 Inertial Sensor over
20// SPI and sending values out on a queue.
21//
22// The sensor is configured to generate samples at 204.8 Hz, and the values are
23// sent out as each sample is received.
24//
25// This is designed to be passed into ::std::thread's constructor so it will run
26// as a separate thread.
27class ADIS16448 {
28 public:
29 // port is where to find the sensor over SPI.
30 // dio1 must be connected to DIO1 on the sensor.
31 ADIS16448(SPI::Port port, DigitalInput *dio1);
32
Brian Silvermana70994f2017-03-16 22:32:55 -070033 // Sets the dummy SPI port to send values on to make the roboRIO deassert the
34 // chip select line. This is mainly useful when there are no other devices
35 // sharing the bus.
36 void SetDummySPI(SPI::Port port);
37
38 // Sets the reset line for the IMU to use for error recovery.
39 void set_reset(DigitalOutput *output) { reset_ = output; }
40
Brian Silverman5f17a972016-02-28 01:49:32 -050041 // For ::std::thread to call.
42 //
43 // Initializes the sensor and then loops until Quit() is called taking
44 // readings.
45 void operator()();
46
47 void Quit() { run_ = false; }
48
Philipp Schrader29d54f22016-04-02 22:14:48 +000049 double gyro_x_zeroed_offset() const { return gyro_x_zeroed_offset_; }
50 double gyro_y_zeroed_offset() const { return gyro_y_zeroed_offset_; }
51 double gyro_z_zeroed_offset() const { return gyro_z_zeroed_offset_; }
52
Brian Silverman5f17a972016-02-28 01:49:32 -050053 private:
Brian Silvermana70994f2017-03-16 22:32:55 -070054 // Try to initialize repeatedly as long as we're supposed to be running.
55 void InitializeUntilSuccessful();
56
Brian Silverman5f17a972016-02-28 01:49:32 -050057 // Converts a 16-bit value at data to a scaled output value where a value of 1
58 // corresponds to lsb_per_output.
59 float ConvertValue(uint8_t *data, double lsb_per_output, bool sign = true);
60
61 // Performs an SPI transaction.
62 // Returns true if it succeeds.
63 template <uint8_t size>
64 bool DoTransaction(uint8_t to_send[size], uint8_t to_receive[size]);
65
66 // Reads one of the gyro's registers and returns the value in value.
67 // next_address is the address of the *next* register to read.
68 // Not sure what gets stored in value for the first read, but it should be
69 // ignored. Passing nullptr for value is allowed to completely ignore it.
70 // Returns true if it succeeds.
71 bool ReadRegister(uint8_t next_address, uint16_t *value);
72
73 // Writes a value to one of the registers.
74 // Returns true if it succeeds.
75 bool WriteRegister(uint8_t address, uint16_t value);
76
77 // Checks the given value of the DIAG_STAT register and logs any errors.
78 // Returns true if there are no errors we care about.
79 bool CheckDiagStatValue(uint16_t value) const;
80
81 // Starts everything up and runs a self test.
82 // Returns true if it succeeds.
83 bool Initialize();
84
Brian Silvermana70994f2017-03-16 22:32:55 -070085 // TODO(Brian): This object has no business owning these ones.
Brian Silverman5f17a972016-02-28 01:49:32 -050086 const ::std::unique_ptr<SPI> spi_;
Brian Silvermana70994f2017-03-16 22:32:55 -070087 ::std::unique_ptr<SPI> dummy_spi_;
Brian Silverman5f17a972016-02-28 01:49:32 -050088 DigitalInput *const dio1_;
Brian Silvermana70994f2017-03-16 22:32:55 -070089 DigitalOutput *reset_ = nullptr;
Brian Silverman5f17a972016-02-28 01:49:32 -050090
91 ::std::atomic<bool> run_{true};
Philipp Schrader29d54f22016-04-02 22:14:48 +000092
93 // The averaged values of the gyro over 6 seconds after power up.
Austin Schuh943fcbd2016-04-03 21:35:41 -070094 bool gyros_are_zeroed_ = false;
Philipp Schrader29d54f22016-04-02 22:14:48 +000095 double gyro_x_zeroed_offset_ = 0.0;
96 double gyro_y_zeroed_offset_ = 0.0;
97 double gyro_z_zeroed_offset_ = 0.0;
Brian Silverman5f17a972016-02-28 01:49:32 -050098};
99
100} // namespace wpilib
101} // namespace frc971
102
103#endif // FRC971_WPILIB_ADIS16448_H_