drivers: sensors: fdc2x1x: Add driver for Texas Instruments FDC2X1X
Adds support for the Texas Instruments FDC2X1X Capacitance-to-Digital Converter for Proximity and Level Sensing Applications. Signed-off-by: Igor Knippenberg <igor.knippenberg@gmail.com>
This commit is contained in:
parent
6a2a26024a
commit
79a3d1b85a
12 changed files with 1874 additions and 0 deletions
|
@ -21,6 +21,7 @@ add_subdirectory_ifdef(CONFIG_CCS811 ccs811)
|
|||
add_subdirectory_ifdef(CONFIG_DHT dht)
|
||||
add_subdirectory_ifdef(CONFIG_DPS310 dps310)
|
||||
add_subdirectory_ifdef(CONFIG_ENS210 ens210)
|
||||
add_subdirectory_ifdef(CONFIG_FDC2X1X fdc2x1x)
|
||||
add_subdirectory_ifdef(CONFIG_FXAS21002 fxas21002)
|
||||
add_subdirectory_ifdef(CONFIG_FXOS8700 fxos8700)
|
||||
add_subdirectory(grove)
|
||||
|
|
|
@ -80,6 +80,8 @@ source "drivers/sensor/dps310/Kconfig"
|
|||
|
||||
source "drivers/sensor/ens210/Kconfig"
|
||||
|
||||
source "drivers/sensor/fdc2x1x/Kconfig"
|
||||
|
||||
source "drivers/sensor/fxas21002/Kconfig"
|
||||
|
||||
source "drivers/sensor/fxos8700/Kconfig"
|
||||
|
|
9
drivers/sensor/fdc2x1x/CMakeLists.txt
Normal file
9
drivers/sensor/fdc2x1x/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Copyright (c) 2020 arithmetics.io
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_FDC2X1X fdc2x1x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_FDC2X1X_TRIGGER fdc2x1x_trigger.c)
|
52
drivers/sensor/fdc2x1x/Kconfig
Normal file
52
drivers/sensor/fdc2x1x/Kconfig
Normal file
|
@ -0,0 +1,52 @@
|
|||
# FDC2X1X Capacitance-to-Digital Converter configuration options
|
||||
|
||||
# Copyright (c) 2020 arithmetics.io
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig FDC2X1X
|
||||
bool "FDC2X1X Capacitance-to-Digital Converter"
|
||||
depends on I2C && NEWLIB_LIBC
|
||||
help
|
||||
Enable driver for FDC2X1X Capacitance-to-Digital Converter.
|
||||
|
||||
if FDC2X1X
|
||||
|
||||
choice
|
||||
prompt "Trigger mode"
|
||||
default FDC2X1X_TRIGGER_NONE
|
||||
help
|
||||
Specify the type of triggering used by the driver.
|
||||
|
||||
config FDC2X1X_TRIGGER_NONE
|
||||
bool "No trigger"
|
||||
|
||||
config FDC2X1X_TRIGGER_GLOBAL_THREAD
|
||||
bool "Use global thread"
|
||||
depends on GPIO
|
||||
select FDC2X1X_TRIGGER
|
||||
|
||||
config FDC2X1X_TRIGGER_OWN_THREAD
|
||||
bool "Use own thread"
|
||||
depends on GPIO
|
||||
select FDC2X1X_TRIGGER
|
||||
|
||||
endchoice
|
||||
|
||||
config FDC2X1X_TRIGGER
|
||||
bool
|
||||
|
||||
config FDC2X1X_THREAD_PRIORITY
|
||||
int "Thread priority"
|
||||
depends on FDC2X1X_TRIGGER_OWN_THREAD && FDC2X1X_TRIGGER
|
||||
default 10
|
||||
help
|
||||
Priority of thread used by the driver to handle interrupts.
|
||||
|
||||
config FDC2X1X_THREAD_STACK_SIZE
|
||||
int "Thread stack size"
|
||||
depends on FDC2X1X_TRIGGER_OWN_THREAD && FDC2X1X_TRIGGER
|
||||
default 1024
|
||||
help
|
||||
Stack size of thread used by the driver to handle interrupts.
|
||||
|
||||
endif # FDC2X1X
|
1082
drivers/sensor/fdc2x1x/fdc2x1x.c
Normal file
1082
drivers/sensor/fdc2x1x/fdc2x1x.c
Normal file
File diff suppressed because it is too large
Load diff
233
drivers/sensor/fdc2x1x/fdc2x1x.h
Normal file
233
drivers/sensor/fdc2x1x/fdc2x1x.h
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright (c) 2020 arithmetics.io
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_FDC2X1X_FDC2X1X_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_FDC2X1X_FDC2X1X_H_
|
||||
|
||||
#include <drivers/sensor.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <drivers/gpio.h>
|
||||
|
||||
#define PI (3.14159265)
|
||||
|
||||
/*
|
||||
* FDC2X1X registers definition
|
||||
*/
|
||||
#define FDC2X1X_DATA_CH0 0x00
|
||||
#define FDC2X1X_DATA_LSB_CH0 0x01
|
||||
#define FDC2X1X_DATA_CH1 0x02
|
||||
#define FDC2X1X_DATA_LSB_CH1 0x03
|
||||
#define FDC2X1X_DATA_CH2 0x04
|
||||
#define FDC2X1X_DATA_LSB_CH2 0x05
|
||||
#define FDC2X1X_DATA_CH3 0x06
|
||||
#define FDC2X1X_DATA_LSB_CH3 0x07
|
||||
#define FDC2X1X_RCOUNT_CH0 0x08
|
||||
#define FDC2X1X_RCOUNT_CH1 0x09
|
||||
#define FDC2X1X_RCOUNT_CH2 0x0A
|
||||
#define FDC2X1X_RCOUNT_CH3 0x0B
|
||||
#define FDC2X1X_OFFSET_CH0 0x0C
|
||||
#define FDC2X1X_OFFSET_CH1 0x0D
|
||||
#define FDC2X1X_OFFSET_CH2 0x0E
|
||||
#define FDC2X1X_OFFSET_CH3 0x0F
|
||||
#define FDC2X1X_SETTLECOUNT_CH0 0x10
|
||||
#define FDC2X1X_SETTLECOUNT_CH1 0x11
|
||||
#define FDC2X1X_SETTLECOUNT_CH2 0x12
|
||||
#define FDC2X1X_SETTLECOUNT_CH3 0x13
|
||||
#define FDC2X1X_CLOCK_DIVIDERS_CH0 0x14
|
||||
#define FDC2X1X_CLOCK_DIVIDERS_CH1 0x15
|
||||
#define FDC2X1X_CLOCK_DIVIDERS_CH2 0x16
|
||||
#define FDC2X1X_CLOCK_DIVIDERS_CH3 0x17
|
||||
#define FDC2X1X_STATUS 0x18
|
||||
#define FDC2X1X_ERROR_CONFIG 0x19
|
||||
#define FDC2X1X_CONFIG 0x1A
|
||||
#define FDC2X1X_MUX_CONFIG 0x1B
|
||||
#define FDC2X1X_RESET_DEV 0x1C
|
||||
#define FDC2X1X_DRIVE_CURRENT_CH0 0x1E
|
||||
#define FDC2X1X_DRIVE_CURRENT_CH1 0x1F
|
||||
#define FDC2X1X_DRIVE_CURRENT_CH2 0x20
|
||||
#define FDC2X1X_DRIVE_CURRENT_CH3 0x21
|
||||
#define FDC2X1X_MANUFACTURER_ID 0x7E
|
||||
#define FDC2X1X_DEVICE_ID 0x7F
|
||||
|
||||
#define FDC2X1X_MANUFACTURER_ID_VAL 0x5449
|
||||
|
||||
#define FDC2X1X_DEVICE_ID_VAL_28BIT 0x3055
|
||||
#define FDC2X1X_DEVICE_ID_VAL 0x3054
|
||||
|
||||
#define FDC2X1X_READ 0x01u
|
||||
#define FDC2X1X_REG_READ(x) (((x & 0xFF) << 1) | FDC2X1X_READ)
|
||||
#define FDC2X1X_REG_WRITE(x) ((x & 0xFF) << 1)
|
||||
#define FDC2X1X_TO_I2C_REG(x) ((x) >> 1)
|
||||
|
||||
/* CLOCK_DIVIDERS_CHX Field Descriptions */
|
||||
#define FDC2X1X_CLK_DIV_CHX_FIN_SEL_MSK GENMASK(13, 12)
|
||||
#define FDC2X1X_CLK_DIV_CHX_FIN_SEL_SET(x) (((x) & 0x3) << 12)
|
||||
#define FDC2X1X_CLK_DIV_CHX_FIN_SEL_GET(x) (((x) >> 12) & 0x3)
|
||||
#define FDC2X1X_CLK_DIV_CHX_FREF_DIV_MSK GENMASK(9, 0)
|
||||
#define FDC2X1X_CLK_DIV_CHX_FREF_DIV_SET(x) ((x) & 0x1FF)
|
||||
#define FDC2X1X_CLK_DIV_CHX_FREF_DIV_GET(x) (((x) >> 0) & 0x1FF)
|
||||
|
||||
/* STATUS Field Descriptions */
|
||||
#define FDC2X1X_STATUS_ERR_CHAN(x) (((x) >> 14) & 0x3)
|
||||
#define FDC2X1X_STATUS_ERR_WD(x) (((x) >> 11) & 0x1)
|
||||
#define FDC2X1X_STATUS_ERR_AHW(x) (((x) >> 10) & 0x1)
|
||||
#define FDC2X1X_STATUS_ERR_ALW(x) (((x) >> 9) & 0x1)
|
||||
#define FDC2X1X_STATUS_DRDY(x) (((x) >> 6) & 0x1)
|
||||
#define FDC2X1X_STATUS_CH0_UNREADCONV_RDY(x) (((x) >> 3) & 0x1)
|
||||
#define FDC2X1X_STATUS_CH1_UNREADCONV_RDY(x) (((x) >> 2) & 0x1)
|
||||
#define FDC2X1X_STATUS_CH2_UNREADCONV_RDY(x) (((x) >> 1) & 0x1)
|
||||
#define FDC2X1X_STATUS_CH3_UNREADCONV_RDY(x) (((x) >> 0) & 0x1)
|
||||
|
||||
/* ERROR_CONFIG */
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2OUT_MSK BIT(13)
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2OUT_SET(x) (((x) & 0x1) << 13)
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2OUT_GET(x) (((x) >> 13) & 0x1)
|
||||
#define FDC2X1X_ERROR_CONFIG_AH_WARN2OUT_MSK BIT(12)
|
||||
#define FDC2X1X_ERROR_CONFIG_AH_WARN2OUT_SET(x) (((x) & 0x1) << 12)
|
||||
#define FDC2X1X_ERROR_CONFIG_AH_WARN2OUT_GET(x) (((x) >> 12) & 0x1)
|
||||
#define FDC2X1X_ERROR_CONFIG_AL_WARN2OUT_MSK BIT(11)
|
||||
#define FDC2X1X_ERROR_CONFIG_AL_WARN2OUT_SET(x) (((x) & 0x1) << 11)
|
||||
#define FDC2X1X_ERROR_CONFIG_AL_WARN2OUT_GET(x) (((x) >> 11) & 0x1)
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2INT_MSK BIT(5)
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2INT_SET(x) (((x) & 0x1) << 5)
|
||||
#define FDC2X1X_ERROR_CONFIG_WD_ERR2INT_GET(x) (((x) >> 5) & 0x1)
|
||||
#define FDC2X1X_ERROR_CONFIG_DRDY_2INT_MSK BIT(0)
|
||||
#define FDC2X1X_ERROR_CONFIG_DRDY_2INT_SET(x) (((x) & 0x1) << 0)
|
||||
#define FDC2X1X_ERROR_CONFIG_DRDY_2INT_GET(x) (((x) >> 0) & 0x1)
|
||||
|
||||
/* CONFIG Field Descriptions */
|
||||
#define FDC2X1X_CFG_ACTIVE_CHAN_MSK GENMASK(15, 14)
|
||||
#define FDC2X1X_CFG_ACTIVE_CHAN_SET(x) (((x) & 0x3) << 14)
|
||||
#define FDC2X1X_CFG_ACTIVE_CHAN_GET(x) (((x) >> 14) & 0x3)
|
||||
#define FDC2X1X_CFG_SLEEP_SET_EN_MSK BIT(13)
|
||||
#define FDC2X1X_CFG_SLEEP_SET_EN_SET(x) (((x) & 0x1) << 13)
|
||||
#define FDC2X1X_CFG_SLEEP_SET_EN_GET(x) (((x) >> 13) & 0x1)
|
||||
#define FDC2X1X_CFG_SENSOR_ACTIVATE_SEL_MSK BIT(11)
|
||||
#define FDC2X1X_CFG_SENSOR_ACTIVATE_SEL_SET(x) (((x) & 0x1) << 11)
|
||||
#define FDC2X1X_CFG_SENSOR_ACTIVATE_SEL_GET(x) (((x) >> 11) & 0x1)
|
||||
#define FDC2X1X_CFG_REF_CLK_SRC_MSK BIT(9)
|
||||
#define FDC2X1X_CFG_REF_CLK_SRC_SET(x) (((x) & 0x1) << 9)
|
||||
#define FDC2X1X_CFG_REF_CLK_SRC_GET(x) (((x) >> 9) & 0x1)
|
||||
#define FDC2X1X_CFG_INTB_DIS_MSK BIT(7)
|
||||
#define FDC2X1X_CFG_INTB_DIS_SET(x) (((x) & 0x1) << 7)
|
||||
#define FDC2X1X_CFG_INTB_DIS_GET(x) (((x) >> 7) & 0x1)
|
||||
#define FDC2X1X_CFG_HIGH_CURRENT_DRV_MSK BIT(6)
|
||||
#define FDC2X1X_CFG_HIGH_CURRENT_DRV_SET(x) (((x) & 0x1) << 6)
|
||||
#define FDC2X1X_CFG_HIGH_CURRENT_DRV_GET(x) (((x) >> 6) & 0x1)
|
||||
|
||||
/* MUX_CONFIG Field Descriptions */
|
||||
#define FDC2X1X_MUX_CFG_AUTOSCAN_EN_MSK BIT(15)
|
||||
#define FDC2X1X_MUX_CFG_AUTOSCAN_EN_SET(x) (((x) & 0x1) << 15)
|
||||
#define FDC2X1X_MUX_CFG_AUTOSCAN_EN_GET(x) (((x) >> 15) & 0x1)
|
||||
#define FDC2X1X_MUX_CFG_RR_SEQUENCE_MSK GENMASK(14, 13)
|
||||
#define FDC2X1X_MUX_CFG_RR_SEQUENCE_SET(x) (((x) & 0x3) << 13)
|
||||
#define FDC2X1X_MUX_CFG_RR_SEQUENCE_GET(x) (((x) >> 13) & 0x3)
|
||||
#define FDC2X1X_MUX_CFG_DEGLITCH_MSK GENMASK(2, 0)
|
||||
#define FDC2X1X_MUX_CFG_DEGLITCH_SET(x) ((x) & 0x7)
|
||||
#define FDC2X1X_MUX_CFG_DEGLITCH_GET(x) (((x) >> 0) & 0x7)
|
||||
|
||||
/* RESET_DEV Field Descriptions */
|
||||
#define FDC2X1X_RESET_DEV_MSK BIT(15)
|
||||
#define FDC2X1X_RESET_DEV_SET(x) (((x) & 0x1) << 15)
|
||||
#define FDC2X1X_RESET_DEV_OUTPUT_GAIN_MSK GENMASK(10, 9)
|
||||
#define FDC2X1X_RESET_DEV_OUTPUT_GAIN_SET(x) (((x) & 0x3) << 9)
|
||||
#define FDC2X1X_RESET_DEV_OUTPUT_GAIN_GET(x) (((x) >> 9) & 0x3)
|
||||
|
||||
/* DRIVE_CURRENT_CHX Field Descriptions */
|
||||
#define FDC2X1X_DRV_CURRENT_CHX_IDRIVE_MSK GENMASK(15, 11)
|
||||
#define FDC2X1X_DRV_CURRENT_CHX_IDRIVE_SET(x) (((x) & 0x1F) << 11)
|
||||
#define FDC2X1X_DRV_CURRENT_CHX_IDRIVE_GET(x) (((x) >> 11) & 0x1F)
|
||||
|
||||
enum fdc2x1x_op_mode {
|
||||
FDC2X1X_ACTIVE_MODE,
|
||||
FDC2X1X_SLEEP_MODE
|
||||
};
|
||||
|
||||
struct fdc2x1x_data {
|
||||
bool fdc221x;
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
uint32_t pm_state;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER
|
||||
struct gpio_callback gpio_cb;
|
||||
uint16_t int_config;
|
||||
|
||||
struct k_mutex trigger_mutex;
|
||||
sensor_trigger_handler_t drdy_handler;
|
||||
struct sensor_trigger drdy_trigger;
|
||||
const struct device *dev;
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
|
||||
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_FDC2X1X_THREAD_STACK_SIZE);
|
||||
struct k_sem gpio_sem;
|
||||
struct k_thread thread;
|
||||
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
|
||||
struct k_work work;
|
||||
#endif
|
||||
#endif /* CONFIG_FDC2X1X_TRIGGER */
|
||||
|
||||
uint32_t *channel_buf;
|
||||
};
|
||||
|
||||
struct fdc2x1x_chx_config {
|
||||
uint16_t rcount;
|
||||
uint16_t offset;
|
||||
uint16_t settle_count;
|
||||
uint16_t fref_divider;
|
||||
uint8_t idrive;
|
||||
uint8_t fin_sel;
|
||||
uint8_t inductance;
|
||||
};
|
||||
|
||||
struct fdc2x1x_config {
|
||||
const struct device *bus;
|
||||
uint8_t i2c_addr;
|
||||
|
||||
const struct device *sd_gpio;
|
||||
gpio_pin_t sd_pin;
|
||||
gpio_dt_flags_t sd_flags;
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER
|
||||
const struct device *intb_gpio;
|
||||
gpio_pin_t intb_pin;
|
||||
gpio_dt_flags_t intb_flags;
|
||||
#endif
|
||||
|
||||
bool fdc2x14;
|
||||
uint8_t num_channels;
|
||||
|
||||
/* Device Settings */
|
||||
bool autoscan_en;
|
||||
uint8_t rr_sequence;
|
||||
uint8_t active_channel;
|
||||
uint8_t output_gain;
|
||||
uint8_t deglitch;
|
||||
uint8_t sensor_activate_sel;
|
||||
uint8_t clk_src;
|
||||
uint8_t current_drv;
|
||||
uint16_t fref;
|
||||
|
||||
/* Channel Settings */
|
||||
const struct fdc2x1x_chx_config *ch_cfg;
|
||||
};
|
||||
|
||||
int fdc2x1x_set_interrupt_pin(const struct device *dev, bool enable);
|
||||
int fdc2x1x_get_status(const struct device *dev, uint16_t *status);
|
||||
int fdc2x1x_reg_write_mask(const struct device *dev, uint8_t reg_addr,
|
||||
uint16_t mask, uint16_t data);
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER
|
||||
|
||||
int fdc2x1x_trigger_set(const struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
|
||||
int fdc2x1x_init_interrupt(const struct device *dev);
|
||||
#endif /* CONFIG_FDC2X1X_TRIGGER */
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SENSOR_FDC2X1X_FDC2X1X_H_ */
|
170
drivers/sensor/fdc2x1x/fdc2x1x_trigger.c
Normal file
170
drivers/sensor/fdc2x1x/fdc2x1x_trigger.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright (c) 2020 arithmetics.io
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ti_fdc2x1x
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <sys/util.h>
|
||||
#include <kernel.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include "fdc2x1x.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(FDC2X1X, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static void fdc2x1x_thread_cb(const struct device *dev)
|
||||
{
|
||||
struct fdc2x1x_data *drv_data = dev->data;
|
||||
uint16_t status;
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
/* INTB asserts after exiting shutdown mode. Drop this interrupt */
|
||||
if (drv_data->pm_state == DEVICE_PM_OFF_STATE) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear the status */
|
||||
if (fdc2x1x_get_status(dev, &status) < 0) {
|
||||
LOG_ERR("Unable to get status.");
|
||||
return;
|
||||
}
|
||||
|
||||
k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
|
||||
if ((drv_data->drdy_handler != NULL) && FDC2X1X_STATUS_DRDY(status)) {
|
||||
drv_data->drdy_handler(dev, &drv_data->drdy_trigger);
|
||||
}
|
||||
k_mutex_unlock(&drv_data->trigger_mutex);
|
||||
}
|
||||
|
||||
static void fdc2x1x_gpio_callback(const struct device *dev,
|
||||
struct gpio_callback *cb, uint32_t pins)
|
||||
{
|
||||
struct fdc2x1x_data *drv_data =
|
||||
CONTAINER_OF(cb, struct fdc2x1x_data, gpio_cb);
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
|
||||
k_work_submit(&drv_data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
|
||||
static void fdc2x1x_thread(struct fdc2x1x_data *drv_data)
|
||||
{
|
||||
while (true) {
|
||||
k_sem_take(&drv_data->gpio_sem, K_FOREVER);
|
||||
fdc2x1x_thread_cb(drv_data->dev);
|
||||
}
|
||||
}
|
||||
|
||||
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
|
||||
static void fdc2x1x_work_cb(struct k_work *work)
|
||||
{
|
||||
struct fdc2x1x_data *drv_data =
|
||||
CONTAINER_OF(work, struct fdc2x1x_data, work);
|
||||
|
||||
fdc2x1x_thread_cb(drv_data->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int fdc2x1x_trigger_set(const struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct fdc2x1x_data *drv_data = dev->data;
|
||||
const struct fdc2x1x_config *cfg = dev->config;
|
||||
uint16_t status, int_mask, int_en;
|
||||
int ret;
|
||||
|
||||
gpio_pin_interrupt_configure(cfg->intb_gpio, cfg->intb_pin,
|
||||
GPIO_INT_DISABLE);
|
||||
|
||||
switch (trig->type) {
|
||||
case SENSOR_TRIG_DATA_READY:
|
||||
k_mutex_lock(&drv_data->trigger_mutex, K_FOREVER);
|
||||
drv_data->drdy_handler = handler;
|
||||
drv_data->drdy_trigger = *trig;
|
||||
k_mutex_unlock(&drv_data->trigger_mutex);
|
||||
|
||||
int_mask = FDC2X1X_ERROR_CONFIG_DRDY_2INT_MSK;
|
||||
break;
|
||||
default:
|
||||
LOG_ERR("Unsupported sensor trigger");
|
||||
ret = -ENOTSUP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
int_en = int_mask;
|
||||
drv_data->int_config |= int_mask;
|
||||
} else {
|
||||
int_en = 0U;
|
||||
}
|
||||
|
||||
ret = fdc2x1x_reg_write_mask(dev,
|
||||
FDC2X1X_ERROR_CONFIG, int_mask, int_en);
|
||||
|
||||
/* Clear INTB pin by reading STATUS register */
|
||||
fdc2x1x_get_status(dev, &status);
|
||||
out:
|
||||
gpio_pin_interrupt_configure(cfg->intb_gpio, cfg->intb_pin,
|
||||
GPIO_INT_EDGE_TO_ACTIVE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fdc2x1x_init_interrupt(const struct device *dev)
|
||||
{
|
||||
struct fdc2x1x_data *drv_data = dev->data;
|
||||
const struct fdc2x1x_config *cfg = dev->config;
|
||||
int ret;
|
||||
|
||||
k_mutex_init(&drv_data->trigger_mutex);
|
||||
|
||||
if (!device_is_ready(cfg->intb_gpio)) {
|
||||
LOG_ERR("%s: intb_gpio device not ready", cfg->intb_gpio->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = fdc2x1x_set_interrupt_pin(dev, true);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpio_pin_configure(cfg->intb_gpio, cfg->intb_pin,
|
||||
GPIO_INPUT | cfg->intb_flags);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
fdc2x1x_gpio_callback,
|
||||
BIT(cfg->intb_pin));
|
||||
|
||||
if (gpio_add_callback(cfg->intb_gpio, &drv_data->gpio_cb) < 0) {
|
||||
LOG_ERR("Failed to set gpio callback!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
drv_data->dev = dev;
|
||||
|
||||
#ifdef CONFIG_FDC2X1X_TRIGGER_OWN_THREAD
|
||||
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
||||
|
||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
||||
CONFIG_FDC2X1X_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)fdc2x1x_thread,
|
||||
drv_data, 0, NULL,
|
||||
K_PRIO_COOP(CONFIG_FDC2X1X_THREAD_PRIORITY),
|
||||
0, K_NO_WAIT);
|
||||
#elif CONFIG_FDC2X1X_TRIGGER_GLOBAL_THREAD
|
||||
drv_data->work.handler = fdc2x1x_work_cb;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
259
dts/bindings/sensor/ti,fdc2x1x.yaml
Normal file
259
dts/bindings/sensor/ti,fdc2x1x.yaml
Normal file
|
@ -0,0 +1,259 @@
|
|||
# Copyright (c) 2020 arithmetics.io
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Texas Instruments FDC2X1X capacitive sensor
|
||||
|
||||
compatible: "ti,fdc2x1x"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
sd-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
||||
description: |
|
||||
The SD pin defaults to active high when consumed by the sensor.
|
||||
The property value should ensure the flags properly describe
|
||||
the signal that is presented to the driver.
|
||||
|
||||
intb-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
||||
description: |
|
||||
The INTB pin defaults to active low when produced by the sensor.
|
||||
The property value should ensure the flags properly describe
|
||||
the signal that is presented to the driver.
|
||||
|
||||
fdc2x14:
|
||||
type: boolean
|
||||
description: |
|
||||
Set to identify the sensor as FDC2114 or FDC2214 (4-channel version)
|
||||
|
||||
autoscan:
|
||||
type: boolean
|
||||
description: |
|
||||
Set the Auto-Scan Mode.
|
||||
|
||||
false = Continuous conversion on the single channel selected by
|
||||
"active-channel" (single channel mode).
|
||||
|
||||
true = Auto-Scan conversions as selected by "rr-sequence"
|
||||
(multichannel mode).
|
||||
|
||||
fref:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Reference frequency of the used clock source in KHz.
|
||||
The internal clock oscillates at around 43360 KHz (43.36 MHz)
|
||||
at 20 degrees Celcius.
|
||||
Recommended external clock source frequency is 40000 KHz (40 MHz).
|
||||
|
||||
rr-sequence:
|
||||
type: int
|
||||
required: false
|
||||
default: 0
|
||||
description: |
|
||||
Auto-Scan Sequence Configuration.
|
||||
The FDC will perform a single conversion on each channel
|
||||
in the sequence selected, and then restart the sequence continuously.
|
||||
|
||||
The sensor performs conversion on Channel 0 to 1 by default after
|
||||
power-on-reset. This setting only applies if autoscan=true
|
||||
(multichannel mode).
|
||||
|
||||
0 = Ch0, Ch1
|
||||
1 = Ch0, Ch1, Ch2 (FDC2114, FDC2214 only)
|
||||
2 = Ch0, Ch1, Ch2, Ch3 (FDC2114, FDC2214 only)
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
|
||||
active-channel:
|
||||
type: int
|
||||
required: false
|
||||
default: 0
|
||||
description: |
|
||||
Selects channel for continuous conversions.
|
||||
|
||||
The sensor performs continuous conversion on Channel 0 by default after
|
||||
power-on-reset. This setting only applies if autoscan=false
|
||||
(single channel mode).
|
||||
|
||||
0 = Perform continuous conversions on Channel 0
|
||||
1 = Perform continuous conversions on Channel 1
|
||||
2 = Perform continuous conversions on Channel 2 (FDC2114, FDC2214 only)
|
||||
3 = Perform continuous conversions on Channel 3 (FDC2114, FDC2214 only)
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
deglitch:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Input deglitch filter bandwidth. Select the lowest setting that exceeds
|
||||
the oscillation tank oscillation frequency.
|
||||
|
||||
1 = 1MHz
|
||||
4 = 3.3MHz
|
||||
5 = 10MHz
|
||||
7 = 33MHz
|
||||
enum:
|
||||
- 1
|
||||
- 4
|
||||
- 5
|
||||
- 7
|
||||
|
||||
sensor-activate-sel:
|
||||
type: string
|
||||
required: false
|
||||
default: "low-power"
|
||||
description: |
|
||||
Sensor Activation Mode Selection.
|
||||
|
||||
The sensor uses low-power activation mode by default after
|
||||
power-on-reset.
|
||||
|
||||
full-current = the FDC will drive maximum
|
||||
sensor current for a shorter sensor activation time.
|
||||
|
||||
low-power = the FDC uses the value programmed by "idrive" during
|
||||
sensor activation to minimize power consumption.
|
||||
enum:
|
||||
- "full-current"
|
||||
- "low-power"
|
||||
|
||||
ref-clk-src:
|
||||
type: string
|
||||
required: false
|
||||
default: "internal"
|
||||
description: |
|
||||
Select Reference Frequency Source.
|
||||
|
||||
The sensor uses the internal clock by default after power-on-reset.
|
||||
|
||||
internal = Use Internal oscillator as reference frequency
|
||||
external = Reference frequency is provided from CLKIN pin.
|
||||
enum:
|
||||
- "internal"
|
||||
- "external"
|
||||
|
||||
current-drive:
|
||||
type: string
|
||||
required: false
|
||||
default: "normal"
|
||||
description: |
|
||||
Select Current Sensor Drive.
|
||||
|
||||
The sensor uses normal current drive by default after power-on-reset.
|
||||
High current drive is not supported if autoscan=false and will default
|
||||
to normal.
|
||||
|
||||
normal = The FDC will drive all channels with normal sensor current
|
||||
(1.5mA max).
|
||||
|
||||
high = The FDC will drive channel 0 with current >1.5mA.
|
||||
enum:
|
||||
- "normal"
|
||||
- "high"
|
||||
|
||||
output-gain:
|
||||
type: int
|
||||
required: false
|
||||
default: 0
|
||||
description: |
|
||||
Output gain control (FDC2112, FDC2114 only)
|
||||
|
||||
The default output gain is 0 after power-on-reset.
|
||||
|
||||
0 = Gain = 1 | Effective Resolution 12 bits | 100% full scale
|
||||
1 = Gain = 4 | Effective Resolution 14 bits | 25% full scale
|
||||
2 = Gain = 8 | Effective Resolution 15 bits | 12.5% full scale
|
||||
3 = Gain = 16 | Effective Resolution 16 bits | 6.25% full scale
|
||||
enum:
|
||||
- 0
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
|
||||
child-binding:
|
||||
description: |
|
||||
Settings for each channel 0-1 (FDC2112 and FDC2212) or
|
||||
0-3 (FDC2114 and FDC2214)
|
||||
|
||||
properties:
|
||||
rcount:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Channel X Reference Count Conversion Interval Time.
|
||||
Valid range: 256 - 65535
|
||||
|
||||
offset:
|
||||
type: int
|
||||
required: false
|
||||
default: 0
|
||||
description: |
|
||||
Channel X Conversion Offset (FDC2112 and FDC2212 only).
|
||||
The default offset value after power-on-reset is 0.
|
||||
Valid range: 0 - 65535
|
||||
|
||||
settlecount:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Channel X Conversion Settling.
|
||||
|
||||
The FDC will use this settling time to allow the LC sensor to
|
||||
stabilize before initiation of a conversion on Channel X.
|
||||
Valid range: 0 - 65535
|
||||
|
||||
fref-divider:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Channel X Reference Divider.
|
||||
|
||||
Sets the divider for Channel X reference.
|
||||
Use this to scale the maximum conversion frequency.
|
||||
Valid range: 1 - 1023
|
||||
|
||||
idrive:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Channel X Sensor drive current.
|
||||
|
||||
This field defines the Drive Current used during the settling +
|
||||
conversion time of Channel X sensor clock.
|
||||
Valid range: 0 - 31
|
||||
|
||||
fin-sel:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Channel X Sensor frequency select.
|
||||
|
||||
For differential sensor configuration:
|
||||
1 = divide by 1. Choose for sensor frequencies between
|
||||
0.01MHz and 8.75MHz
|
||||
2 = divide by 2. Choose for sensor frequencies between 5MHz
|
||||
and 10MHz
|
||||
|
||||
For single-ended sensor configuration:
|
||||
2 = divide by 2. Choose for sensor frequencies between
|
||||
0.01MHz and 10MHz
|
||||
enum:
|
||||
- 1 # Divide by 1
|
||||
- 2 # Divide by 2
|
||||
|
||||
inductance:
|
||||
type: int
|
||||
required: true
|
||||
description: |
|
||||
Inductor value used on the PCB for the sensing network of the
|
||||
specific channel, which is usually 18uH.
|
45
include/drivers/sensor/fdc2x1x.h
Normal file
45
include/drivers/sensor/fdc2x1x.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2020 arithmetics.io
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Extended public API for the Texas Instruments FDC2X1X
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <drivers/sensor.h>
|
||||
|
||||
enum sensor_channel_fdc2x1x {
|
||||
/** CH0 Capacitance, in Picofarad **/
|
||||
SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH0 = SENSOR_CHAN_PRIV_START,
|
||||
/** CH1 Capacitance, in Picofarad **/
|
||||
SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH1,
|
||||
/** CH2 Capacitance, in Picofarad **/
|
||||
SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH2,
|
||||
/** CH3 Capacitance, in Picofarad **/
|
||||
SENSOR_CHAN_FDC2X1X_CAPACITANCE_CH3,
|
||||
|
||||
/** CH0 Frequency, in MHz **/
|
||||
SENSOR_CHAN_FDC2X1X_FREQ_CH0,
|
||||
/** CH1 Frequency, in MHz **/
|
||||
SENSOR_CHAN_FDC2X1X_FREQ_CH1,
|
||||
/** CH2 Frequency, in MHz **/
|
||||
SENSOR_CHAN_FDC2X1X_FREQ_CH2,
|
||||
/** CH3 Frequency, in MHz **/
|
||||
SENSOR_CHAN_FDC2X1X_FREQ_CH3,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_FDC2X1X_ */
|
|
@ -593,3 +593,20 @@ test_i2c_pcal6408a: pcal6408a@4b {
|
|||
int-gpios = <&test_gpio 0 0>;
|
||||
reset-gpios = <&test_gpio 0 0>;
|
||||
};
|
||||
|
||||
test_i2c_fdc2x1x: fdc2x1x@2a {
|
||||
compatible = "ti,fdc2x1x";
|
||||
label = "FDC2X1X";
|
||||
reg = <0x2a>;
|
||||
intb-gpios = <&test_gpio 0 0>;
|
||||
deglitch = <5>;
|
||||
fref = <43360>;
|
||||
channel_0 {
|
||||
rcount = <7499>;
|
||||
settlecount = <48>;
|
||||
fref-divider = <1>;
|
||||
idrive = <10>;
|
||||
fin-sel = <2>;
|
||||
inductance = <18>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@ CONFIG_CCS811=y
|
|||
CONFIG_DHT=y
|
||||
CONFIG_DPS310=y
|
||||
CONFIG_ENS210=y
|
||||
CONFIG_FDC2X1X=y
|
||||
CONFIG_FXAS21002=y
|
||||
CONFIG_FXOS8700=y
|
||||
CONFIG_HMC5883L=y
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
CONFIG_TEST=y
|
||||
CONFIG_TEST_USERSPACE=y
|
||||
CONFIG_MAX_THREAD_BYTES=3
|
||||
CONFIG_I2C=y
|
||||
CONFIG_ADC=y
|
||||
CONFIG_GPIO=y
|
||||
|
@ -24,6 +25,8 @@ CONFIG_BMG160=y
|
|||
CONFIG_BMG160_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_BMI160=y
|
||||
CONFIG_BMI160_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_FDC2X1X=y
|
||||
CONFIG_FDC2X1X_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_FXAS21002=y
|
||||
CONFIG_FXAS21002_TRIGGER_OWN_THREAD=y
|
||||
CONFIG_FXOS8700=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue