drivers/sensors: Add driver for ST LIS2DH accelerometer. From Timo Voutilainen <time.voutilainen@haltian.com> et al.

This commit is contained in:
Juha Niskanen 2017-04-03 07:28:22 -06:00 committed by Gregory Nutt
parent 1b6630ee75
commit dfe6a672c1
5 changed files with 2519 additions and 2 deletions

View File

@ -75,12 +75,41 @@ config SENSOR_KXTJ9_I2C_BUS_SPEED
endif # SENSOR_KXTJ9
config LIS2DH
bool "STMicro LIS2DH device support"
default n
select I2C
---help---
Enable driver support for the STMicro LIS2DH accelerometer
if LIS2DH
config DEBUG_LIS2DH
bool "Debug support for the LIS2DH"
default n
---help---
Enables debug features for the LIS2DH
config LIS2DH_NPOLLWAITERS
int "Number of waiters to poll"
default 2
---help---
Maximum number of threads that can be waiting on poll()
config LIS2DH_DRIVER_SELFTEST
bool "Enable selftest in LIS2DH driver"
default n
---help---
Enable selftest in LIS2DH driver
endif # LIS2DH
config LIS3DSH
bool "STMicro LIS3DSH 3-Axis acclerometer support"
bool "STMicro LIS3DSH 3-Axis accelerometer support"
default n
select SPI
---help---
Enable driver support for the STMicro LIS3DSH 3-Axis acclerometer.
Enable driver support for the STMicro LIS3DSH 3-Axis accelerometer.
config LIS331DL
bool "STMicro LIS331DL device support"

View File

@ -53,6 +53,10 @@ ifeq ($(CONFIG_SENSOR_KXTJ9),y)
CSRCS += kxtj9.c
endif
ifeq ($(CONFIG_LIS2DH),y)
CSRCS += lis2dh.c
endif
ifeq ($(CONFIG_LIS3DSH),y)
CSRCS += lis3dsh.c
endif

2033
drivers/sensors/lis2dh.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -133,4 +133,14 @@
#define SNIOC_PRESSURE_OUT _SNIOC(0x0034)
#define SNIOC_SENSOR_OFF _SNIOC(0x0035)
/* IOCTL commands unique to the LIS2DH */
#define SNIOC_WRITESETUP _SNIOC(0x0036) /* Arg: uint8_t value */
#define SNIOC_WRITE_INT1THRESHOLD _SNIOC(0x0037) /* Arg: uint8_t value */
#define SNIOC_WRITE_INT2THRESHOLD _SNIOC(0x0038) /* Arg: uint8_t value */
#define SNIOC_RESET_HPFILTER _SNIOC(0x0039) /* Arg: uint8_t value */
#define SNIOC_START_SELFTEST _SNIOC(0x003a) /* Arg: uint8_t value */
#define SNIOC_WHO_AM_I _SNIOC(0x003b)
#define SNIOC_READ_TEMP _SNIOC(0x003c) /* Arg: int16_t value */
#endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */

View File

