PX4 Firmware
PX4 Autopilot Software http://px4.io
FXAS21002C.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2017-2019 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 "FXAS21002C.hpp"
35 
36 /* SPI protocol address bits */
37 #define DIR_READ(a) ((a) | (1 << 7))
38 #define DIR_WRITE(a) ((a) & 0x7f)
39 #define swap16(w) __builtin_bswap16((w))
40 
41 #define FXAS21002C_STATUS 0x00
42 #define FXAS21002C_OUT_X_MSB 0x01
43 #define FXAS21002C_OUT_X_LSB 0x02
44 #define FXAS21002C_OUT_Y_MSB 0x03
45 #define FXAS21002C_OUT_Y_LSB 0x04
46 #define FXAS21002C_OUT_Z_MSB 0x05
47 #define FXAS21002C_OUT_Z_LSB 0x06
48 
49 #define FXAS21002C_DR_STATUS 0x07
50 # define DR_STATUS_ZYXOW (1 << 7)
51 # define DR_STATUS_ZOW (1 << 6)
52 # define DR_STATUS_YOW (1 << 5)
53 # define DR_STATUS_XOW (1 << 4)
54 # define DR_STATUS_ZYXDR (1 << 3)
55 # define DR_STATUS_ZDR (1 << 2)
56 # define DR_STATUS_YDR (1 << 1)
57 # define DR_STATUS_XDR (1 << 0)
58 
59 #define FXAS21002C_F_STATUS 0x08
60 # define F_STATUS_F_OVF (1 << 7)
61 # define F_STATUS_F_WMKF (1 << 6)
62 # define F_STATUS_F_CNT_SHIFTS 0
63 # define F_STATUS_F_CNT_MASK (0x3f << F_STATUS_F_CNT_SHIFTS)
64 
65 #define FXAS21002C_F_SETUP 0x09
66 # define F_SETUP_F_MODE_SHIFTS 6
67 # define F_SETUP_F_MODE_MASK (0x3 << F_SETUP_F_MODE_SHIFTS)
68 # define F_SETUP_F_WMRK_SHIFTS 0
69 # define F_SETUP_F_WMRK_MASK (0x3f << F_SETUP_F_WMRK_SHIFTS)
70 
71 #define FXAS21002C_F_EVENT 0x0a
72 # define F_EVENT_F_EVENT (1 << 5)
73 # define F_EVENT_FE_TIME_SHIFTS 0
74 # define F_EVENT_FE_TIME_MASK (0x1f << F_EVENT_FE_TIME_SHIFTS)
75 
76 #define FXAS21002C_INT_SRC_FLAG 0x0b
77 # define INT_SRC_FLAG_BOOTEND (1 << 3)
78 # define INT_SRC_FLAG_SRC_FIFO (1 << 2)
79 # define INT_SRC_FLAG_SRC_RT (1 << 1)
80 # define INT_SRC_FLAG_SRC_DRDY (1 << 0)
81 
82 #define FXAS21002C_WHO_AM_I 0x0c
83 #define WHO_AM_I 0xd7
84 
85 #define FXAS21002C_CTRL_REG0 0x0d
86 # define CTRL_REG0_BW_SHIFTS 6
87 # define CTRL_REG0_BW_MASK (0x3 << CTRL_REG0_BW_SHIFTS)
88 # define CTRL_REG0_BW(n) (((n) & 0x3) << CTRL_REG0_BW_SHIFTS)
89 # define CTRL_REG0_BW_HIGH CTRL_REG0_BW(0)
90 # define CTRL_REG0_BW_MED CTRL_REG0_BW(1)
91 # define CTRL_REG0_BW_LOW CTRL_REG0_BW(2)
92 # define CTRL_REG0_SPIW (1 << 6)
93 # define CTRL_REG0_SEL_SHIFTS 3
94 # define CTRL_REG0_SEL_MASK (0x2 << CTRL_REG0_SEL_SHIFTS)
95 # define CTRL_REG0_HPF_EN (1 << 2)
96 # define CTRL_REG0_FS_SHIFTS 0
97 # define CTRL_REG0_FS_MASK (0x3 << CTRL_REG0_FS_SHIFTS)
98 # define CTRL_REG0_FS_2000_DPS (0 << CTRL_REG0_FS_SHIFTS)
99 # define CTRL_REG0_FS_1000_DPS (1 << CTRL_REG0_FS_SHIFTS)
100 # define CTRL_REG0_FS_500_DPS (2 << CTRL_REG0_FS_SHIFTS)
101 # define CTRL_REG0_FS_250_DPS (3 << CTRL_REG0_FS_SHIFTS)
102 
103 #define FXAS21002C_RT_CFG 0x0e
104 # define RT_CFG_ELE (1 << 3)
105 # define RT_CFG_ZTEFE (1 << 2)
106 # define RT_CFG_YTEFE (1 << 1)
107 # define RT_CFG_XTEFE (1 << 0)
108 
109 #define FXAS21002C_RT_SRC 0x0f
110 # define RT_SRC_EA (1 << 6)
111 # define RT_SRC_ZRT (1 << 5)
112 # define RT_SRC_Z_RT_POL (1 << 4)
113 # define RT_SRC_YRT (1 << 3)
114 # define RT_SRC_Y_RT_POL (1 << 2)
115 # define RT_SRC_XRT (1 << 1)
116 # define RT_SRC_X_RT_POL (1 << 0)
117 
118 #define FXAS21002C_RT_THS 0x10
119 # define RT_THS_DBCNTM (1 << 7)
120 # define RT_THS_THS_SHIFTS 0
121 # define RT_THS_THS_MASK (0x7f << RT_THS_THS_SHIFTS)
122 
123 #define FXAS21002C_RT_COUNT 0x11
124 #define FXAS21002C_TEMP 0x12
125 
126 #define FXAS21002C_CTRL_REG1 0x13
127 # define CTRL_REG1_RST (1 << 6)
128 # define CTRL_REG1_ST (1 << 5)
129 # define CTRL_REG1_DR_SHIFTS 2
130 # define CTRL_REG1_DR_MASK (0x07 << CTRL_REG1_DR_SHIFTS)
131 # define CTRL_REG1_DR_12_5 (7 << CTRL_REG1_DR_SHIFTS)
132 # define CTRL_REG1_DR_12_5_1 (6 << CTRL_REG1_DR_SHIFTS)
133 # define CTRL_REG1_DR_25HZ (5 << CTRL_REG1_DR_SHIFTS)
134 # define CTRL_REG1_DR_50HZ (4 << CTRL_REG1_DR_SHIFTS)
135 # define CTRL_REG1_DR_100HZ (3 << CTRL_REG1_DR_SHIFTS)
136 # define CTRL_REG1_DR_200HZ (2 << CTRL_REG1_DR_SHIFTS)
137 # define CTRL_REG1_DR_400HZ (1 << CTRL_REG1_DR_SHIFTS)
138 # define CTRL_REG1_DR_800HZ (0 << CTRL_REG1_DR_SHIFTS)
139 # define CTRL_REG1_ACTIVE (1 << 1)
140 # define CTRL_REG1_READY (1 << 0)
141 
142 #define FXAS21002C_CTRL_REG2 0x14
143 # define CTRL_REG2_INT_CFG_FIFO (1 << 7)
144 # define CTRL_REG2_INT_EN_FIFO (1 << 6)
145 # define CTRL_REG2_INT_CFG_RT (1 << 5)
146 # define CTRL_REG2_INT_EN_RT (1 << 4)
147 # define CTRL_REG2_INT_CFG_DRDY (1 << 3)
148 # define CTRL_REG2_INT_EN_DRDY (1 << 2)
149 # define CTRL_REG2_IPOL (1 << 1)
150 # define CTRL_REG2_PP_OD (1 << 0)
151 
152 #define FXAS21002C_CTRL_REG3 0x15
153 # define CTRL_REG3_WRAPTOONE (1 << 3)
154 # define CTRL_REG3_EXTCTRLEN (1 << 2)
155 # define CTRL_REG3_FS_DOUBLE (1 << 0)
156 
157 #define DEF_REG(r) {r, #r}
158 
159 /* default values for this device */
160 #define FXAS21002C_MAX_RATE 800
161 #define FXAS21002C_DEFAULT_RATE FXAS21002C_MAX_RATE
162 #define FXAS21002C_DEFAULT_RANGE_DPS 2000
163 #define FXAS21002C_DEFAULT_ONCHIP_FILTER_FREQ 64 // ODR dependant
164 
165 /*
166  we set the timer interrupt to run a bit faster than the desired
167  sample rate and then throw away duplicates using the data ready bit.
168  This time reduction is enough to cope with worst case timing jitter
169  due to other timers
170  Typical reductions for the MPU6000 is 20% so 20% of 1/800 is 250 us
171  */
172 #define FXAS21002C_TIMER_REDUCTION 250
173 
174 /*
175  list of registers that will be checked in check_registers(). Note
176  that ADDR_WHO_AM_I must be first in the list.
177  */
178 static constexpr uint8_t _checked_registers[] {
185 };
186 
187 using namespace time_literals;
188 
189 FXAS21002C::FXAS21002C(int bus, uint32_t device, enum Rotation rotation) :
190  SPI("FXAS21002C", nullptr, bus, device, SPIDEV_MODE0, 2 * 1000 * 1000),
191  ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(this->get_device_id())),
192  _px4_gyro(get_device_id(), (external() ? ORB_PRIO_VERY_HIGH : ORB_PRIO_DEFAULT), rotation),
193  _sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": read")),
194  _errors(perf_alloc(PC_COUNT, MODULE_NAME": err")),
195  _bad_registers(perf_alloc(PC_COUNT, MODULE_NAME": bad register")),
196  _duplicates(perf_alloc(PC_COUNT, MODULE_NAME": duplicate reading"))
197 {
199 }
200 
202 {
203  /* make sure we are truly inactive */
204  stop();
205 
206  /* delete the perf counter */
211 }
212 
213 int
215 {
216  /* do SPI init (and probe) first */
217  if (SPI::init() != OK) {
218  PX4_ERR("SPI init failed");
219  return PX4_ERROR;
220  }
221 
222  reset();
223 
224  start();
225 
226  return PX4_OK;
227 }
228 
229 void
231 {
232  /* write 0 0 0 000 00 = 0x00 to CTRL_REG1 to place FXOS21002 in Standby
233  * [6]: RST=0
234  * [5]: ST=0 self test disabled
235  * [4-2]: DR[2-0]=000 for 200Hz ODR
236  * [1-0]: Active=0, Ready=0 for Standby mode
237  */
239 
240  /* write 0000 0000 = 0x00 to CTRL_REG0 to configure range and filters
241  * [7-6]: BW[1-0]=00, LPF 64 @ 800Hz ODR
242  * [5]: SPIW=0 4 wire SPI
243  * [4-3]: SEL[1-0]=00 for 10Hz HPF at 200Hz ODR
244  * [2]: HPF_EN=0 disable HPF
245  * [1-0]: FS[1-0]=00 for 1600dps (TBD CHANGE TO 2000dps when final trimmed parts available)
246  */
248 
249  /* write CTRL_REG1 to configure 800Hz ODR and enter Active mode */
251 
252  /* Set the default */
256 
257  _read = 0;
258 }
259 
260 int
262 {
263  /* verify that the device is attached and functioning */
264  bool success = (read_reg(FXAS21002C_WHO_AM_I) == WHO_AM_I);
265 
266  if (success) {
268  return OK;
269  }
270 
271  return -EIO;
272 }
273 
274 uint8_t
275 FXAS21002C::read_reg(unsigned reg)
276 {
277  uint8_t cmd[2];
278 
279  cmd[0] = DIR_READ(reg);
280  cmd[1] = 0;
281 
282  transfer(cmd, cmd, sizeof(cmd));
283 
284  return cmd[1];
285 }
286 
287 void
288 FXAS21002C::write_reg(unsigned reg, uint8_t value)
289 {
290  uint8_t cmd[2];
291 
292  cmd[0] = DIR_WRITE(reg);
293  cmd[1] = value;
294 
295  transfer(cmd, nullptr, sizeof(cmd));
296 }
297 
298 void
299 FXAS21002C::write_checked_reg(unsigned reg, uint8_t value)
300 {
301  write_reg(reg, value);
302 
303  for (uint8_t i = 0; i < FXAS21002C_NUM_CHECKED_REGISTERS; i++) {
304  if (reg == _checked_registers[i]) {
305  _checked_values[i] = value;
306  }
307  }
308 }
309 
310 void
311 FXAS21002C::modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
312 {
313  uint8_t val = read_reg(reg);
314  val &= ~clearbits;
315  val |= setbits;
316  write_checked_reg(reg, val);
317 }
318 
319 int
320 FXAS21002C::set_range(unsigned max_dps)
321 {
322  uint8_t bits = CTRL_REG0_FS_250_DPS;
323  float new_range_scale_dps_digit;
324 
325  if (max_dps == 0) {
326  max_dps = 2000;
327  }
328 
329  if (max_dps <= 250) {
330  //new_range = 250;
331  new_range_scale_dps_digit = 7.8125e-3f;
332  bits = CTRL_REG0_FS_250_DPS;
333 
334  } else if (max_dps <= 500) {
335  //new_range = 500;
336  new_range_scale_dps_digit = 15.625e-3f;
337  bits = CTRL_REG0_FS_500_DPS;
338 
339  } else if (max_dps <= 1000) {
340  //new_range = 1000;
341  new_range_scale_dps_digit = 31.25e-3f;
342  bits = CTRL_REG0_FS_1000_DPS;
343 
344  } else if (max_dps <= 2000) {
345  //new_range = 2000;
346  new_range_scale_dps_digit = 62.5e-3f;
347  bits = CTRL_REG0_FS_2000_DPS;
348 
349  } else {
350  return -EINVAL;
351  }
352 
353  set_standby(_current_rate, true);
354 
355  _px4_gyro.set_scale(new_range_scale_dps_digit / 180.0f * M_PI_F);
356 
358  set_standby(_current_rate, false);
359 
360  return OK;
361 }
362 
363 void
364 FXAS21002C::set_standby(int rate, bool standby_true)
365 {
366  uint8_t c = 0;
367  uint8_t s = 0;
368 
369  if (standby_true) {
371 
372  } else {
374  }
375 
377 
378  // From the data sheet
379 
380  int wait_ms = (1000 / rate) + 60 + 1;
381 
382  usleep(wait_ms * 1000);
383 }
384 
385 int
386 FXAS21002C::set_samplerate(unsigned frequency)
387 {
388  uint8_t bits = 0;
389 
390  unsigned last_rate = _current_rate;
391 
392  if (frequency == 0) {
393  frequency = FXAS21002C_DEFAULT_RATE;
394  }
395 
396  if (frequency <= 13) {
397  _current_rate = 13;
398  bits = CTRL_REG1_DR_12_5;
399 
400  } else if (frequency <= 25) {
401  _current_rate = 25;
402  bits = CTRL_REG1_DR_25HZ;
403 
404  } else if (frequency <= 50) {
405  _current_rate = 50;
406  bits = CTRL_REG1_DR_50HZ;
407 
408  } else if (frequency <= 100) {
409  _current_rate = 100;
410  bits = CTRL_REG1_DR_100HZ;
411 
412  } else if (frequency <= 200) {
413  _current_rate = 200;
414  bits = CTRL_REG1_DR_200HZ;
415 
416  } else if (frequency <= 400) {
417  _current_rate = 400;
418  bits = CTRL_REG1_DR_400HZ;
419 
420  } else if (frequency <= 800) {
421  _current_rate = 800;
422  bits = CTRL_REG1_DR_800HZ;
423 
424  } else {
425  return -EINVAL;
426  }
427 
428  set_standby(last_rate, true);
430  set_standby(_current_rate, false);
431 
433 
434  return OK;
435 }
436 
437 void
439 {
440  int high = 256 / (800 / _current_rate);
441  int med = high / 2 ;
442  int low = med / 2;
443 
444  if (_current_rate <= 25) {
445  low = -1;
446  }
447 
448  if (_current_rate == 13) {
449  med = -1;
450  low = -1;
451  }
452 
453  uint8_t filter = CTRL_REG0_BW_HIGH;
454 
455  if (frequency_hz == 0) {
456  filter = CTRL_REG0_BW_HIGH;
457 
458  } else if (frequency_hz <= low) {
459  filter = CTRL_REG0_BW_LOW;
460 
461  } else if (frequency_hz <= med) {
462  filter = CTRL_REG0_BW_MED;
463 
464  } else if (frequency_hz <= high) {
465  filter = CTRL_REG0_BW_HIGH;
466  }
467 
468  set_standby(_current_rate, true);
470  set_standby(_current_rate, false);
471 }
472 
473 void
475 {
476  /* make sure we are stopped first */
477  stop();
478 
479  /* start polling at the specified rate */
480  ScheduleOnInterval((1_s / FXAS21002C_DEFAULT_RATE) - FXAS21002C_TIMER_REDUCTION, 10000);
481 }
482 
483 void
485 {
486  ScheduleClear();
487 }
488 
489 void
491 {
492  /* make another measurement */
493  measure();
494 }
495 
496 void
498 {
499  uint8_t v;
500 
501  if ((v = read_reg(_checked_registers[_checked_next])) != _checked_values[_checked_next]) {
502  /*
503  if we get the wrong value then we know the SPI bus
504  or sensor is very sick. We set _register_wait to 20
505  and wait until we have seen 20 good values in a row
506  before we consider the sensor to be OK again.
507  */
509 
510  /*
511  try to fix the bad register value. We only try to
512  fix one per loop to prevent a bad sensor hogging the
513  bus. We skip zero as that is the WHO_AM_I, which
514  is not writeable
515  */
516  if (_checked_next != 0) {
517  write_reg(_checked_registers[_checked_next], _checked_values[_checked_next]);
518  }
519 
520  _register_wait = 20;
521  }
522 
523  _checked_next = (_checked_next + 1) % FXAS21002C_NUM_CHECKED_REGISTERS;
524 }
525 
526 void
528 {
529  // start the performance counter
531 
532  /* status register and data as read back from the device */
533 #pragma pack(push, 1)
534  struct {
535  uint8_t cmd;
536  uint8_t status;
537  int16_t x;
538  int16_t y;
539  int16_t z;
540  } raw_gyro_report{};
541 #pragma pack(pop)
542 
543  check_registers();
544 
545  if (_register_wait != 0) {
546  // we are waiting for some good transfers before using
547  // the sensor again.
548  _register_wait--;
550  return;
551  }
552 
553  /* fetch data from the sensor */
554  raw_gyro_report.cmd = DIR_READ(FXAS21002C_STATUS);
555  const hrt_abstime timestamp_sample = hrt_absolute_time();
556  transfer((uint8_t *)&raw_gyro_report, (uint8_t *)&raw_gyro_report, sizeof(raw_gyro_report));
557 
558  if (!(raw_gyro_report.status & DR_STATUS_ZYXDR)) {
561  return;
562  }
563 
564  /*
565  * The TEMP register contains an 8-bit 2's complement temperature value with a range
566  * of –128 °C to +127 °C and a scaling of 1 °C/LSB. The temperature data is only
567  * compensated (factory trim values applied) when the device is operating in the Active
568  * mode and actively measuring the angular rate.
569  */
570  if ((_read % _current_rate) == 0) {
571  const float temperature = read_reg(FXAS21002C_TEMP) * 1.0f;
572  _px4_gyro.set_temperature(temperature);
573  }
574 
575  // report the error count as the number of bad
576  // register reads. This allows the higher level
577  // code to decide if it should use this sensor based on
578  // whether it has had failures
580 
581  int16_t x_raw = swap16(raw_gyro_report.x);
582  int16_t y_raw = swap16(raw_gyro_report.y);
583  int16_t z_raw = swap16(raw_gyro_report.z);
584 
585  _px4_gyro.update(timestamp_sample, x_raw, y_raw, z_raw);
586 
587  _read++;
588 
589  /* stop the perf counter */
591 }
592 
593 void
595 {
596  printf("gyro reads: %u\n", _read);
601  ::printf("checked_next: %u\n", _checked_next);
602 
603  for (uint8_t i = 0; i < FXAS21002C_NUM_CHECKED_REGISTERS; i++) {
604  uint8_t v = read_reg(_checked_registers[i]);
605 
606  if (v != _checked_values[i]) {
607  ::printf("reg %02x:%02x should be %02x\n",
608  (unsigned)_checked_registers[i],
609  (unsigned)v,
610  (unsigned)_checked_values[i]);
611  }
612  }
613 
615 }
616 
617 void
619 {
620  const struct {
621  uint8_t reg;
622  const char *name;
623  } regmap[] = {
646  };
647 
648  for (uint8_t i = 0; i < sizeof(regmap) / sizeof(regmap[0]); i++) {
649  printf("0x%02x %d:%s\n", read_reg(regmap[i].reg), regmap[i].reg, regmap[i].name);
650  }
651 }
652 
653 void
655 {
656  // trigger an error
658 }
perf_counter_t _errors
Definition: FXAS21002C.hpp:84
FXAS21002C(int bus, uint32_t device, enum Rotation rotation)
Definition: FXAS21002C.cpp:189
#define FXAS21002C_DEFAULT_ONCHIP_FILTER_FREQ
Definition: FXAS21002C.cpp:163
#define FXAS21002C_OUT_X_LSB
Definition: FXAS21002C.cpp:43
static struct vehicle_status_s status
Definition: Commander.cpp:138
#define FXAS21002C_DEFAULT_RATE
Definition: FXAS21002C.cpp:161
void test_error()
deliberately trigger an error
Definition: FXAS21002C.cpp:654
measure the time elapsed performing an event
Definition: perf_counter.h:56
#define CTRL_REG1_DR_800HZ
Definition: FXAS21002C.cpp:138
virtual int probe()
Definition: FXAS21002C.cpp:261
void print_status()
void modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
Modify a register in the FXAS21002C.
Definition: FXAS21002C.cpp:311
void start()
Start automatic measurement.
Definition: FXAS21002C.cpp:474
void set_standby(int rate, bool standby_true)
Put the chip In stand by.
Definition: FXAS21002C.cpp:364
void print_registers()
dump register values
Definition: FXAS21002C.cpp:618
#define CTRL_REG0_FS_MASK
Definition: FXAS21002C.cpp:97
#define CTRL_REG0_FS_1000_DPS
Definition: FXAS21002C.cpp:99
#define FXAS21002C_CTRL_REG0
Definition: FXAS21002C.cpp:85
#define FXAS21002C_STATUS
Definition: FXAS21002C.cpp:41
#define CTRL_REG1_DR_25HZ
Definition: FXAS21002C.cpp:133
#define CTRL_REG1_DR_MASK
Definition: FXAS21002C.cpp:130
#define FXAS21002C_F_SETUP
Definition: FXAS21002C.cpp:65
#define FXAS21002C_RT_COUNT
Definition: FXAS21002C.cpp:123
#define FXAS21002C_TEMP
Definition: FXAS21002C.cpp:124
uint8_t _checked_next
Definition: FXAS21002C.hpp:97
void check_registers(void)
check key registers for correct values
Definition: FXAS21002C.cpp:497
void reset()
Reset chip.
Definition: FXAS21002C.cpp:230
#define DEF_REG(r)
Definition: FXAS21002C.cpp:157
#define FXAS21002C_DEFAULT_RANGE_DPS
Definition: FXAS21002C.cpp:162
Namespace encapsulating all device framework classes, functions and data.
Definition: CDev.cpp:47
count the number of times an event occurs
Definition: perf_counter.h:55
void write_reg(unsigned reg, uint8_t value)
Write a register in the FXAS21002C.
Definition: FXAS21002C.cpp:288
#define CTRL_REG0_BW_LOW
Definition: FXAS21002C.cpp:91
#define CTRL_REG0_FS_250_DPS
Definition: FXAS21002C.cpp:101
void set_device_type(uint8_t devtype)
#define FXAS21002C_OUT_Y_LSB
Definition: FXAS21002C.cpp:45
#define FXAS21002C_DR_STATUS
Definition: FXAS21002C.cpp:49
#define FXAS21002C_OUT_X_MSB
Definition: FXAS21002C.cpp:42
#define FXAS21002C_CTRL_REG2
Definition: FXAS21002C.cpp:142
#define FXAS21002C_OUT_Z_LSB
Definition: FXAS21002C.cpp:47
#define FXAS21002C_RT_THS
Definition: FXAS21002C.cpp:118
#define FXAS21002C_WHO_AM_I
Definition: FXAS21002C.cpp:82
perf_counter_t _sample_perf
Definition: FXAS21002C.hpp:83
void update(hrt_abstime timestamp, float x, float y, float z)
uint8_t read_reg(unsigned reg)
Read a register from the FXAS21002C.
Definition: FXAS21002C.cpp:275
void stop()
Stop automatic measurement.
Definition: FXAS21002C.cpp:484
PX4Gyroscope _px4_gyro
Definition: FXAS21002C.hpp:77
#define CTRL_REG1_DR_12_5
Definition: FXAS21002C.cpp:131
void perf_count(perf_counter_t handle)
Count a performance event.
#define DR_STATUS_ZYXDR
Definition: FXAS21002C.cpp:54
#define DIR_WRITE(a)
Definition: FXAS21002C.cpp:38
#define FXAS21002C_OUT_Z_MSB
Definition: FXAS21002C.cpp:46
#define WHO_AM_I
Definition: FXAS21002C.cpp:83
void perf_free(perf_counter_t handle)
Free a counter.
virtual ~FXAS21002C()
Definition: FXAS21002C.cpp:201
void init()
Activates/configures the hardware registers.
void set_sample_rate(unsigned rate)
#define perf_alloc(a, b)
Definition: px4io.h:59
Rotation
Enum for board and external compass rotations.
Definition: rotation.h:51
#define CTRL_REG0_BW_MED
Definition: FXAS21002C.cpp:90
perf_counter_t _bad_registers
Definition: FXAS21002C.hpp:85
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
void set_onchip_lowpass_filter(int frequency_hz)
Definition: FXAS21002C.cpp:438
#define CTRL_REG0_BW_HIGH
Definition: FXAS21002C.cpp:89
void set_error_count(uint64_t error_count)
void perf_end(perf_counter_t handle)
End a performance event.
#define CTRL_REG0_BW_MASK
Definition: FXAS21002C.cpp:87
int set_range(unsigned max_dps)
Set the FXAS21002C measurement range.
Definition: FXAS21002C.cpp:320
virtual int init()
Definition: FXAS21002C.cpp:214
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units.
Definition: drv_hrt.h:58
#define DRV_GYR_DEVTYPE_FXAS2100C
Definition: drv_sensor.h:105
Driver for the NXP FXAS21002C 3-Axis Digital Angular Rate Gyroscope connected via SPI...
#define FXAS21002C_TIMER_REDUCTION
Definition: FXAS21002C.cpp:172
#define CTRL_REG1_DR_100HZ
Definition: FXAS21002C.cpp:135
void measure()
Fetch accel measurements from the sensor and update the report ring.
Definition: FXAS21002C.cpp:527
const char * name
Definition: tests_main.c:58
void set_temperature(float temperature)
#define swap16(w)
Definition: FXAS21002C.cpp:39
#define DIR_READ(a)
Definition: FXAS21002C.cpp:37
void Run() override
Definition: FXAS21002C.cpp:490
uint8_t _checked_values[FXAS21002C_NUM_CHECKED_REGISTERS]
Definition: FXAS21002C.hpp:96
#define CTRL_REG1_DR_50HZ
Definition: FXAS21002C.cpp:134
int set_samplerate(unsigned frequency)
Set the FXAS21002C internal sampling frequency.
Definition: FXAS21002C.cpp:386
#define FXAS21002C_CTRL_REG3
Definition: FXAS21002C.cpp:152
#define CTRL_REG0_FS_500_DPS
Definition: FXAS21002C.cpp:100
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
uint64_t perf_event_count(perf_counter_t handle)
Return current event_count.
unsigned _current_rate
Definition: FXAS21002C.hpp:79
#define FXAS21002C_CTRL_REG1
Definition: FXAS21002C.cpp:126
#define CTRL_REG1_ACTIVE
Definition: FXAS21002C.cpp:139
Definition: bst.cpp:62
#define CTRL_REG1_READY
Definition: FXAS21002C.cpp:140
void print_info()
Diagnostics - print some basic information about the driver.
Definition: FXAS21002C.cpp:594
#define FXAS21002C_RT_CFG
Definition: FXAS21002C.cpp:103
#define FXAS21002C_OUT_Y_MSB
Definition: FXAS21002C.cpp:44
#define OK
Definition: uavcan_main.cpp:71
#define M_PI_F
Definition: ashtech.cpp:44
#define FXAS21002C_RT_SRC
Definition: FXAS21002C.cpp:109
void set_scale(float scale)
#define FXAS21002C_INT_SRC_FLAG
Definition: FXAS21002C.cpp:76
perf_counter_t _duplicates
Definition: FXAS21002C.hpp:86
#define FXAS21002C_F_EVENT
Definition: FXAS21002C.cpp:71
#define CTRL_REG1_DR_200HZ
Definition: FXAS21002C.cpp:136
void perf_begin(perf_counter_t handle)
Begin a performance event.
uint8_t _register_wait
Definition: FXAS21002C.hpp:88
#define FXAS21002C_F_STATUS
Definition: FXAS21002C.cpp:59
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
void write_checked_reg(unsigned reg, uint8_t value)
Write a register in the FXAS21002C, updating _checked_values.
Definition: FXAS21002C.cpp:299
static constexpr int FXAS21002C_NUM_CHECKED_REGISTERS
Definition: FXAS21002C.hpp:94
#define CTRL_REG1_DR_400HZ
Definition: FXAS21002C.cpp:137
unsigned _read
Definition: FXAS21002C.hpp:81
#define CTRL_REG0_FS_2000_DPS
Definition: FXAS21002C.cpp:98
static constexpr uint8_t _checked_registers[]
Definition: FXAS21002C.cpp:178