mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
317 lines
11 KiB
C
317 lines
11 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_itg320x ITG320X 3-axis gyroscope
|
|
* @ingroup drivers_sensors
|
|
* @ingroup drivers_saul
|
|
* @brief Device driver for InvenSense ITG320X 3-axis gyroscope
|
|
*
|
|
* The driver can be used with InvenSense ITG3200, ITG3205, and MPU3050.
|
|
* The latter one can be used only with reduced feature set.
|
|
*
|
|
* The driver implements polling mode as well as interrupt mode. Thus,
|
|
* the application may use two different approaches to retrieve new data,
|
|
* either
|
|
*
|
|
* - periodically fetching the data at a rate lower than the sensor's
|
|
* output data rate (ODR), or
|
|
* - fetching the data when the data-ready interrupt is triggered.
|
|
*
|
|
* To use the latter approach, module `itg320x_int` has to be enabled and the
|
|
* GPIO to which the sensor's **INT** output pin is connected has to be
|
|
* configured.
|
|
*
|
|
* This driver provides @ref drivers_saul capabilities.
|
|
*
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Device driver for InvenSense ITG320X 3-axis gyroscope
|
|
*
|
|
* @author Gunar Schorcht <gunar@schorcht.net>
|
|
*/
|
|
|
|
#ifndef ITG320X_H
|
|
#define ITG320X_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "periph/gpio.h"
|
|
#include "periph/i2c.h"
|
|
|
|
/**
|
|
* @name I2C addresses
|
|
* @{
|
|
*/
|
|
#define ITG320X_I2C_ADDRESS_1 (0x68) /**< AD0 pin low */
|
|
#define ITG320X_I2C_ADDRESS_2 (0x69) /**< AD0 pin high */
|
|
/** @} */
|
|
|
|
/** ITG320X chip id defined in Who Am I */
|
|
#define ITG320X_ID (0x68)
|
|
|
|
/**
|
|
* @brief Named return values
|
|
*/
|
|
typedef enum {
|
|
ITG320X_OK = 0, /**< success */
|
|
ITG320X_ERROR_I2C = -1, /**< I2C communication error */
|
|
ITG320X_ERROR_WRONG_ID = -2, /**< wrong id read */
|
|
ITG320X_ERROR_NO_DATA = -3, /**< no data are available */
|
|
ITG320X_ERROR_RAW_DATA = -4, /**< reading raw data failed */
|
|
} itg320x_error_codes_t;
|
|
|
|
/**
|
|
* @brief Low pass filter bandwidth
|
|
*
|
|
* @note Low pass filter bandwidth determines the internal sample rate (ISR).
|
|
* The internal sample rate (ISR) together with sample rate divider
|
|
* (ISR_DIV) determines the output data rate ODR = ISR / (ISR_DIV + 1)
|
|
* where internal sample rate (ISR) is 8 kHz for #ITG320X_LPF_BW_256,
|
|
* or 1 kHz otherwise.
|
|
*/
|
|
typedef enum {
|
|
ITG320X_LPF_BW_256 = 0, /**< 256 Hz, ISR = 8 kHz */
|
|
ITG320X_LPF_BW_188, /**< 188 Hz, ISR = 1 kHz */
|
|
ITG320X_LPF_BW_98, /**< 98 Hz, ISR = 1 kHz */
|
|
ITG320X_LPF_BW_42, /**< 42 Hz, ISR = 1 kHz */
|
|
ITG320X_LPF_BW_20, /**< 20 Hz, ISR = 1 kHz */
|
|
ITG320X_LPF_BW_10, /**< 10 Hz, ISR = 1 kHz */
|
|
ITG320X_LPF_BW_5, /**< 5 Hz, ISR = 1 kHz (default) */
|
|
} itg320x_lpf_bw_t;
|
|
|
|
/**
|
|
* @brief Logic level for INT output pin (ITG320X_REG_INT_CFG<7>)
|
|
*/
|
|
typedef enum {
|
|
ITG320X_INT_HIGH = 0x00, /**< INT output is active high (default) */
|
|
ITG320X_INT_LOW = 0x80, /**< INT output is active low */
|
|
} itg320x_int_level_t;
|
|
|
|
/**
|
|
* @brief Drive type for INT output pin (ITG320X_REG_INT_CFG<6>)
|
|
*/
|
|
typedef enum {
|
|
ITG320X_INT_PUSH_PULL = 0x00, /**< INT output is of type push/pull (default) */
|
|
ITG320X_INT_OPEN_DRAIN = 0x40 /**< INT output is of type open drain */
|
|
} itg320x_int_drive_t;
|
|
|
|
/**
|
|
* @brief Clock source selection (ITG320X_REG_PWR_MGM<2:0>)
|
|
*/
|
|
typedef enum {
|
|
ITG320X_CLK_INTERNAL = 0, /**< Internal oscillator */
|
|
ITG320X_CLK_PLL_X_GYRO, /**< PLL with X Gyro reference (default) */
|
|
ITG320X_CLK_PLL_Y_GYRO, /**< PLL with X Gyro reference */
|
|
ITG320X_CLK_PLL_Z_GYRO, /**< PLL with X Gyro reference */
|
|
ITG320X_CLK_PLL_32K, /**< PLL with external 32.768 kHz reference */
|
|
ITG320X_CLK_PLL_19M, /**< PLL with external 19.2 MHz reference */
|
|
} itg320x_clk_sel_t;
|
|
|
|
/**
|
|
* @brief Angular rate values in tenths of a degree per second
|
|
*/
|
|
typedef struct {
|
|
int16_t x; /**< angular rate x-axis (roll) */
|
|
int16_t y; /**< angular rate y-axis (pitch) */
|
|
int16_t z; /**< angular rate y-axis (yaw) */
|
|
} itg320x_data_t;
|
|
|
|
/**
|
|
* @brief Raw data set as two complements
|
|
*
|
|
* According to the sensor sensitivity of 1/14.375 degrees per second, the
|
|
* raw data values have to be divided by 14.375 to obtain the measurements
|
|
* in degrees per second.
|
|
*/
|
|
typedef struct {
|
|
int16_t x; /**< angular rate x-axis as 16 bit two's complements (roll) */
|
|
int16_t y; /**< angular rate y-axis as 16 bit two's complements (pitch) */
|
|
int16_t z; /**< angular rate z-axis as 16 bit two's complements (yaw) */
|
|
} itg320x_raw_data_t;
|
|
|
|
/**
|
|
* @brief ITG320X device initialization parameters
|
|
*/
|
|
typedef struct {
|
|
i2c_t dev; /**< I2C device (default I2C_DEV(0)) */
|
|
uint8_t addr; /**< I2C slave address (default #ITG320X_I2C_ADDRESS_1) */
|
|
|
|
uint8_t isr_div; /**< Internal sample rate divider ISR_DIV (default 99)
|
|
ODR = ISR / (ISR_DIV + 1) where internal sample rate
|
|
is 1 kHz or 8 kHz dependent on the low pass filter
|
|
bandwidth #lpf_bw */
|
|
|
|
itg320x_lpf_bw_t lpf_bw; /**< Low pass filter bandwidth
|
|
(default #ITG320X_LPF_BW_5, ISR 1 kHz) */
|
|
itg320x_clk_sel_t clk_sel; /**< Clock source selection
|
|
(default ITG320X_CLK_PLL_X_GYRO) */
|
|
|
|
#if MODULE_ITG320X_INT || DOXYGEN
|
|
gpio_t int_pin; /**< DRDY interrupt pin: #GPIO_UNDEF if
|
|
not used */
|
|
itg320x_int_level_t int_level; /**< Logic level for INT output pin
|
|
(default #ITG320X_INT_LOW) */
|
|
itg320x_int_drive_t int_drive; /**< Drive type for INT output pin
|
|
(default #ITG320X_INT_PUSH_PULL */
|
|
#endif /* MODULE_ITG320X_INT || DOXYGEN */
|
|
} itg320x_params_t;
|
|
|
|
/**
|
|
* @brief ITG320X sensor device data structure type
|
|
*/
|
|
typedef struct {
|
|
itg320x_params_t params; /**< device initialization parameters */
|
|
} itg320x_t;
|
|
|
|
#if MODULE_ITG320X_INT || DOXYGEN
|
|
/**
|
|
* @brief ITG320X data ready interrupt (DRDY) callback function type
|
|
*
|
|
* Function prototype for the function which is called on DRDY interrupt if
|
|
* the interrupt is activated by #itg320x_init_int
|
|
*
|
|
* @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 (*itg320x_drdy_int_cb_t)(void *);
|
|
|
|
#endif /* MODULE_ITG320X_INT || DOXYGEN */
|
|
|
|
/**
|
|
* @brief Initialize the ITG320X 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 ITG320X sensor to be initialized
|
|
* @param[in] params ITG320X initialization parameters
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_init(itg320x_t *dev, const itg320x_params_t *params);
|
|
|
|
#if MODULE_ITG320X_INT || DOXYGEN
|
|
/**
|
|
* @brief Initialize and activate the DRDY interrupt of ITG320X 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 `itg320x_int` is enabled.
|
|
*
|
|
* @param[in] dev device descriptor of ITG320X sensor
|
|
* @param[in] cb function called when DRDY interrupt is triggered
|
|
* @param[in] arg argument for the callback function
|
|
*/
|
|
int itg320x_init_int(const itg320x_t *dev, itg320x_drdy_int_cb_t cb, void *arg);
|
|
|
|
#endif /* MODULE_ITG320X_INT || DOXYGEN */
|
|
|
|
/**
|
|
* @brief Data-ready status function
|
|
*
|
|
* The function checks the status register and returns
|
|
*
|
|
* @param[in] dev device descriptor of ITG320X sensor
|
|
*
|
|
* @retval ITG320X_OK new data available
|
|
* @retval ITG320X_ERROR_NO_DATA no new data available
|
|
* @retval ITG320X_ERROR_* negative error code,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_data_ready(const itg320x_t *dev);
|
|
|
|
/**
|
|
* @brief Read one sample of angular rates in tenths of a degree per second
|
|
*
|
|
* Raw magnetometer data are read from the sensor and normalized with
|
|
* respect to full scale +-2000 dps. Angular rate values are given in
|
|
* tenths of a degrees per second:
|
|
*
|
|
* @param[in] dev device descriptor of ITG320X sensor
|
|
* @param[out] data result vector in tenths of a degrees per second
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_read(const itg320x_t *dev, itg320x_data_t *data);
|
|
|
|
/**
|
|
* @brief Read one sample of raw sensor data as 16 bit two's complements
|
|
*
|
|
* @param[in] dev device descriptor of ITG320X sensor
|
|
* @param[out] raw raw data vector
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_read_raw(const itg320x_t *dev, itg320x_raw_data_t *raw);
|
|
|
|
/**
|
|
* @brief Read temperature in tenths of a degree Celsius
|
|
*
|
|
* @param[in] dev device descriptor of ITG320X sensor
|
|
* @param[out] temp temperature tenths of a degree Celsius
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_read_temp(const itg320x_t *dev, int16_t* temp);
|
|
|
|
/**
|
|
* @brief Power down the sensor
|
|
*
|
|
* Changes the sensor operation mode to sleep mode in which almost all
|
|
* including the gyros are switched off.
|
|
*
|
|
* @param[in] dev Device descriptor of ITG320X device to read from
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_power_down(itg320x_t *dev);
|
|
|
|
/**
|
|
* @brief Power up the sensor
|
|
*
|
|
* Swichtes the sensor back into active operation mode. It takes
|
|
* up to 20 ms since the gyros have to be switched on again.
|
|
*
|
|
* @param[in] dev Device descriptor of ITG320X device to read from
|
|
*
|
|
* @retval ITG320X_OK on success
|
|
* @retval ITG320X_ERROR_* a negative error code on error,
|
|
* see #itg320x_error_codes_t
|
|
*/
|
|
int itg320x_power_up(itg320x_t *dev);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ITG320X_H */
|
|
/** @} */
|