@ -0,0 +1,441 @@
/****************************************************************************
* include/nuttx/sensors/lis2dh.h
* LIS2DH accelerometer driver
*
* Copyright (C) 2014-2017 Haltian Ltd. All rights reserved.
* Authors: Timo Voutilainen <timo.voutilainen@haltian.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_SENSORS_LIS2DH_H
#define __INCLUDE_NUTTX_SENSORS_LIS2DH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/sensors/ioctl.h>
/****************************************************************************
* Pre-Processor Declarations
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
#define ST_LIS2DH_WHOAMI_VALUE 0x33 /* Valid WHOAMI register value */
/* LIS2DH Internal Registers **********************************************/
#define ST_LIS2DH_WHOAMI_REG 0x0f /* WHOAMI register */
#define ST_LIS2DH_STATUS_AUX_REG 0x07 /* Temperature status */
#define ST_LIS2DH_OUT_TEMP_L_REG 0x0c /* Temperature data */
#define ST_LIS2DH_OUT_TEMP_H_REG 0x0d /* Temperature data */
#define ST_LIS2DH_TEMP_CFG_REG 0x1f
#define ST_LIS2DH_CTRL_REG1 0x20
/* CR1 ODR 4 MSBs (XXXX---) */
#define ST_LIS2DH_CR1_ODR_PWR_DWN 0x00
#define ST_LIS2DH_CR1_ODR_1HZ 0x10 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_10HZ 0x20 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_25HZ 0x30 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_50HZ 0x40 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_100HZ 0x50 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_200HZ 0x60 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_400HZ 0x70 /* HR / Normal / Low Power */
#define ST_LIS2DH_CR1_ODR_1620HZ 0x80 /* Low Power */
#define ST_LIS2DH_CR1_ODR_1344_5376HZ 0x90 /* HR / Normal: 1344Hz, Low power: 5376Hz*/
#define ST_LIS2DH_CR1_LOWP_ENABLE 0x08 /* Low power mode enable */
#define ST_LIS2DH_CR1_ZEN 0x04 /* Z-Axis Enable */
#define ST_LIS2DH_CR1_YEN 0x02 /* Y-Axis Enable */
#define ST_LIS2DH_CR1_XEN 0x01 /* X-Axis Enable */
#define ST_LIS2DH_CTRL_REG2 0x21
/* HPM1 .... HP FILT_MODE (XX------) */
#define ST_LIS2DH_CR2_HPFILT_M_NORM 0x00 /* Normal mode (reset reading REFERENCE/DATACAPTURE (26h) register) */
#define ST_LIS2DH_CR2_HPFILT_M_REFSIG 0x40 /* Reference signal for filtering */
#define ST_LIS2DH_CR2_HPFILT_M_NORM2 0x80 /* Normal mode */
#define ST_LIS2DH_CR2_HPFILT_M_AUTOR 0xc0 /* Autoreset on interrupt event */
#define ST_LIS2DH_CR2_FDS 0x08
/* HPIS1 HPFILT ENABLE for INT1 (-------X) */
#define ST_LIS2DH_CR2_HPENABLED_INT1 0x01 /* HP filter enabled for INT1 */
/* HPIS2 HPFILT ENABLE for INT2 (------X-) */
#define ST_LIS2DH_CR2_HPENABLED_INT2 0x02 /* HP filter enabled for INT2 */
#define ST_LIS2DH_CTRL_REG3 0x22
/* I1_AOI1 ENABLE for INT2 (-X------) */
#define ST_LIS2DH_CR3_I1_AOI1_ENABLED 0x40 /* AOI1 interrupt on INT1 pin.*/
#define ST_LIS2DH_CR3_I1_AOI2_ENABLED 0x20 /* AOI2 interrupt on INT1 pin.*/
#define ST_LIS2DH_CTRL_REG4 0x23
/* BDU ... Block Data Update (X-------) */
#define ST_LIS2DH_CR4_BDU_CONT 0x00 /* Continuous update (Default) */
#define ST_LIS2DH_CR4_BDU_UPD_ON_READ 0x80 /* Output registers not updated until MSB and LSB have been read */
#define ST_LIS2DH_CR4_FULL_SCALE_2G 0x0
#define ST_LIS2DH_CR4_FULL_SCALE_4G 0x10
#define ST_LIS2DH_CR4_FULL_SCALE_8G 0x20
#define ST_LIS2DH_CR4_FULL_SCALE_16G 0x30
/* HR .. Operation mode selector (----X---) */
#define ST_LIS2DH_CR4_HR_ENABLED 0x08 /* See section 2.6.3 in datasheet */
#define ST_LIS2DH_CTRL_REG5 0x24
#define ST_LIS2DH_CR5_BOOT 0x80
#define ST_LIS2DH_CR5_FIFO_EN 0x40
#define ST_LIS2DH_CR5_LIR_INT1 0x08
#define ST_LIS2DH_CR5_D4D_INT1 0x04
#define ST_LIS2DH_CR5_LIR_INT2 0x02
#define ST_LIS2DH_CR5_D4D_INT2 0x01
#define ST_LIS2DH_CTRL_REG6 0x25
#define ST_LIS2DH_REFERENCE_REG 0x26
#define ST_LIS2DH_STATUS_REG 0x27 /* Status Register */
#define ST_LIS2DH_SR_ZYXOR 0x80 /* OR'ed X,Y and Z data over-run */
#define ST_LIS2DH_SR_ZOR 0x40 /* individual data over-run ... */
#define ST_LIS2DH_SR_YOR 0x20
#define ST_LIS2DH_SR_XOR 0x10
#define ST_LIS2DH_SR_ZYXDA 0x08 /* OR'ed X,Y and Z data available */
#define ST_LIS2DH_SR_ZDA 0x04 /* individual data available ... */
#define ST_LIS2DH_SR_YDA 0x02
#define ST_LIS2DH_SR_XDA 0x01
#define ST_LIS2DH_OUT_X_L_REG 0x28
#define ST_LIS2DH_OUT_X_H_REG 0x29
#define ST_LIS2DH_OUT_Y_L_REG 0x2a
#define ST_LIS2DH_OUT_Y_H_REG 0x2b
#define ST_LIS2DH_OUT_Z_L_REG 0x2c
#define ST_LIS2DH_OUT_Z_H_REG 0x2d
#define ST_LIS2DH_FIFO_CTRL_REG 0x2e
#define ST_LIS2DH_FIFOCR_THRESHOLD_MASK 0x1f
#define ST_LIS2DH_FIFOCR_THRESHOLD(x) ((x) & ST_LIS2DH_FIFOCR_THRESHOLD_MASK)
#define ST_LIS2DH_FIFOCR_INT1 0x00
#define ST_LIS2DH_FIFOCR_INT2 0x20
#define ST_LIS2DH_FIFOCR_MODE_MASK 0xc0
#define ST_LIS2DH_FIFO_SRC_REG 0x2f
#define ST_LIS2DH_FIFOSR_NUM_SAMP_MASK 0x1f
#define ST_LIS2DH_FIFOSR_EMPTY 0x20
#define ST_LIS2DH_FIFOSR_OVRN_FIFO 0x40
#define ST_LIS2DH_FIFOSR_WTM 0x80
#define ST_LIS2DH_INT1_CFG_REG 0x30
#define ST_LIS2DH_INT_CFG_AOI 0x80
#define ST_LIS2DH_INT_CFG_6D 0x40
#define ST_LIS2DH_INT_CFG_ZHIE 0x20
#define ST_LIS2DH_INT_CFG_ZLIE 0x10
#define ST_LIS2DH_INT_CFG_YHIE 0x08
#define ST_LIS2DH_INT_CFG_YLIE 0x04
#define ST_LIS2DH_INT_CFG_XHIE 0x02
#define ST_LIS2DH_INT_CFG_XLIE 0x01
#define ST_LIS2DH_INT1_SRC_REG 0x31
#define ST_LIS2DH_INT_SR_XLOW 0x01
#define ST_LIS2DH_INT_SR_XHIGH 0x02
#define ST_LIS2DH_INT_SR_YLOW 0x04
#define ST_LIS2DH_INT_SR_YHIGH 0x08
#define ST_LIS2DH_INT_SR_ZLOW 0x10
#define ST_LIS2DH_INT_SR_ZHIGH 0x20
#define ST_LIS2DH_INT_SR_ACTIVE 0x40
#define ST_LIS2DH_INT1_THS_REG 0x32 /* 7-bit value for threshold */
#define ST_LIS2DH_INT1_DUR_REG 0x33 /* 7-bit value for duration */
#define ST_LIS2DH_INT2_CFG_REG 0x34
#define ST_LIS2DH_INT2_SRC_REG 0x35
#define ST_LIS2DH_INT2_THS_REG 0x36 /* 7-bit value for threshold */
#define ST_LIS2DH_INT2_DUR_REG 0x37 /* 7-bit value for duration */
#define ST_LIS2DH_CLICK_CFG_REG 0x38
#define ST_LIS2DH_CLICK_SRC_REG 0x39
#define ST_LIS2DH_CLICK_THS_REG 0x3a
#define ST_LIS2DH_TIME_LIMIT_REG 0x3b
#define ST_LIS2DH_TIME_LATENCY_REG 0x3c
#define ST_LIS2DH_TIME_WINDOW_REG 0x3d
#define ST_LIS2DH_ACT_DUR_REG 0x3f
/************************************************************************************
* Public Types
************************************************************************************/
enum lis2dh_ouput_data_rate
{
LIS2DH_ODR_POWER_DOWN = 0x00,
LIS2DH_ODR_1HZ = 0x10,
LIS2DH_ODR_10HZ = 0x20,
LIS2DH_ODR_25HZ = 0x30,
LIS2DH_ODR_50HZ = 0x40,
LIS2DH_ODR_100HZ = 0x50,
LIS2DH_ODR_200HZ = 0x60,
LIS2DH_ODR_400HZ = 0x70,
LIS2DH_ODR_1620HZ = 0x80,
LIS2DH_ODR_5376HZ = 0x90,
};
enum lis2dh_high_pass_filter_mode
{
LIS2DH_REFERENCE_SIGNAL = 0x40,
LIS2DH_NORMAL_MODE = 0x80,
LIS2DH_AUTORESET_ON_INTERRUPT = 0xc0,
};
enum lis2dh_scale_range
{
LIS2DH_RANGE_2G = 0x00,
LIS2DH_RANGE_4G = 0x10,
LIS2DH_RANGE_8G = 0x20,
LIS2DH_RANGE_16G = 0x30,
};
enum lis2dh_self_test
{
LIS2DH_NORMAL = 0x00,
LIS2DH_SELF_TEST0 = 0x02,
LIS2DH_SELF_TEST1 = 0x04,
};
enum lis2dh_fifo_mode
{
LIS2DH_BYPASS_MODE = 0x00,
LIS2DH_FIFO_MODE = 0x40,
LIS2DH_STREAM_MODE = 0x80,
LIS2DH_TRIGGER_MODE = 0xc0,
};
enum lis2dh_interrupt_mode
{
LIS2DH_OR_COMBINATION = 0x00,
LIS2DH_6D_MOVEMENT = 0x40,
LIS2DH_AND_COMBINATION = 0x80,
LIS2DH_6D_POSITION = 0xc0,
};
struct lis2dh_vector_s
{
int16_t x, y, z;
} packed_struct;
struct lis2dh_res_header
{
uint8_t meas_count;
bool int1_occurred;
uint8_t int1_source;
bool int2_occurred;
uint8_t int2_source;
} packed_struct;
struct lis2dh_result
{
struct lis2dh_res_header header;
struct lis2dh_vector_s measurements[0];
} packed_struct;
struct lis2dh_setup
{
bool temp_enable:1;
bool xy_axis_fixup:1;
uint8_t data_rate;
uint8_t low_power_mode_enable;
uint8_t zen;
uint8_t yen;
uint8_t xen;
uint8_t hpmode;
uint8_t hpcf;
uint8_t fds;
uint8_t hpclick;
uint8_t hpis2;
uint8_t hpis1;
uint8_t int1_click_enable;
uint8_t int1_aoi_enable;
uint8_t int2_aoi_enable;
uint8_t int1_drdy_enable;
uint8_t int2_drdy_enable;
uint8_t int_wtm_enable;
uint8_t int_overrun_enable;
uint8_t bdu;
uint8_t endian;
uint8_t fullscale;
uint8_t high_resolution_enable;
uint8_t selftest;
uint8_t spi_mode;
uint8_t reboot;
uint8_t fifo_enable;
uint8_t int1_latch;
uint8_t int1_4d_enable;
uint8_t int2_latch;
uint8_t int2_4d_enable;
uint8_t int2_click_enable;
uint8_t int_enable;
uint8_t boot_int1_enable;
uint8_t high_low_active;
uint8_t reference;
uint8_t fifo_mode;
uint8_t trigger_selection;
uint8_t fifo_trigger_threshold;
uint8_t int1_interrupt_mode;
uint8_t int1_enable_6d;
uint8_t int1_int_z_high_enable;
uint8_t int1_int_z_low_enable;
uint8_t int1_int_y_high_enable;
uint8_t int1_int_y_low_enable;
uint8_t int1_int_x_high_enable;
uint8_t int1_int_x_low_enable;
uint8_t int1_int_threshold;
uint8_t int1_int_duration;
uint8_t int2_interrupt_mode;
uint8_t int2_enable_6d;
uint8_t int2_int_z_high_enable;
uint8_t int2_int_z_low_enable;
uint8_t int2_int_y_high_enable;
uint8_t int2_int_y_low_enable;
uint8_t int2_int_x_high_enable;
uint8_t int2_int_x_low_enable;
uint8_t int2_int_threshold;
uint8_t int2_int_duration;
uint8_t z_double_click_enable;
uint8_t z_single_click_enable;
uint8_t y_double_click_enable;
uint8_t y_single_click_enable;
uint8_t x_double_click_enable;
uint8_t x_single_click_enable;
uint8_t click_threshold;
uint8_t click_time_limit;
uint8_t click_time_latency;
uint8_t click_time_window;
};
struct lis2dh_config_s
{
/* Device characterization */
int irq; /* IRQ number received by interrupt handler. */
/* IRQ/GPIO access callbacks. These operations all hidden behind
* callbacks to isolate the lis2dh driver from differences in GPIO
* interrupt handling by varying boards and MCUs.
*
* irq_attach - Attach the lis2dh interrupt handler to the GPIO interrupt
* irq_enable - Enable or disable the GPIO interrupt
* clear_irq - Acknowledge/clear any pending GPIO interrupt
*
*/
CODE int (*irq_attach)(FAR struct lis2dh_config_s *state, xcpt_t isr, FAR void *arg);
CODE void (*irq_enable)(FAR const struct lis2dh_config_s *state, bool enable);
CODE void (*irq_clear)(FAR const struct lis2dh_config_s *state);
CODE bool (*read_int1_pin)(void);
CODE bool (*read_int2_pin)(void);
};
struct lis2dh_raw_data_s
{
uint16_t out_x;
uint16_t out_y;
uint16_t out_z;
} packed_struct;
typedef struct lis2dh_raw_data_s lis2dh_raw_data_t;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: lis2dh_register
*
* Description:
* Register the LIS2DH character device as 'devpath'
*
* Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/acc0"
* i2c - An instance of the I2C interface to use to communicate with LIS2DH
* addr - The I2C address of the LIS2DH. The base I2C address of the LIS2DH
* is 0x18. Bit 0 can be controlled via SA0 pad - when connected to
* voltage supply the address is 0x19.
* config - Pointer to LIS2DH configuration
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int lis2dh_register(FAR const char *devpath, FAR struct i2c_master_s *i2c,
uint8_t addr, FAR struct lis2dh_config_s *config);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __INCLUDE_NUTTX_SENSORS_LIS2DH_H */