Firmware
mpu9250.h
1 /****************************************************************************
2  *
3  * Copyright (c) 2016 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 #include <stdint.h>
35 
36 #include <perf/perf_counter.h>
37 #include <systemlib/conversions.h>
38 
39 #include <nuttx/wqueue.h>
40 
41 #include <board_config.h>
42 #include <drivers/drv_hrt.h>
43 
46 #include <drivers/drv_accel.h>
47 #include <drivers/drv_gyro.h>
48 #include <drivers/drv_mag.h>
49 #include <mathlib/math/filter/LowPassFilter2p.hpp>
51 #include <systemlib/err.h>
52 
53 #include <uORB/uORB.h>
54 #include <uORB/topics/debug_key_value.h>
55 
56 #include "mag.h"
57 #include "accel.h"
58 #include "gyro.h"
59 
60 
61 #if defined(PX4_I2C_OBDEV_MPU9250) || defined(PX4_I2C_BUS_EXPANSION)
62 # define USE_I2C
63 #endif
64 
65 
66 // MPU 9250 registers
67 #define MPUREG_WHOAMI 0x75
68 #define MPUREG_SMPLRT_DIV 0x19
69 #define MPUREG_CONFIG 0x1A
70 #define MPUREG_GYRO_CONFIG 0x1B
71 #define MPUREG_ACCEL_CONFIG 0x1C
72 #define MPUREG_ACCEL_CONFIG2 0x1D
73 #define MPUREG_LPACCEL_ODR 0x1E
74 #define MPUREG_WOM_THRESH 0x1F
75 #define MPUREG_FIFO_EN 0x23
76 #define MPUREG_I2C_MST_CTRL 0x24
77 #define MPUREG_I2C_SLV0_ADDR 0x25
78 #define MPUREG_I2C_SLV0_REG 0x26
79 #define MPUREG_I2C_SLV0_CTRL 0x27
80 #define MPUREG_I2C_SLV1_ADDR 0x28
81 #define MPUREG_I2C_SLV1_REG 0x29
82 #define MPUREG_I2C_SLV1_CTRL 0x2A
83 #define MPUREG_I2C_SLV2_ADDR 0x2B
84 #define MPUREG_I2C_SLV2_REG 0x2C
85 #define MPUREG_I2C_SLV2_CTRL 0x2D
86 #define MPUREG_I2C_SLV3_ADDR 0x2E
87 #define MPUREG_I2C_SLV3_REG 0x2F
88 #define MPUREG_I2C_SLV3_CTRL 0x30
89 #define MPUREG_I2C_SLV4_ADDR 0x31
90 #define MPUREG_I2C_SLV4_REG 0x32
91 #define MPUREG_I2C_SLV4_DO 0x33
92 #define MPUREG_I2C_SLV4_CTRL 0x34
93 #define MPUREG_I2C_SLV4_DI 0x35
94 #define MPUREG_I2C_MST_STATUS 0x36
95 #define MPUREG_INT_PIN_CFG 0x37
96 #define MPUREG_INT_ENABLE 0x38
97 #define MPUREG_INT_STATUS 0x3A
98 #define MPUREG_ACCEL_XOUT_H 0x3B
99 #define MPUREG_ACCEL_XOUT_L 0x3C
100 #define MPUREG_ACCEL_YOUT_H 0x3D
101 #define MPUREG_ACCEL_YOUT_L 0x3E
102 #define MPUREG_ACCEL_ZOUT_H 0x3F
103 #define MPUREG_ACCEL_ZOUT_L 0x40
104 #define MPUREG_TEMP_OUT_H 0x41
105 #define MPUREG_TEMP_OUT_L 0x42
106 #define MPUREG_GYRO_XOUT_H 0x43
107 #define MPUREG_GYRO_XOUT_L 0x44
108 #define MPUREG_GYRO_YOUT_H 0x45
109 #define MPUREG_GYRO_YOUT_L 0x46
110 #define MPUREG_GYRO_ZOUT_H 0x47
111 #define MPUREG_GYRO_ZOUT_L 0x48
112 #define MPUREG_EXT_SENS_DATA_00 0x49
113 #define MPUREG_I2C_SLV0_D0 0x63
114 #define MPUREG_I2C_SLV1_D0 0x64
115 #define MPUREG_I2C_SLV2_D0 0x65
116 #define MPUREG_I2C_SLV3_D0 0x66
117 #define MPUREG_I2C_MST_DELAY_CTRL 0x67
118 #define MPUREG_SIGNAL_PATH_RESET 0x68
119 #define MPUREG_MOT_DETECT_CTRL 0x69
120 #define MPUREG_USER_CTRL 0x6A
121 #define MPUREG_PWR_MGMT_1 0x6B
122 #define MPUREG_PWR_MGMT_2 0x6C
123 #define MPUREG_FIFO_COUNTH 0x72
124 #define MPUREG_FIFO_COUNTL 0x73
125 #define MPUREG_FIFO_R_W 0x74
126 
127 // Configuration bits MPU 9250
128 #define BIT_SLEEP 0x40
129 #define BIT_H_RESET 0x80
130 #define MPU_CLK_SEL_AUTO 0x01
131 
132 #define BITS_GYRO_ST_X 0x80
133 #define BITS_GYRO_ST_Y 0x40
134 #define BITS_GYRO_ST_Z 0x20
135 #define BITS_FS_250DPS 0x00
136 #define BITS_FS_500DPS 0x08
137 #define BITS_FS_1000DPS 0x10
138 #define BITS_FS_2000DPS 0x18
139 #define BITS_FS_MASK 0x18
140 
141 #define BITS_DLPF_CFG_250HZ 0x00
142 #define BITS_DLPF_CFG_184HZ 0x01
143 #define BITS_DLPF_CFG_92HZ 0x02
144 #define BITS_DLPF_CFG_41HZ 0x03
145 #define BITS_DLPF_CFG_20HZ 0x04
146 #define BITS_DLPF_CFG_10HZ 0x05
147 #define BITS_DLPF_CFG_5HZ 0x06
148 #define BITS_DLPF_CFG_3600HZ 0x07
149 #define BITS_DLPF_CFG_MASK 0x07
150 
151 #define BITS_ACCEL_CONFIG2_41HZ 0x03
152 
153 #define BIT_RAW_RDY_EN 0x01
154 #define BIT_INT_ANYRD_2CLEAR 0x10
155 #define BIT_INT_BYPASS_EN 0x02
156 
157 #define BIT_I2C_READ_FLAG 0x80
158 
159 #define BIT_I2C_SLV0_NACK 0x01
160 #define BIT_I2C_FIFO_EN 0x40
161 #define BIT_I2C_MST_EN 0x20
162 #define BIT_I2C_IF_DIS 0x10
163 #define BIT_FIFO_RST 0x04
164 #define BIT_I2C_MST_RST 0x02
165 #define BIT_SIG_COND_RST 0x01
166 
167 #define BIT_I2C_SLV0_EN 0x80
168 #define BIT_I2C_SLV0_BYTE_SW 0x40
169 #define BIT_I2C_SLV0_REG_DIS 0x20
170 #define BIT_I2C_SLV0_REG_GRP 0x10
171 
172 #define BIT_I2C_MST_MULT_MST_EN 0x80
173 #define BIT_I2C_MST_WAIT_FOR_ES 0x40
174 #define BIT_I2C_MST_SLV_3_FIFO_EN 0x20
175 #define BIT_I2C_MST_P_NSR 0x10
176 #define BITS_I2C_MST_CLOCK_258HZ 0x08
177 #define BITS_I2C_MST_CLOCK_400HZ 0x0D
178 
179 #define BIT_I2C_SLV0_DLY_EN 0x01
180 #define BIT_I2C_SLV1_DLY_EN 0x02
181 #define BIT_I2C_SLV2_DLY_EN 0x04
182 #define BIT_I2C_SLV3_DLY_EN 0x08
183 
184 #define MPU_WHOAMI_9250 0x71
185 #define MPU_WHOAMI_6500 0x70
186 
187 #define MPU9250_ACCEL_DEFAULT_RATE 1000
188 #define MPU9250_ACCEL_MAX_OUTPUT_RATE 280
189 #define MPU9250_ACCEL_DEFAULT_DRIVER_FILTER_FREQ 30
190 #define MPU9250_GYRO_DEFAULT_RATE 1000
191 /* rates need to be the same between accel and gyro */
192 #define MPU9250_GYRO_MAX_OUTPUT_RATE MPU9250_ACCEL_MAX_OUTPUT_RATE
193 #define MPU9250_GYRO_DEFAULT_DRIVER_FILTER_FREQ 30
194 
195 #define MPU9250_DEFAULT_ONCHIP_FILTER_FREQ 92
196 
197 
198 #define BANK0 0x0000
199 #define BANK1 0x0100
200 #define BANK2 0x0200
201 #define BANK3 0x0300
202 
203 #define BANK_REG_MASK 0x0300
204 #define REG_BANK(r) (((r) & BANK_REG_MASK)>>4)
205 #define REG_ADDRESS(r) ((r) & ~BANK_REG_MASK)
206 
207 #pragma pack(push, 1)
208 
212 struct MPUReport {
213  uint8_t cmd;
214  uint8_t status;
215  uint8_t accel_x[2];
216  uint8_t accel_y[2];
217  uint8_t accel_z[2];
218  uint8_t temp[2];
219  uint8_t gyro_x[2];
220  uint8_t gyro_y[2];
221  uint8_t gyro_z[2];
222  struct ak8963_regs mag;
223 };
224 #pragma pack(pop)
225 
226 #define MPU_MAX_WRITE_BUFFER_SIZE (2)
227 
228 
229 /*
230  The MPU9250 can only handle high bus speeds on the sensor and
231  interrupt status registers. All other registers have a maximum 1MHz
232  Communication with all registers of the device is performed using either
233  I2C at 400kHz or SPI at 1MHz. For applications requiring faster communications,
234  the sensor and interrupt registers may be read using SPI at 20MHz
235  */
236 #define MPU9250_LOW_BUS_SPEED 0
237 #define MPU9250_HIGH_BUS_SPEED 0x8000
238 #define MPU9250_REG_MASK 0x00FF
239 # define MPU9250_IS_HIGH_SPEED(r) ((r) & MPU9250_HIGH_BUS_SPEED)
240 # define MPU9250_REG(r) ((r) & MPU9250_REG_MASK)
241 # define MPU9250_SET_SPEED(r, s) ((r)|(s))
242 # define MPU9250_HIGH_SPEED_OP(r) MPU9250_SET_SPEED((r), MPU9250_HIGH_BUS_SPEED)
243 # define MPU9250_LOW_SPEED_OP(r) ((r) &~MPU9250_HIGH_BUS_SPEED)
244 
245 /* interface factories */
246 extern device::Device *MPU9250_SPI_interface(int bus, uint32_t cs, bool external_bus);
247 extern device::Device *MPU9250_I2C_interface(int bus, uint32_t address, bool external_bus);
248 extern int MPU9250_probe(device::Device *dev);
249 
250 typedef device::Device *(*MPU9250_constructor)(int, uint32_t, bool);
251 
252 class MPU9250_mag;
253 class MPU9250_accel;
254 class MPU9250_gyro;
255 
256 class MPU9250
257 {
258 public:
259  MPU9250(device::Device *interface, device::Device *mag_interface, const char *path_accel, const char *path_gyro,
260  const char *path_mag,
261  enum Rotation rotation,
262  bool magnetometer_only);
263 
264  virtual ~MPU9250();
265 
266  virtual int init();
267  uint8_t get_whoami();
268 
272  void print_info();
273 
274 protected:
275  device::Device *_interface;
276  uint8_t _whoami;
278  virtual int probe();
279 
280  friend class MPU9250_accel;
281  friend class MPU9250_mag;
282  friend class MPU9250_gyro;
283 
284 private:
285  MPU9250_accel *_accel;
286  MPU9250_gyro *_gyro;
287  MPU9250_mag *_mag;
288  uint8_t _selected_bank; /* Remember selected memory bank to avoid polling / setting on each read/write */
289  bool
290  _magnetometer_only; /* To disable accel and gyro reporting if only magnetometer is used (e.g. as external magnetometer) */
291 
292 #if defined(USE_I2C)
293  /*
294  * SPI bus based device use hrt
295  * I2C bus needs to use work queue
296  */
297  work_s _work{};
298 #endif
299  bool _use_hrt;
300 
301  struct hrt_call _call {};
302  unsigned _call_interval;
303 
304  ringbuffer::RingBuffer *_accel_reports;
305 
306  struct accel_calibration_s _accel_scale;
307  float _accel_range_scale;
308  float _accel_range_m_s2;
309  orb_advert_t _accel_topic;
310 
311  ringbuffer::RingBuffer *_gyro_reports;
312 
313  struct gyro_calibration_s _gyro_scale;
314  float _gyro_range_scale;
315  float _gyro_range_rad_s;
316 
317  unsigned _dlpf_freq;
318 
319  unsigned _sample_rate;
320  perf_counter_t _accel_reads;
321  perf_counter_t _gyro_reads;
322  perf_counter_t _sample_perf;
323  perf_counter_t _bad_transfers;
324  perf_counter_t _bad_registers;
325  perf_counter_t _good_transfers;
326  perf_counter_t _reset_retries;
327  perf_counter_t _duplicates;
328 
329  uint8_t _register_wait;
330  uint64_t _reset_wait;
331 
332  math::LowPassFilter2p _accel_filter_x;
333  math::LowPassFilter2p _accel_filter_y;
334  math::LowPassFilter2p _accel_filter_z;
335  math::LowPassFilter2p _gyro_filter_x;
336  math::LowPassFilter2p _gyro_filter_y;
337  math::LowPassFilter2p _gyro_filter_z;
338 
339  Integrator _accel_int;
340  Integrator _gyro_int;
341 
342  enum Rotation _rotation;
343 
344  // this is used to support runtime checking of key
345  // configuration registers to detect SPI bus errors and sensor
346  // reset
347 
348 #ifndef MAX
349 #define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
350 #endif
351 
352  static constexpr int MPU9250_NUM_CHECKED_REGISTERS{11};
353  static const uint16_t _mpu9250_checked_registers[MPU9250_NUM_CHECKED_REGISTERS];
354 
355  const uint16_t *_checked_registers;
356 
357  uint8_t _checked_values[MPU9250_NUM_CHECKED_REGISTERS];
358  uint8_t _checked_bad[MPU9250_NUM_CHECKED_REGISTERS];
359  unsigned _checked_next;
360  unsigned _num_checked_registers;
361 
362 
363  // last temperature reading for print_info()
364  float _last_temperature;
365 
366  bool check_null_data(uint16_t *data, uint8_t size);
367  bool check_duplicate(uint8_t *accel_data);
368  // keep last accel reading for duplicate detection
369  uint8_t _last_accel_data[6];
370  bool _got_duplicate;
371 
375  void start();
376 
380  void stop();
381 
387  int reset();
388 
389 
393  int reset_mpu();
394 
395 
396 #if defined(USE_I2C)
397 
411  void cycle();
412 
419  static void cycle_trampoline(void *arg);
420 
421  void use_i2c(bool on_true) { _use_hrt = !on_true; }
422 
423 #endif
424 
425  bool is_i2c(void) { return !_use_hrt; }
426 
427 
428 
429 
439  static void measure_trampoline(void *arg);
440 
444  void measure();
445 
453  uint8_t read_reg(unsigned reg, uint32_t speed = MPU9250_LOW_BUS_SPEED);
454  uint16_t read_reg16(unsigned reg);
455 
456 
466  uint8_t read_reg_range(unsigned start_reg, uint32_t speed, uint8_t *buf, uint16_t count);
467 
474  void write_reg(unsigned reg, uint8_t value);
475 
485  void modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits);
486 
493  void write_checked_reg(unsigned reg, uint8_t value);
494 
504  void modify_checked_reg(unsigned reg, uint8_t clearbits, uint8_t setbits);
505 
512  int set_accel_range(unsigned max_g);
513 
517  uint16_t swap16(uint16_t val) { return (val >> 8) | (val << 8); }
518 
524  bool is_external() { return _interface->external(); }
525 
526  /*
527  set low pass filter frequency
528  */
529  void _set_dlpf_filter(uint16_t frequency_hz);
530 
531  /*
532  set sample rate (approximate) - 1kHz to 5Hz
533  */
534  void _set_sample_rate(unsigned desired_sample_rate_hz);
535 
536  /*
537  set poll rate
538  */
539  int _set_pollrate(unsigned long rate);
540 
541  /*
542  check that key registers still have the right value
543  */
544  void check_registers(void);
545 
546  /* do not allow to copy this class due to pointer data members */
547  MPU9250(const MPU9250 &);
548  MPU9250 operator=(const MPU9250 &);
549 };
A flexible ringbuffer class.
Accelerometer driver interface.
Gyroscope driver interface.
Definition: mag.h:103
gyro scaling factors; Vout = (Vin * Vscale) + Voffset
Definition: drv_gyro.h:54
Helper class implementing the accel driver node.
Definition: accel.h:41
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
Vector rotation library.
High-resolution timer with callouts and timekeeping.
accel scaling factors; Vout = Vscale * (Vin + Voffset)
Definition: drv_accel.h:54
Definition: integrator.h:48
Report conversation within the mpu, including command byte and interrupt status.
Definition: icm20948.h:333
Helper class implementing the gyro driver node.
Definition: gyro.h:41
Header common to all counters.
Definition: perf_counter.cpp:65
Definition of commonly used conversions.
void reset(enum BMP280_BUS busid)
Reset the driver.
Definition: bmp280.cpp:743
Rotation
Enum for board and external compass rotations.
Definition: rotation.h:51
Fundamental base class for all physical drivers (I2C, SPI).
Definition: Device.hpp:65
Definition: mpu9250.h:256
API for the uORB lightweight object broker.
Helper class implementing the magnetometer driver node.
Definition: mag.h:131
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
A resettable integrator.
Callout record.
Definition: drv_hrt.h:72
Definition: LowPassFilter2p.hpp:43
Performance measuring tools.