diff options
author | Mario Tesi <mario.tesi@st.com> | 2018-12-11 09:21:07 +0100 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-03-06 06:51:38 -0800 |
commit | 9b3355b2f3fdc921b72a35a7bb2ae6cfe7395faa (patch) | |
tree | 14f4a6dded2b75f126e953dc39d0426755a3c140 /driver/accelgyro_lsm6dso.h | |
parent | 247f511b36985c840d7f70f173129e85e62fcf7f (diff) | |
download | chrome-ec-9b3355b2f3fdc921b72a35a7bb2ae6cfe7395faa.tar.gz |
driver: lsm6dso: Add support to LSM6DSO IMU
Added support to LSM6DSO IMU sensor.
Features included in this driver are:
- Basic Sensor Read acc/gyro data
- ODR and FS runtime configuration
- FIFO water mark interrupt
- Shared commons function with ST MEMs devices
BUG=none
BRANCH=master
TEST=Tested on discovery target BOARD with
LSM6DSO connected to EC i2c master bus and motion
sense task running.
Commands used to test LSM6DSO device are:
- accelinit
- accelrange
- accelinfo
All basic features tested, including:
1) ODR change:
- accelrate 0 [13000:208000]
- accelrate 1 [13000:208000]
2) FS Range change:
- accelrange 0 [2:16]
- accelrange 1 [250:2000]
3) Interrupt on FIFO water mark
Signed-off-by: Mario Tesi <mario.tesi@st.com>
Change-Id: If2984f7d0d30b0ef475e0525aca2bc365aa4fe21
Signed-off-by: Mario Tesi <mario.tesi@st.com>
Reviewed-on: https://chromium-review.googlesource.com/1371364
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Enrico Granata <egranata@chromium.org>
Reviewed-by: Enrico Granata <egranata@chromium.org>
Diffstat (limited to 'driver/accelgyro_lsm6dso.h')
-rw-r--r-- | driver/accelgyro_lsm6dso.h | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/driver/accelgyro_lsm6dso.h b/driver/accelgyro_lsm6dso.h new file mode 100644 index 0000000000..7748c7fe94 --- /dev/null +++ b/driver/accelgyro_lsm6dso.h @@ -0,0 +1,233 @@ +/* Copyright 2019 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* LSM6DSO Accel and Gyro driver for Chrome EC */ + +#ifndef __CROS_EC_ACCELGYRO_LSM6DSO_H +#define __CROS_EC_ACCELGYRO_LSM6DSO_H + +#include "stm_mems_common.h" + +#define LSM6DSO_I2C_ADDR(__x) (__x << 1) + +/* + * 7-bit address is 110101xb. Where 'x' is determined + * by the voltage on the ADDR pin + */ +#define LSM6DSO_ADDR0 LSM6DSO_I2C_ADDR(0x6a) +#define LSM6DSO_ADDR1 LSM6DSO_I2C_ADDR(0x6b) + +/* Access to embedded sensor hub register bank */ +#define LSM6DSO_FUNC_CFG_ACC_ADDR 0x01 +#define LSM6DSO_FUNC_CFG_EN 0x80 + +/* Who Am I */ +#define LSM6DSO_WHO_AM_I_REG 0x0f +#define LSM6DSO_WHO_AM_I 0x6c + +/* Common defines for Acc and Gyro sensors */ +#define LSM6DSO_EN_BIT 0x01 +#define LSM6DSO_DIS_BIT 0x00 + +#define LSM6DSO_GYRO_OUT_X_L_ADDR 0x22 +#define LSM6DSO_ACCEL_OUT_X_L_ADDR 0x28 + +#define LSM6DSO_CTRL1_ADDR 0x10 +#define LSM6DSO_CTRL2_ADDR 0x11 +#define LSM6DSO_CTRL3_ADDR 0x12 +#define LSM6DSO_SW_RESET 0x01 +#define LSM6DSO_IF_INC 0x04 +#define LSM6DSO_PP_OD 0x10 +#define LSM6DSO_H_L_ACTIVE 0x20 +#define LSM6DSO_BDU 0x40 + +#define LSM6DSO_CTRL4_ADDR 0x13 +#define LSM6DSO_INT2_ON_INT1_MASK 0x20 + +#define LSM6DSO_CTRL5_ADDR 0x14 +#define LSM6DSO_CTRL6_ADDR 0x15 +#define LSM6DSO_CTRL7_ADDR 0x16 +#define LSM6DSO_CTRL8_ADDR 0x17 +#define LSM6DSO_CTRL9_ADDR 0x18 + +#define LSM6DSO_CTRL10_ADDR 0x19 +#define LSM6DSO_TIMESTAMP_EN 0x20 + +#define LSM6DSO_STATUS_REG 0x1e + +/* Output data rate registers and masks */ +#define LSM6DSO_ODR_REG(_sensor) \ + (LSM6DSO_CTRL1_ADDR + (_sensor)) +#define LSM6DSO_ODR_MASK 0xf0 + +/* Hardware FIFO size in byte */ +#define LSM6DSO_MAX_FIFO_SIZE 4096 +#define LSM6DSO_MAX_FIFO_LENGTH (LSM6DSO_MAX_FIFO_SIZE / OUT_XYZ_SIZE) + +/* FIFO decimator registers and bitmask */ +#define LSM6DSO_FIFO_CTRL1_ADDR 0x07 +#define LSM6DSO_FIFO_CTRL2_ADDR 0x08 + +#define LSM6DSO_FIFO_CTRL3_ADDR 0x09 +#define LSM6DSO_FIFO_ODR_XL_MASK 0x0f +#define LSM6DSO_FIFO_ODR_G_MASK 0xf0 + +#define LSM6DSO_FIFO_CTRL4_ADDR 0x0a +#define LSM6DSO_FIFO_MODE_MASK 0x07 + +#define LSM6DSO_INT1_CTRL 0x0d +#define LSM6DSO_INT2_CTRL 0x0e +#define LSM6DSO_INT_FIFO_TH 0x08 +#define LSM6DSO_INT_FIFO_OVR 0x10 +#define LSM6DSO_INT_FIFO_FULL 0x20 + +#define LSM6DSO_FIFO_STS1_ADDR 0x3a +#define LSM6DSO_FIFO_STS2_ADDR 0x3b +#define LSM6DSO_FIFO_DIFF_MASK 0x07ff +#define LSM6DSO_FIFO_FULL 0x2000 +#define LSM6DSO_FIFO_DATA_OVR 0x4000 +#define LSM6DSO_FIFO_WATERMARK 0x8000 + +/* Out FIFO data register */ +#define LSM6DSO_FIFO_DATA_ADDR_TAG 0x78 + +/* Registers value for supported FIFO mode */ +#define LSM6DSO_FIFO_MODE_BYPASS_VAL 0x00 +#define LSM6DSO_FIFO_MODE_CONTINUOUS_VAL 0x06 + +/* Define device available in FIFO pattern */ +enum lsm6dso_dev_fifo { + LSM6DSO_FIFO_DEV_INVALID = -1, + LSM6DSO_FIFO_DEV_GYRO = 0, + LSM6DSO_FIFO_DEV_ACCEL, + LSM6DSO_FIFO_DEV_NUM, +}; + +/* Define FIFO data pattern, tag and len */ +#define LSM6DSO_SAMPLE_SIZE 6 +#define LSM6DSO_TS_SAMPLE_SIZE 4 +#define LSM6DSO_TAG_SIZE 1 +#define LSM6DSO_FIFO_SAMPLE_SIZE LSM6DSO_SAMPLE_SIZE + LSM6DSO_TAG_SIZE +#define LSM6DSO_MAX_FIFO_DEPTH 416 + +enum lsm6dso_tag_fifo { + LSM6DSO_GYRO_TAG = 0x01, + LSM6DSO_ACC_TAG = 0x02, +}; + +struct lsm6dso_fstatus { + uint16_t len; + uint16_t pattern; +}; + +/* Absolute maximum rate for Acc and Gyro sensors */ +#define LSM6DSO_ODR_MIN_VAL 13000 +#define LSM6DSO_ODR_MAX_VAL \ + MOTION_MAX_SENSOR_FREQUENCY(416000, 13000) + +/* ODR reg value from selected data rate in mHz */ +#define LSM6DSO_ODR_TO_REG(_odr) (__fls(_odr / LSM6DSO_ODR_MIN_VAL) + 1) + +#define LSM6DSO_FIFO_ODR_TO_REG(_s) \ + (_s->type == MOTIONSENSE_TYPE_ACCEL ? LSM6DSO_FIFO_ODR_XL_MASK : \ + LSM6DSO_FIFO_ODR_G_MASK) + +/* Normalized ODR values from selected data rate in mHz */ +#define LSM6DSO_REG_TO_ODR(_reg) (LSM6DSO_ODR_MIN_VAL << (_reg - 1)) + +/* Full Scale ranges value and gain for Acc */ +#define LSM6DSO_FS_LIST_NUM 4 + +#define LSM6DSO_ACCEL_FS_ADDR 0x10 +#define LSM6DSO_ACCEL_FS_MASK 0x0c + +#define LSM6DSO_ACCEL_FS_2G_VAL 0x00 +#define LSM6DSO_ACCEL_FS_4G_VAL 0x02 +#define LSM6DSO_ACCEL_FS_8G_VAL 0x03 +#define LSM6DSO_ACCEL_FS_16G_VAL 0x01 + +#define LSM6DSO_ACCEL_FS_MAX_VAL 16 + +/* Accel reg value from Full Scale range */ +static inline uint8_t lsm6dso_accel_fs_reg(int fs) +{ + uint8_t ret; + + switch(fs) { + case 2: + ret = LSM6DSO_ACCEL_FS_2G_VAL; + break; + case 16: + ret = LSM6DSO_ACCEL_FS_16G_VAL; + break; + default: + ret = __fls(fs); + break; + } + + return ret; +} + +/* Accel normalized FS value from Full Scale */ +#define LSM6DSO_ACCEL_NORMALIZE_FS(_fs) (1 << __fls(_fs)) + +/* Full Scale range value and gain for Gyro */ +#define LSM6DSO_GYRO_FS_ADDR 0x11 +#define LSM6DSO_GYRO_FS_MASK 0x0c + +/* Minimal Gyro range in mDPS */ +#define LSM6DSO_GYRO_FS_MIN_VAL_MDPS ((8750 << 15) / 1000) +#define LSM6DSO_GYRO_FS_MAX_REG_VAL 3 + +/* Gyro reg value for Full Scale selection in DPS */ +#define LSM6DSO_GYRO_FS_REG(_fs) \ + __fls(MAX(1, (_fs * 1000) / LSM6DSO_GYRO_FS_MIN_VAL_MDPS)) + +/* Gyro normalized FS value (in DPS) from Full Scale register */ +#define LSM6DSO_GYRO_NORMALIZE_FS(_reg) \ + ((LSM6DSO_GYRO_FS_MIN_VAL_MDPS << (_reg)) / 1000) + +/* FS register address/mask for Acc/Gyro sensors */ +#define LSM6DSO_RANGE_REG(_sensor) (LSM6DSO_ACCEL_FS_ADDR + (_sensor)) +#define LSM6DSO_RANGE_MASK 0x0c + +/* Status register bit for Acc/Gyro data ready */ +enum lsm6dso_status { + LSM6DSO_STS_DOWN = 0x00, + LSM6DSO_STS_XLDA_UP = 0x01, + LSM6DSO_STS_GDA_UP = 0x02 +}; + +/* Status register bitmask for Acc/Gyro data ready */ +#define LSM6DSO_STS_XLDA_MASK 0x01 +#define LSM6DSO_STS_GDA_MASK 0x02 + +/* Sensor resolution in number of bits: fixed 16 bit */ +#define LSM6DSO_RESOLUTION 16 + +/* Aggregate private data for all supported sensor (Acc, Gyro) */ +struct lsm6dso_data { + struct stprivate_data st_data[LSM6DSO_FIFO_DEV_NUM]; +}; + +/* + * Note: The specific number of samples to discard depends on the filters + * configured for the chip, as well as the ODR being set. For most of our + * allowed ODRs, 3 should suffice. + * See: ST's LSM6DSO application notes (AN5192) Tables 12 and 18 for details + */ +#define LSM6DSO_DISCARD_SAMPLES 3 + +#define LSM6DSO_GET_DATA(_s) ((struct stprivate_data *)((_s)->drv_data)) + +/* Macro to initialize motion_sensors structure */ +#define LSM6DSO_ST_DATA(g, type) (&(&(g))->st_data[(type)]) +#define LSM6DSO_MAIN_SENSOR(_s) ((_s) - (_s)->type) + +extern const struct accelgyro_drv lsm6dso_drv; + +void lsm6dso_interrupt(enum gpio_signal signal); + +#endif /* __CROS_EC_ACCELGYRO_LSM6DSO_H */ |