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_HP206C hp206c)
|
||||
add_subdirectory_ifdef(CONFIG_HTS221 hts221)
|
||||
add_subdirectory_ifdef(CONFIG_IIS3DHHC iis3dhhc)
|
||||
add_subdirectory_ifdef(CONFIG_ISL29035 isl29035)
|
||||
add_subdirectory_ifdef(CONFIG_LIS2DH lis2dh)
|
||||
add_subdirectory_ifdef(CONFIG_LIS2DS12 lis2ds12)
|
||||
|
|
|
@ -73,6 +73,8 @@ source "drivers/sensor/hp206c/Kconfig"
|
|||
|
||||
source "drivers/sensor/hts221/Kconfig"
|
||||
|
||||
source "drivers/sensor/iis3dhhc/Kconfig"
|
||||
|
||||
source "drivers/sensor/isl29035/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
|
||||
#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
|
||||
#define DT_INST_0_ST_LIS2DH_LABEL ""
|
||||
#define DT_INST_0_ST_LIS2DH_BASE_ADDRESS 0
|
||||
|
|
|
@ -6,6 +6,7 @@ CONFIG_SENSOR=y
|
|||
CONFIG_SPI=y
|
||||
CONFIG_LOG=y
|
||||
CONFIG_SENSOR_LOG_LEVEL_DBG=y
|
||||
CONFIG_IIS3DHHC=y
|
||||
CONFIG_ISL29035=y
|
||||
CONFIG_LIS2DH=y
|
||||
CONFIG_LIS2DS12=y
|
||||
|
|
|
@ -5,6 +5,8 @@ CONFIG_ADC=y
|
|||
CONFIG_GPIO=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SENSOR=y
|
||||
CONFIG_IIS3DHHC=y
|
||||
CONFIG_IIS3DHHC_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_ISL29035=y
|
||||
CONFIG_ISL29035_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_LIS2DH=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue