42 #include <px4_platform_common/time.h> 46 CDev(
"LIS3MDL", path),
47 ScheduledWorkItem(MODULE_NAME,
px4::device_bus_to_wq(interface->get_device_id())),
48 _interface(interface),
122 uint8_t num_samples = 10;
125 int fd = (int)enable;
127 float sum_excited[3] = {0.0f, 0.0f, 0.0f};
128 float sum_non_excited[3] = {0.0f, 0.0f, 0.0f};
132 warn(
"FAILED: SENSORIOCSPOLLRATE 50Hz");
139 PX4_WARN(
"FAILED: MAGIOCSRANGE 12 Ga");
147 for (uint8_t i = 0; i < num_samples; i++) {
153 ret =
::poll(&fds, 1, 2000);
156 warn(
"ERROR: TIMEOUT 1");
161 sz =
::read(fd, &report,
sizeof(report));
163 if (sz !=
sizeof(report)) {
164 warn(
"ERROR: READ 1");
171 for (uint8_t i = 0; i < num_samples; i++) {
177 ret =
::poll(&fds, 1, 2000);
180 warn(
"ERROR: TIMEOUT 2");
185 sz =
::read(fd, &report,
sizeof(report));
187 if (sz !=
sizeof(report)) {
188 warn(
"ERROR: READ 2");
193 sum_non_excited[0] += report.x;
194 sum_non_excited[1] += report.y;
195 sum_non_excited[2] += report.z;
198 sum_non_excited[0] /= num_samples;
199 sum_non_excited[1] /= num_samples;
200 sum_non_excited[2] /= num_samples;
204 PX4_WARN(
"FAILED: MAGIOCEXSTRAP 1");
212 for (uint8_t i = 0; i < num_samples; i++) {
218 ret =
::poll(&fds, 1, 2000);
221 warn(
"ERROR: TIMEOUT 1");
226 sz =
::read(fd, &report,
sizeof(report));
228 if (sz !=
sizeof(report)) {
229 warn(
"ERROR: READ 1");
236 for (uint8_t i = 0; i < 10; i++) {
242 ret =
::poll(&fds, 1, 2000);
245 warn(
"ERROR: TIMEOUT 2");
250 sz =
::read(fd, &report,
sizeof(report));
252 if (sz !=
sizeof(report)) {
253 warn(
"ERROR: READ 2");
258 sum_excited[0] += report.x;
259 sum_excited[1] += report.y;
260 sum_excited[2] += report.z;
263 sum_excited[0] /= num_samples;
264 sum_excited[1] /= num_samples;
265 sum_excited[2] /= num_samples;
267 if (1.0
f < fabsf(sum_excited[0] - sum_non_excited[0]) && fabsf(sum_excited[0] - sum_non_excited[0]) < 3.0
f &&
268 1.0
f < fabsf(sum_excited[1] - sum_non_excited[1]) && fabsf(sum_excited[1] - sum_non_excited[1]) < 3.0
f &&
269 0.1
f < fabsf(sum_excited[2] - sum_non_excited[2]) && fabsf(sum_excited[2] - sum_non_excited[2]) < 1.0
f) {
297 offset_valid =
false;
304 return !offset_valid;
329 #pragma pack(push, 1) 345 uint8_t buf_rx[2] = {0};
352 bool sensor_is_onboard =
false;
371 PX4_WARN(
"Register read error.");
375 report.x = (int16_t)((lis_report.x[1] << 8) | lis_report.x[0]);
376 report.y = (int16_t)((lis_report.y[1] << 8) | lis_report.y[0]);
377 report.z = (int16_t)((lis_report.z[1] << 8) | lis_report.z[0]);
379 report.t = (int16_t)((buf_rx[1] << 8) | buf_rx[0]);
381 float temperature = report.t;
382 new_mag_report.temperature = 25.0f + (temperature / 8.0f);
388 new_mag_report.is_external = !sensor_is_onboard;
393 new_mag_report.x_raw = report.x;
394 new_mag_report.y_raw = report.y;
395 new_mag_report.z_raw = report.z;
528 unsigned interval = (1000000 / arg);
569 case DEVIOCGDEVICEID:
574 return CDev::ioctl(file_pointer, cmd, arg);
608 _reports->print_info(
"report queue");
634 unsigned count = buffer_len /
sizeof(
struct mag_report);
658 return ret ? ret : -EAGAIN;
718 ::printf(
"set_excitement enable=%d cntl1=0x%x\n", (
int)enable, (
unsigned)
_cntl_reg1);
726 uint8_t conf_reg_ret = 0;
731 return !(_cntl_reg1 == conf_reg_ret);
742 }
else if (range <= 8) {
747 }
else if (range <= 12) {
769 uint8_t range_bits_in = 0;
#define MAGIOCGSCALE
copy the mag scaling constants to the structure pointed to by (arg)
void print_info()
Diagnostics - print some basic information about the driver.
#define MAGIOCGEXTERNAL
determine if mag is external or onboard
int reset()
Resets the device.
virtual int read(struct file *file_pointer, char *buffer, size_t buffer_len)
measure the time elapsed performing an event
int read_reg(uint8_t reg, uint8_t &val)
Reads a register.
#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...
#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)
Writes a register.
enum OPERATING_MODE _mode
mag scaling factors; Vout = (Vin * Vscale) + Voffset
perf_counter_t _sample_perf
count the number of times an event occurs
bool _continuous_mode_set
#define DRV_MAG_DEVTYPE_LIS3MDL
#define CNTL_REG5_DEFAULT
perf_counter_t _comms_errors
virtual void poll_notify(pollevent_t events)
Report new poll events.
#define MAGIOCSRANGE
set the measurement range to handle (at least) arg Gauss
void stop()
Stop the automatic measurement state machine.
#define SENSORIOCSPOLLRATE
Set the driver polling rate to (arg) Hz, or one of the SENSOR_POLLRATE constants. ...
virtual int ioctl(struct file *file_pointer, int cmd, unsigned long arg)
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
#define MODE_REG_SINGLE_MODE
int set_excitement(unsigned enable)
Performs the on-sensor scale calibration routine.
int measure()
Issue a measurement command.
device identifier information
void perf_count(perf_counter_t handle)
Count a performance event.
void Run() override
Performs a poll cycle; collect from the previous measurement and start a new one. ...
#define MAGIOCSSCALE
set the mag scaling constants to the structure pointed to by (arg)
#define MODE_REG_CONTINOUS_MODE
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
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...
Rotation
Enum for board and external compass rotations.
perf_counter_t _range_errors
#define LIS3MDL_CONVERSION_INTERVAL
LIS3MDL internal constants and data structures.
uint8_t _temperature_counter
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
struct mag_calibration_s _scale
LIS3MDL(device::Device *interface, const char *path, enum Rotation rotation)
perf_counter_t _conf_errors
int check_offset()
Check the current offset calibration.
int set_range(unsigned range)
Sets the sensor internal range to handle at least the argument in Gauss.
void start()
Initialises the automatic measurement state machine and start it.
#define CNTL_REG3_DEFAULT
void perf_end(perf_counter_t handle)
End a performance event.
#define CNTL_REG1_DEFAULT
Shared defines for the LIS3MDL driver.
int orb_publish(const struct orb_metadata *meta, orb_advert_t handle, const void *data)
int calibrate(struct file *file_pointer, unsigned enable)
Performs the on-sensor scale calibration routine.
uint8_t _temperature_error_count
int set_default_register_values()
Configures the device with default register values.
struct @83::@85::@87 file
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 CNTL_REG4_DEFAULT
int orb_unadvertise(orb_advert_t handle)
Fundamental base class for all physical drivers (I2C, SPI).
int collect()
Collect the result of the most recent measurement.
bool _calibrated
the calibration is valid
#define CNTL_REG2_DEFAULT
bool _pub_blocked
true if publishing should be blocked
unsigned int _measure_interval
orb_advert_t orb_advertise_multi(const struct orb_metadata *meta, const void *data, int *instance, int priority)
int check_scale()
Check the current scale calibration.
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).
virtual int poll(file_t *filep, px4_pollfd_struct_t *fds, bool setup)
Perform a poll setup/teardown operation.
ringbuffer::RingBuffer * _reports