mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
lsm303dlhc: initial import of lsm303dlhc driver
TODO: Accelerometer does not return valid values yet
This commit is contained in:
parent
8ab6e691d0
commit
88fce936e9
@ -168,10 +168,10 @@ extern "C" {
|
||||
#define GPIO_1_EXTI_CFG() (AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI8_PA)
|
||||
#define GPIO_1_IRQ EXTI9_5_IRQn
|
||||
/* GPIO channel 2 config */
|
||||
#define GPIO_2_PORT GPIOA
|
||||
#define GPIO_2_PORT GPIOB
|
||||
#define GPIO_2_PIN 12
|
||||
#define GPIO_2_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPAEN)
|
||||
#define GPIO_2_EXTI_CFG() (AFIO->EXTICR[3] |= AFIO_EXTICR4_EXTI12_PA)
|
||||
#define GPIO_2_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPBEN)
|
||||
#define GPIO_2_EXTI_CFG() (AFIO->EXTICR[3] |= AFIO_EXTICR4_EXTI12_PB)
|
||||
#define GPIO_2_IRQ EXTI15_10_IRQn
|
||||
/* GPIO channel 3 config */
|
||||
#define GPIO_3_PORT GPIOB
|
||||
@ -204,11 +204,11 @@ extern "C" {
|
||||
#define GPIO_7_EXTI_CFG() (AFIO->EXTICR[2] |= AFIO_EXTICR3_EXTI11_PC)
|
||||
#define GPIO_7_IRQ EXTI15_10_IRQn
|
||||
/* GPIO channel 8 config */
|
||||
#define GPIO_8_PORT GPIOA
|
||||
#define GPIO_8_PIN 5
|
||||
#define GPIO_8_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPAEN)
|
||||
#define GPIO_8_EXTI_CFG() (AFIO->EXTICR[1] |= AFIO_EXTICR2_EXTI5_PA)
|
||||
#define GPIO_8_IRQ EXTI9_5_IRQn
|
||||
#define GPIO_8_PORT GPIOB
|
||||
#define GPIO_8_PIN 2
|
||||
#define GPIO_8_CLKEN() (RCC->APB2ENR |= RCC_APB2ENR_IOPBEN)
|
||||
#define GPIO_8_EXTI_CFG() (AFIO->EXTICR[1] |= AFIO_EXTICR1_EXTI2_PB)
|
||||
#define GPIO_8_IRQ EXTI2_IRQn
|
||||
/* GPIO channel 9 config */
|
||||
#define GPIO_9_PORT GPIOA
|
||||
#define GPIO_9_PIN 6
|
||||
|
@ -55,5 +55,8 @@ endif
|
||||
ifneq (,$(filter netdev_802154,$(USEMODULE)))
|
||||
DIRS += netdev/802154
|
||||
endif
|
||||
ifneq (,$(filter lsm303dlhc,$(USEMODULE)))
|
||||
DIRS += lsm303dlhc
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
@ -16,3 +16,6 @@ endif
|
||||
ifneq (,$(filter lps331ap,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lps331ap/include
|
||||
endif
|
||||
ifneq (,$(filter lsm303dlhc,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lsm303dlhc/include
|
||||
endif
|
||||
|
215
drivers/include/lsm303dlhc.h
Normal file
215
drivers/include/lsm303dlhc.h
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* 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 driver_lsm303dlhc LSM303DLHC 3D accelerometer/magnetometer
|
||||
* @ingroup drivers
|
||||
* @brief Device driver for the LSM303DLHC 3D accelerometer/magnetometer
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver interface for the LSM303DLHC 3D accelerometer/magnetometer
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef __LSM303DLHC_H
|
||||
#define __LSM303DLHC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph/i2c.h"
|
||||
#include "periph/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The sensors default I2C address
|
||||
*/
|
||||
#define LSM303DLHC_ACC_DEFAULT_ADDRESS (0x19)
|
||||
#define LSM303DLHC_MAG_DEFAULT_ADDRESS (0x1e)
|
||||
|
||||
/**
|
||||
* @brief 3d data container
|
||||
*/
|
||||
typedef struct {
|
||||
int16_t x_axis;
|
||||
int16_t y_axis;
|
||||
int16_t z_axis;
|
||||
} lsm303dlhc_3d_data_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for LSM303DLHC sensors
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< I2C device */
|
||||
uint8_t acc_address; /**< accelerometer's I2C address */
|
||||
uint8_t mag_address; /**< magnetometer's I2C address */
|
||||
} lsm303dlhc_t;
|
||||
|
||||
/**
|
||||
* @brief Possible accelerometer sample rates
|
||||
*/
|
||||
typedef enum {
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_1HZ = 0x10, /**< 1Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_10HZ = 0x20, /**< 10Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_25HZ = 0x30, /**< 25Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_50HZ = 0x40, /**< 50Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_100HZ = 0x50, /**< 100Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_200HZ = 0x60, /**< 200Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_400HZ = 0x70, /**< 400Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_1620HZ = 0x80, /**< 1620Hz sample rate */
|
||||
LSM303DLHC_ACC_SAMPLE_RATE_N1344HZ_L5376HZ = 0x90 /**< 1344Hz normal mode,
|
||||
* 5376Hz low power mode */
|
||||
} lsm303dlhc_acc_sample_rate_t;
|
||||
|
||||
/**
|
||||
* @brief Possible accelerometer scales
|
||||
*/
|
||||
typedef enum {
|
||||
LSM303DLHC_ACC_SCALE_2G = 0x00, /**< +- 2g range */
|
||||
LSM303DLHC_ACC_SCALE_4G = 0x10, /**< +- 4g range */
|
||||
LSM303DLHC_ACC_SCALE_8G = 0x20, /**< +- 8g range */
|
||||
LSM303DLHC_ACC_SCALE_16G = 0x30, /**< +-16g range */
|
||||
} lsm303dlhc_acc_scale_t;
|
||||
|
||||
/**
|
||||
* @brief Possible magnetometer sample rates
|
||||
*/
|
||||
typedef enum {
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_0_75HZ = 0x00, /**< 0.75Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_1_5HZ = 0x04, /**< 1.5 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_3HZ = 0x08, /**< 3 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_7_5HZ = 0x0c, /**< 7.5 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_15HZ = 0x10, /**< 15 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_30HZ = 0x14, /**< 30 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_75HZ = 0x18, /**< 75 Hz sample rate */
|
||||
LSM303DLHC_MAG_SAMPLE_RATE_220HZ = 0x1c, /**< 220 Hz sample rate */
|
||||
} lsm303dlhc_mag_sample_rate_t;
|
||||
|
||||
/**
|
||||
* @brief Possible magnetometer gain values
|
||||
*/
|
||||
typedef enum {
|
||||
LSM303DLHC_MAG_GAIN_1100_980_GAUSS = 0x20, /**< 1100Gauss XYZ 980Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_855_760_GAUSS = 0x40, /**< 855Gauss XYZ 760Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_670_600_GAUSS = 0x60, /**< 670Gauss XYZ 600Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_450_400_GAUSS = 0x80, /**< 450Gauss XYZ 400Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_400_355_GAUSS = 0xa0, /**< 400Gauss XYZ 355Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_330_295_GAUSS = 0xc0, /**< 330Gauss XYZ 295Gauss Z */
|
||||
LSM303DLHC_MAG_GAIN_230_205_GAUSS = 0xe0, /**< 230Gauss XYZ 205Gauss Z */
|
||||
} lsm303dlhc_mag_gain_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a new LSM303DLHC device
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
* @param[in] i2c I2C device the sensor is connected to
|
||||
* @param[in] acc_pin GPIO pin connected to accelerometer
|
||||
* @param[in] mag_pin GPIO pin connected to magnetometer
|
||||
* @param[in] acc_address I2C address of the accelerometer
|
||||
* @param[in] acc_sample_rate accelerometer sample rate
|
||||
* @param[in] acc_scale accelerometer scale (from +- 2g to +-16g)
|
||||
* @param[in] mag_address I2C address of the magnetometer
|
||||
* @param[in] mag_sample_rate magnetometer sample rate
|
||||
* @param[in] mag_gain magnetometer gain
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_init(lsm303dlhc_t *dev, i2c_t i2c, gpio_t acc_pin, gpio_t mag_pin,
|
||||
uint8_t acc_address,
|
||||
lsm303dlhc_acc_sample_rate_t acc_sample_rate,
|
||||
lsm303dlhc_acc_scale_t acc_scale,
|
||||
uint8_t mag_address,
|
||||
lsm303dlhc_mag_sample_rate_t mag_sample_rate,
|
||||
lsm303dlhc_mag_gain_t mag_gain);
|
||||
|
||||
/**
|
||||
* @brief Read a accelerometer value from the sensor.
|
||||
*
|
||||
* @details This function provides raw acceleration data. To get the
|
||||
* corresponding values in g please refer to the following
|
||||
* table:
|
||||
* measurement range | factor
|
||||
* --------------------+---------
|
||||
* +- 2g | 1*10^-3
|
||||
* +- 4g | 2*10^-3
|
||||
* +- 8g | 4*10^-3
|
||||
* +-16g | 12*10^-3
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
* @param[out] data the measured accelerometer data
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_read_acc(lsm303dlhc_t *dev, lsm303dlhc_3d_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Read a magnetometer value from the sensor.
|
||||
*
|
||||
* @details This function returns raw magnetic data. To get the
|
||||
* corresponding values in gauss please refer to the following
|
||||
* table:
|
||||
* measurement range | factor
|
||||
* --------------------+---------
|
||||
* +- 1.3 gauss | 1/1100
|
||||
* +- 1.9 gauss | 1/855
|
||||
* +- 2.5 gauss | 1/670
|
||||
* +- 4.0 gauss | 1/450
|
||||
* +- 4.7 gauss | 1/400
|
||||
* +- 5.6 gauss | 1/330
|
||||
* +- 8.1 gauss | 1/230
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
* @param[out] data the measured magnetometer data
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_read_mag(lsm303dlhc_t *dev, lsm303dlhc_3d_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Read a temperature value from the sensor.
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
* @param[out] value the measured temperature
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_read_temp(lsm303dlhc_t *dev, int16_t *value);
|
||||
|
||||
/**
|
||||
* @brief Enable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_enable(lsm303dlhc_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Disable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of an LSM303DLHC device
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lsm303dlhc_disable(lsm303dlhc_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LSM303DLHC_H */
|
||||
/** @} */
|
3
drivers/lsm303dlhc/Makefile
Normal file
3
drivers/lsm303dlhc/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = lsm303dlhc
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
178
drivers/lsm303dlhc/include/lsm303dlhc-internal.h
Normal file
178
drivers/lsm303dlhc/include/lsm303dlhc-internal.h
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup driver_lsm303dlhc
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Definitions for the LSM303DLHC 3D accelerometer/magnetometer
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef __LSM303DLHC_INTERNAL_H
|
||||
#define __LSM303DLHC_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name LSM303DLHC accelerometer registers
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_REG_CTRL1_A (0x20)
|
||||
#define LSM303DLHC_REG_CTRL2_A (0x21)
|
||||
#define LSM303DLHC_REG_CTRL3_A (0x22)
|
||||
#define LSM303DLHC_REG_CTRL4_A (0x23)
|
||||
#define LSM303DLHC_REG_CTRL5_A (0x24)
|
||||
#define LSM303DLHC_REG_CTRL6_A (0x25)
|
||||
#define LSM303DLHC_REG_REFERENCE_A (0x26)
|
||||
#define LSM303DLHC_REG_STATUS_A (0x27)
|
||||
#define LSM303DLHC_REG_OUT_X_L_A (0x28)
|
||||
#define LSM303DLHC_REG_OUT_X_H_A (0x29)
|
||||
#define LSM303DLHC_REG_OUT_Y_L_A (0x2a)
|
||||
#define LSM303DLHC_REG_OUT_Y_H_A (0x2b)
|
||||
#define LSM303DLHC_REG_OUT_Z_L_A (0x2c)
|
||||
#define LSM303DLHC_REG_OUT_Z_H_A (0x2d)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CTRL1_A register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_CTRL1_A_XEN (0x01)
|
||||
#define LSM303DLHC_CTRL1_A_YEN (0x02)
|
||||
#define LSM303DLHC_CTRL1_A_ZEN (0x04)
|
||||
#define LSM303DLHC_CTRL1_A_LOW_POWER (0x08)
|
||||
#define LSM303DLHC_CTRL1_A_POWEROFF (0x00)
|
||||
#define LSM303DLHC_CTRL1_A_1HZ (0x10)
|
||||
#define LSM303DLHC_CTRL1_A_10HZ (0x20)
|
||||
#define LSM303DLHC_CTRL1_A_25HZ (0x30)
|
||||
#define LSM303DLHC_CTRL1_A_50HZ (0x40)
|
||||
#define LSM303DLHC_CTRL1_A_100HZ (0x50)
|
||||
#define LSM303DLHC_CTRL1_A_200HZ (0x60)
|
||||
#define LSM303DLHC_CTRL1_A_400HZ (0x70)
|
||||
#define LSM303DLHC_CTRL1_A_1620HZ (0x80)
|
||||
#define LSM303DLHC_CTRL1_A_N1344HZ_L5376HZ (0x90)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CTRL3_A register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_CTRL3_A_I1_CLICK (0x80)
|
||||
#define LSM303DLHC_CTRL3_A_I1_AOI1 (0x40)
|
||||
#define LSM303DLHC_CTRL3_A_I1_AOI2 (0x20)
|
||||
#define LSM303DLHC_CTRL3_A_I1_DRDY1 (0x10)
|
||||
#define LSM303DLHC_CTRL3_A_I1_DRDY2 (0x80)
|
||||
#define LSM303DLHC_CTRL3_A_I1_WTM (0x40)
|
||||
#define LSM303DLHC_CTRL3_A_I1_OVERRUN (0x20)
|
||||
#define LSM303DLHC_CTRL3_A_I1_NONE (0x00)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CTRL4_A register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_CTRL4_A_BDU (0x80)
|
||||
#define LSM303DLHC_CTRL4_A_BLE (0x40)
|
||||
#define LSM303DLHC_CTRL4_A_SCALE_2G (0x00)
|
||||
#define LSM303DLHC_CTRL4_A_SCALE_4G (0x10)
|
||||
#define LSM303DLHC_CTRL4_A_SCALE_8G (0x20)
|
||||
#define LSM303DLHC_CTRL4_A_SCALE_16G (0x30)
|
||||
#define LSM303DLHC_CTRL4_A_HR (0x04)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC STATUS_A register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_STATUS_ZYXOR (0x80)
|
||||
#define LSM303DLHC_STATUS_ZOR (0x40)
|
||||
#define LSM303DLHC_STATUS_YOR (0x20)
|
||||
#define LSM303DLHC_STATUS_XOR (0x10)
|
||||
#define LSM303DLHC_STATUS_ZYXDA (0x08)
|
||||
#define LSM303DLHC_STATUS_ZDA (0x04)
|
||||
#define LSM303DLHC_STATUS_YDA (0x02)
|
||||
#define LSM303DLHC_STATUS_XDA (0x01)
|
||||
/** *} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CTRL4_A register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_REG_CTRL5_A_BOOT (0x80)
|
||||
#define LSM303DLHC_REG_CTRL5_A_FIFO_EN (0x40)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LSM303DLHC magnetometer registers
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_REG_CRA_M (0x00)
|
||||
#define LSM303DLHC_REG_CRB_M (0x01)
|
||||
#define LSM303DLHC_REG_MR_M (0x02)
|
||||
#define LSM303DLHC_REG_OUT_X_H_M (0x03)
|
||||
#define LSM303DLHC_REG_OUT_X_L_M (0x04)
|
||||
#define LSM303DLHC_REG_OUT_Y_H_M (0x05)
|
||||
#define LSM303DLHC_REG_OUT_Y_L_M (0x06)
|
||||
#define LSM303DLHC_REG_OUT_Z_H_M (0x07)
|
||||
#define LSM303DLHC_REG_OUT_Z_L_M (0x08)
|
||||
#define LSM303DLHC_REG_SR_M (0x09)
|
||||
#define LSM303DLHC_REG_TEMP_OUT_L (0x32)
|
||||
#define LSM303DLHC_REG_TEMP_OUT_H (0x31)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CRA_REG_M register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_TEMP_EN (0x80)
|
||||
#define LSM303DLHC_TEMP_DIS (0x00)
|
||||
|
||||
#define LSM303DLHC_TEMP_SAMPLE_0_75HZ (0x00)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_1_5HZ (0x04)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_3HZ (0x08)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_7_5HZ (0x0c)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_15HZ (0x10)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_30HZ (0x14)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_75HZ (0x18)
|
||||
#define LSM303DLHC_TEMP_SAMPLE_220HZ (0x1c)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC CRB_REG_M register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_GAIN_1 (0x20)
|
||||
#define LSM303DLHC_GAIN_2 (0x40)
|
||||
#define LSM303DLHC_GAIN_3 (0x60)
|
||||
#define LSM303DLHC_GAIN_4 (0x80)
|
||||
#define LSM303DLHC_GAIN_5 (0xa0)
|
||||
#define LSM303DLHC_GAIN_6 (0xc0)
|
||||
#define LSM303DLHC_GAIN_7 (0xe0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Masks for the LSM303DLHC MR_REG_M register
|
||||
* @{
|
||||
*/
|
||||
#define LSM303DLHC_MAG_MODE_CONTINUOUS (0x00)
|
||||
#define LSM303DLHC_MAG_MODE_SINGLE (0x01)
|
||||
#define LSM303DLHC_MAG_MODE_SLEEP (0x02)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LSM303DLHC_INTERNAL_H */
|
||||
/** @} */
|
209
drivers/lsm303dlhc/lsm303dlhc.c
Normal file
209
drivers/lsm303dlhc/lsm303dlhc.c
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup driver_lsm303dlhc
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver implementation for the LSM303DLHC light sensor
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "lsm303dlhc.h"
|
||||
#include "lsm303dlhc-internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
int lsm303dlhc_init(lsm303dlhc_t *dev, i2c_t i2c, gpio_t acc_pin, gpio_t mag_pin,
|
||||
uint8_t acc_address,
|
||||
lsm303dlhc_acc_sample_rate_t acc_sample_rate,
|
||||
lsm303dlhc_acc_scale_t acc_scale,
|
||||
uint8_t mag_address,
|
||||
lsm303dlhc_mag_sample_rate_t mag_sample_rate,
|
||||
lsm303dlhc_mag_gain_t mag_gain)
|
||||
{
|
||||
int res;
|
||||
char tmp;
|
||||
|
||||
dev->i2c = i2c;
|
||||
dev->acc_address = acc_address;
|
||||
dev->mag_address = mag_address;
|
||||
|
||||
i2c_init_master(i2c, I2C_SPEED_NORMAL);
|
||||
|
||||
DEBUG("lsm303dlhc reboot ");
|
||||
res = i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CTRL5_A, LSM303DLHC_REG_CTRL5_A_BOOT);
|
||||
DEBUG("[OK]");
|
||||
|
||||
/* configure accelerometer */
|
||||
/* enable all three axis and set sample rate */
|
||||
tmp = (LSM303DLHC_CTRL1_A_XEN
|
||||
| LSM303DLHC_CTRL1_A_YEN
|
||||
| LSM303DLHC_CTRL1_A_ZEN
|
||||
| acc_sample_rate);
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CTRL1_A, tmp);
|
||||
/* update on read, MSB @ low address, scale and high-resolution */
|
||||
tmp = (acc_scale | LSM303DLHC_CTRL4_A_HR);
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CTRL4_A, tmp);
|
||||
/* no interrupt generation */
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CTRL3_A, LSM303DLHC_CTRL3_A_I1_NONE);
|
||||
/* configure acc data ready pin */
|
||||
gpio_init_in(acc_pin, GPIO_NOPULL);
|
||||
|
||||
/* configure magnetometer and temperature */
|
||||
/* enable temperature output and set sample rate */
|
||||
tmp = LSM303DLHC_TEMP_EN | mag_sample_rate;
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_CRA_M, tmp);
|
||||
/* configure z-axis gain */
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_CRB_M, mag_gain);
|
||||
/* set continuous mode */
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_MR_M, LSM303DLHC_MAG_MODE_CONTINUOUS);
|
||||
/* configure mag data ready pin */
|
||||
gpio_init_in(mag_pin, GPIO_NOPULL);
|
||||
|
||||
return (res < 7) ? -1 : 0;
|
||||
}
|
||||
|
||||
int lsm303dlhc_read_acc(lsm303dlhc_t *dev, lsm303dlhc_3d_data_t *data)
|
||||
{
|
||||
int res;
|
||||
char tmp;
|
||||
|
||||
i2c_read_reg(dev->i2c, dev->acc_address, LSM303DLHC_REG_STATUS_A, &tmp);
|
||||
DEBUG("lsm303dlhc status: %x\n", tmp);
|
||||
DEBUG("lsm303dlhc: wait for acc values ... ");
|
||||
|
||||
res = i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_X_L_A, &tmp);
|
||||
data->x_axis = tmp;
|
||||
res += i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_X_H_A, &tmp);
|
||||
data->x_axis |= tmp<<8;
|
||||
res += i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_Y_L_A, &tmp);
|
||||
data->y_axis = tmp;
|
||||
res += i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_Y_H_A, &tmp);
|
||||
data->y_axis |= tmp<<8;
|
||||
res += i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_Z_L_A, &tmp);
|
||||
data->z_axis = tmp;
|
||||
res += i2c_read_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_OUT_Z_H_A, &tmp);
|
||||
data->z_axis |= tmp<<8;
|
||||
DEBUG("read ... ");
|
||||
|
||||
if (res < 6) {
|
||||
DEBUG("[!!failed!!]\n");
|
||||
return -1;
|
||||
}
|
||||
DEBUG("[done]\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsm303dlhc_read_mag(lsm303dlhc_t *dev, lsm303dlhc_3d_data_t *data)
|
||||
{
|
||||
int res;
|
||||
|
||||
DEBUG("lsm303dlhc: wait for mag values... ");
|
||||
while (gpio_read(GPIO_8) == 0){}
|
||||
|
||||
DEBUG("read ... ");
|
||||
|
||||
res = i2c_read_regs(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_OUT_X_H_M, (char*)data, 6);
|
||||
|
||||
if (res < 6) {
|
||||
DEBUG("[!!failed!!]\n");
|
||||
return -1;
|
||||
}
|
||||
DEBUG("[done]\n");
|
||||
|
||||
/* interchange y and z axis and fix endiness */
|
||||
int16_t tmp = data->y_axis;
|
||||
data->x_axis = ((data->x_axis<<8)|((data->x_axis>>8)&0xff));
|
||||
data->y_axis = ((data->z_axis<<8)|((data->z_axis>>8)&0xff));
|
||||
data->z_axis = ((tmp<<8)|((tmp>>8)&0xff));
|
||||
|
||||
/* compensate z-axis sensitivity */
|
||||
/* gain is currently hardcoded to LSM303DLHC_GAIN_5 */
|
||||
data->z_axis = ((data->z_axis * 400) / 355);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsm303dlhc_read_temp(lsm303dlhc_t *dev, int16_t *value)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = i2c_read_regs(dev->i2c, dev->mag_address, LSM303DLHC_REG_TEMP_OUT_H, (char*)value, 2);
|
||||
|
||||
if (res < 2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*value = (((*value) >> 8) & 0xff) | (*value << 8);
|
||||
|
||||
DEBUG("LSM303DLHC: raw temp: %i\n", *value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lsm303dlhc_disable(lsm303dlhc_t *dev)
|
||||
{
|
||||
int res;
|
||||
res = i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CTRL1_A, LSM303DLHC_CTRL1_A_POWEROFF);
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_MR_M, LSM303DLHC_MAG_MODE_SLEEP);
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address,
|
||||
LSM303DLHC_REG_CRA_M, LSM303DLHC_TEMP_DIS);
|
||||
|
||||
return (res < 3) ? -1 : 0;
|
||||
}
|
||||
|
||||
int lsm303dlhc_enable(lsm303dlhc_t *dev)
|
||||
{
|
||||
int res;
|
||||
char tmp = (LSM303DLHC_CTRL1_A_XEN
|
||||
| LSM303DLHC_CTRL1_A_YEN
|
||||
| LSM303DLHC_CTRL1_A_ZEN
|
||||
| LSM303DLHC_CTRL1_A_N1344HZ_L5376HZ);
|
||||
res = i2c_write_reg(dev->i2c, dev->acc_address, LSM303DLHC_REG_CTRL1_A, tmp);
|
||||
|
||||
tmp = (LSM303DLHC_CTRL4_A_BDU| LSM303DLHC_CTRL4_A_SCALE_2G | LSM303DLHC_CTRL4_A_HR);
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address, LSM303DLHC_REG_CTRL4_A, tmp);
|
||||
res += i2c_write_reg(dev->i2c, dev->acc_address, LSM303DLHC_REG_CTRL3_A, LSM303DLHC_CTRL3_A_I1_DRDY1);
|
||||
gpio_init_in(GPIO_2, GPIO_NOPULL);
|
||||
|
||||
tmp = LSM303DLHC_TEMP_EN | LSM303DLHC_TEMP_SAMPLE_75HZ;
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address, LSM303DLHC_REG_CRA_M, tmp);
|
||||
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_CRB_M, LSM303DLHC_GAIN_5);
|
||||
|
||||
res += i2c_write_reg(dev->i2c, dev->mag_address,
|
||||
LSM303DLHC_REG_MR_M, LSM303DLHC_MAG_MODE_CONTINUOUS);
|
||||
|
||||
gpio_init_in(GPIO_8, GPIO_NOPULL);
|
||||
|
||||
return (res < 6) ? -1 : 0;
|
||||
}
|
35
tests/driver_lsm303dlhc/Makefile
Normal file
35
tests/driver_lsm303dlhc/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
APPLICATION = driver_lsm303dlhc
|
||||
include ../Makefile.tests_common
|
||||
|
||||
FEATURES_REQUIRED = periph_i2c
|
||||
|
||||
# Define default pin mappings for some boards:
|
||||
ifneq (,$(filter iot-lab_M3,$(BOARD)))
|
||||
export TEST_LSM303DLHC_MAG_ADDR=30
|
||||
export TEST_LSM303DLHC_ACC_ADDR=25
|
||||
export TEST_LSM303DLHC_I2C ?=I2C_0
|
||||
endif
|
||||
|
||||
USEMODULE += lsm303dlhc
|
||||
USEMODULE += vtimer
|
||||
|
||||
ifneq (,$(TEST_LSM303DLHC_I2C))
|
||||
CFLAGS += -DTEST_LSM303DLHC_I2C=$(TEST_LSM303DLHC_I2C)
|
||||
else
|
||||
# set random default
|
||||
CFLAGS += -DTEST_LSM303DLHC_I2C=I2C_0
|
||||
endif
|
||||
ifneq (,$(TEST_LSM303DLHC_MAG_ADDR))
|
||||
CFLAGS += -DTEST_LSM303DLHC_MAG_ADDR=$(TEST_LSM303DLHC_MAG_ADDR)
|
||||
else
|
||||
# set random default
|
||||
CFLAGS += -DTEST_LSM303DLHC_MAG_ADDR=30
|
||||
endif
|
||||
ifneq (,$(TEST_LSM303DLHC_ACC_ADDR))
|
||||
CFLAGS += -DTEST_LSM303DLHC_ACC_ADDR=$(TEST_LSM303DLHC_ACC_ADDR)
|
||||
else
|
||||
# set random default
|
||||
CFLAGS += -DTEST_LSM303DLHC_ACC_ADDR=25
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
93
tests/driver_lsm303dlhc/main.c
Normal file
93
tests/driver_lsm303dlhc/main.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the LSM303DLHC accelerometer/magnetometer
|
||||
*
|
||||
* @author Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef TEST_LSM303DLHC_I2C
|
||||
#error "TEST_LSM303DLHC_I2C not defined"
|
||||
#endif
|
||||
#ifndef TEST_LSM303DLHC_MAG_ADDR
|
||||
#error "TEST_LSM303DLHC_MAG_ADDR not defined"
|
||||
#endif
|
||||
#ifndef TEST_LSM303DLHC_ACC_ADDR
|
||||
#error "TEST_LSM303DLHC_ACC_ADDR not defined"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "lsm303dlhc.h"
|
||||
|
||||
#define SLEEP (100 * 1000U)
|
||||
#define ACC_S_RATE LSM303DLHC_ACC_SAMPLE_RATE_10HZ
|
||||
#define ACC_SCALE LSM303DLHC_ACC_SCALE_2G
|
||||
#define MAG_S_RATE LSM303DLHC_MAG_SAMPLE_RATE_75HZ
|
||||
#define MAG_GAIN LSM303DLHC_MAG_GAIN_400_355_GAUSS
|
||||
#define ACC_PIN GPIO_2
|
||||
#define MAG_PIN GPIO_8
|
||||
|
||||
int main(void)
|
||||
{
|
||||
lsm303dlhc_t dev;
|
||||
int16_t temp_value;
|
||||
lsm303dlhc_3d_data_t mag_value;
|
||||
lsm303dlhc_3d_data_t acc_value;
|
||||
|
||||
puts("LSM303DLHC temperature test application\n");
|
||||
printf("Initializing LSM303DLHC sensor at I2C_%i... ", TEST_LSM303DLHC_I2C);
|
||||
|
||||
if (lsm303dlhc_init(&dev, TEST_LSM303DLHC_I2C, ACC_PIN, MAG_PIN,
|
||||
TEST_LSM303DLHC_ACC_ADDR, ACC_S_RATE, ACC_SCALE,
|
||||
TEST_LSM303DLHC_MAG_ADDR, MAG_S_RATE, MAG_GAIN) == 0) {
|
||||
puts("[OK]\n");
|
||||
}
|
||||
else {
|
||||
puts("[Failed]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (lsm303dlhc_read_acc(&dev, &acc_value) == 0) {
|
||||
printf("Accelerometer x: %i y: %i z: %i\n", acc_value.x_axis,
|
||||
acc_value.y_axis,
|
||||
acc_value.z_axis);
|
||||
}
|
||||
else {
|
||||
puts("\nFailed reading accelerometer values\n");
|
||||
}
|
||||
if (lsm303dlhc_read_temp(&dev, &temp_value) == 0) {
|
||||
printf("Temperature value: %i degrees\n", temp_value);
|
||||
}
|
||||
else {
|
||||
puts("\nFailed reading value\n");
|
||||
}
|
||||
|
||||
if (lsm303dlhc_read_mag(&dev, &mag_value) == 0) {
|
||||
printf("Magnetometer x: %i y: %i z: %i\n", mag_value.x_axis,
|
||||
mag_value.y_axis,
|
||||
mag_value.z_axis);
|
||||
}
|
||||
else {
|
||||
puts("\nFailed reading magnetometer values\n");
|
||||
}
|
||||
|
||||
vtimer_usleep(SLEEP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user