Microchip® Advanced Software Framework

hmc5883l.c File Reference

Honeywell HMC5883L 3-axis magnetometer.

This file contains functions for initializing and reading data from a Honeywell HMC5883L 3-axis magnetometer.

Copyright (c) 2014-2018 Microchip Technology Inc. and its subsidiaries.

#include <string.h>
#include <math.h>
#include "hmc5883l.h"

Data Structures

struct  angle_t
 
struct  cal_data_t
 Sensor calibration data. More...
 
struct  hmc588l_axis_t
 HMC 5883l axis data format. More...
 

Macros

#define CAL_OFFSETS_ADDR   (0)
 
#define CAL_SENSITIVITY_ADDR   (0 + sizeof(vector3_t))
 
#define DATA_OUTPUT_OVERFLOW   ((int16_t)0xf000)
 
#define READ_DELAY_MSEC   (100) /* delay in msec between consecutive */
 
#define SELF_TEST_DELAY_MSEC   (250) /* delay in msec during self test */
 

Enumerations

enum  {
  index_90uT,
  index_130uT,
  index_190uT,
  index_250uT,
  index_400uT,
  index_470uT,
  index_560uT,
  index_810uT
}
 
enum  {
  index_1hz,
  index_2hz,
  index_3hz,
  index_8hz,
  index_15hz,
  index_30hz,
  index_75hz
}
 

Functions

static void hmc5883l_apply_offset (vector3_t *input)
 Apply stored offset values to sensor reading. More...
 
static void hmc5883l_apply_sensitivity (vector3_t *input)
 Apply stored sensitivity scaling factors to sensor reading. More...
 
static bool hmc5883l_calibrate (sensor_t *sensor, sensor_calibration_t calib_type, int step, void *info)
 Calibrate magnetometer. More...
 
static bool hmc5883l_device_id (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer device ID. More...
 
static bool hmc5883l_get_data (sensor_hal_t *hal, vector3_t *data)
 Read magnetometer vector data. More...
 
static bool hmc5883l_get_field (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer vector (3-axis) data. More...
 
static bool hmc5883l_get_heading (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer heading/direction data. More...
 
bool hmc5883l_init (sensor_t *sensor, int resvd)
 Honeywell HMC5883L magnetometer driver initialization. More...
 
static bool hmc5883l_ioctl (sensor_t *sensor, sensor_command_t cmd, void *arg)
 HMC5883L ioctl control entry point. More...
 
static bool hmc5883l_read (sensor_t *sensor, sensor_read_t type, sensor_data_t *data)
 Read sensor data. More...
 
static bool hmc5883l_selftest (sensor_t *sensor, int *test_code, void *arg)
 Perform self-test function. More...
 
static bool hmc5883l_set_bandwidth (sensor_hal_t *hal, int16_t bw)
 Set the sample bandwidth for the magnetometer. More...
 
static bool hmc5883l_set_range (sensor_hal_t *hal, int16_t range)
 Set the range for the magnetometer. More...
 

Variables

static const sensor_map_t band_table []
 Honeywell HMC5883L Bandwidth Table (hertz, register value) More...
 
static cal_data_t cal_data
 
static int dev_range
 Current range index for device. More...
 
static const sensor_map_t range_table []
 Honeywell HMC5883L Range Table (microtesla, register value) More...
 
static const int scale_table []
 Honeywell HMC5883L Data Scaling Table (counts per milligauss) More...
 

#define CAL_OFFSETS_ADDR   (0)
Todo:
Flash memory addresses should be configurable.

Referenced by hmc5883l_calibrate().

#define CAL_SENSITIVITY_ADDR   (0 + sizeof(vector3_t))

Referenced by hmc5883l_calibrate().

#define DATA_OUTPUT_OVERFLOW   ((int16_t)0xf000)

Referenced by hmc5883l_get_data().

#define READ_DELAY_MSEC   (100) /* delay in msec between consecutive */

Referenced by hmc5883l_calibrate().

#define SELF_TEST_DELAY_MSEC   (250) /* delay in msec during self test */

Referenced by hmc5883l_selftest().

anonymous enum
Enumerator
index_90uT 
index_130uT 
index_190uT 
index_250uT 
index_400uT 
index_470uT 
index_560uT 
index_810uT 
anonymous enum
Enumerator
index_1hz 
index_2hz 
index_3hz 
index_8hz 
index_15hz 
index_30hz 
index_75hz 

static void hmc5883l_apply_offset ( vector3_t input)
static

Apply stored offset values to sensor reading.

This function applies stored calibration offsets to the "input" vector of magnetometer values (the magnetic field vector) and returns the modified values. The offsets are calculated based on sensitivity-adjusted readings, so this function should be used after the values that have been adjusted using hmc5883l_apply_sensitivity().

Parameters
inputContains the measured magnetic field values, adjusted for sensitivity. The offset-adjusted values will replace the contents.
Return values
truesuccessfully adjusted sensor readings
falseFailed to adjust sensor readings

References cal_data_t::offsets, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by hmc5883l_get_field(), and hmc5883l_get_heading().

static void hmc5883l_apply_sensitivity ( vector3_t input)
static

Apply stored sensitivity scaling factors to sensor reading.

This function applies stored sensitivity scaling to the "input" vector of magnetometer values (the magnetic field vector) and returns the modified values.

Parameters
inputContains the measured magnetic field values. The sensitivty-adjusted values will replace the contents.
Return values
truesuccessfully adjusted sensor readings
falseFailed to adjust sensor readings

References cal_data_t::sensitivity, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by hmc5883l_calibrate(), hmc5883l_get_field(), and hmc5883l_get_heading().

bool hmc5883l_calibrate ( sensor_t sensor,
sensor_calibration_t  calib_type,
int  step,
void *  info 
)
static

Calibrate magnetometer.

This function measures the magnetometer output if 3 different device orientations, calculates average offset values, and stores these offsets in non-volatile memory. The offsets will later be used during normal measurements, to compensate for fixed magnetic effects.

This routine must be called 3 times total, with the "step" parameter indicating what stage of the calibration is being performed. This multi-step mechanism allows the application to prompt for physical placement of the sensor device before this routine is called.

Parameters
sensorAddress of an initialized sensor descriptor.
dataThe address of a vector storing sensor axis data.
stepThe calibration stage number (1 to 3).
infoUnimplemented (ignored) parameter.
Returns
bool true if the call succeeds, else false is returned.

References sensor_data_t::axis, CAL_OFFSETS_ADDR, CAL_SENSITIVITY_ADDR, delay_ms, dummy_data, sensor_desc::err, sensor_desc::hal, hmc5883l_apply_sensitivity(), hmc5883l_get_data(), hmc5883l_selftest(), HMC5883L_TEST_X_NORM, HMC5883L_TEST_Y_NORM, HMC5883L_TEST_Z_NORM, MANUAL_CALIBRATE, nvram_read(), nvram_write(), cal_data_t::offsets, READ_DELAY_MSEC, cal_data_t::sensitivity, SENSOR_ERR_IO, SENSOR_TEST_BIAS_POS, SENSOR_TEST_ERR_NONE, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by hmc5883l_init().

static bool hmc5883l_device_id ( sensor_hal_t hal,
sensor_data_t data 
)
static

Read magnetometer device ID.

This function reads the magnetometer hardware identification registers and returns these values to the addresses specified in the function parameters.

Parameters
halAddress of an initialized sensor hardware descriptor.
dataAddress of sensor_data_t structure to return values.
Returns
bool true if the call succeeds, else false is returned.

References cpu_to_be32, sensor_data_t::device, HMC5883L_ID_REG_A, and sensor_bus_read.

Referenced by hmc5883l_init(), and hmc5883l_read().

static bool hmc5883l_get_data ( sensor_hal_t hal,
vector3_t data 
)
static

Read magnetometer vector data.

This function obtains magnetometer data for all three axes of the Honeywell device. The data is read from six device registers using a multi-byte bus transfer. The 13-bit raw results are then assembled from the two register values for each axis, including extending the sign bit, to form a signed 16-bit value.

Parameters
halAddress of an initialized sensor hardware descriptor.
dataThe address of a vector storing sensor axis data.
Returns
bool true if the call succeeds, else false is returned.

References sensor_axis_vec_t::axis, DATA_OUTPUT_OVERFLOW, gpio_pin_is_low, HMC5883L_MAG_X_HI, HMC5883L_MODE_REG, hmc588l_axis_t::lsb, sensor_hal::mcu_sigint, MODE_SINGLE, orient, sensor_hal::orientation, sensor_bus_put, sensor_bus_read, sensor_axis_vec_t::sign, vector3_t::x, sensor_orient_t::x, vector3_t::y, sensor_orient_t::y, vector3_t::z, and sensor_orient_t::z.

Referenced by hmc5883l_calibrate(), hmc5883l_get_field(), hmc5883l_get_heading(), and hmc5883l_selftest().

static bool hmc5883l_get_field ( sensor_hal_t hal,
sensor_data_t data 
)
static

Read magnetometer vector (3-axis) data.

This function obtains magnetometer data for all three axes of the Honeywell device. The data is read from six device registers using a multi-byte bus transfer. The 10-bit raw results are then assembled from the two register values for each axis, including extending the sign bit, to form a signed 32-bit value.

Along with the actual sensor data, the LSB byte contains a "new" flag indicating if the data for this axis has been updated since the last time the axis data was read. Reading either LSB or MSB data will clear this flag.

Parameters
halAddress of an initialized sensor device descriptor.
dataThe address of a vector storing sensor axis data.
Returns
bool true if the call succeeds, else false is returned.

References sensor_data_t::axis, dev_range, GAUSS_TO_MICRO_TESLA, hmc5883l_apply_offset(), hmc5883l_apply_sensitivity(), hmc5883l_get_data(), scale_table, sensor_data_t::scaled, vector3_scale(), vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by hmc5883l_read().

static bool hmc5883l_get_heading ( sensor_hal_t hal,
sensor_data_t data 
)
static

Read magnetometer heading/direction data.

This function obtains magnetometer data for all three axes of the Honeywell device. The data is read from six device registers using a multi-byte bus transfer. The 10-bit raw results are then assembled from the two register values for each axis, including extending the sign bit, to form a signed 32-bit value.

Along with the actual sensor data, the LSB byte contains a "new" flag indicating if the data for this axis has been updated since the last time the axis data was read. Reading either LSB or MSB data will clear this flag.

Parameters
halAddress of an initialized sensor device descriptor.
dataThe address of a vector storing sensor axis data.
Returns
bool true if the call succeeds, else false is returned.

References dev_range, field_direction(), GAUSS_TO_MICRO_TESLA, sensor_data_t::heading, hmc5883l_apply_offset(), hmc5883l_apply_sensitivity(), hmc5883l_get_data(), and scale_table.

Referenced by hmc5883l_read().

static bool hmc5883l_ioctl ( sensor_t sensor,
sensor_command_t  cmd,
void *  arg 
)
static

HMC5883L ioctl control entry point.

Parameters
sensorAddress of an initialized sensor descriptor.
cmdCommand to execute
argArgument for command (varies)
Returns
bool true if the call succeeds, else false is returned.

References sensor_desc::err, sensor_desc::hal, hmc5883l_set_bandwidth(), hmc5883l_set_range(), SENSOR_ERR_UNSUPPORTED, SENSOR_SET_BANDWIDTH, SENSOR_SET_RANGE, and status.

Referenced by hmc5883l_init().

static bool hmc5883l_read ( sensor_t sensor,
sensor_read_t  type,
sensor_data_t data 
)
static

Read sensor data.

This routine calls the appropriate internal data function to obtain the specified type of data from the sensor device.

Parameters
sensorAddress of an initialized sensor device descriptor.
typeType of sensor data to read.
dataThe address where data values are returned.
Returns
bool true if the call succeeds, else false is returned.

References sensor_desc::err, sensor_desc::hal, hmc5883l_device_id(), hmc5883l_get_field(), hmc5883l_get_heading(), SENSOR_ERR_FUNCTION, SENSOR_READ_FIELD, SENSOR_READ_HEADING, and SENSOR_READ_ID.

Referenced by hmc5883l_init().

bool hmc5883l_selftest ( sensor_t sensor,
int *  test_code,
void *  arg 
)
static

Perform self-test function.

This function sets up and executes an built-in self test function within the HMC5883L device.

Parameters
sensorAddress of an initialized sensor descriptor.
test_codeAddress of a numeric code of which test to perform This location will contain the specific test result code when the function returns.
Returns
bool true if the call succeeds, else false is returned.

References data, DATA_RATE_15HZ, delay_ms, sensor_desc::hal, HMC5883L_CONFIG_REG_A, HMC5883L_CONFIG_REG_B, hmc5883l_get_data(), HMC5883L_MODE_REG, HMC5883L_TEST_GAIN, HMC5883L_TEST_X_MAX, HMC5883L_TEST_X_MIN, HMC5883L_TEST_Y_MAX, HMC5883L_TEST_Y_MIN, HMC5883L_TEST_Z_MAX, HMC5883L_TEST_Z_MIN, MEAS_AVG_1, MEAS_MODE_NEG, MEAS_MODE_POS, MODE_SINGLE, SELF_TEST_DELAY_MSEC, sensor_bus_put, sensor_bus_read, sensor_bus_write, SENSOR_TEST_BIAS_NEG, SENSOR_TEST_BIAS_POS, SENSOR_TEST_DEFAULT, SENSOR_TEST_ERR_FUNCTION, SENSOR_TEST_ERR_NONE, SENSOR_TEST_ERR_RANGE, SENSOR_TEST_ERR_READ, SENSOR_TEST_ERR_WRITE, status, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by hmc5883l_calibrate(), and hmc5883l_init().

static bool hmc5883l_set_bandwidth ( sensor_hal_t hal,
int16_t  bw 
)
static

Set the sample bandwidth for the magnetometer.

Parameters
halAddress of an initialized sensor hardware descriptor.
bandThe index of a driver-specific bandwidth table entry.
Returns
bool true if the call succeeds, else false is returned.

References DATA_RATE, HMC5883L_CONFIG_REG_A, sensor_bus_get, and sensor_bus_put.

Referenced by hmc5883l_init(), and hmc5883l_ioctl().

static bool hmc5883l_set_range ( sensor_hal_t hal,
int16_t  range 
)
static

Set the range for the magnetometer.

Parameters
halAddress of an initialized sensor hardware descriptor.
rangeThe index of a driver-specific range table entry.
Returns
bool true if the call succeeds, else false is returned.

References dev_range, HMC5883L_CONFIG_REG_B, and sensor_bus_put.

Referenced by hmc5883l_init(), and hmc5883l_ioctl().

const sensor_map_t band_table[]
static
Initial value:
= {
{{2}, DATA_RATE_1_5HZ},
{{3}, DATA_RATE_3HZ},
{{8}, DATA_RATE_7_5HZ},
{{15}, DATA_RATE_15HZ},
{{30}, DATA_RATE_30HZ},
{{75}, DATA_RATE_75HZ},
}
#define DATA_RATE_1_5HZ
Definition: hmc5883l.h:111
#define DATA_RATE_75HZ
Definition: hmc5883l.h:116
#define DATA_RATE_0_75HZ
Definition: hmc5883l.h:110
#define DATA_RATE_3HZ
Definition: hmc5883l.h:112
#define DATA_RATE_30HZ
Definition: hmc5883l.h:115
#define DATA_RATE_7_5HZ
Definition: hmc5883l.h:113
#define DATA_RATE_15HZ
Definition: hmc5883l.h:114

Honeywell HMC5883L Bandwidth Table (hertz, register value)

cal_data_t cal_data
static
int dev_range
static

Current range index for device.

Referenced by hmc5883l_get_field(), hmc5883l_get_heading(), and hmc5883l_set_range().

const sensor_map_t range_table[]
static
Initial value:
= {
{{90}, GAIN_0_9GA},
{{130}, GAIN_1_3GA},
{{190}, GAIN_1_9GA},
{{250}, GAIN_2_5GA},
{{400}, GAIN_4_0GA},
{{470}, GAIN_4_7GA},
{{560}, GAIN_5_6GA},
{{810}, GAIN_8_1GA},
}
#define GAIN_4_0GA
Definition: hmc5883l.h:130
#define GAIN_0_9GA
Definition: hmc5883l.h:126
#define GAIN_1_9GA
Definition: hmc5883l.h:128
#define GAIN_1_3GA
Definition: hmc5883l.h:127
#define GAIN_4_7GA
Definition: hmc5883l.h:131
#define GAIN_8_1GA
Definition: hmc5883l.h:133
#define GAIN_2_5GA
Definition: hmc5883l.h:129
#define GAIN_5_6GA
Definition: hmc5883l.h:132

Honeywell HMC5883L Range Table (microtesla, register value)

const int scale_table[]
static
Initial value:
= {
}
#define SCALE_1_9GA
Definition: hmc5883l.h:61
#define SCALE_1_3GA
Definition: hmc5883l.h:60
#define SCALE_0_9GA
Data scaling - varies by range/gain setting.
Definition: hmc5883l.h:59
#define SCALE_5_6GA
Definition: hmc5883l.h:65
#define SCALE_4_0GA
Definition: hmc5883l.h:63
#define SCALE_2_5GA
Definition: hmc5883l.h:62
#define SCALE_8_1GA
Definition: hmc5883l.h:66
#define SCALE_4_7GA
Definition: hmc5883l.h:64

Honeywell HMC5883L Data Scaling Table (counts per milligauss)

Referenced by hmc5883l_get_field(), and hmc5883l_get_heading().