37 CDev(
"HMC5883", path),
38 ScheduledWorkItem(MODULE_NAME,
px4::device_bus_to_wq(interface->get_device_id())),
39 _interface(interface),
132 }
else if (range <= 1.3
f) {
137 }
else if (range <= 2) {
142 }
else if (range <= 3) {
147 }
else if (range <= 4) {
152 }
else if (range <= 4.7
f) {
157 }
else if (range <= 5.6
f) {
179 uint8_t range_bits_in = 0;
198 uint8_t range_bits_in = 0;
225 uint8_t conf_reg_in = 0;
246 unsigned count = buflen /
sizeof(
struct mag_report);
270 return ret ? ret : -EAGAIN;
304 unsigned dummy = arg;
336 unsigned interval = (1000000 / arg);
387 return CDev::ioctl(filp, cmd, arg);
486 #pragma pack(push, 1) 498 uint8_t check_counter;
502 bool sensor_is_onboard =
false;
531 report.x = (((int16_t)hmc_report.x[0]) << 8) + hmc_report.x[1];
532 report.y = (((int16_t)hmc_report.y[0]) << 8) + hmc_report.y[1];
533 report.z = (((int16_t)hmc_report.z[0]) << 8) + hmc_report.z[1];
539 if ((
abs(report.x) > 2048) ||
540 (
abs(report.y) > 2048) ||
541 (
abs(report.z) > 2048)) {
547 new_report.temperature = 0;
558 uint8_t raw_temperature[2];
563 raw_temperature,
sizeof(raw_temperature));
566 int16_t temp16 = (((int16_t)raw_temperature[0]) << 8) +
568 new_report.temperature = 25 + (temp16 / (16 * 8.0f));
596 new_report.x_raw = -report.y;
597 new_report.y_raw = report.x;
599 new_report.z_raw = report.z;
606 new_report.is_external = !sensor_is_onboard;
608 if (sensor_is_onboard) {
611 report.y = -report.y;
612 report.x = -report.x;
664 if (check_counter == 0) {
668 if (check_counter == 128) {
684 uint8_t good_count = 0;
687 int fd = (int)enable;
691 mscale_previous.
x_scale = 1.0f;
693 mscale_previous.
y_scale = 1.0f;
695 mscale_previous.
z_scale = 1.0f;
705 float sum_excited[3] = {0.0f, 0.0f, 0.0f};
712 float expected_cal[3] = { 1.16f, 1.08f, 1.08f };
716 warn(
"FAILED: SENSORIOCSPOLLRATE 50Hz");
724 warnx(
"FAILED: MAGIOCSRANGE 2.5 Ga");
730 warnx(
"FAILED: MAGIOCEXSTRAP 1");
736 warn(
"FAILED: MAGIOCGSCALE 1");
742 warn(
"FAILED: MAGIOCSSCALE 1");
748 for (uint8_t i = 0; i < 10; i++) {
749 px4_pollfd_struct_t fds{};
757 warn(
"ERROR: TIMEOUT 1");
762 sz =
px4_read(fd, &report,
sizeof(report));
764 if (sz !=
sizeof(report)) {
765 warn(
"ERROR: READ 1");
772 for (uint8_t i = 0; i < 150 && good_count < 50; i++) {
773 px4_pollfd_struct_t fds{};
781 warn(
"ERROR: TIMEOUT 2");
786 sz =
px4_read(fd, &report,
sizeof(report));
788 if (sz !=
sizeof(report)) {
789 warn(
"ERROR: READ 2");
794 float cal[3] = {fabsf(expected_cal[0] / report.x),
795 fabsf(expected_cal[1] / report.y),
796 fabsf(expected_cal[2] / report.z)
799 if (cal[0] > 0.3
f && cal[0] < 1.7
f &&
800 cal[1] > 0.3
f && cal[1] < 1.7
f &&
801 cal[2] > 0.3
f && cal[2] < 1.7
f) {
803 sum_excited[0] += cal[0];
804 sum_excited[1] += cal[1];
805 sum_excited[2] += cal[2];
809 if (good_count < 5) {
816 scaling[0] = sum_excited[0] / good_count;
817 scaling[1] = sum_excited[1] / good_count;
818 scaling[2] = sum_excited[2] / good_count;
821 mscale_previous.x_scale = 1.0f / scaling[0];
822 mscale_previous.y_scale = 1.0f / scaling[1];
823 mscale_previous.z_scale = 1.0f / scaling[2];
830 warn(
"FAILED: MAGIOCSSCALE 2");
836 warnx(
"FAILED: MAGIOCSRANGE 1.9 Ga");
840 warnx(
"FAILED: MAGIOCEXSTRAP 0");
846 warnx(
"FAILED: SCALE");
881 offset_valid =
false;
888 return !offset_valid;
903 if (((
int)enable) < 0) {
906 }
else if (enable > 0) {
919 uint8_t conf_reg_ret = 0;
973 uint8_t conf_reg_ret = 0;
1020 _reports->print_info(
"report queue");
void print_info()
Diagnostics - print some basic information about the driver.
#define MAGIOCGSCALE
copy the mag scaling constants to the structure pointed to by (arg)
int measure()
Issue a measurement command.
#define MAGIOCGEXTERNAL
determine if mag is external or onboard
unsigned _measure_interval
measure the time elapsed performing an event
#define MAGIOCEXSTRAP
excite strap
virtual int register_class_devname(const char *class_devname)
Register a class device name, automatically adding device class instance suffix if need be...
void Run() override
Perform a poll cycle; collect from the previous measurement and start a new one.
#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
int write_reg(uint8_t reg, uint8_t val)
Write a register.
perf_counter_t _conf_errors
mag scaling factors; Vout = (Vin * Vscale) + Voffset
#define HMC5883_CONVERSION_INTERVAL
#define DRV_MAG_DEVTYPE_HMC5883
Sensor type definitions.
int set_range(unsigned range)
Set the sensor range.
count the number of times an event occurs
perf_counter_t _comms_errors
uint8_t _temperature_error_count
bool _sensor_ok
sensor was found and reports ok
perf_counter_t _sample_perf
virtual void poll_notify(pollevent_t events)
Report new poll events.
#define MAGIOCSRANGE
set the measurement range to handle (at least) arg Gauss
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
ringbuffer::RingBuffer * _reports
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
#define MODE_REG_SINGLE_MODE
device identifier information
void perf_count(perf_counter_t handle)
Count a performance event.
HMC5883(device::Device *interface, const char *path, enum Rotation rotation)
int set_temperature_compensation(unsigned enable)
enable hmc5983 temperature compensation
#define MAGIOCSSCALE
set the mag scaling constants to the structure pointed to by (arg)
struct mag_calibration_s _scale
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
int read_reg(uint8_t reg, uint8_t &val)
Read a register.
virtual int unregister_class_devname(const char *class_devname, unsigned class_instance)
Register a class device name, automatically adding device class instance suffix if need be...
#define ADDR_TEMP_OUT_MSB
Rotation
Enum for board and external compass rotations.
int check_scale()
Check the current scale calibration.
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
void perf_end(perf_counter_t handle)
End a performance event.
uint8_t _temperature_counter
virtual ssize_t read(cdev::file_t *filp, char *buffer, size_t buflen)
Perform a read from the device.
int collect()
Collect the result of the most recent measurement.
#define HMC5983_TEMP_SENSOR_ENABLE
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
void check_conf(void)
check the sensor configuration.
int reset()
Reset the device.
int check_offset()
Check the current offset calibration.
virtual int ioctl(cdev::file_t *filp, int cmd, unsigned long arg)
Perform an ioctl operation on the device.
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.
#define MAGIOCSTEMPCOMP
enable/disable temperature compensation
Fundamental base class for all physical drivers (I2C, SPI).
void check_range(void)
check the sensor range.
void start()
Initialise the automatic measurement state machine and start it.
#define ADDR_DATA_OUT_X_MSB
bool _pub_blocked
true if publishing should be blocked
perf_counter_t _range_errors
Dual< Scalar, N > abs(const Dual< Scalar, N > &a)
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
void stop()
Stop the automatic measurement state machine.
int calibrate(cdev::file_t *filp, unsigned enable)
Perform the on-sensor scale calibration routine.
void perf_begin(perf_counter_t handle)
Begin a performance event.
#define DEVICE_DEBUG(FMT,...)
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
int set_excitement(unsigned enable)
Perform the on-sensor scale calibration routine.
float meas_to_float(uint8_t in[2])
Convert a big-endian signed 16-bit value to a float.