PX4 Firmware
PX4 Autopilot Software http://px4.io
bma180.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (c) 2012-2014 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 /**
35  * @file bma180.cpp
36  * Driver for the Bosch BMA 180 MEMS accelerometer connected via SPI.
37  */
38 
39 #include <px4_platform_common/px4_config.h>
40 #include <px4_platform_common/defines.h>
41 #include <ecl/geo/geo.h>
42 
43 #include <sys/types.h>
44 #include <stdint.h>
45 #include <stdbool.h>
46 #include <stddef.h>
47 #include <stdlib.h>
48 #include <semaphore.h>
49 #include <string.h>
50 #include <fcntl.h>
51 #include <poll.h>
52 #include <errno.h>
53 #include <stdio.h>
54 #include <math.h>
55 #include <unistd.h>
56 
57 #include <perf/perf_counter.h>
58 #include <systemlib/err.h>
59 #include <nuttx/arch.h>
60 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
61 #include <nuttx/clock.h>
62 
63 #include <drivers/drv_hrt.h>
64 #include <board_config.h>
65 
66 #include <drivers/device/spi.h>
67 #include <drivers/drv_accel.h>
69 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
70 
71 #define ACCEL_DEVICE_PATH "/dev/bma180"
72 
73 
74 #define DIR_READ (1<<7)
75 #define DIR_WRITE (0<<7)
76 
77 #define ADDR_CHIP_ID 0x00
78 #define CHIP_ID 0x03
79 
80 #define ADDR_ACC_X_LSB 0x02
81 #define ADDR_ACC_Y_LSB 0x04
82 #define ADDR_ACC_Z_LSB 0x06
83 #define ADDR_TEMPERATURE 0x08
84 
85 #define ADDR_CTRL_REG0 0x0D
86 #define REG0_WRITE_ENABLE 0x10
87 
88 #define ADDR_RESET 0x10
89 #define SOFT_RESET 0xB6
90 
91 #define ADDR_BW_TCS 0x20
92 #define BW_TCS_BW_MASK (0xf<<4)
93 #define BW_TCS_BW_10HZ (0<<4)
94 #define BW_TCS_BW_20HZ (1<<4)
95 #define BW_TCS_BW_40HZ (2<<4)
96 #define BW_TCS_BW_75HZ (3<<4)
97 #define BW_TCS_BW_150HZ (4<<4)
98 #define BW_TCS_BW_300HZ (5<<4)
99 #define BW_TCS_BW_600HZ (6<<4)
100 #define BW_TCS_BW_1200HZ (7<<4)
101 
102 #define ADDR_HIGH_DUR 0x27
103 #define HIGH_DUR_DIS_I2C (1<<0)
104 
105 #define ADDR_TCO_Z 0x30
106 #define TCO_Z_MODE_MASK 0x3
107 
108 #define ADDR_GAIN_Y 0x33
109 #define GAIN_Y_SHADOW_DIS (1<<0)
110 
111 #define ADDR_OFFSET_LSB1 0x35
112 #define OFFSET_LSB1_RANGE_MASK (7<<1)
113 #define OFFSET_LSB1_RANGE_1G (0<<1)
114 #define OFFSET_LSB1_RANGE_2G (2<<1)
115 #define OFFSET_LSB1_RANGE_3G (3<<1)
116 #define OFFSET_LSB1_RANGE_4G (4<<1)
117 #define OFFSET_LSB1_RANGE_8G (5<<1)
118 #define OFFSET_LSB1_RANGE_16G (6<<1)
119 
120 #define ADDR_OFFSET_T 0x37
121 #define OFFSET_T_READOUT_12BIT (1<<0)
122 
123 extern "C" { __EXPORT int bma180_main(int argc, char *argv[]); }
124 
125 class BMA180 : public device::SPI, public px4::ScheduledWorkItem
126 {
127 public:
128  BMA180(int bus, uint32_t device);
129  virtual ~BMA180();
130 
131  virtual int init();
132 
133  virtual ssize_t read(struct file *filp, char *buffer, size_t buflen);
134  virtual int ioctl(struct file *filp, int cmd, unsigned long arg);
135 
136  /**
137  * Diagnostics - print some basic information about the driver.
138  */
139  void print_info();
140 
141 protected:
142  virtual int probe();
143 
144 private:
145 
146  unsigned _call_interval;
147 
148  ringbuffer::RingBuffer *_reports;
149 
155 
157  unsigned _current_range;
158 
160 
161  /**
162  * Start automatic measurement.
163  */
164  void start();
165 
166  /**
167  * Stop automatic measurement.
168  */
169  void stop();
170 
171  void Run() override;
172 
173  /**
174  * Fetch measurements from the sensor and update the report ring.
175  */
176  void measure();
177 
178  /**
179  * Read a register from the BMA180
180  *
181  * @param The register to read.
182  * @return The value that was read.
183  */
184  uint8_t read_reg(unsigned reg);
185 
186  /**
187  * Write a register in the BMA180
188  *
189  * @param reg The register to write.
190  * @param value The new value to write.
191  */
192  void write_reg(unsigned reg, uint8_t value);
193 
194  /**
195  * Modify a register in the BMA180
196  *
197  * Bits are cleared before bits are set.
198  *
199  * @param reg The register to modify.
200  * @param clearbits Bits in the register to clear.
201  * @param setbits Bits in the register to set.
202  */
203  void modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits);
204 
205  /**
206  * Set the BMA180 measurement range.
207  *
208  * @param max_g The maximum G value the range must support.
209  * @return OK if the value can be supported, -ERANGE otherwise.
210  */
211  int set_range(unsigned max_g);
212 
213  /**
214  * Set the BMA180 internal lowpass filter frequency.
215  *
216  * @param frequency The internal lowpass filter frequency is set to a value
217  * equal or greater to this.
218  * Zero selects the highest frequency supported.
219  * @return OK if the value can be supported.
220  */
221  int set_lowpass(unsigned frequency);
222 };
223 
224 BMA180::BMA180(int bus, uint32_t device) :
225  SPI("BMA180", ACCEL_DEVICE_PATH, bus, device, SPIDEV_MODE3, 8000000),
226  ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(this->get_device_id())),
227  _call_interval(0),
228  _reports(nullptr),
229  _accel_range_scale(0.0f),
230  _accel_range_m_s2(0.0f),
231  _accel_topic(nullptr),
232  _class_instance(-1),
233  _current_lowpass(0),
234  _current_range(0),
235  _sample_perf(perf_alloc(PC_ELAPSED, "bma180_read"))
236 {
237  _device_id.devid_s.devtype = DRV_ACC_DEVTYPE_BMA180;
238 
239  // default scale factors
241  _accel_scale.x_scale = 1.0f;
243  _accel_scale.y_scale = 1.0f;
245  _accel_scale.z_scale = 1.0f;
246 }
247 
249 {
250  /* make sure we are truly inactive */
251  stop();
252 
253  /* free any existing reports */
254  if (_reports != nullptr) {
255  delete _reports;
256  }
257 
258  /* delete the perf counter */
260 }
261 
262 int
264 {
265  int ret = PX4_ERROR;
266 
267  /* do SPI init (and probe) first */
268  if (SPI::init() != OK) {
269  goto out;
270  }
271 
272  /* allocate basic report buffers */
273  _reports = new ringbuffer::RingBuffer(2, sizeof(sensor_accel_s));
274 
275  if (_reports == nullptr) {
276  goto out;
277  }
278 
279  /* perform soft reset (p48) */
281 
282  /* wait 10 ms (datasheet incorrectly lists 10 us on page 49) */
283  usleep(10000);
284 
285  /* enable writing to chip config */
287 
288  /* disable I2C interface */
290 
291  /* switch to low-noise mode */
293 
294  /* disable 12-bit mode */
296 
297  /* disable shadow-disable mode */
299 
300  /* disable writing to chip config */
302 
303  if (set_range(4)) { warnx("Failed setting range"); }
304 
305  if (set_lowpass(75)) { warnx("Failed setting lowpass"); }
306 
307  if (read_reg(ADDR_CHIP_ID) == CHIP_ID) {
308  ret = OK;
309 
310  } else {
311  ret = PX4_ERROR;
312  }
313 
314  _class_instance = register_class_devname(ACCEL_DEVICE_PATH);
315 
316  /* advertise sensor topic, measure manually to initialize valid report */
317  measure();
318 
320  sensor_accel_s arp;
321  _reports->get(&arp);
322 
323  /* measurement will have generated a report, publish */
324  _accel_topic = orb_advertise(ORB_ID(sensor_accel), &arp);
325  }
326 
327 out:
328  return ret;
329 }
330 
331 int
333 {
334  /* dummy read to ensure SPI state machine is sane */
336 
337  if (read_reg(ADDR_CHIP_ID) == CHIP_ID) {
338  return OK;
339  }
340 
341  return -EIO;
342 }
343 
344 ssize_t
345 BMA180::read(struct file *filp, char *buffer, size_t buflen)
346 {
347  unsigned count = buflen / sizeof(sensor_accel_s);
348  sensor_accel_s *arp = reinterpret_cast<sensor_accel_s *>(buffer);
349  int ret = 0;
350 
351  /* buffer must be large enough */
352  if (count < 1) {
353  return -ENOSPC;
354  }
355 
356  /* if automatic measurement is enabled */
357  if (_call_interval > 0) {
358 
359  /*
360  * While there is space in the caller's buffer, and reports, copy them.
361  * Note that we may be pre-empted by the measurement code while we are doing this;
362  * we are careful to avoid racing with it.
363  */
364  while (count--) {
365  if (_reports->get(arp)) {
366  ret += sizeof(*arp);
367  arp++;
368  }
369  }
370 
371  /* if there was no data, warn the caller */
372  return ret ? ret : -EAGAIN;
373  }
374 
375  /* manual measurement */
376  _reports->flush();
377  measure();
378 
379  /* measurement will have generated a report, copy it out */
380  if (_reports->get(arp)) {
381  ret = sizeof(*arp);
382  }
383 
384  return ret;
385 }
386 
387 int
388 BMA180::ioctl(struct file *filp, int cmd, unsigned long arg)
389 {
390  switch (cmd) {
391 
392  case SENSORIOCSPOLLRATE: {
393  switch (arg) {
394 
395  /* zero would be bad */
396  case 0:
397  return -EINVAL;
398 
399 
400  /* set default polling rate */
402  /* With internal low pass filters enabled, 250 Hz is sufficient */
403  return ioctl(filp, SENSORIOCSPOLLRATE, 250);
404 
405  /* adjust to a legal polling interval in Hz */
406  default: {
407  /* do we need to start internal polling? */
408  bool want_start = (_call_interval == 0);
409 
410  /* convert hz to hrt interval via microseconds */
411  unsigned interval = 1000000 / arg;
412 
413  /* check against maximum sane rate */
414  if (interval < 1000) {
415  return -EINVAL;
416  }
417 
418  /* if we need to start the poll state machine, do it */
419  if (want_start) {
420  start();
421  }
422 
423  return OK;
424  }
425  }
426  }
427 
428  case SENSORIOCRESET:
429  /* XXX implement */
430  return -EINVAL;
431 
432  case ACCELIOCSSCALE:
433  /* copy scale in */
434  memcpy(&_accel_scale, (struct accel_calibration_s *) arg, sizeof(_accel_scale));
435  return OK;
436 
437  default:
438  /* give it to the superclass */
439  return SPI::ioctl(filp, cmd, arg);
440  }
441 }
442 
443 uint8_t
444 BMA180::read_reg(unsigned reg)
445 {
446  uint8_t cmd[2];
447 
448  cmd[0] = reg | DIR_READ;
449 
450  transfer(cmd, cmd, sizeof(cmd));
451 
452  return cmd[1];
453 }
454 
455 void
456 BMA180::write_reg(unsigned reg, uint8_t value)
457 {
458  uint8_t cmd[2];
459 
460  cmd[0] = reg | DIR_WRITE;
461  cmd[1] = value;
462 
463  transfer(cmd, nullptr, sizeof(cmd));
464 }
465 
466 void
467 BMA180::modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
468 {
469  uint8_t val;
470 
471  val = read_reg(reg);
472  val &= ~clearbits;
473  val |= setbits;
474  write_reg(reg, val);
475 }
476 
477 int
478 BMA180::set_range(unsigned max_g)
479 {
480  uint8_t rangebits;
481 
482  if (max_g == 0) {
483  max_g = 16;
484  }
485 
486  if (max_g > 16) {
487  return -ERANGE;
488  }
489 
490  if (max_g <= 2) {
491  _current_range = 2;
492  rangebits = OFFSET_LSB1_RANGE_2G;
493 
494  } else if (max_g <= 3) {
495  _current_range = 3;
496  rangebits = OFFSET_LSB1_RANGE_3G;
497 
498  } else if (max_g <= 4) {
499  _current_range = 4;
500  rangebits = OFFSET_LSB1_RANGE_4G;
501 
502  } else if (max_g <= 8) {
503  _current_range = 8;
504  rangebits = OFFSET_LSB1_RANGE_8G;
505 
506  } else if (max_g <= 16) {
507  _current_range = 16;
508  rangebits = OFFSET_LSB1_RANGE_16G;
509 
510  } else {
511  return -EINVAL;
512  }
513 
514  /* set new range scaling factor */
517 
518  /* enable writing to chip config */
520 
521  /* adjust sensor configuration */
523 
524  /* block writing to chip config */
526 
527  /* check if wanted value is now in register */
529  (OFFSET_LSB1_RANGE_MASK & rangebits));
530 }
531 
532 int
533 BMA180::set_lowpass(unsigned frequency)
534 {
535  uint8_t bwbits;
536 
537  if (frequency > 1200) {
538  return -ERANGE;
539 
540  } else if (frequency > 600) {
541  bwbits = BW_TCS_BW_1200HZ;
542 
543  } else if (frequency > 300) {
544  bwbits = BW_TCS_BW_600HZ;
545 
546  } else if (frequency > 150) {
547  bwbits = BW_TCS_BW_300HZ;
548 
549  } else if (frequency > 75) {
550  bwbits = BW_TCS_BW_150HZ;
551 
552  } else if (frequency > 40) {
553  bwbits = BW_TCS_BW_75HZ;
554 
555  } else if (frequency > 20) {
556  bwbits = BW_TCS_BW_40HZ;
557 
558  } else if (frequency > 10) {
559  bwbits = BW_TCS_BW_20HZ;
560 
561  } else {
562  bwbits = BW_TCS_BW_10HZ;
563  }
564 
565  /* enable writing to chip config */
567 
568  /* adjust sensor configuration */
570 
571  /* block writing to chip config */
573 
574  /* check if wanted value is now in register */
575  return !((read_reg(ADDR_BW_TCS) & BW_TCS_BW_MASK) ==
576  (BW_TCS_BW_MASK & bwbits));
577 }
578 
579 void
581 {
582  /* make sure we are stopped first */
583  stop();
584 
585  /* reset the report ring */
586  _reports->flush();
587 
588  /* start polling at the specified rate */
589  ScheduleOnInterval(_call_interval, 10000);
590 }
591 
592 void
594 {
595  ScheduleClear();
596 }
597 
598 void
600 {
601  /* make another measurement */
602  measure();
603 }
604 
605 void
607 {
608  /* BMA180 measurement registers */
609 // #pragma pack(push, 1)
610 // struct {
611 // uint8_t cmd;
612 // int16_t x;
613 // int16_t y;
614 // int16_t z;
615 // } raw_report;
616 // #pragma pack(pop)
617 
618  sensor_accel_s report;
619 
620  /* start the performance counter */
622 
623  /*
624  * Fetch the full set of measurements from the BMA180 in one pass;
625  * starting from the X LSB.
626  */
627  //raw_report.cmd = ADDR_ACC_X_LSB;
628  // XXX PX4DEV transfer((uint8_t *)&raw_report, (uint8_t *)&raw_report, sizeof(raw_report));
629 
630  /*
631  * Adjust and scale results to SI units.
632  *
633  * Note that we ignore the "new data" bits. At any time we read, each
634  * of the axis measurements are the "most recent", even if we've seen
635  * them before. There is no good way to synchronise with the internal
636  * measurement flow without using the external interrupt.
637  */
638  report.timestamp = hrt_absolute_time();
639  report.error_count = 0;
640  /*
641  * y of board is x of sensor and x of board is -y of sensor
642  * perform only the axis assignment here.
643  * Two non-value bits are discarded directly
644  */
645  report.y_raw = read_reg(ADDR_ACC_X_LSB + 0);
646  report.y_raw |= read_reg(ADDR_ACC_X_LSB + 1) << 8;
647  report.x_raw = read_reg(ADDR_ACC_X_LSB + 2);
648  report.x_raw |= read_reg(ADDR_ACC_X_LSB + 3) << 8;
649  report.z_raw = read_reg(ADDR_ACC_X_LSB + 4);
650  report.z_raw |= read_reg(ADDR_ACC_X_LSB + 5) << 8;
651 
652  /* discard two non-value bits in the 16 bit measurement */
653  report.x_raw = (report.x_raw / 4);
654  report.y_raw = (report.y_raw / 4);
655  report.z_raw = (report.z_raw / 4);
656 
657  /* invert y axis, due to 14 bit data no overflow can occur in the negation */
658  report.y_raw = -report.y_raw;
659 
663  report.scaling = _accel_range_scale;
664 
665  _reports->force(&report);
666 
667  /* notify anyone waiting for data */
668  poll_notify(POLLIN);
669 
670  /* publish for subscribers */
671  if (_accel_topic != nullptr && !(_pub_blocked)) {
672  orb_publish(ORB_ID(sensor_accel), _accel_topic, &report);
673  }
674 
675  /* stop the perf counter */
677 }
678 
679 void
681 {
683  _reports->print_info("report queue");
684 }
685 
686 /**
687  * Local functions in support of the shell command.
688  */
689 namespace bma180
690 {
691 
693 
694 void start();
695 void test();
696 void reset();
697 void info();
698 
699 /**
700  * Start the driver.
701  */
702 void
704 {
705  int fd;
706 
707  if (g_dev != nullptr) {
708  errx(1, "already started");
709  }
710 
711  /* create the driver */
712  g_dev = new BMA180(1 /* XXX magic number */, PX4_SPIDEV_BMA);
713 
714  if (g_dev == nullptr) {
715  goto fail;
716  }
717 
718  if (OK != g_dev->init()) {
719  goto fail;
720  }
721 
722  /* set the poll rate to default, starts automatic data collection */
723  fd = open(ACCEL_DEVICE_PATH, O_RDONLY);
724 
725  if (fd < 0) {
726  goto fail;
727  }
728 
730  goto fail;
731  }
732 
733  exit(0);
734 fail:
735 
736  if (g_dev != nullptr) {
737  delete g_dev;
738  g_dev = nullptr;
739  }
740 
741  errx(1, "driver start failed");
742 }
743 
744 /**
745  * Perform some basic functional tests on the driver;
746  * make sure we can collect data from the sensor in polled
747  * and automatic modes.
748  */
749 void
751 {
752  int fd = -1;
753  sensor_accel_s a_report;
754  ssize_t sz;
755 
756  /* get the driver */
757  fd = open(ACCEL_DEVICE_PATH, O_RDONLY);
758 
759  if (fd < 0) {
760  err(1, "%s open failed (try 'bma180 start' if the driver is not running)",
762  }
763 
764 
765  /* do a simple demand read */
766  sz = read(fd, &a_report, sizeof(a_report));
767 
768  if (sz != sizeof(a_report)) {
769  err(1, "immediate acc read failed");
770  }
771 
772  print_message(a_report);
773 
774  reset();
775  errx(0, "PASS");
776 }
777 
778 /**
779  * Reset the driver.
780  */
781 void
783 {
784  int fd = open(ACCEL_DEVICE_PATH, O_RDONLY);
785 
786  if (fd < 0) {
787  err(1, "failed ");
788  }
789 
790  if (ioctl(fd, SENSORIOCRESET, 0) < 0) {
791  err(1, "driver reset failed");
792  }
793 
795  err(1, "driver poll restart failed");
796  }
797 
798  exit(0);
799 }
800 
801 /**
802  * Print a little info about the driver.
803  */
804 void
806 {
807  if (g_dev == nullptr) {
808  errx(1, "BMA180: driver not running");
809  }
810 
811  printf("state @ %p\n", g_dev);
812  g_dev->print_info();
813 
814  exit(0);
815 }
816 
817 
818 } // namespace
819 
820 int
821 bma180_main(int argc, char *argv[])
822 {
823  if (argc < 2) {
824  goto out_error;
825  }
826 
827  /*
828  * Start/load the driver.
829  */
830  if (!strcmp(argv[1], "start")) {
831  bma180::start();
832  }
833 
834  /*
835  * Test the driver/device.
836  */
837  if (!strcmp(argv[1], "test")) {
838  bma180::test();
839  }
840 
841  /*
842  * Reset the driver.
843  */
844  if (!strcmp(argv[1], "reset")) {
845  bma180::reset();
846  }
847 
848  /*
849  * Print driver information.
850  */
851  if (!strcmp(argv[1], "info")) {
852  bma180::info();
853  }
854 
855 out_error:
856  errx(1, "unrecognised command, try 'start', 'test', 'reset' or 'info'");
857 }
#define ADDR_BW_TCS
Definition: bma180.cpp:91
Accelerometer driver interface.
ringbuffer::RingBuffer * _reports
Definition: bma180.cpp:148
#define BW_TCS_BW_MASK
Definition: bma180.cpp:92
int set_range(unsigned max_g)
Set the BMA180 measurement range.
Definition: bma180.cpp:478
uint64_t timestamp
Definition: sensor_accel.h:53
orb_advert_t _accel_topic
Definition: bma180.cpp:153
virtual ssize_t read(struct file *filp, char *buffer, size_t buflen)
Definition: bma180.cpp:345
measure the time elapsed performing an event
Definition: perf_counter.h:56
#define OFFSET_LSB1_RANGE_8G
Definition: bma180.cpp:117
void test()
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
Definition: bma180.cpp:750
Definition of geo / math functions to perform geodesic calculations.
void print_info()
Diagnostics - print some basic information about the driver.
Definition: bma180.cpp:680
void modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
Modify a register in the BMA180.
Definition: bma180.cpp:467
void measure()
Fetch measurements from the sensor and update the report ring.
Definition: bma180.cpp:606
unsigned _current_range
Definition: bma180.cpp:157
#define REG0_WRITE_ENABLE
Definition: bma180.cpp:86
#define ADDR_CTRL_REG0
Definition: bma180.cpp:85
#define SENSOR_POLLRATE_DEFAULT
poll at driver normal rate
Definition: drv_sensor.h:136
#define ADDR_CHIP_ID
Definition: bma180.cpp:77
#define BW_TCS_BW_10HZ
Definition: bma180.cpp:93
Definition: I2C.hpp:51
void stop()
Stop automatic measurement.
Definition: bma180.cpp:593
unsigned _call_interval
Definition: bma180.cpp:146
orb_advert_t orb_advertise(const struct orb_metadata *meta, const void *data)
Definition: uORB.cpp:43
void start()
Start the driver.
Definition: bma180.cpp:703
#define OFFSET_T_READOUT_12BIT
Definition: bma180.cpp:121
BMA180(int bus, uint32_t device)
Definition: bma180.cpp:224
BMA180 * g_dev
Definition: bma180.cpp:692
#define OFFSET_LSB1_RANGE_MASK
Definition: bma180.cpp:112
#define HIGH_DUR_DIS_I2C
Definition: bma180.cpp:103
Namespace encapsulating all device framework classes, functions and data.
Definition: CDev.cpp:47
virtual ~BMA180()
Definition: bma180.cpp:248
High-resolution timer with callouts and timekeeping.
#define ADDR_RESET
Definition: bma180.cpp:88
Local functions in support of the shell command.
Definition: bma180.cpp:689
static constexpr float CONSTANTS_ONE_G
Definition: geo.h:51
accel scaling factors; Vout = Vscale * (Vin + Voffset)
Definition: drv_accel.h:54
uint8_t read_reg(unsigned reg)
Read a register from the BMA180.
Definition: bma180.cpp:444
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
Definition: drv_sensor.h:134
#define ADDR_OFFSET_T
Definition: bma180.cpp:120
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
#define OFFSET_LSB1_RANGE_2G
Definition: bma180.cpp:114
#define BW_TCS_BW_300HZ
Definition: bma180.cpp:98
int _class_instance
Definition: bma180.cpp:154
#define CHIP_ID
Definition: bma180.cpp:78
Header common to all counters.
void perf_free(perf_counter_t handle)
Free a counter.
#define TCO_Z_MODE_MASK
Definition: bma180.cpp:106
void init()
Activates/configures the hardware registers.
#define perf_alloc(a, b)
Definition: px4io.h:59
#define ADDR_GAIN_Y
Definition: bma180.cpp:108
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
#define BW_TCS_BW_20HZ
Definition: bma180.cpp:94
#define warnx(...)
Definition: err.h:95
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
#define ADDR_HIGH_DUR
Definition: bma180.cpp:102
void perf_end(perf_counter_t handle)
End a performance event.
#define GAIN_Y_SHADOW_DIS
Definition: bma180.cpp:109
uint64_t error_count
Definition: sensor_accel.h:54
virtual int ioctl(struct file *filp, int cmd, unsigned long arg)
Definition: bma180.cpp:388
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
int fd
Definition: dataman.cpp:146
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
Definition: uORB.cpp:70
#define err(eval,...)
Definition: err.h:83
float _accel_range_scale
Definition: bma180.cpp:151
#define OFFSET_LSB1_RANGE_16G
Definition: bma180.cpp:118
void start()
Start automatic measurement.
Definition: bma180.cpp:580
perf_counter_t _sample_perf
Definition: bma180.cpp:159
#define OFFSET_LSB1_RANGE_3G
Definition: bma180.cpp:115
#define ACCELIOCSSCALE
set the accel scaling constants to the structure pointed to by (arg)
Definition: drv_accel.h:73
void Run() override
Definition: bma180.cpp:599
#define OFFSET_LSB1_RANGE_4G
Definition: bma180.cpp:116
virtual int init()
Definition: bma180.cpp:263
struct @83::@85::@87 file
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
#define BW_TCS_BW_75HZ
Definition: bma180.cpp:96
__EXPORT int bma180_main(int argc, char *argv[])
Definition: bma180.cpp:821
#define SENSORIOCRESET
Reset the sensor to its default configuration.
Definition: drv_sensor.h:141
struct accel_calibration_s _accel_scale
Definition: bma180.cpp:150
int set_lowpass(unsigned frequency)
Set the BMA180 internal lowpass filter frequency.
Definition: bma180.cpp:533
#define ADDR_ACC_X_LSB
Definition: bma180.cpp:80
#define errx(eval,...)
Definition: err.h:89
Definition: bst.cpp:62
#define DRV_ACC_DEVTYPE_BMA180
Definition: drv_sensor.h:66
#define OK
Definition: uavcan_main.cpp:71
#define BW_TCS_BW_40HZ
Definition: bma180.cpp:95
void write_reg(unsigned reg, uint8_t value)
Write a register in the BMA180.
Definition: bma180.cpp:456
#define DIR_READ
Definition: bma180.cpp:74
#define DIR_WRITE
Definition: bma180.cpp:75
#define ACCEL_DEVICE_PATH
Definition: bma180.cpp:71
#define ADDR_TCO_Z
Definition: bma180.cpp:105
void info()
Print a little info about the driver.
Definition: bma180.cpp:805
#define SOFT_RESET
Definition: bma180.cpp:89
#define ADDR_OFFSET_LSB1
Definition: bma180.cpp:111
void reset()
Reset the driver.
Definition: bma180.cpp:782
#define BW_TCS_BW_600HZ
Definition: bma180.cpp:99
#define BW_TCS_BW_150HZ
Definition: bma180.cpp:97
void perf_begin(perf_counter_t handle)
Begin a performance event.
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
#define BW_TCS_BW_1200HZ
Definition: bma180.cpp:100
unsigned _current_lowpass
Definition: bma180.cpp:156
Performance measuring tools.
float _accel_range_m_s2
Definition: bma180.cpp:152
virtual int probe()
Definition: bma180.cpp:332