1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/drivers/include/hmc5883l.h
2020-04-01 13:37:22 +02:00

297 lines
10 KiB
C

/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup drivers_hmc5883l HMC5883L 3-axis digital compass
* @ingroup drivers_sensors
* @ingroup drivers_saul
* @brief Device driver for the Honeywell HMC5883L 3-axis digital compass
*
* The driver implements basic polling mode. The application can use
* different approaches to get new data, either
*
* - using the #hmc5883l_read function at a lower rate than the the DOR, or
* - using the data-ready interrupt (**DRDY**), see #hmc5883l_init_int.
*
* The data-ready interrupt (**DRDY**) is only be available when module
* `hmc5883l_int` is enabled.
*
* This driver provides @ref drivers_saul capabilities.
*
* @{
*
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
*/
#ifndef HMC5883L_H
#define HMC5883L_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdbool.h>
#include <stdint.h>
#include "periph/gpio.h"
#include "periph/i2c.h"
/** Definition of error codes */
typedef enum {
HMC5883L_OK = 0, /**< success */
HMC5883L_ERROR_I2C = -1, /**< any I2C communication error */
HMC5883L_ERROR_WRONG_ID = -2, /**< wrong id read */
HMC5883L_ERROR_NO_DATA = -3, /**< no data are available */
HMC5883L_ERROR_RAW_DATA = -4, /**< reading raw data failed */
HMC5883L_ERROR_COMMON = -5, /**< common error */
} hmc5883l_error_codes_t;
/**
* @brief Data output rates (DOR)
*
* The values correspond to bits <4:2> of the HMC5883L_REG_CFG_A register.
*/
typedef enum {
HMC5883L_DOR_0_75 = 0x00, /**< 0.75 Hz */
HMC5883L_DOR_1_5 = 0x04, /**< 1.5 Hz */
HMC5883L_DOR_3 = 0x08, /**< 3 Hz */
HMC5883L_DOR_7_5 = 0x0c, /**< 7.5 Hz */
HMC5883L_DOR_15 = 0x10, /**< 15 Hz (default) */
HMC5883L_DOR_30 = 0x14, /**< 30 Hz */
HMC5883L_DOR_75 = 0x18, /**< 75 Hz */
} hmc5883l_dor_t;
/**
* @brief Measurement modes
*
* The values correspond to bits <1:0> of the HMC5883L_REG_CFG_A register.
*/
typedef enum {
HMC5883L_MEAS_MODE_NORMAL = 0x00, /**< Normal measurement config */
HMC5883L_MEAS_MODE_BIAS_POS = 0x01, /**< Positive bias config for all axes */
HMC5883L_MEAS_MODE_BIAS_NEG = 0x02, /**< Negative bias config for all axes */
} hmc5883l_meas_mode_t;
/**
* @brief Measurement avaraging (number of samples are averaged for output)
*
* The values correspond to bits <6:5> of the HMC5883L_REG_CFG_A register.
*/
typedef enum {
HMC5883L_MEAS_AVG_NONE = 0x00, /**< No averaging */
HMC5883L_MEAS_AVG_2 = 0x20, /**< 2 samples are averaged */
HMC5883L_MEAS_AVG_4 = 0x40, /**< 4 samples are averaged */
HMC5883L_MEAS_AVG_8 = 0x60, /**< 8 samples are averaged */
} hmc5883l_meas_avg_t;
/**
* @brief Operation modes
*
* Values correspond to bits <1:0> of HMC5883L_REG_MODE register
*/
typedef enum {
HMC5883L_OP_MODE_CONTINUOUS = 0x00, /**< Continuous measurement */
HMC5883L_OP_MODE_SINGLE = 0x01, /**< Single measurement */
HMC5883L_OP_MODE_IDLE = 0x02, /**< Idle mode */
} hmc5883l_op_mode_t;
/**
* @brief Gain (determines the sensitivity and the range)
*
* The values correspond to bits <7:5> of the HMC5883L_REG_CFG_B_GN register.
*/
typedef enum {
HMC5883L_GAIN_1370 = 0x00, /**< Range +-0.88 Gs, Resolution 0.73 mGs/LSB */
HMC5883L_GAIN_1090 = 0x20, /**< Range +-1.3 Gs, Resolution 0.92 mGs/LSB */
HMC5883L_GAIN_820 = 0x40, /**< Range +-1.9 Gs, Resolution 1.22 mGs/LSB */
HMC5883L_GAIN_660 = 0x60, /**< Range +-2.5 Gs, Resolution 1.52 mGs/LSB */
HMC5883L_GAIN_440 = 0x80, /**< Range +-4.0 Gs, Resolution 2.27 mGs/LSB */
HMC5883L_GAIN_390 = 0xa0, /**< Range +-4.7 Gs, Resolution 2.56 mGs/LSB */
HMC5883L_GAIN_330 = 0xc0, /**< Range +-5.6 Gs, Resolution 3.03 mGs/LSB */
HMC5883L_GAIN_230 = 0xe0, /**< Range +-8.1 Gs, Resolution 4.35 mGs/LSB */
} hmc5883l_gain_t;
/**
* @brief Magnetic field values in milli-Gauss (mGs)
*/
typedef struct {
int16_t x; /**< magnetic field x-axis */
int16_t y; /**< magnetic field y-axis */
int16_t z; /**< magnetic field y-axis */
} hmc5883l_data_t;
/**
* @brief Raw data set as two complements
*/
typedef struct {
int16_t x; /**< magnetic field x-axis as 16 bit two's complements */
int16_t y; /**< magnetic field y-axis as 16 bit two's complements */
int16_t z; /**< magnetic field z-axis as 16 bit two's complements */
} hmc5883l_raw_data_t;
#if MODULE_HMC5883L_INT || DOXYGEN
/**
* @brief HMC5883L DRDY interrupt callback function type
*
* Function prototype for the function which is called on DRDY interrupt if
* the interrupt is activated by #hmc5883l_init_int and the interrupt pin is
* defined in device initialization parameters.
*
* @note The @p cb function is called in interrupt context. The application
* should do nothing time consuming and not directly access sensor data.
*/
typedef void (*hmc5883l_drdy_int_cb_t)(void *);
#endif /* MODULE_HMC5883L_INT || DOXYGEN */
/**
* @brief HMC5883L device initialization parameters
*/
typedef struct {
unsigned dev; /**< I2C device */
#if MODULE_HMC5883L_INT
gpio_t int_pin; /**< DRDY interrupt pin: if #GPIO_UNDEF, interrupts are not used */
#endif
hmc5883l_meas_mode_t meas_mode; /**< Measurement mode (default #HMC5883L_MEAS_MODE_NORMAL) */
hmc5883l_meas_avg_t meas_avg; /**< Measurement avaraging (default #HMC5883L_MEAS_AVG_NONE) */
hmc5883l_dor_t dor; /**< Data output rate (default #HMC5883L_DOR_15) */
hmc5883l_op_mode_t op_mode; /**< Operation mode (#HMC5883L_OP_MODE_CONTINUOUS) */
hmc5883l_gain_t gain; /**< Gain (default #HMC5883L_GAIN_1090) */
} hmc5883l_params_t;
/**
* @brief HMC5883L sensor device data structure type
*/
typedef struct {
unsigned dev; /**< I2C device */
#if MODULE_HMC5883L_INT
gpio_t int_pin; /**< DRDY interrupt pin: if #GPIO_UNDEF, interrupts are not used */
#endif
hmc5883l_op_mode_t op_mode; /**< Operation mode (#HMC5883L_OP_MODE_CONTINUOUS) */
hmc5883l_gain_t gain; /**< Gain (default #HMC5883L_GAIN_1090) */
} hmc5883l_t;
/**
* @brief Initialize the HMC5883L sensor device
*
* This function resets the sensor and initializes the sensor according to
* given initialization parameters. All registers are reset to default values.
*
* @param[in] dev device descriptor of HMC5883L sensor to be initialized
* @param[in] params HMC5883L initialization parameters
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* a negative error code on error,
* see #hmc5883l_error_codes_t
*/
int hmc5883l_init(hmc5883l_t *dev, const hmc5883l_params_t *params);
#if MODULE_HMC5883L_INT || DOXYGEN
/**
* @brief Initialize and activate the DRDY interrupt of HMC5883L sensor device
*
* This function activates the DRDY interrupt and initializes the pin defined
* as the interrupt pin in the initialization parameters of the device. The
* @p cb parameter specifies the function, along with an optional argument
* @p arg, which is called when a DRDY interrupt is triggered.
*
* @warning The given callback function @p cb is executed in interrupt context.
* Make sure not to call any driver API function in that context.
* @note This function is only available when module `hmc5883l_int` is enabled.
*
* @param[in] dev device descriptor of HMC5883L sensor
* @param[in] cb function called when DRDY interrupt is triggered
* @param[in] arg argument for the callback function
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* a negative error code on error,
* see #hmc5883l_error_codes_t
*/
int hmc5883l_init_int(hmc5883l_t *dev, hmc5883l_drdy_int_cb_t cb, void *arg);
#endif /* MODULE_HMC5883L_INT || DOXYGEN */
/**
* @brief Data-ready status function
*
* The function checks the status register and returns
*
* @param[in] dev device descriptor of HMC5883L sensor
*
* @retval HMC5883L_OK new data available
* @retval HMC5883L_ERROR_NO_DATA no new data available
* @retval HMC5883L_ERROR_* negative error code,
* see #hmc5883l_error_codes_t
*/
int hmc5883l_data_ready(const hmc5883l_t *dev);
/**
* @brief Read one sample of magnetic field values in milli-Gauss (mGs)
*
* Raw magnetometer data are read from the sensor and normalized them
* with respect to configured gain. Magnetic field values are given in
* milli-Gauss (mGs) to preserve full resolution:
*
* @param[in] dev device descriptor of HMC5883L sensor
* @param[out] data result vector in milli-Gauss (mGs) per axis
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* a negative error code on error,
* see #hmc5883l_error_codes_t
*/
int hmc5883l_read(const hmc5883l_t *dev, hmc5883l_data_t *data);
/**
* @brief Read one sample of raw sensor data as 16 bit two's complements
*
* @param[in] dev device descriptor of HMC5883L sensor
* @param raw raw data vector
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* a negative error code on error,
* see #hmc5883l_error_codes_t
*/
int hmc5883l_read_raw(const hmc5883l_t *dev, hmc5883l_raw_data_t *raw);
/**
* @brief Power down the sensor
*
* Changes the sensor operation mode to #HMC5883L_OP_MODE_IDLE in which
* almost all internal blocks are switched off. I2C interface is
* still active. The content of the configuration registers is preserved.
*
* @param[in] dev Device descriptor of HMC5883L device to read from
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* negative error code, see #hmc5883l_error_codes_t
*/
int hmc5883l_power_down(hmc5883l_t *dev);
/**
* @brief Power up the sensor
*
* Swichtes the sensor back into the last active operation mode.
*
* @param[in] dev Device descriptor of HMC5883L device to read from
*
* @retval HMC5883L_OK on success
* @retval HMC5883L_ERROR_* negative error code, see #hmc5883l_error_codes_t
*/
int hmc5883l_power_up(hmc5883l_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* HMC5883L_H */
/** @} */