230 lines
8.7 KiB
C
230 lines
8.7 KiB
C
/*
|
|
* 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_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_ */
|