Microchip® Advanced Software Framework

ak8975.c File Reference

AKM AK8975 3-axis magnetometer.

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

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

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

Macros

#define SELF_TEST_DELAY   (0x80000)
 Delay loop count during self-test. More...
 

Functions

static void ak8975_apply_offset (vector3_t *input)
 Apply stored offset values to sensor reading. More...
 
static bool ak8975_calibrate (sensor_t *sensor, sensor_calibration_t calib_type, int step, void *info)
 Calibrate magnetometer. More...
 
static bool ak8975_check_overflow (const vector3_t *data)
 @ brief Test for magnetic sensor overflow More...
 
static bool ak8975_device_id (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer device ID. More...
 
static bool ak8975_get_data (sensor_hal_t *hal, uint8_t mode, vector3_t *data)
 Read magnetometer vector data. More...
 
static bool ak8975_get_field (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer vector (3-axis) data. More...
 
static bool ak8975_get_heading (sensor_hal_t *hal, sensor_data_t *data)
 Read magnetometer heading/direction data. More...
 
bool ak8975_init (sensor_t *sensor, int resvd)
 AKM AK8975 magnetometer driver initialization. More...
 
static bool ak8975_ioctl (sensor_t *sensor, sensor_command_t cmd, void *arg)
 AK8975 ioctl control entry point. More...
 
static bool ak8975_read (sensor_t *sensor, sensor_read_t type, sensor_data_t *data)
 Read sensor data. More...
 
static bool ak8975_selftest (sensor_t *sensor, int *test_code, void *arg)
 Perform self-test function. More...
 
static bool ak8975_set_state (sensor_hal_t *hal, sensor_state_t state)
 AKM AK8975 device state set routine. More...
 

Variables

static vector3_t calibrated_offsets
 Sensor Calibration Data. More...
 

#define SELF_TEST_DELAY   (0x80000)

Delay loop count during self-test.

Referenced by ak8975_selftest().

static void ak8975_apply_offset ( vector3_t input)
inlinestatic

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.

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

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

Referenced by ak8975_get_field(), and ak8975_get_heading().

static bool ak8975_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 device descriptor.
calib_typeThe address of a vector storing sensor axis data.
stepThe calibration stage number [1,3].
infoUnimplemented (ignored) parameter.
Returns
bool true if the call succeeds, else false is returned.

References ak8975_check_overflow(), ak8975_get_data(), AK8975_SINGLE_MODE, sensor_desc::err, sensor_desc::hal, MANUAL_CALIBRATE, nvram_read(), nvram_write(), SENSOR_ERR_IO, SENSOR_ERR_PARAMS, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by ak8975_init().

static bool ak8975_check_overflow ( const vector3_t data)
inlinestatic

@ brief Test for magnetic sensor overflow

AK8975/B has the limitation for measurement range that the sum of the absolute values of each axis should be smaller than 2400 microtesla:

     |x| + |y| + |z| < 2400 uT

When the magnetic field exceeds this limitation, data stored at measurement data are not correct. This is called "Magnetic Sensor Overflow".

When magnetic sensor overflow occurs, HOFL but turns to "1". When the next measurement starts, it returns to "0".

Returns
bool true if Magnetic Sensor Overflow criteria are satisfied.

References abs, AK8975_DATA_RESOLUTION, MICRO_TESLA_PER_COUNT, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by ak8975_calibrate(), ak8975_get_field(), and ak8975_get_heading().

static bool ak8975_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 AK8975_REG_WIA, sensor_data_t::device, and sensor_bus_get.

Referenced by ak8975_read().

static bool ak8975_get_data ( sensor_hal_t hal,
uint8_t  mode,
vector3_t data 
)
static

Read magnetometer vector data.

This function obtains magnetometer data for all three axes of the AKM 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 AK8975_REG_CNTL1, AK8975_REG_HXL, sensor_axis_vec_t::axis, gpio_pin_is_low, sensor_hal::mcu_sigint, 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 ak8975_calibrate(), ak8975_get_field(), ak8975_get_heading(), and ak8975_selftest().

static bool ak8975_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 AKM 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 hardware descriptor.
dataThe address of a vector storing sensor axis data.
Returns
bool true if the call succeeds, else false is returned.

References ak8975_apply_offset(), ak8975_check_overflow(), ak8975_get_data(), AK8975_SINGLE_MODE, sensor_data_t::axis, MICRO_TESLA_PER_COUNT, sensor_data_t::scaled, vector3_scale(), vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by ak8975_read().

static bool ak8975_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 AKM 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 hardware descriptor.
dataThe address of a vector storing sensor axis data.
Returns
bool true if the call succeeds, else false is returned.

References ak8975_apply_offset(), ak8975_check_overflow(), ak8975_get_data(), AK8975_SINGLE_MODE, field_direction(), sensor_data_t::heading, and MICRO_TESLA_PER_COUNT.

Referenced by ak8975_read().

bool ak8975_init ( sensor_t sensor,
int  resvd 
)

AKM AK8975 magnetometer driver initialization.

This is the main initialization function for the AK8975 device.

Parameters
sensorAddress of a sensor device descriptor.
resvdReserved value.
Returns
bool true if the call succeeds, else false is returned.

References ak8975_calibrate(), AK8975_DATA_RESOLUTION, ak8975_ioctl(), ak8975_read(), AK8975_REG_WIA, ak8975_selftest(), AK8975_WIA_VALUE, sensor_desc::drv, sensor_device_t::func, sensor_desc::hal, nvram_read(), sensor_funcs_t::read, sensor_hal::resolution, sensor_bus_get, SENSOR_CAPS_3_AXIS, SENSOR_CAPS_SELFTEST, SENSOR_SCALE_micro, SENSOR_UNITS_tesla, SENSOR_VENDOR_AKM, vector3_t::x, vector3_t::y, and vector3_t::z.

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

AK8975 ioctl control entry point.

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

References ak8975_set_state(), sensor_desc::err, sensor_desc::hal, SENSOR_ERR_UNSUPPORTED, SENSOR_SET_STATE, and status.

Referenced by ak8975_init().

static bool ak8975_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 ak8975_device_id(), ak8975_get_field(), ak8975_get_heading(), sensor_desc::err, sensor_desc::hal, SENSOR_ERR_FUNCTION, SENSOR_READ_FIELD, SENSOR_READ_HEADING, and SENSOR_READ_ID.

Referenced by ak8975_init().

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

Perform self-test function.

This function sets up and executes the built-in self test function of the AK8975 sensor device.

Parameters
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 AK8975_ASTC_SELF, ak8975_get_data(), AK8975_POWER_DOWN_MODE, AK8975_REG_ASTC, AK8975_REG_CNTL1, AK8975_SELF_TEST_MODE, AK8975_TEST_X_MAX, AK8975_TEST_X_MIN, AK8975_TEST_Y_MAX, AK8975_TEST_Y_MIN, AK8975_TEST_Z_MAX, AK8975_TEST_Z_MIN, data, sensor_desc::hal, SELF_TEST_DELAY, sensor_bus_put, SENSOR_TEST_ERR_NONE, SENSOR_TEST_ERR_RANGE, SENSOR_TEST_ERR_READ, vector3_t::x, vector3_t::y, and vector3_t::z.

Referenced by ak8975_init().

static bool ak8975_set_state ( sensor_hal_t hal,
sensor_state_t  state 
)
static

AKM AK8975 device state set routine.

This function places the AK8975 device in the specified state.

Parameters
sensorAddress of a sensor device descriptor.
stateState device will be placed into.
Returns
bool true if the call succeeds, else false is returned.

References AK8975_POWER_DOWN_MODE, AK8975_REG_CNTL1, sensor_bus_put, SENSOR_STATE_POWER_DOWN, and SENSOR_STATE_SLEEP.

Referenced by ak8975_ioctl().

vector3_t calibrated_offsets
static

Sensor Calibration Data.

This variable stores copies of axis calibration offsets stored in NVRAM.

The current implementation will either use software floating-point routines from the toolchain or fixed-point math routines in the ASF. All fractional sensor data should use types defined in precision.h where the type scalar_t is an alias for a C/C++ floating-point type or an integer type used by fixed-point arithmetic functions defined in the API.