1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 04:52:59 +01:00

drivers: added L3G4200D gyroscope driver

This commit is contained in:
Hauke Petersen 2014-10-20 20:01:48 +02:00 committed by Hauke Petersen
parent 4555b9ea7a
commit da64a7f438
6 changed files with 374 additions and 0 deletions

View File

@ -52,6 +52,9 @@ endif
ifneq (,$(filter lps331ap,$(USEMODULE)))
DIRS += lps331ap
endif
ifneq (,$(filter l3g4200d,$(USEMODULE)))
DIRS += l3g4200d
endif
ifneq (,$(filter netdev_802154,$(USEMODULE)))
DIRS += netdev/802154
endif

View File

@ -19,3 +19,6 @@ endif
ifneq (,$(filter lsm303dlhc,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lsm303dlhc/include
endif
ifneq (,$(filter l3g4200d,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/l3g4200d/include
endif

143
drivers/include/l3g4200d.h Normal file
View File

@ -0,0 +1,143 @@
/*
* 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_l3g4200d L3G4200D gyroscope
* @ingroup drivers
* @brief Device driver for the L3G4200D gyroscope
* @{
*
* @file
* @brief Device driver interface for the L3G4200D gyroscope
*
* @note The current state of the driver only implements a very basic polling mode.
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __L3G4200D_H
#define __L3G4200D_H
#include <stdint.h>
#include "periph/i2c.h"
#include "periph/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The sensors default I2C address
*/
#define L3G4200D_DEFAULT_ADDRESS 0x68
/**
* @brief Device descriptor for L3G4200D sensors
*/
typedef struct {
i2c_t i2c; /**< I2C device the sensor is connected to */
uint8_t addr; /**< the sensors slave address on the I2C bus */
gpio_t int1; /**< INT1 pin */
gpio_t int2; /**< INT2 (DRDY) pin */
int32_t scale; /**< scaling factor to normalize results */
} l3g4200d_t;
/**
* @brief Result vector for gyro measurement
*/
typedef struct {
int16_t acc_x; /**< roll rate in dgs (degree per second) */
int16_t acc_y; /**< pitch rate in dgs */
int16_t acc_z; /**< yaw rate in dgs */
} l3g4200d_data_t;
/**
* @brief Measurement scale for the gyro
*/
typedef enum {
L3G4200D_SCALE_250DPS = 0x0, /**< scale: 250 degree per second */
L3G4200D_SCALE_500DPS = 0x1, /**< scale: 500 degree per second */
L3G4200D_SCALE_2000DPS = 0x2 /**< scale: 2000 degree per second */
} l3g4200d_scale_t;
/**
* @brief Sampling frequency and bandwidth settings for the gyro
*/
typedef enum {
L3G4200D_MODE_100_12 = 0x0, /**< data rate: 100Hz, cut-off: 12.5Hz */
L3G4200D_MODE_100_25 = 0x1, /**< data rate: 100Hz, cut-off: 25Hz */
L3G4200D_MODE_200_12 = 0x4, /**< data rate: 200Hz, cut-off: 12.5Hz */
L3G4200D_MODE_200_25 = 0x5, /**< data rate: 200Hz, cut-off: 25Hz */
L3G4200D_MODE_200_50 = 0x6, /**< data rate: 200Hz, cut-off: 50Hz */
L3G4200D_MODE_200_70 = 0x7, /**< data rate: 200Hz, cut-off: 70Hz */
L3G4200D_MODE_400_20 = 0x8, /**< data rate: 400Hz, cut-off: 20Hz */
L3G4200D_MODE_400_25 = 0x9, /**< data rate: 400Hz, cut-off: 25Hz */
L3G4200D_MODE_400_50 = 0xa, /**< data rate: 400Hz, cut-off: 50Hz */
L3G4200D_MODE_400_110 = 0xb, /**< data rate: 400Hz, cut-off: 110Hz */
L3G4200D_MODE_800_30 = 0xc, /**< data rate: 800Hz, cut-off: 30Hz */
L3G4200D_MODE_800_35 = 0xd, /**< data rate: 800Hz, cut-off: 35Hz */
L3G4200D_MODE_800_50 = 0xe, /**< data rate: 800Hz, cut-off: 50Hz */
L3G4200D_MODE_800_110 = 0xf /**< data rate: 800Hz, cut-off: 110Hz */
} l3g4200d_mode_t;
/**
* @brief Initialize a gyro
*
* @param[out] dev device descriptor of sensor to initialize
* @param[in] i2c I2C bus the gyro is connected to
* @param[in] address gyro's I2C slave address
* @param[in] int1_pin INT pin the gyro is connected to
* @param[in] int2_pin DRDY pin the gyro is connected to
* @param[in] mode bandwidth and sampling rate settings
* @param[in] scale scaling of results
*
* @return 0 on success
* @return -1 on error
*/
int l3g4200d_init(l3g4200d_t *dev, i2c_t i2c, uint8_t address,
gpio_t int1_pin, gpio_t int2_pin,
l3g4200d_mode_t mode, l3g4200d_scale_t scale);
/**
* @brief Read angular speed value in degree per second from gyro
*
* @param[in] dev device descriptor of gyro
* @param[out] acc_data result vector in dps per axis
*
* @return 0 on success
* @return -1 on error
*/
int l3g4200d_read(l3g4200d_t *dev, l3g4200d_data_t *acc_data);
/**
* @brief Power-up the given device
*
* @param[in] dev device to enable
*
* @return 0 on success
* @return -1 on error
*/
int l3g4200d_enable(l3g4200d_t *dev);
/**
* @brief Power-down the given device
*
* @param[in] dev device to power-down
*
* @return 0 on success
* @return -1 on error
*/
int l3g4200d_disable(l3g4200d_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* __L3G4200D_H */
/** @} */

View File

@ -0,0 +1,3 @@
MODULE = l3g4200d
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,94 @@
/*
* 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_l3g4200d
* @{
*
* @file
* @brief Definitions for the L3G4200D gyroscope
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*/
#ifndef __L3G4200D_REGS_H
#define __L3G4200D_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Flag for reading multiple bytes
*/
#define L3G4200D_AUTOINC 0x80
/**
* @name L3G4200D register definitions
* @{
*/
#define L3G4200D_REG_WHO_AM_I 0x0f
#define L3G4200D_REG_CTRL1 0x20
#define L3G4200D_REG_CTRL2 0x21
#define L3G4200D_REG_CTRL3 0x22
#define L3G4200D_REG_CTRL4 0x23
#define L3G4200D_REG_CTRL5 0x24
#define L3G4200D_REG_REF 0x25
#define L3G4200D_REG_OUT_TEMP 0x26
#define L3G4200D_REG_STATUS 0x27
#define L3G4200D_REG_OUT_X_L 0x28
#define L3G4200D_REG_OUT_X_H 0x29
#define L3G4200D_REG_OUT_Y_L 0x2a
#define L3G4200D_REG_OUT_Y_H 0x2b
#define L3G4200D_REG_OUT_Z_L 0x2c
#define L3G4200D_REG_OUT_Z_H 0x2d
#define L3G4200D_REG_FIFO_CTRL 0x2e
#define L3G4200D_REG_FIFO_SRC 0x2f
#define L3G4200D_REG_INT1_CFG 0x30
#define L3G4200D_REG_INT1_SRC 0x31
#define L3G4200D_REG_INT1_THS_XH 0x32
#define L3G4200D_REG_INT1_THS_XL 0x33
#define L3G4200D_REG_INT1_THS_YH 0x34
#define L3G4200D_REG_INT1_THS_YL 0x35
#define L3G4200D_REG_INT1_THS_ZL 0x36
#define L3G4200D_REG_INT1_THS_ZH 0x37
#define L3G4200D_REG_INT1_DURATION 0x38
/** @} */
/**
* @name CTRL1 bitfields
* @{
*/
#define L3G4200D_CTRL1_PD 0x08
#define L3G4200D_CTRL1_ZEN 0x04
#define L3G4200D_CTRL1_YEN 0x02
#define L3G4200D_CTRL1_XEN 0x01
#define L3G4200D_CTRL1_ALLON 0x0f
#define L3G4200D_CTRL1_MODE_POS (4)
/** @} */
/**
* @name CTRL4 bitfields
*/
#define L3G4200D_CTRL4_BDU 0x80
#define L3G4200D_CTRL4_BLE 0x40
#define L3G4200D_CTRL4_FS1 0x20
#define L3G4200D_CTRL4_FS2 0x10
#define L3G4200D_CTRL4_ST1 0x04
#define L3G4200D_CTRL4_ST2 0x02
#define L3G4200D_CTRL4_SIM 0x01
#define L3G4200D_CTRL4_FS_POS (4)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* __L3G4200D_REGS_H */
/** @} */

128
drivers/l3g4200d/l3g4200d.c Normal file
View File

@ -0,0 +1,128 @@
#/*
* 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_l3g4200d
* @{
*
* @file
* @brief Device driver implementation for the L3G4200D gyroscope
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
*
* @}
*/
#include <stdint.h>
#include "l3g4200d.h"
#include "l3g4200d-regs.h"
#include "periph/i2c.h"
#include "periph/gpio.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define I2C_SPEED I2C_SPEED_FAST
#define MAX_VAL 0x7fff
int l3g4200d_init(l3g4200d_t *dev, i2c_t i2c, uint8_t address,
gpio_t int1_pin, gpio_t int2_pin,
l3g4200d_mode_t mode, l3g4200d_scale_t scale)
{
char tmp;
/* initialize the I2C bus */
if (i2c_init_master(i2c, I2C_SPEED) < 0) {
return -1;
}
/* write device descriptor */
dev->i2c = i2c;
dev->addr = address;
dev->int1 = int1_pin;
dev->int2 = int2_pin;
/* set scale */
switch (scale) {
case L3G4200D_SCALE_250DPS:
dev->scale = 250;
break;
case L3G4200D_SCALE_500DPS:
dev->scale = 500;
break;
case L3G4200D_SCALE_2000DPS:
dev->scale = 2000;
break;
default:
dev->scale = 500;
break;
}
/* configure CTRL_REG1 */
tmp = ((mode & 0xf) << L3G4200D_CTRL1_MODE_POS) | L3G4200D_CTRL1_ALLON;
if (i2c_write_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL1, tmp) != 1) {
return -1;
}
tmp = ((scale & 0x3) << L3G4200D_CTRL4_FS_POS) | L3G4200D_CTRL4_BDU;
if (i2c_write_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL4, tmp) != 1) {
return -1;
}
return 0;
}
int l3g4200d_read(l3g4200d_t *dev, l3g4200d_data_t *data)
{
char tmp[6];
int16_t res;
/* get acceleration in x direction */
i2c_read_regs(dev->i2c, dev->addr, L3G4200D_REG_OUT_X_L | L3G4200D_AUTOINC, tmp, 6);
/* parse and normalize data into result vector */
res = (tmp[1] << 8) | tmp[0];
data->acc_x = (int16_t)((dev->scale * res) / MAX_VAL);
res = (tmp[3] << 8) | tmp[2];
data->acc_y = (int16_t)((dev->scale * res) / MAX_VAL);
res = (tmp[5] << 8) | tmp[4];
data->acc_z = (int16_t)((dev->scale * res) / MAX_VAL);
return 0;
}
int l3g4200d_enable(l3g4200d_t *dev)
{
char tmp;
int res;
res = i2c_read_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL1, &tmp);
if (res < 1) {
return res;
}
tmp |= L3G4200D_CTRL1_PD;
if (i2c_write_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL1, tmp) != 1) {
return -1;
}
return 0;
}
int l3g4200d_disable(l3g4200d_t *dev)
{
char tmp;
int res;
res = i2c_read_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL1, &tmp);
if (res < 1) {
return res;
}
tmp &= ~L3G4200D_CTRL1_PD;
if (i2c_write_reg(dev->i2c, dev->addr, L3G4200D_REG_CTRL1, tmp) != 1) {
return -1;
}
return 0;
}