driver/sensor: add LIS2DS12 sensor support
Add support to STM LIS2DS12 3-axis accelerometer driver. The driver support I2C and SPI bus communication and both polling and drdy trigger mode. Currently it uses high resolution only as power mode. Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
0e7a6ec9ab
commit
fdce786c07
14 changed files with 1078 additions and 0 deletions
|
@ -21,6 +21,7 @@ add_subdirectory_ifdef(CONFIG_HP206C hp206c)
|
||||||
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
||||||
add_subdirectory_ifdef(CONFIG_ISL29035 isl29035)
|
add_subdirectory_ifdef(CONFIG_ISL29035 isl29035)
|
||||||
add_subdirectory_ifdef(CONFIG_LIS2DH lis2dh)
|
add_subdirectory_ifdef(CONFIG_LIS2DH lis2dh)
|
||||||
|
add_subdirectory_ifdef(CONFIG_LIS2DS12 lis2ds12)
|
||||||
add_subdirectory_ifdef(CONFIG_LIS2MDL lis2mdl)
|
add_subdirectory_ifdef(CONFIG_LIS2MDL lis2mdl)
|
||||||
add_subdirectory_ifdef(CONFIG_LIS3DH lis3dh)
|
add_subdirectory_ifdef(CONFIG_LIS3DH lis3dh)
|
||||||
add_subdirectory_ifdef(CONFIG_LIS3MDL lis3mdl)
|
add_subdirectory_ifdef(CONFIG_LIS3MDL lis3mdl)
|
||||||
|
|
|
@ -71,6 +71,8 @@ source "drivers/sensor/isl29035/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/lis2dh/Kconfig"
|
source "drivers/sensor/lis2dh/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/sensor/lis2ds12/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/lis2mdl/Kconfig"
|
source "drivers/sensor/lis2mdl/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/lis3dh/Kconfig"
|
source "drivers/sensor/lis3dh/Kconfig"
|
||||||
|
|
6
drivers/sensor/lis2ds12/CMakeLists.txt
Normal file
6
drivers/sensor/lis2ds12/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LIS2DS12 lis2ds12)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LIS2DS12 lis2ds12_i2c.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LIS2DS12 lis2ds12_spi.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_LIS2DS12_TRIGGER lis2ds12_trigger.c)
|
90
drivers/sensor/lis2ds12/Kconfig
Normal file
90
drivers/sensor/lis2ds12/Kconfig
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
menuconfig LIS2DS12
|
||||||
|
bool "LIS2DS12 I2C/SPI accelerometer sensor driver"
|
||||||
|
depends on (I2C && HAS_DTS_I2C) || (SPI && HAS_DTS_SPI)
|
||||||
|
help
|
||||||
|
Enable driver for LIS2DS12 accelerometer sensor driver
|
||||||
|
|
||||||
|
if LIS2DS12
|
||||||
|
|
||||||
|
choice LIS2DS12_TRIGGER_MODE
|
||||||
|
prompt "Trigger mode"
|
||||||
|
help
|
||||||
|
Specify the type of triggering to be used by the driver.
|
||||||
|
|
||||||
|
config LIS2DS12_TRIGGER_NONE
|
||||||
|
bool "No trigger"
|
||||||
|
|
||||||
|
config LIS2DS12_TRIGGER_GLOBAL_THREAD
|
||||||
|
bool "Use global thread"
|
||||||
|
depends on GPIO
|
||||||
|
select LIS2DS12_TRIGGER
|
||||||
|
|
||||||
|
config LIS2DS12_TRIGGER_OWN_THREAD
|
||||||
|
bool "Use own thread"
|
||||||
|
depends on GPIO
|
||||||
|
select LIS2DS12_TRIGGER
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config LIS2DS12_TRIGGER
|
||||||
|
bool
|
||||||
|
|
||||||
|
config LIS2DS12_THREAD_PRIORITY
|
||||||
|
int "Thread priority"
|
||||||
|
depends on LIS2DS12_TRIGGER_OWN_THREAD
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Priority of thread used by the driver to handle interrupts.
|
||||||
|
|
||||||
|
config LIS2DS12_THREAD_STACK_SIZE
|
||||||
|
int "Thread stack size"
|
||||||
|
depends on LIS2DS12_TRIGGER_OWN_THREAD
|
||||||
|
default 1024
|
||||||
|
help
|
||||||
|
Stack size of thread used by the driver to handle interrupts.
|
||||||
|
|
||||||
|
config LIS2DS12_ENABLE_TEMP
|
||||||
|
bool "Enable temperature"
|
||||||
|
help
|
||||||
|
Enable/disable temperature
|
||||||
|
|
||||||
|
menu "Attributes"
|
||||||
|
|
||||||
|
config LIS2DS12_FS
|
||||||
|
int "Accelerometer full-scale range"
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Specify the default accelerometer full-scale range.
|
||||||
|
An X value for the config represents a range of +/- X G. Valid values
|
||||||
|
are:
|
||||||
|
0: Full Scale selected at runtime
|
||||||
|
2: +/- 2g
|
||||||
|
4: +/- 4g
|
||||||
|
8: +/- 8g
|
||||||
|
16: +/- 16g
|
||||||
|
|
||||||
|
config LIS2DS12_ODR
|
||||||
|
int "Accelerometer Output data rate frequency"
|
||||||
|
range 0 10
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Specify the default accelerometer output data rate expressed in
|
||||||
|
samples per second (Hz).
|
||||||
|
0: ODR selected at runtime
|
||||||
|
1: 12.5Hz
|
||||||
|
2: 25Hz
|
||||||
|
3: 50Hz
|
||||||
|
4: 100Hz
|
||||||
|
5: 200Hz
|
||||||
|
6: 400Hz
|
||||||
|
7: 800Hz
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif # LIS2DS12
|
317
drivers/sensor/lis2ds12/lis2ds12.c
Normal file
317
drivers/sensor/lis2ds12/lis2ds12.c
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
/* ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/lis2ds12.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sensor.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <misc/byteorder.h>
|
||||||
|
#include <misc/__assert.h>
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#include "lis2ds12.h"
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_REGISTER(LIS2DS12);
|
||||||
|
|
||||||
|
static struct lis2ds12_data lis2ds12_data;
|
||||||
|
|
||||||
|
static struct lis2ds12_config lis2ds12_config = {
|
||||||
|
.comm_master_dev_name = DT_ST_LIS2DS12_0_BUS_NAME,
|
||||||
|
#if defined(DT_ST_LIS2DS12_BUS_SPI)
|
||||||
|
.bus_init = lis2ds12_spi_init,
|
||||||
|
#elif defined(DT_ST_LIS2DS12_BUS_I2C)
|
||||||
|
.bus_init = lis2ds12_i2c_init,
|
||||||
|
#else
|
||||||
|
#error "BUS MACRO NOT DEFINED IN DTS"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(LIS2DS12_ODR_RUNTIME)
|
||||||
|
static const u16_t lis2ds12_hr_odr_map[] = {0, 12, 25, 50, 100, 200, 400, 800};
|
||||||
|
|
||||||
|
static int lis2ds12_freq_to_odr_val(u16_t freq)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lis2ds12_hr_odr_map); i++) {
|
||||||
|
if (freq == lis2ds12_hr_odr_map[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_accel_odr_set(struct device *dev, u16_t freq)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
int odr;
|
||||||
|
|
||||||
|
odr = lis2ds12_freq_to_odr_val(freq);
|
||||||
|
if (odr < 0) {
|
||||||
|
return odr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL1,
|
||||||
|
LIS2DS12_MASK_CTRL1_ODR,
|
||||||
|
odr << LIS2DS12_SHIFT_CTRL1_ODR) < 0) {
|
||||||
|
LOG_DBG("failed to set accelerometer sampling rate");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIS2DS12_FS_RUNTIME
|
||||||
|
static const u16_t lis2ds12_accel_fs_map[] = {2, 16, 4, 8};
|
||||||
|
static const u16_t lis2ds12_accel_fs_sens[] = {1, 8, 2, 4};
|
||||||
|
|
||||||
|
static int lis2ds12_accel_range_to_fs_val(s32_t range)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(lis2ds12_accel_fs_map); i++) {
|
||||||
|
if (range == lis2ds12_accel_fs_map[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_accel_range_set(struct device *dev, s32_t range)
|
||||||
|
{
|
||||||
|
int fs;
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
fs = lis2ds12_accel_range_to_fs_val(range);
|
||||||
|
if (fs < 0) {
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL1,
|
||||||
|
LIS2DS12_MASK_CTRL1_FS,
|
||||||
|
fs << LIS2DS12_SHIFT_CTRL1_FS) < 0) {
|
||||||
|
LOG_DBG("failed to set accelerometer full-scale");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->gain = (float)(lis2ds12_accel_fs_sens[fs] * GAIN_XL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int lis2ds12_accel_config(struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr,
|
||||||
|
const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
switch (attr) {
|
||||||
|
#ifdef LIS2DS12_FS_RUNTIME
|
||||||
|
case SENSOR_ATTR_FULL_SCALE:
|
||||||
|
return lis2ds12_accel_range_set(dev, sensor_ms2_to_g(val));
|
||||||
|
#endif
|
||||||
|
#ifdef LIS2DS12_ODR_RUNTIME
|
||||||
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||||
|
return lis2ds12_accel_odr_set(dev, val->val1);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
LOG_DBG("Accel attribute not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_attr_set(struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr,
|
||||||
|
const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
return lis2ds12_accel_config(dev, chan, attr, val);
|
||||||
|
default:
|
||||||
|
LOG_WRN("attr_set() not supported on this channel.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_sample_fetch_accel(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
u8_t buf[6];
|
||||||
|
|
||||||
|
if (data->hw_tf->read_data(data, LIS2DS12_REG_OUTX_L,
|
||||||
|
buf, sizeof(buf)) < 0) {
|
||||||
|
LOG_DBG("failed to read sample");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->sample_x = (s16_t)((u16_t)(buf[0]) | ((u16_t)(buf[1]) << 8));
|
||||||
|
data->sample_y = (s16_t)((u16_t)(buf[2]) | ((u16_t)(buf[3]) << 8));
|
||||||
|
data->sample_z = (s16_t)((u16_t)(buf[4]) | ((u16_t)(buf[5]) << 8));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_sample_fetch(struct device *dev, enum sensor_channel chan)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
lis2ds12_sample_fetch_accel(dev);
|
||||||
|
break;
|
||||||
|
#if defined(CONFIG_LIS2DS12_ENABLE_TEMP)
|
||||||
|
case SENSOR_CHAN_DIE_TEMP:
|
||||||
|
lis2ds12_sample_fetch_temp(dev);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case SENSOR_CHAN_ALL:
|
||||||
|
lis2ds12_sample_fetch_accel(dev);
|
||||||
|
#if defined(CONFIG_LIS2DS12_ENABLE_TEMP)
|
||||||
|
lis2ds12_sample_fetch_temp(dev);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void lis2ds12_convert(struct sensor_value *val, int raw_val,
|
||||||
|
float gain)
|
||||||
|
{
|
||||||
|
s64_t dval;
|
||||||
|
|
||||||
|
/* Gain is in mg/LSB */
|
||||||
|
/* Convert to m/s^2 */
|
||||||
|
dval = ((s64_t)raw_val * gain * SENSOR_G) / 1000;
|
||||||
|
val->val1 = dval / 1000000LL;
|
||||||
|
val->val2 = dval % 1000000LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lis2ds12_get_channel(enum sensor_channel chan,
|
||||||
|
struct sensor_value *val,
|
||||||
|
struct lis2ds12_data *data,
|
||||||
|
float gain)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
lis2ds12_convert(val, data->sample_x, gain);
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
lis2ds12_convert(val, data->sample_y, gain);
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
lis2ds12_convert(val, data->sample_z, gain);
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
lis2ds12_convert(val, data->sample_x, gain);
|
||||||
|
lis2ds12_convert(val + 1, data->sample_y, gain);
|
||||||
|
lis2ds12_convert(val + 2, data->sample_z, gain);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_channel_get(struct device *dev,
|
||||||
|
enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
return lis2ds12_get_channel(chan, val, data, data->gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sensor_driver_api lis2ds12_api_funcs = {
|
||||||
|
.attr_set = lis2ds12_attr_set,
|
||||||
|
#if defined(CONFIG_LIS2DS12_TRIGGER)
|
||||||
|
.trigger_set = lis2ds12_trigger_set,
|
||||||
|
#endif
|
||||||
|
.sample_fetch = lis2ds12_sample_fetch,
|
||||||
|
.channel_get = lis2ds12_channel_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int lis2ds12_init(struct device *dev)
|
||||||
|
{
|
||||||
|
const struct lis2ds12_config * const config = dev->config->config_info;
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
u8_t chip_id;
|
||||||
|
|
||||||
|
data->comm_master = device_get_binding(config->comm_master_dev_name);
|
||||||
|
if (!data->comm_master) {
|
||||||
|
LOG_DBG("master not found: %s",
|
||||||
|
config->comm_master_dev_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->bus_init(dev);
|
||||||
|
|
||||||
|
/* s/w reset the sensor */
|
||||||
|
if (data->hw_tf->write_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL2,
|
||||||
|
LIS2DS12_SOFT_RESET) < 0) {
|
||||||
|
LOG_DBG("s/w reset fail");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->hw_tf->read_reg(data, LIS2DS12_REG_WHO_AM_I, &chip_id) < 0) {
|
||||||
|
LOG_DBG("failed reading chip id");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chip_id != LIS2DS12_VAL_WHO_AM_I) {
|
||||||
|
LOG_DBG("invalid chip id 0x%x", chip_id);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("chip id 0x%x", chip_id);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2DS12_TRIGGER
|
||||||
|
if (lis2ds12_trigger_init(dev) < 0) {
|
||||||
|
LOG_ERR("Failed to initialize triggers.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set sensor default odr */
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL1,
|
||||||
|
LIS2DS12_MASK_CTRL1_ODR,
|
||||||
|
LIS2DS12_DEFAULT_ODR) < 0) {
|
||||||
|
LOG_DBG("failed setting odr");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set sensor default scale */
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL1,
|
||||||
|
LIS2DS12_MASK_CTRL1_FS,
|
||||||
|
LIS2DS12_DEFAULT_FS) < 0) {
|
||||||
|
LOG_DBG("failed setting scale");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
data->gain = LIS2DS12_DEFAULT_GAIN;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEVICE_AND_API_INIT(lis2ds12, DT_ST_LIS2DS12_0_LABEL, lis2ds12_init,
|
||||||
|
&lis2ds12_data, &lis2ds12_config, POST_KERNEL,
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, &lis2ds12_api_funcs);
|
142
drivers/sensor/lis2ds12/lis2ds12.h
Normal file
142
drivers/sensor/lis2ds12/lis2ds12.h
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/* ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/lis2ds12.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_DRIVERS_SENSOR_LIS2DS12_LIS2DS12_H_
|
||||||
|
#define ZEPHYR_DRIVERS_SENSOR_LIS2DS12_LIS2DS12_H_
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <sensor.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_WHO_AM_I 0x0F
|
||||||
|
#define LIS2DS12_VAL_WHO_AM_I 0x43
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_CTRL1 0x20
|
||||||
|
#define LIS2DS12_MASK_CTRL1_ODR (BIT(7) | BIT(6) | \
|
||||||
|
BIT(5) | BIT(4))
|
||||||
|
#define LIS2DS12_SHIFT_CTRL1_ODR 4
|
||||||
|
#define LIS2DS12_MASK_CTRL1_FS (BIT(3) | BIT(2))
|
||||||
|
#define LIS2DS12_SHIFT_CTRL1_FS 2
|
||||||
|
#define LIS2DS12_MASK_CTRL1_HF_ODR BIT(1)
|
||||||
|
#define LIS2DS12_MASK_CTRL1_HF_BDU BIT(0)
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_CTRL2 0x21
|
||||||
|
#define LIS2DS12_SOFT_RESET 0x40
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_CTRL3 0x22
|
||||||
|
#define LIS2DS12_SHIFT_LIR 0x02
|
||||||
|
#define LIS2DS12_MASK_LIR 0x04
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_CTRL4 0x23
|
||||||
|
#define LIS2DS12_SHIFT_INT1_DRDY 0x00
|
||||||
|
#define LIS2DS12_MASK_INT1_DRDY 0x01
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_OUT_T 0x26
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_STATUS 0x27
|
||||||
|
#define LIS2DS12_INT_DRDY 0x01
|
||||||
|
|
||||||
|
#define LIS2DS12_REG_OUTX_L 0x28
|
||||||
|
#define LIS2DS12_REG_OUTX_H 0x29
|
||||||
|
#define LIS2DS12_REG_OUTY_L 0x2A
|
||||||
|
#define LIS2DS12_REG_OUTY_H 0x2B
|
||||||
|
#define LIS2DS12_REG_OUTZ_L 0x2C
|
||||||
|
#define LIS2DS12_REG_OUTZ_H 0x2D
|
||||||
|
|
||||||
|
|
||||||
|
#if (CONFIG_LIS2DS12_ODR == 0)
|
||||||
|
#define LIS2DS12_ODR_RUNTIME 1
|
||||||
|
#define LIS2DS12_DEFAULT_ODR 0
|
||||||
|
#else
|
||||||
|
#define LIS2DS12_DEFAULT_ODR (CONFIG_LIS2DS12_ODR << 4)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Accel sensor sensitivity unit is 0.061 mg/LSB */
|
||||||
|
#define GAIN_XL (61LL / 1000.0)
|
||||||
|
|
||||||
|
#if CONFIG_LIS2DS12_FS == 0
|
||||||
|
#define LIS2DS12_FS_RUNTIME 1
|
||||||
|
#define LIS2DS12_DEFAULT_FS (0 << 2)
|
||||||
|
#define LIS2DS12_DEFAULT_GAIN GAIN_XL
|
||||||
|
#elif CONFIG_LIS2DS12_FS == 2
|
||||||
|
#define LIS2DS12_DEFAULT_FS (0 << 2)
|
||||||
|
#define LIS2DS12_DEFAULT_GAIN GAIN_XL
|
||||||
|
#elif CONFIG_LIS2DS12_FS == 4
|
||||||
|
#define LIS2DS12_DEFAULT_FS (2 << 2)
|
||||||
|
#define LIS2DS12_DEFAULT_GAIN (2.0 * GAIN_XL)
|
||||||
|
#elif CONFIG_LIS2DS12_FS == 8
|
||||||
|
#define LIS2DS12_DEFAULT_FS (3 << 2)
|
||||||
|
#define LIS2DS12_DEFAULT_GAIN (4.0 * GAIN_XL)
|
||||||
|
#elif CONFIG_LIS2DS12_FS == 16
|
||||||
|
#define LIS2DS12_DEFAULT_FS (1 << 2)
|
||||||
|
#define LIS2DS12_DEFAULT_GAIN (8.0 * GAIN_XL)
|
||||||
|
#else
|
||||||
|
#error "Bad LIS2DS12 FS value (should be 0, 2, 4, 8, 16)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct lis2ds12_config {
|
||||||
|
char *comm_master_dev_name;
|
||||||
|
int (*bus_init)(struct device *dev);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lis2ds12_data;
|
||||||
|
|
||||||
|
struct lis2ds12_transfer_function {
|
||||||
|
int (*read_data)(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len);
|
||||||
|
int (*write_data)(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len);
|
||||||
|
int (*read_reg)(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value);
|
||||||
|
int (*write_reg)(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t value);
|
||||||
|
int (*update_reg)(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t mask, u8_t value);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lis2ds12_data {
|
||||||
|
struct device *comm_master;
|
||||||
|
int sample_x;
|
||||||
|
int sample_y;
|
||||||
|
int sample_z;
|
||||||
|
float gain;
|
||||||
|
const struct lis2ds12_transfer_function *hw_tf;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2DS12_TRIGGER
|
||||||
|
struct device *gpio;
|
||||||
|
struct gpio_callback gpio_cb;
|
||||||
|
|
||||||
|
struct sensor_trigger data_ready_trigger;
|
||||||
|
sensor_trigger_handler_t data_ready_handler;
|
||||||
|
|
||||||
|
#if defined(CONFIG_LIS2DS12_TRIGGER_OWN_THREAD)
|
||||||
|
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_LIS2DS12_THREAD_STACK_SIZE);
|
||||||
|
struct k_thread thread;
|
||||||
|
struct k_sem trig_sem;
|
||||||
|
#elif defined(CONFIG_LIS2DS12_TRIGGER_GLOBAL_THREAD)
|
||||||
|
struct k_work work;
|
||||||
|
struct device *dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CONFIG_LIS2DS12_TRIGGER */
|
||||||
|
};
|
||||||
|
|
||||||
|
int lis2ds12_spi_init(struct device *dev);
|
||||||
|
int lis2ds12_i2c_init(struct device *dev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2DS12_TRIGGER
|
||||||
|
int lis2ds12_trigger_set(struct device *dev,
|
||||||
|
const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler);
|
||||||
|
|
||||||
|
int lis2ds12_trigger_init(struct device *dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_DRIVERS_SENSOR_LIS2DS12_LIS2DS12_H_ */
|
75
drivers/sensor/lis2ds12/lis2ds12_i2c.c
Normal file
75
drivers/sensor/lis2ds12/lis2ds12_i2c.c
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
/* ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/lis2ds12.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <i2c.h>
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#include "lis2ds12.h"
|
||||||
|
|
||||||
|
#ifdef DT_ST_LIS2DS12_BUS_I2C
|
||||||
|
|
||||||
|
static u16_t lis2ds12_i2c_slave_addr = DT_ST_LIS2DS12_0_BASE_ADDRESS;
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_DECLARE(LIS2DS12);
|
||||||
|
|
||||||
|
static int lis2ds12_i2c_read_data(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
return i2c_burst_read(data->comm_master, lis2ds12_i2c_slave_addr,
|
||||||
|
reg_addr, value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_i2c_write_data(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
return i2c_burst_write(data->comm_master, lis2ds12_i2c_slave_addr,
|
||||||
|
reg_addr, value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_i2c_read_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value)
|
||||||
|
{
|
||||||
|
return i2c_reg_read_byte(data->comm_master, lis2ds12_i2c_slave_addr,
|
||||||
|
reg_addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_i2c_write_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t value)
|
||||||
|
{
|
||||||
|
return i2c_reg_write_byte(data->comm_master, lis2ds12_i2c_slave_addr,
|
||||||
|
reg_addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_i2c_update_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t mask, u8_t value)
|
||||||
|
{
|
||||||
|
return i2c_reg_update_byte(data->comm_master, lis2ds12_i2c_slave_addr,
|
||||||
|
reg_addr, mask, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct lis2ds12_transfer_function lis2ds12_i2c_transfer_fn = {
|
||||||
|
.read_data = lis2ds12_i2c_read_data,
|
||||||
|
.write_data = lis2ds12_i2c_write_data,
|
||||||
|
.read_reg = lis2ds12_i2c_read_reg,
|
||||||
|
.write_reg = lis2ds12_i2c_write_reg,
|
||||||
|
.update_reg = lis2ds12_i2c_update_reg,
|
||||||
|
};
|
||||||
|
|
||||||
|
int lis2ds12_i2c_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
data->hw_tf = &lis2ds12_i2c_transfer_fn;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* DT_ST_LIS2DS12_BUS_I2C */
|
182
drivers/sensor/lis2ds12/lis2ds12_spi.c
Normal file
182
drivers/sensor/lis2ds12/lis2ds12_spi.c
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/* ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/lis2ds12.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <spi.h>
|
||||||
|
#include "lis2ds12.h"
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#ifdef DT_ST_LIS2DS12_BUS_SPI
|
||||||
|
|
||||||
|
#define LIS2DS12_SPI_READ (1 << 7)
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_DECLARE(LIS2DS12);
|
||||||
|
|
||||||
|
#if defined(CONFIG_LIS2DS12_SPI_GPIO_CS)
|
||||||
|
static struct spi_cs_control lis2ds12_cs_ctrl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct spi_config lis2ds12_spi_conf = {
|
||||||
|
.frequency = DT_ST_LIS2DS12_0_SPI_MAX_FREQUENCY,
|
||||||
|
.operation = (SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
|
||||||
|
SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE),
|
||||||
|
.slave = DT_ST_LIS2DS12_0_BASE_ADDRESS,
|
||||||
|
.cs = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int lis2ds12_raw_read(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
struct spi_config *spi_cfg = &lis2ds12_spi_conf;
|
||||||
|
u8_t buffer_tx[2] = { reg_addr | LIS2DS12_SPI_READ, 0 };
|
||||||
|
const struct spi_buf tx_buf = {
|
||||||
|
.buf = buffer_tx,
|
||||||
|
.len = 2,
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = &tx_buf,
|
||||||
|
.count = 1
|
||||||
|
};
|
||||||
|
const struct spi_buf rx_buf[2] = {
|
||||||
|
{
|
||||||
|
.buf = NULL,
|
||||||
|
.len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.buf = value,
|
||||||
|
.len = len,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set rx = {
|
||||||
|
.buffers = rx_buf,
|
||||||
|
.count = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (len > 64) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_transceive(data->comm_master, spi_cfg, &tx, &rx)) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_raw_write(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
struct spi_config *spi_cfg = &lis2ds12_spi_conf;
|
||||||
|
u8_t buffer_tx[1] = { reg_addr & ~LIS2DS12_SPI_READ };
|
||||||
|
const struct spi_buf tx_buf[2] = {
|
||||||
|
{
|
||||||
|
.buf = buffer_tx,
|
||||||
|
.len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.buf = value,
|
||||||
|
.len = len,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_buf,
|
||||||
|
.count = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (len > 64) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spi_write(data->comm_master, spi_cfg, &tx)) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_spi_read_data(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
return lis2ds12_raw_read(data, reg_addr, value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_spi_write_data(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value, u8_t len)
|
||||||
|
{
|
||||||
|
return lis2ds12_raw_write(data, reg_addr, value, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_spi_read_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t *value)
|
||||||
|
{
|
||||||
|
return lis2ds12_raw_read(data, reg_addr, value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_spi_write_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t value)
|
||||||
|
{
|
||||||
|
u8_t tmp_val = value;
|
||||||
|
|
||||||
|
return lis2ds12_raw_write(data, reg_addr, &tmp_val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lis2ds12_spi_update_reg(struct lis2ds12_data *data, u8_t reg_addr,
|
||||||
|
u8_t mask, u8_t value)
|
||||||
|
{
|
||||||
|
u8_t tmp_val;
|
||||||
|
|
||||||
|
lis2ds12_raw_read(data, reg_addr, &tmp_val, 1);
|
||||||
|
tmp_val = (tmp_val & ~mask) | (value & mask);
|
||||||
|
|
||||||
|
return lis2ds12_raw_write(data, reg_addr, &tmp_val, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct lis2ds12_transfer_function lis2ds12_spi_transfer_fn = {
|
||||||
|
.read_data = lis2ds12_spi_read_data,
|
||||||
|
.write_data = lis2ds12_spi_write_data,
|
||||||
|
.read_reg = lis2ds12_spi_read_reg,
|
||||||
|
.write_reg = lis2ds12_spi_write_reg,
|
||||||
|
.update_reg = lis2ds12_spi_update_reg,
|
||||||
|
};
|
||||||
|
|
||||||
|
int lis2ds12_spi_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
data->hw_tf = &lis2ds12_spi_transfer_fn;
|
||||||
|
|
||||||
|
#if defined(CONFIG_LIS2DS12_SPI_GPIO_CS)
|
||||||
|
/* handle SPI CS thru GPIO if it is the case */
|
||||||
|
if (IS_ENABLED(CONFIG_LIS2DS12_SPI_GPIO_CS)) {
|
||||||
|
lis2ds12_cs_ctrl.gpio_dev = device_get_binding(
|
||||||
|
CONFIG_LIS2DS12_SPI_GPIO_CS_DRV_NAME);
|
||||||
|
if (!lis2ds12_cs_ctrl.gpio_dev) {
|
||||||
|
LOG_ERR("Unable to get GPIO SPI CS device");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
lis2ds12_cs_ctrl.gpio_pin = CONFIG_LIS2DS12_SPI_GPIO_CS_PIN;
|
||||||
|
lis2ds12_cs_ctrl.delay = 0;
|
||||||
|
|
||||||
|
lis2ds12_spi_conf.cs = &lis2ds12_cs_ctrl;
|
||||||
|
|
||||||
|
LOG_DBG("SPI GPIO CS configured on %s:%u",
|
||||||
|
CONFIG_LIS2DS12_SPI_GPIO_CS_DRV_NAME,
|
||||||
|
CONFIG_LIS2DS12_SPI_GPIO_CS_PIN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* DT_ST_LIS2DS12_BUS_SPI */
|
192
drivers/sensor/lis2ds12/lis2ds12_trigger.c
Normal file
192
drivers/sensor/lis2ds12/lis2ds12_trigger.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
/* ST Microelectronics LIS2DS12 3-axis accelerometer driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/lis2ds12.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <device.h>
|
||||||
|
#include <i2c.h>
|
||||||
|
#include <misc/__assert.h>
|
||||||
|
#include <misc/util.h>
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <sensor.h>
|
||||||
|
|
||||||
|
#include "lis2ds12.h"
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
#include <logging/log.h>
|
||||||
|
LOG_MODULE_DECLARE(LIS2DS12);
|
||||||
|
|
||||||
|
static void lis2ds12_gpio_callback(struct device *dev,
|
||||||
|
struct gpio_callback *cb, u32_t pins)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data =
|
||||||
|
CONTAINER_OF(cb, struct lis2ds12_data, gpio_cb);
|
||||||
|
|
||||||
|
ARG_UNUSED(pins);
|
||||||
|
|
||||||
|
gpio_pin_disable_callback(dev, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN);
|
||||||
|
|
||||||
|
#if defined(CONFIG_LIS2DS12_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_give(&data->trig_sem);
|
||||||
|
#elif defined(CONFIG_LIS2DS12_TRIGGER_GLOBAL_THREAD)
|
||||||
|
k_work_submit(&data->work);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lis2ds12_handle_drdy_int(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
if (data->data_ready_handler != NULL) {
|
||||||
|
data->data_ready_handler(dev, &data->data_ready_trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lis2ds12_handle_int(void *arg)
|
||||||
|
{
|
||||||
|
struct device *dev = arg;
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
u8_t status;
|
||||||
|
|
||||||
|
if (data->hw_tf->read_reg(data, LIS2DS12_REG_STATUS, &status) < 0) {
|
||||||
|
LOG_ERR("status reading error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status & LIS2DS12_INT_DRDY) {
|
||||||
|
lis2ds12_handle_drdy_int(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_enable_callback(data->gpio, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2DS12_TRIGGER_OWN_THREAD
|
||||||
|
static void lis2ds12_thread(int dev_ptr, int unused)
|
||||||
|
{
|
||||||
|
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
ARG_UNUSED(unused);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&data->trig_sem, K_FOREVER);
|
||||||
|
lis2ds12_handle_int(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIS2DS12_TRIGGER_GLOBAL_THREAD
|
||||||
|
static void lis2ds12_work_cb(struct k_work *work)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data =
|
||||||
|
CONTAINER_OF(work, struct lis2ds12_data, work);
|
||||||
|
|
||||||
|
lis2ds12_handle_int(data->dev);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int lis2ds12_init_interrupt(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
/* Enable latched mode */
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL3,
|
||||||
|
LIS2DS12_MASK_LIR,
|
||||||
|
(1 << LIS2DS12_SHIFT_LIR)) < 0) {
|
||||||
|
LOG_ERR("Could not enable LIR mode.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable data-ready interrupt */
|
||||||
|
if (data->hw_tf->update_reg(data,
|
||||||
|
LIS2DS12_REG_CTRL4,
|
||||||
|
LIS2DS12_MASK_INT1_DRDY,
|
||||||
|
(1 << LIS2DS12_SHIFT_INT1_DRDY)) < 0) {
|
||||||
|
LOG_ERR("Could not enable data-ready interrupt.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lis2ds12_trigger_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
/* setup data ready gpio interrupt */
|
||||||
|
data->gpio = device_get_binding(DT_ST_LIS2DS12_0_IRQ_GPIOS_CONTROLLER);
|
||||||
|
if (data->gpio == NULL) {
|
||||||
|
LOG_ERR("Cannot get pointer to %s device.",
|
||||||
|
DT_ST_LIS2DS12_0_IRQ_GPIOS_CONTROLLER);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_configure(data->gpio, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN,
|
||||||
|
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||||
|
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
|
||||||
|
|
||||||
|
gpio_init_callback(&data->gpio_cb,
|
||||||
|
lis2ds12_gpio_callback,
|
||||||
|
BIT(DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN));
|
||||||
|
|
||||||
|
if (gpio_add_callback(data->gpio, &data->gpio_cb) < 0) {
|
||||||
|
LOG_ERR("Could not set gpio callback.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_LIS2DS12_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_init(&data->trig_sem, 0, UINT_MAX);
|
||||||
|
|
||||||
|
k_thread_create(&data->thread, data->thread_stack,
|
||||||
|
CONFIG_LIS2DS12_THREAD_STACK_SIZE,
|
||||||
|
(k_thread_entry_t)lis2ds12_thread, dev,
|
||||||
|
0, NULL, K_PRIO_COOP(CONFIG_LIS2DS12_THREAD_PRIORITY),
|
||||||
|
0, 0);
|
||||||
|
#elif defined(CONFIG_LIS2DS12_TRIGGER_GLOBAL_THREAD)
|
||||||
|
data->work.handler = lis2ds12_work_cb;
|
||||||
|
data->dev = dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gpio_pin_enable_callback(data->gpio, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lis2ds12_trigger_set(struct device *dev,
|
||||||
|
const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler)
|
||||||
|
{
|
||||||
|
struct lis2ds12_data *data = dev->driver_data;
|
||||||
|
u8_t buf[6];
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(trig->type == SENSOR_TRIG_DATA_READY);
|
||||||
|
|
||||||
|
gpio_pin_disable_callback(data->gpio, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN);
|
||||||
|
|
||||||
|
data->data_ready_handler = handler;
|
||||||
|
if (handler == NULL) {
|
||||||
|
LOG_WRN("lis2ds12: no handler");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* re-trigger lost interrupt */
|
||||||
|
if (data->hw_tf->read_data(data, LIS2DS12_REG_OUTX_L,
|
||||||
|
buf, sizeof(buf)) < 0) {
|
||||||
|
LOG_ERR("status reading error");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->data_ready_trigger = *trig;
|
||||||
|
|
||||||
|
lis2ds12_init_interrupt(dev);
|
||||||
|
gpio_pin_enable_callback(data->gpio, DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
24
dts/bindings/sensor/st,lis2ds12-i2c.yaml
Normal file
24
dts/bindings/sensor/st,lis2ds12-i2c.yaml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
title: STMicroelectronics MEMS sensors LIS2DS12
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
description: >
|
||||||
|
This binding gives a base representation of LIS2DS12 3-axis accelerometer
|
||||||
|
|
||||||
|
inherits:
|
||||||
|
!include i2c-device.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
constraint: "st,lis2ds12"
|
||||||
|
|
||||||
|
irq-gpios:
|
||||||
|
type: compound
|
||||||
|
category: required
|
||||||
|
generation: define, use-prop-name
|
||||||
|
...
|
25
dts/bindings/sensor/st,lis2ds12-spi.yaml
Normal file
25
dts/bindings/sensor/st,lis2ds12-spi.yaml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
title: STMicroelectronics MEMS sensors LIS2DS12 SPI
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
description: >
|
||||||
|
This binding gives a base representation of LIS2DS12 3-axis accelerometer
|
||||||
|
accessed through SPI bus
|
||||||
|
|
||||||
|
inherits:
|
||||||
|
!include spi-device.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
constraint: "st,lis2ds12"
|
||||||
|
|
||||||
|
irq-gpios:
|
||||||
|
type: compound
|
||||||
|
category: required
|
||||||
|
generation: define, use-prop-name
|
||||||
|
...
|
|
@ -158,6 +158,15 @@
|
||||||
#define DT_SENSIRION_SHT3XD_0_BUS_NAME ""
|
#define DT_SENSIRION_SHT3XD_0_BUS_NAME ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DT_ST_LIS2DS12_0_LABEL
|
||||||
|
#define DT_ST_LIS2DS12_0_LABEL ""
|
||||||
|
#define DT_ST_LIS2DS12_0_BUS_NAME ""
|
||||||
|
#define DT_ST_LIS2DS12_0_BASE_ADDRESS 0x19
|
||||||
|
#define DT_ST_LIS2DS12_0_IRQ_GPIOS_CONTROLLER ""
|
||||||
|
#define DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN 0
|
||||||
|
#define DT_ST_LIS2DS12_BUS_I2C 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DT_LIS3DH_DEV_NAME
|
#ifndef DT_LIS3DH_DEV_NAME
|
||||||
#define DT_LIS3DH_DEV_NAME ""
|
#define DT_LIS3DH_DEV_NAME ""
|
||||||
#define DT_LIS3DH_I2C_ADDRESS 0x19
|
#define DT_LIS3DH_I2C_ADDRESS 0x19
|
||||||
|
@ -219,6 +228,16 @@
|
||||||
#define DT_LIS2DH_INT2_GPIO_PIN 1
|
#define DT_LIS2DH_INT2_GPIO_PIN 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DT_ST_LIS2DS12_0_LABEL
|
||||||
|
#define DT_ST_LIS2DS12_0_LABEL ""
|
||||||
|
#define DT_ST_LIS2DS12_0_BUS_NAME ""
|
||||||
|
#define DT_ST_LIS2DS12_0_SPI_MAX_FREQUENCY 100000
|
||||||
|
#define DT_ST_LIS2DS12_0_BASE_ADDRESS 1
|
||||||
|
#define DT_ST_LIS2DS12_0_IRQ_GPIOS_CONTROLLER ""
|
||||||
|
#define DT_ST_LIS2DS12_0_IRQ_GPIOS_PIN 0
|
||||||
|
#define DT_ST_LIS2DS12_BUS_SPI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DT_MICROCHIP_ENC28J60_0_LABEL
|
#ifndef DT_MICROCHIP_ENC28J60_0_LABEL
|
||||||
#define DT_MICROCHIP_ENC28J60_0_BASE_ADDRESS 0
|
#define DT_MICROCHIP_ENC28J60_0_BASE_ADDRESS 0
|
||||||
#define DT_MICROCHIP_ENC28J60_0_BUS_NAME ""
|
#define DT_MICROCHIP_ENC28J60_0_BUS_NAME ""
|
||||||
|
|
|
@ -7,6 +7,7 @@ CONFIG_LOG=y
|
||||||
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
||||||
CONFIG_ISL29035=y
|
CONFIG_ISL29035=y
|
||||||
CONFIG_LIS2DH=y
|
CONFIG_LIS2DH=y
|
||||||
|
CONFIG_LIS2DS12=y
|
||||||
CONFIG_LIS2MDL=y
|
CONFIG_LIS2MDL=y
|
||||||
CONFIG_LIS3DH=y
|
CONFIG_LIS3DH=y
|
||||||
CONFIG_LIS3MDL=y
|
CONFIG_LIS3MDL=y
|
||||||
|
|
|
@ -8,6 +8,8 @@ CONFIG_ISL29035=y
|
||||||
CONFIG_ISL29035_TRIGGER_OWN_THREAD=y
|
CONFIG_ISL29035_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_LIS2DH=y
|
CONFIG_LIS2DH=y
|
||||||
CONFIG_LIS2DH_TRIGGER_OWN_THREAD=y
|
CONFIG_LIS2DH_TRIGGER_OWN_THREAD=y
|
||||||
|
CONFIG_LIS2DS12=y
|
||||||
|
CONFIG_LIS2DS12_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_LIS2MDL=y
|
CONFIG_LIS2MDL=y
|
||||||
CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y
|
CONFIG_LIS2MDL_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_LIS3DH=y
|
CONFIG_LIS3DH=y
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue