driver/sensor: add IIS3DHHC accelerometer sensor
Add support to STM IIS3DHHC the ultra-low noise, high-stability three-axis linear accelerometer. Signed-off-by: Armando Visconti <armando.visconti@st.com>
This commit is contained in:
parent
b4094ea6c1
commit
871d132577
12 changed files with 754 additions and 0 deletions
|
@ -24,6 +24,7 @@ add_subdirectory_ifdef(CONFIG_TI_HDC ti_hdc)
|
||||||
add_subdirectory_ifdef(CONFIG_HMC5883L hmc5883l)
|
add_subdirectory_ifdef(CONFIG_HMC5883L hmc5883l)
|
||||||
add_subdirectory_ifdef(CONFIG_HP206C hp206c)
|
add_subdirectory_ifdef(CONFIG_HP206C hp206c)
|
||||||
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
||||||
|
add_subdirectory_ifdef(CONFIG_IIS3DHHC iis3dhhc)
|
||||||
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_LIS2DS12 lis2ds12)
|
||||||
|
|
|
@ -73,6 +73,8 @@ source "drivers/sensor/hp206c/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/hts221/Kconfig"
|
source "drivers/sensor/hts221/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/sensor/iis3dhhc/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/isl29035/Kconfig"
|
source "drivers/sensor/isl29035/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/lis2dh/Kconfig"
|
source "drivers/sensor/lis2dh/Kconfig"
|
||||||
|
|
11
drivers/sensor/iis3dhhc/CMakeLists.txt
Normal file
11
drivers/sensor/iis3dhhc/CMakeLists.txt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# ST Microelectronics IIS3DHHC accelerometer sensor
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_IIS3DHHC iis3dhhc.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_IIS3DHHC iis3dhhc_spi.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_IIS3DHHC_TRIGGER iis3dhhc_trigger.c)
|
72
drivers/sensor/iis3dhhc/Kconfig
Normal file
72
drivers/sensor/iis3dhhc/Kconfig
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
# ST Microelectronics IIS3DHHC accelerometer sensor
|
||||||
|
#
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
menuconfig IIS3DHHC
|
||||||
|
bool "IIS3DHHC accelerometer sensor"
|
||||||
|
depends on SPI
|
||||||
|
select HAS_STMEMSC
|
||||||
|
select USE_STDC_IIS3DHHC
|
||||||
|
help
|
||||||
|
Enable driver for IIS3DHHC SPI-based accelerometer sensor.
|
||||||
|
|
||||||
|
if IIS3DHHC
|
||||||
|
|
||||||
|
choice IIS3DHHC_TRIGGER_MODE
|
||||||
|
prompt "Trigger mode"
|
||||||
|
default IIS3DHHC_TRIGGER_GLOBAL_THREAD
|
||||||
|
help
|
||||||
|
Specify the type of triggering to be used by the driver.
|
||||||
|
|
||||||
|
config IIS3DHHC_TRIGGER_NONE
|
||||||
|
bool "No trigger"
|
||||||
|
|
||||||
|
config IIS3DHHC_TRIGGER_GLOBAL_THREAD
|
||||||
|
bool "Use global thread"
|
||||||
|
depends on GPIO
|
||||||
|
select IIS3DHHC_TRIGGER
|
||||||
|
|
||||||
|
config IIS3DHHC_TRIGGER_OWN_THREAD
|
||||||
|
bool "Use own thread"
|
||||||
|
depends on GPIO
|
||||||
|
select IIS3DHHC_TRIGGER
|
||||||
|
|
||||||
|
endchoice # IIS3DHHC_TRIGGER_MODE
|
||||||
|
|
||||||
|
config IIS3DHHC_TRIGGER
|
||||||
|
bool
|
||||||
|
|
||||||
|
config IIS3DHHC_THREAD_PRIORITY
|
||||||
|
int "Thread priority"
|
||||||
|
depends on IIS3DHHC_TRIGGER_OWN_THREAD
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Priority of thread used by the driver to handle interrupts.
|
||||||
|
|
||||||
|
config IIS3DHHC_THREAD_STACK_SIZE
|
||||||
|
int "Thread stack size"
|
||||||
|
depends on IIS3DHHC_TRIGGER_OWN_THREAD
|
||||||
|
default 1024
|
||||||
|
help
|
||||||
|
Stack size of thread used by the driver to handle interrupts.
|
||||||
|
|
||||||
|
menu "Attributes"
|
||||||
|
|
||||||
|
config IIS3DHHC_NORM_MODE
|
||||||
|
bool "Enable Sensor at 1KHz"
|
||||||
|
default y
|
||||||
|
|
||||||
|
config IIS3DHHC_DRDY_INT1
|
||||||
|
bool "Data ready interrupt to INT1 pin"
|
||||||
|
depends on IIS3DHHC_TRIGGER
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Say Y to route data ready interrupt to INT1 pin. Say N to route to
|
||||||
|
INT2 pin.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endif # IIS3DHHC
|
257
drivers/sensor/iis3dhhc/iis3dhhc.c
Normal file
257
drivers/sensor/iis3dhhc/iis3dhhc.c
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
/* ST Microelectronics IIS3DHHC accelerometer senor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/iis3dhhc.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include <init.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
#include <sys/__assert.h>
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#include "iis3dhhc.h"
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_REGISTER(IIS3DHHC);
|
||||||
|
|
||||||
|
static int iis3dhhc_sample_fetch(struct device *dev,
|
||||||
|
enum sensor_channel chan)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *data = dev->driver_data;
|
||||||
|
axis3bit16_t raw_accel;
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
|
||||||
|
|
||||||
|
iis3dhhc_acceleration_raw_get(data->ctx, raw_accel.u8bit);
|
||||||
|
data->acc[0] = sys_le16_to_cpu(raw_accel.i16bit[0]);
|
||||||
|
data->acc[1] = sys_le16_to_cpu(raw_accel.i16bit[1]);
|
||||||
|
data->acc[2] = sys_le16_to_cpu(raw_accel.i16bit[2]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IIS3DHHC_FROM_LSB_TO_ums2(lsb) \
|
||||||
|
((IIS3DHHC_FROM_LSB_TO_mg((s64_t)lsb) * SENSOR_G) / 1000LL)
|
||||||
|
|
||||||
|
static inline void iis3dhhc_convert(struct sensor_value *val,
|
||||||
|
s16_t raw_val)
|
||||||
|
{
|
||||||
|
s64_t micro_ms2;
|
||||||
|
|
||||||
|
/* Convert to m/s^2 */
|
||||||
|
micro_ms2 = IIS3DHHC_FROM_LSB_TO_ums2((s64_t)raw_val);
|
||||||
|
val->val1 = micro_ms2 / 1000000LL;
|
||||||
|
val->val2 = micro_ms2 % 1000000LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void iis3dhhc_channel_get_acc(struct device *dev,
|
||||||
|
enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u8_t ofs_start, ofs_stop;
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
struct sensor_value *pval = val;
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
ofs_start = ofs_stop = 0U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
ofs_start = ofs_stop = 1U;
|
||||||
|
break;
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
ofs_start = ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ofs_start = 0U; ofs_stop = 2U;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = ofs_start; i <= ofs_stop ; i++) {
|
||||||
|
iis3dhhc_convert(pval++, iis3dhhc->acc[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iis3dhhc_channel_get(struct device *dev,
|
||||||
|
enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_ACCEL_X:
|
||||||
|
case SENSOR_CHAN_ACCEL_Y:
|
||||||
|
case SENSOR_CHAN_ACCEL_Z:
|
||||||
|
case SENSOR_CHAN_ACCEL_XYZ:
|
||||||
|
iis3dhhc_channel_get_acc(dev, chan, val);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
LOG_DBG("Channel not supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iis3dhhc_odr_set(struct device *dev,
|
||||||
|
const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *data = dev->driver_data;
|
||||||
|
iis3dhhc_norm_mod_en_t en;
|
||||||
|
|
||||||
|
switch (val->val1) {
|
||||||
|
case 0:
|
||||||
|
en = IIS3DHHC_POWER_DOWN;
|
||||||
|
break;
|
||||||
|
case 1000:
|
||||||
|
en = IIS3DHHC_1kHz1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iis3dhhc_data_rate_set(data->ctx, en)) {
|
||||||
|
LOG_DBG("failed to set sampling rate");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iis3dhhc_attr_set(struct device *dev, enum sensor_channel chan,
|
||||||
|
enum sensor_attribute attr,
|
||||||
|
const struct sensor_value *val)
|
||||||
|
{
|
||||||
|
if (chan != SENSOR_CHAN_ALL) {
|
||||||
|
LOG_WRN("attr_set() not supported on this channel.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (attr) {
|
||||||
|
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||||
|
return iis3dhhc_odr_set(dev, val);
|
||||||
|
default:
|
||||||
|
LOG_DBG("operation not supported.");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sensor_driver_api iis3dhhc_api_funcs = {
|
||||||
|
.attr_set = iis3dhhc_attr_set,
|
||||||
|
.sample_fetch = iis3dhhc_sample_fetch,
|
||||||
|
.channel_get = iis3dhhc_channel_get,
|
||||||
|
#if CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
.trigger_set = iis3dhhc_trigger_set,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static int iis3dhhc_init_chip(struct device *dev)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *data = dev->driver_data;
|
||||||
|
u8_t chip_id, rst;
|
||||||
|
|
||||||
|
if (iis3dhhc_device_id_get(data->ctx, &chip_id) < 0) {
|
||||||
|
LOG_DBG("Failed reading chip id");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chip_id != IIS3DHHC_ID) {
|
||||||
|
LOG_DBG("Invalid chip id 0x%x", chip_id);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restore default configuration
|
||||||
|
*/
|
||||||
|
iis3dhhc_reset_set(data->ctx, PROPERTY_ENABLE);
|
||||||
|
do {
|
||||||
|
iis3dhhc_reset_get(data->ctx, &rst);
|
||||||
|
} while (rst);
|
||||||
|
|
||||||
|
/* Enable Block Data Update */
|
||||||
|
iis3dhhc_block_data_update_set(data->ctx, PROPERTY_ENABLE);
|
||||||
|
|
||||||
|
/* Set Output Data Rate */
|
||||||
|
#ifdef CONFIG_IIS3DHHC_NORM_MODE
|
||||||
|
iis3dhhc_data_rate_set(data->ctx, 1);
|
||||||
|
#else
|
||||||
|
iis3dhhc_data_rate_set(data->ctx, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable temperature compensation */
|
||||||
|
iis3dhhc_offset_temp_comp_set(data->ctx, PROPERTY_ENABLE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iis3dhhc_init(struct device *dev)
|
||||||
|
{
|
||||||
|
const struct iis3dhhc_config * const config = dev->config->config_info;
|
||||||
|
struct iis3dhhc_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
data->bus = device_get_binding(config->master_dev_name);
|
||||||
|
if (!data->bus) {
|
||||||
|
LOG_DBG("bus master not found: %s", config->master_dev_name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
config->bus_init(dev);
|
||||||
|
|
||||||
|
if (iis3dhhc_init_chip(dev) < 0) {
|
||||||
|
LOG_DBG("Failed to initialize chip");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
if (iis3dhhc_init_interrupt(dev) < 0) {
|
||||||
|
LOG_ERR("Failed to initialize interrupt.");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct iis3dhhc_data iis3dhhc_data;
|
||||||
|
|
||||||
|
static const struct iis3dhhc_config iis3dhhc_config = {
|
||||||
|
.master_dev_name = DT_INST_0_ST_IIS3DHHC_BUS_NAME,
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
#ifdef CONFIG_IIS3DHHC_DRDY_INT1
|
||||||
|
.int_port = DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_CONTROLLER_0,
|
||||||
|
.int_pin = DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_PIN_0,
|
||||||
|
#else
|
||||||
|
.int_port = DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_CONTROLLER_1,
|
||||||
|
.int_pin = DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_PIN_1,
|
||||||
|
#endif /* CONFIG_IIS3DHHC_DRDY_INT1 */
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER */
|
||||||
|
#if defined(DT_ST_IIS3DHHC_BUS_SPI)
|
||||||
|
.bus_init = iis3dhhc_spi_init,
|
||||||
|
.spi_conf.frequency = DT_INST_0_ST_IIS3DHHC_SPI_MAX_FREQUENCY,
|
||||||
|
.spi_conf.operation = (SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
|
||||||
|
SPI_MODE_CPHA | SPI_WORD_SET(8) |
|
||||||
|
SPI_LINES_SINGLE),
|
||||||
|
.spi_conf.slave = DT_INST_0_ST_IIS3DHHC_BASE_ADDRESS,
|
||||||
|
#if defined(DT_INST_0_ST_IIS3DHHC_CS_GPIO_CONTROLLER)
|
||||||
|
.gpio_cs_port = DT_INST_0_ST_IIS3DHHC_CS_GPIOS_CONTROLLER,
|
||||||
|
.cs_gpio = DT_INST_0_ST_IIS3DHHC_CS_GPIOS_PIN,
|
||||||
|
|
||||||
|
.spi_conf.cs = &iis3dhhc_data.cs_ctrl,
|
||||||
|
#else
|
||||||
|
.spi_conf.cs = NULL,
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "BUS MACRO NOT DEFINED IN DTS"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
DEVICE_AND_API_INIT(iis3dhhc, DT_INST_0_ST_IIS3DHHC_LABEL, iis3dhhc_init,
|
||||||
|
&iis3dhhc_data, &iis3dhhc_config, POST_KERNEL,
|
||||||
|
CONFIG_SENSOR_INIT_PRIORITY, &iis3dhhc_api_funcs);
|
80
drivers/sensor/iis3dhhc/iis3dhhc.h
Normal file
80
drivers/sensor/iis3dhhc/iis3dhhc.h
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/* ST Microelectronics IIS3DHHC accelerometer sensor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/iis3dhhc.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_DRIVERS_SENSOR_IIS3DHHC_IIS3DHHC_H_
|
||||||
|
#define ZEPHYR_DRIVERS_SENSOR_IIS3DHHC_IIS3DHHC_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <drivers/spi.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <drivers/sensor.h>
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
#include <sys/util.h>
|
||||||
|
#include "iis3dhhc_reg.h"
|
||||||
|
|
||||||
|
struct iis3dhhc_config {
|
||||||
|
char *master_dev_name;
|
||||||
|
int (*bus_init)(struct device *dev);
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
const char *int_port;
|
||||||
|
u8_t int_pin;
|
||||||
|
#endif
|
||||||
|
#ifdef DT_ST_IIS3DHHC_BUS_SPI
|
||||||
|
struct spi_config spi_conf;
|
||||||
|
#if defined(DT_INST_0_ST_IIS3DHHC_CS_GPIO_CONTROLLER)
|
||||||
|
const char *gpio_cs_port;
|
||||||
|
u8_t cs_gpio;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct iis3dhhc_data {
|
||||||
|
struct device *bus;
|
||||||
|
s16_t acc[3];
|
||||||
|
|
||||||
|
iis3dhhc_ctx_t *ctx;
|
||||||
|
|
||||||
|
#ifdef DT_ST_IIS3DHHC_BUS_SPI
|
||||||
|
iis3dhhc_ctx_t ctx_spi;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
struct device *gpio;
|
||||||
|
u32_t pin;
|
||||||
|
struct gpio_callback gpio_cb;
|
||||||
|
|
||||||
|
sensor_trigger_handler_t handler_drdy;
|
||||||
|
|
||||||
|
#if defined(CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD)
|
||||||
|
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_IIS3DHHC_THREAD_STACK_SIZE);
|
||||||
|
struct k_thread thread;
|
||||||
|
struct k_sem gpio_sem;
|
||||||
|
#elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD)
|
||||||
|
struct k_work work;
|
||||||
|
struct device *dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER */
|
||||||
|
#if defined(DT_INST_0_ST_IIS3DHHC_CS_GPIO_CONTROLLER)
|
||||||
|
struct spi_cs_control cs_ctrl;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int iis3dhhc_spi_init(struct device *dev);
|
||||||
|
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER
|
||||||
|
int iis3dhhc_trigger_set(struct device *dev,
|
||||||
|
const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler);
|
||||||
|
|
||||||
|
int iis3dhhc_init_interrupt(struct device *dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_DRIVERS_SENSOR_IIS3DHHC_IIS3DHHC_H_ */
|
126
drivers/sensor/iis3dhhc/iis3dhhc_spi.c
Normal file
126
drivers/sensor/iis3dhhc/iis3dhhc_spi.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/* ST Microelectronics IIS3DHHC accelerometer sensor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/iis3dhhc.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "iis3dhhc.h"
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#ifdef DT_ST_IIS3DHHC_BUS_SPI
|
||||||
|
|
||||||
|
#define IIS3DHHC_SPI_READ (1 << 7)
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_DECLARE(IIS3DHHC);
|
||||||
|
|
||||||
|
static struct spi_config iis3dhhc_spi_conf = {
|
||||||
|
.frequency = DT_INST_0_ST_IIS3DHHC_SPI_MAX_FREQUENCY,
|
||||||
|
.operation = (SPI_OP_MODE_MASTER | SPI_MODE_CPOL |
|
||||||
|
SPI_MODE_CPHA | SPI_WORD_SET(8) | SPI_LINES_SINGLE),
|
||||||
|
.slave = DT_INST_0_ST_IIS3DHHC_BASE_ADDRESS,
|
||||||
|
.cs = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int iis3dhhc_spi_read(struct iis3dhhc_data *ctx, u8_t reg,
|
||||||
|
u8_t *data, u16_t len)
|
||||||
|
{
|
||||||
|
struct spi_config *spi_cfg = &iis3dhhc_spi_conf;
|
||||||
|
u8_t buffer_tx[2] = { reg | IIS3DHHC_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 = data,
|
||||||
|
.len = len,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set rx = {
|
||||||
|
.buffers = rx_buf,
|
||||||
|
.count = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
if (spi_transceive(ctx->bus, spi_cfg, &tx, &rx)) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int iis3dhhc_spi_write(struct iis3dhhc_data *ctx, u8_t reg,
|
||||||
|
u8_t *data, u16_t len)
|
||||||
|
{
|
||||||
|
struct spi_config *spi_cfg = &iis3dhhc_spi_conf;
|
||||||
|
u8_t buffer_tx[1] = { reg & ~IIS3DHHC_SPI_READ };
|
||||||
|
const struct spi_buf tx_buf[2] = {
|
||||||
|
{
|
||||||
|
.buf = buffer_tx,
|
||||||
|
.len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.buf = data,
|
||||||
|
.len = len,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const struct spi_buf_set tx = {
|
||||||
|
.buffers = tx_buf,
|
||||||
|
.count = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (spi_write(ctx->bus, spi_cfg, &tx)) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iis3dhhc_ctx_t iis3dhhc_spi_ctx = {
|
||||||
|
.read_reg = (iis3dhhc_read_ptr) iis3dhhc_spi_read,
|
||||||
|
.write_reg = (iis3dhhc_write_ptr) iis3dhhc_spi_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
int iis3dhhc_spi_init(struct device *dev)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *data = dev->driver_data;
|
||||||
|
|
||||||
|
data->ctx = &iis3dhhc_spi_ctx;
|
||||||
|
data->ctx->handle = data;
|
||||||
|
|
||||||
|
#if defined(DT_INST_0_ST_IIS3DHHC_CS_GPIOS_CONTROLLER)
|
||||||
|
/* handle SPI CS thru GPIO if it is the case */
|
||||||
|
data->cs_ctrl.gpio_dev = device_get_binding(
|
||||||
|
DT_INST_0_ST_IIS3DHHC_CS_GPIOS_CONTROLLER);
|
||||||
|
if (!data->cs_ctrl.gpio_dev) {
|
||||||
|
LOG_ERR("Unable to get GPIO SPI CS device");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->cs_ctrl.gpio_pin = DT_INST_0_ST_IIS3DHHC_CS_GPIOS_PIN;
|
||||||
|
data->cs_ctrl.delay = 0U;
|
||||||
|
|
||||||
|
iis3dhhc_spi_conf.cs = &data->cs_ctrl;
|
||||||
|
|
||||||
|
LOG_DBG("SPI GPIO CS configured on %s:%u",
|
||||||
|
DT_INST_0_ST_IIS3DHHC_CS_GPIOS_CONTROLLER,
|
||||||
|
DT_INST_0_ST_IIS3DHHC_CS_GPIOS_PIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* DT_ST_IIS3DHHC_BUS_SPI */
|
172
drivers/sensor/iis3dhhc/iis3dhhc_trigger.c
Normal file
172
drivers/sensor/iis3dhhc/iis3dhhc_trigger.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
/* ST Microelectronics IIS3DHHC accelerometer sensor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 STMicroelectronics
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Datasheet:
|
||||||
|
* https://www.st.com/resource/en/datasheet/iis3dhhc.pdf
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kernel.h>
|
||||||
|
#include <drivers/sensor.h>
|
||||||
|
#include <drivers/gpio.h>
|
||||||
|
#include <logging/log.h>
|
||||||
|
|
||||||
|
#include "iis3dhhc.h"
|
||||||
|
|
||||||
|
#define LOG_LEVEL CONFIG_SENSOR_LOG_LEVEL
|
||||||
|
LOG_MODULE_DECLARE(IIS3DHHC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iis3dhhc_enable_int - enable selected int pin to generate interrupt
|
||||||
|
*/
|
||||||
|
static int iis3dhhc_enable_int(struct device *dev, int enable)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
|
||||||
|
/* set interrupt */
|
||||||
|
#ifdef CONFIG_IIS3DHHC_DRDY_INT1
|
||||||
|
return iis3dhhc_drdy_on_int1_set(iis3dhhc->ctx, enable);
|
||||||
|
#else
|
||||||
|
return iis3dhhc_drdy_on_int2_set(iis3dhhc->ctx, enable);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iis3dhhc_trigger_set - link external trigger to event data ready
|
||||||
|
*/
|
||||||
|
int iis3dhhc_trigger_set(struct device *dev,
|
||||||
|
const struct sensor_trigger *trig,
|
||||||
|
sensor_trigger_handler_t handler)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
axis3bit16_t raw;
|
||||||
|
|
||||||
|
if (trig->chan == SENSOR_CHAN_ACCEL_XYZ) {
|
||||||
|
iis3dhhc->handler_drdy = handler;
|
||||||
|
if (handler) {
|
||||||
|
/* dummy read: re-trigger interrupt */
|
||||||
|
iis3dhhc_acceleration_raw_get(iis3dhhc->ctx, raw.u8bit);
|
||||||
|
return iis3dhhc_enable_int(dev, PROPERTY_ENABLE);
|
||||||
|
} else {
|
||||||
|
return iis3dhhc_enable_int(dev, PROPERTY_DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iis3dhhc_handle_interrupt - handle the drdy event
|
||||||
|
* read data and call handler if registered any
|
||||||
|
*/
|
||||||
|
static void iis3dhhc_handle_interrupt(void *arg)
|
||||||
|
{
|
||||||
|
struct device *dev = arg;
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
struct sensor_trigger drdy_trigger = {
|
||||||
|
.type = SENSOR_TRIG_DATA_READY,
|
||||||
|
};
|
||||||
|
const struct iis3dhhc_config *cfg = dev->config->config_info;
|
||||||
|
|
||||||
|
if (iis3dhhc->handler_drdy != NULL) {
|
||||||
|
iis3dhhc->handler_drdy(dev, &drdy_trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_pin_enable_callback(iis3dhhc->gpio, cfg->int_pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iis3dhhc_gpio_callback(struct device *dev,
|
||||||
|
struct gpio_callback *cb, u32_t pins)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *iis3dhhc =
|
||||||
|
CONTAINER_OF(cb, struct iis3dhhc_data, gpio_cb);
|
||||||
|
const struct iis3dhhc_config *cfg = dev->config->config_info;
|
||||||
|
|
||||||
|
ARG_UNUSED(pins);
|
||||||
|
|
||||||
|
gpio_pin_disable_callback(dev, cfg->int_pin);
|
||||||
|
|
||||||
|
#if defined(CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_give(&iis3dhhc->gpio_sem);
|
||||||
|
#elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD)
|
||||||
|
k_work_submit(&iis3dhhc->work);
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD
|
||||||
|
static void iis3dhhc_thread(int dev_ptr, int unused)
|
||||||
|
{
|
||||||
|
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
|
||||||
|
ARG_UNUSED(unused);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
k_sem_take(&iis3dhhc->gpio_sem, K_FOREVER);
|
||||||
|
iis3dhhc_handle_interrupt(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */
|
||||||
|
|
||||||
|
#ifdef CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD
|
||||||
|
static void iis3dhhc_work_cb(struct k_work *work)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *iis3dhhc =
|
||||||
|
CONTAINER_OF(work, struct iis3dhhc_data, work);
|
||||||
|
|
||||||
|
iis3dhhc_handle_interrupt(iis3dhhc->dev);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD */
|
||||||
|
|
||||||
|
int iis3dhhc_init_interrupt(struct device *dev)
|
||||||
|
{
|
||||||
|
struct iis3dhhc_data *iis3dhhc = dev->driver_data;
|
||||||
|
const struct iis3dhhc_config *cfg = dev->config->config_info;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* setup data ready gpio interrupt (INT1 or INT2) */
|
||||||
|
iis3dhhc->gpio = device_get_binding(cfg->int_port);
|
||||||
|
if (iis3dhhc->gpio == NULL) {
|
||||||
|
LOG_DBG("Cannot get pointer to %s device", cfg->int_port);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD)
|
||||||
|
k_sem_init(&iis3dhhc->gpio_sem, 0, UINT_MAX);
|
||||||
|
|
||||||
|
k_thread_create(&iis3dhhc->thread, iis3dhhc->thread_stack,
|
||||||
|
CONFIG_IIS3DHHC_THREAD_STACK_SIZE,
|
||||||
|
(k_thread_entry_t)iis3dhhc_thread, dev,
|
||||||
|
0, NULL, K_PRIO_COOP(CONFIG_IIS3DHHC_THREAD_PRIORITY),
|
||||||
|
0, 0);
|
||||||
|
#elif defined(CONFIG_IIS3DHHC_TRIGGER_GLOBAL_THREAD)
|
||||||
|
iis3dhhc->work.handler = iis3dhhc_work_cb;
|
||||||
|
iis3dhhc->dev = dev;
|
||||||
|
#endif /* CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD */
|
||||||
|
|
||||||
|
ret = gpio_pin_configure(iis3dhhc->gpio, cfg->int_pin,
|
||||||
|
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||||
|
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DBG("Could not configure gpio");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_init_callback(&iis3dhhc->gpio_cb,
|
||||||
|
iis3dhhc_gpio_callback,
|
||||||
|
BIT(cfg->int_pin));
|
||||||
|
|
||||||
|
if (gpio_add_callback(iis3dhhc->gpio, &iis3dhhc->gpio_cb) < 0) {
|
||||||
|
LOG_DBG("Could not set gpio callback");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable interrupt on int1/int2 in pulse mode */
|
||||||
|
if (iis3dhhc_drdy_notification_mode_set(iis3dhhc->ctx, IIS3DHHC_PULSED)) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gpio_pin_enable_callback(iis3dhhc->gpio, cfg->int_pin);
|
||||||
|
}
|
18
dts/bindings/sensor/st,iis3dhhc-spi.yaml
Normal file
18
dts/bindings/sensor/st,iis3dhhc-spi.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright (c) 2019 STMicroelectronics
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
title: STMicroelectronics MEMS sensors IIS3DHHC SPI
|
||||||
|
|
||||||
|
description: >
|
||||||
|
This binding gives a base representation of IIS3DHHC 3-axis accelerometer
|
||||||
|
accessed through SPI bus
|
||||||
|
|
||||||
|
compatible: "st,iis3dhhc"
|
||||||
|
|
||||||
|
include: spi-device.yaml
|
||||||
|
|
||||||
|
properties:
|
||||||
|
irq-gpios:
|
||||||
|
type: phandle-array
|
||||||
|
required: false
|
||||||
|
description: DRDY pin
|
|
@ -266,6 +266,18 @@
|
||||||
#define DT_INST_0_BOSCH_BMI160_SPI_MAX_FREQUENCY 6400000
|
#define DT_INST_0_BOSCH_BMI160_SPI_MAX_FREQUENCY 6400000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DT_INST_0_ST_IIS3DHHC_LABEL
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_LABEL ""
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_BASE_ADDRESS 0
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_BUS_NAME ""
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_CONTROLLER_0 ""
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_PIN_0 0
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_CONTROLLER_1 ""
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_IRQ_GPIOS_PIN_1 0
|
||||||
|
#define DT_INST_0_ST_IIS3DHHC_SPI_MAX_FREQUENCY 6400000
|
||||||
|
#define DT_ST_IIS3DHHC_BUS_SPI 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DT_INST_0_ST_LIS2DH_LABEL
|
#ifndef DT_INST_0_ST_LIS2DH_LABEL
|
||||||
#define DT_INST_0_ST_LIS2DH_LABEL ""
|
#define DT_INST_0_ST_LIS2DH_LABEL ""
|
||||||
#define DT_INST_0_ST_LIS2DH_BASE_ADDRESS 0
|
#define DT_INST_0_ST_LIS2DH_BASE_ADDRESS 0
|
||||||
|
|
|
@ -6,6 +6,7 @@ CONFIG_SENSOR=y
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_LOG=y
|
CONFIG_LOG=y
|
||||||
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
||||||
|
CONFIG_IIS3DHHC=y
|
||||||
CONFIG_ISL29035=y
|
CONFIG_ISL29035=y
|
||||||
CONFIG_LIS2DH=y
|
CONFIG_LIS2DH=y
|
||||||
CONFIG_LIS2DS12=y
|
CONFIG_LIS2DS12=y
|
||||||
|
|
|
@ -5,6 +5,8 @@ CONFIG_ADC=y
|
||||||
CONFIG_GPIO=y
|
CONFIG_GPIO=y
|
||||||
CONFIG_SPI=y
|
CONFIG_SPI=y
|
||||||
CONFIG_SENSOR=y
|
CONFIG_SENSOR=y
|
||||||
|
CONFIG_IIS3DHHC=y
|
||||||
|
CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_ISL29035=y
|
CONFIG_ISL29035=y
|
||||||
CONFIG_ISL29035_TRIGGER_OWN_THREAD=y
|
CONFIG_ISL29035_TRIGGER_OWN_THREAD=y
|
||||||
CONFIG_LIS2DH=y
|
CONFIG_LIS2DH=y
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue