40 #include <px4_platform_common/getopt.h> 56 void regdump(
bool external_bus);
72 if (*g_dev_ptr !=
nullptr)
75 PX4_ERR(
"already started");
81 #if defined(PX4_I2C_BUS_EXPANSION) 82 *g_dev_ptr =
new BMM150(PX4_I2C_BUS_EXPANSION, path, rotation);
84 PX4_ERR(
"External I2C not available");
89 #if defined(PX4_I2C_BUS_ONBOARD) 90 *g_dev_ptr =
new BMM150(PX4_I2C_BUS_ONBOARD, path, rotation);
92 PX4_ERR(
"Internal I2C not available");
97 if (*g_dev_ptr ==
nullptr) {
102 if (
OK != (*g_dev_ptr)->init()) {
107 fd = open(path, O_RDONLY);
123 if (*g_dev_ptr !=
nullptr) {
125 *g_dev_ptr =
nullptr;
128 PX4_ERR(
"driver start failed");
143 fd = open(path, O_RDONLY);
146 PX4_ERR(
"%s open failed (try 'bmm150 start' if the driver is not running)", path);
152 PX4_ERR(
"reset to Max polling rate");
157 sz =
read(fd, &m_report,
sizeof(m_report));
159 if (sz !=
sizeof(m_report)) {
160 PX4_ERR(
"immediate mag read failed");
164 PX4_WARN(
"single read");
165 PX4_WARN(
"time: %lld", m_report.timestamp);
166 PX4_WARN(
"mag x: \t%8.4f\t", (
double)m_report.x);
167 PX4_WARN(
"mag y: \t%8.4f\t", (
double)m_report.y);
168 PX4_WARN(
"mag z: \t%8.4f\t", (
double)m_report.z);
169 PX4_WARN(
"mag x: \t%d\traw 0x%0x", (
short)m_report.x_raw, (
unsigned short)m_report.x_raw);
170 PX4_WARN(
"mag y: \t%d\traw 0x%0x", (
short)m_report.y_raw, (
unsigned short)m_report.y_raw);
171 PX4_WARN(
"mag z: \t%d\traw 0x%0x", (
short)m_report.z_raw, (
unsigned short)m_report.z_raw);
183 int fd = open(path, O_RDONLY);
191 PX4_ERR(
"driver reset failed");
196 PX4_ERR(
"driver poll restart failed");
209 if (*g_dev_ptr ==
nullptr) {
210 PX4_ERR(
"driver not running");
214 printf(
"state @ %p\n", *g_dev_ptr);
215 (*g_dev_ptr)->print_info();
229 if (*g_dev_ptr ==
nullptr) {
230 PX4_ERR(
"driver not running");
234 printf(
"regdump @ %p\n", *g_dev_ptr);
235 (*g_dev_ptr)->print_registers();
243 PX4_WARN(
"missing command: try 'start', 'info', 'test', 'stop',\n'reset', 'regdump'");
244 PX4_WARN(
"options:");
245 PX4_WARN(
" -X (external bus)");
254 ScheduledWorkItem(MODULE_NAME,
px4::device_bus_to_wq(get_device_id())),
258 _collect_phase(false),
385 PX4_WARN(
"ADVERT FAIL");
452 return ret ? ret : -EAGAIN;
493 if ((wait_gap != 0) && (
_running)) {
495 ScheduleDelayed(wait_gap);
540 bool mag_notify =
true;
541 uint8_t mag_data[8],
status;
542 uint16_t resistance, lsb, msb, msblsb;
568 lsb = ((mag_data[0] & 0xF8) >> 3);
569 msb = (((int8_t)mag_data[1]) << 5);
570 msblsb = (msb | lsb);
571 mrb.x_raw = (int16_t)msblsb;
575 lsb = ((mag_data[2] & 0xF8) >> 3);
576 msb = (((int8_t)mag_data[3]) << 5);
577 msblsb = (msb | lsb);
578 mrb.y_raw = (int16_t)msblsb;
581 lsb = ((mag_data[4] & 0xFE) >> 1);
582 msb = (((int8_t)mag_data[5]) << 7);
583 msblsb = (msb | lsb);
584 mrb.z_raw = (int16_t)msblsb;
587 lsb = ((mag_data[6] & 0xFC) >> 2);
588 msb = (mag_data[7] << 6);
589 msblsb = (msb | lsb);
590 resistance = (uint16_t)msblsb;
593 if (!(status & 0x01)) {
602 if (mrb.x_raw == 0 &&
618 if ((resistance != 0) && (
dig_xyz1 != 0)) {
619 mrb.x = ((
dig_xyz1 * 16384.0 / resistance) - 16384.0);
620 mrb.x = (((mrb.x_raw * ((((
dig_xy2 * ((float)(mrb.x * mrb.x / (
float)268435456.0)) + mrb.x *
dig_xy1 /
621 (
float)16384.0)) + (
float)256.0) * (
dig_x2 + (float)160.0))) / (float)8192.0) + (
dig_x1 * (float)8.0)) / (
float)16.0;
634 if ((resistance != 0) && (
dig_xyz1 != 0)) {
636 mrb.y = ((((float)
dig_xyz1) * (float)16384.0 / resistance) - (float)16384.0);
637 mrb.y = (((mrb.y_raw * ((((
dig_xy2 * (mrb.y * mrb.y / (float)268435456.0) + mrb.y *
dig_xy1 / (float)16384.0)) +
638 (
float)256.0) * (
dig_y2 + (float)160.0))) / (float)8192.0) + (
dig_y1 * (float)8.0)) / (
float)16.0;
656 dig_z2 +
dig_z1 * resistance / (
float)32768.0) * (float)4.0)) / (
float)16.0;
666 mrb.is_external = external();
683 mrb.device_id = _device_id.devid;
696 if (mag_notify && !(_pub_blocked)) {
728 unsigned interval = (1000000 / arg);
765 return I2C::ioctl(filp, cmd, arg);
806 const uint8_t cmd = reg;
809 transfer(&cmd, 1, &ret, 1);
817 const uint8_t cmd[2] = { reg, value};
819 return transfer(cmd, 2,
nullptr, 0);
825 const uint8_t cmd = reg;
827 return transfer(&cmd, 1, data, len);
849 switch (power_mode) {
866 setbits |= power_mode;
915 setbits |= data_rate;
926 uint8_t
data[2] = {0};
927 uint16_t msb, lsb, msblsb;
938 msb = (data[1] << 8);
939 msblsb = (msb | lsb);
940 dig_z1 = (uint16_t)msblsb;
944 msb = ((int8_t)data[1] << 8);
945 msblsb = (msb | lsb);
950 msb = ((int8_t)data[1] << 8);
951 msblsb = (msb | lsb);
956 msb = ((int8_t)data[1] << 8);
957 msblsb = (msb | lsb);
962 msb = ((data[1] & 0x7F) << 8);
963 msblsb = (msb | lsb);
974 return transfer((
const uint8_t *)cmd,
sizeof(cmd),
nullptr, 0);
982 return transfer((
const uint8_t *)cmd,
sizeof(cmd),
nullptr, 0);
990 uint8_t data_rate, rep_xy, rep_z;
992 if (presetmode == 1) {
997 }
else if (presetmode == 2) {
1002 }
else if (presetmode == 3) {
1007 }
else if (presetmode == 4) {
1035 printf(
"scaling (%.2f %.2f %.2f) 1/range_scale %.2f ",
1045 printf(
"BMM150 registers\n");
1049 printf(
"Chip Id: %02x:%02x ", (
unsigned)reg, (
unsigned)v);
1054 printf(
"Int sett Ctrl reg: %02x:%02x ", (
unsigned)reg, (
unsigned)v);
1059 printf(
"Axes En Ctrl reg: %02x:%02x ", (
unsigned)reg, (
unsigned)v);
1069 const char *myoptarg =
nullptr;
1070 bool external_bus =
false;
1073 while ((ch = px4_getopt(argc, argv,
"XR:", &myoptind, &myoptarg)) != EOF) {
1076 external_bus =
true;
1080 rotation = (
enum Rotation)atoi(myoptarg);
1089 if (myoptind >= argc) {
1094 const char *verb = argv[myoptind];
1099 if (!strcmp(verb,
"start")) {
1107 if (!strcmp(verb,
"test")) {
1114 if (!strcmp(verb,
"reset")) {
1121 if (!strcmp(verb,
"info")) {
1128 if (!strcmp(verb,
"regdump")) {
#define BMM150_CONVERSION_INTERVAL
#define MAGIOCGSCALE
copy the mag scaling constants to the structure pointed to by (arg)
#define BMM150_ENHANCED_DR
#define BMM150_HIGHACCURACY_REPXY
int8_t dig_x2
trim x2 data
#define BMM150_REGULAR_DR
static struct vehicle_status_s status
#define BMM150_SOFT_RESET_MASK
#define BMM150_DIG_XYZ1_LSB
int reset()
Resets the chip.
measure the time elapsed performing an event
#define BMM150_REGULAR_REPXY
uint16_t dig_xyz1
trim xyz1 data
#define BMM150_ENHANCED_REPXY
#define BMM150_DATA_X_LSB_REG
perf_counter_t _comms_errors
#define MAGIOCEXSTRAP
excite strap
#define BMM150_DATA_RATE_25HZ
#define DRV_MAG_DEVTYPE_BMM150
#define BMM150_HIGHACCURACY_REPZ
#define SENSOR_POLLRATE_DEFAULT
poll at driver normal rate
__EXPORT void rotate_3f(enum Rotation rot, float &x, float &y, float &z)
rotate a 3 element float vector in-place
#define BMM150_DIG_Z2_LSB
#define BMM150_INT_SETT_CTRL_REG
#define BMM150_HIGHACCURACY_DR
#define BMM150_LOWPOWER_REPZ
#define BMM150_DATA_RATE_06HZ
int set_rep_xy(uint8_t rep_xy)
#define BMM150_DATA_RATE_15HZ
#define BMM150_CHIP_ID_REG
#define BMM150_POWER_CTRL_REG
#define BMM150_DEFAULT_POWER_MODE
int init_trim_registers(void)
int8_t dig_y2
trim y2 data
count the number of times an event occurs
#define BMM150_XY_REP_CTRL_REG
#define BMM150_LOWPOWER_REPXY
virtual int ioctl(struct file *filp, int cmd, unsigned long arg)
uint8_t read_reg(uint8_t reg)
Read a register from the BMM150.
#define BMM150_ENHANCED_REPZ
ringbuffer::RingBuffer * _reports
perf_counter_t _duplicates
int write_reg(uint8_t reg, uint8_t value)
Write a register in the BMM150.
int8_t dig_y1
trim y1 data
static void read(bootloader_app_shared_t *pshared)
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
#define BMM150_AXES_EN_CTRL_REG
int set_power_mode(uint8_t power)
uint16_t dig_z1
trim z1 data
void print_info()
Diagnostics - print some basic information about the driver.
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
void perf_count(perf_counter_t handle)
Count a performance event.
virtual ssize_t read(struct file *filp, char *buffer, size_t buflen)
#define MAGIOCSSCALE
set the mag scaling constants to the structure pointed to by (arg)
uint8_t dig_xy1
trim xy1 data
#define BMM150_FORCED_MODE
int8_t dig_x1
trim x1 data
#define BMM150_DEFAULT_ODR
#define BMM150_Z_REP_CTRL_REG
void regdump(bool external_bus)
Dump the register information.
void perf_free(perf_counter_t handle)
Free a counter.
#define MAG_BASE_DEVICE_PATH
void init()
Activates/configures the hardware registers.
#define MAGIOCCALIBRATE
perform self-calibration, update scale factors to canonical units
#define BMM150_SLAVE_ADDRESS
int get_data(uint8_t reg, uint8_t *data, unsigned len)
Read the specified number of bytes from BMM150.
Rotation
Enum for board and external compass rotations.
void modify_reg(unsigned reg, uint8_t clearbits, uint8_t setbits)
Modify a register in the BMM150.
#define BMM150_DATA_RATE_08HZ
int set_presetmode(uint8_t presetmode)
perf_counter_t _good_transfers
int16_t dig_z4
trim z4 data
#define BMM150_DEVICE_PATH_MAG_EXT
perf_counter_t _measure_perf
void perf_end(perf_counter_t handle)
End a performance event.
#define BMM150_DIG_Z1_LSB
BMM150(int bus, const char *path, enum Rotation rotation)
#define BMM150_OUTPUT_DATA_RATE_MASK
void usage()
Prints info about the driver argument usage.
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
#define BMM150_SLEEP_MODE
perf_counter_t _bad_transfers
int16_t dig_z2
trim z2 data
__EXPORT int bmm150_main(int argc, char *argv[])
driver 'main' command
#define BMM150_LOWPOWER_DR
#define BMM150_DIG_Z4_LSB
#define BMM150_REGULAR_REPZ
uint8_t _output_data_rate
#define BMM150_SOFT_RESET_VALUE
void stop()
Stop automatic measurement.
mag_report _last_report
used for info()
struct @83::@85::@87 file
int set_rep_z(uint8_t rep_z)
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout.
#define SENSORIOCRESET
Reset the sensor to its default configuration.
uint64_t perf_event_count(perf_counter_t handle)
Return current event_count.
int orb_unadvertise(orb_advert_t handle)
void perf_cancel(perf_counter_t handle)
Cancel a performance event.
#define BMM150_DIG_Z3_LSB
#define BMM150_DEVICE_PATH_MAG
int16_t dig_z3
trim z3 data
int set_data_rate(uint8_t data_rate)
#define BMM150_MAX_DATA_RATE
int self_test()
Measurement self test.
#define BMM150_NORMAL_MODE
#define BMM150_PRESETMODE_REGULAR
#define BMM150_OVERFLOW_OUTPUT_FLOAT
#define BMM150_DATA_RATE_02HZ
void start(bool, enum Rotation)
Start the driver.
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
perf_counter_t _sample_perf
#define BMM150_DATA_RATE_10HZ
bool _calibrated
the calibration is valid
void start()
Start automatic measurement.
void perf_begin(perf_counter_t handle)
Begin a performance event.
#define DEVICE_DEBUG(FMT,...)
#define BMM150_DATA_RATE_20HZ
#define BMM150_HALL_OVERFLOW_ADCVAL
int8_t dig_xy2
trim xy2 data
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
#define BMM150_FLIP_OVERFLOW_ADCVAL
#define BMM150_DATA_RATE_30HZ
struct mag_calibration_s _scale
#define BMM150_POWER_MASK