drivers: sensors: adxl372: Add driver for ADXL372 high-g accelerometer
This patch adds support for the Analog Devices ADXL372 ultra-low power, 3-axis, +/-200 g MEMS accelerometer. The ADXL372 can be either connected via a SPI or I2C interface. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
This commit is contained in:
parent
22b61c7f43
commit
a3e7cea1df
7 changed files with 1899 additions and 0 deletions
|
@ -1,5 +1,6 @@
|
|||
add_subdirectory_ifdef(CONFIG_ADT7420 adt7420)
|
||||
add_subdirectory_ifdef(CONFIG_ADXL362 adxl362)
|
||||
add_subdirectory_ifdef(CONFIG_ADXL372 adxl372)
|
||||
add_subdirectory_ifdef(CONFIG_AK8975 ak8975)
|
||||
add_subdirectory_ifdef(CONFIG_AMG88XX amg88xx)
|
||||
add_subdirectory_ifdef(CONFIG_APDS9960 apds9960)
|
||||
|
|
|
@ -39,6 +39,8 @@ source "drivers/sensor/adt7420/Kconfig"
|
|||
|
||||
source "drivers/sensor/adxl362/Kconfig"
|
||||
|
||||
source "drivers/sensor/adxl372/Kconfig"
|
||||
|
||||
source "drivers/sensor/ak8975/Kconfig"
|
||||
|
||||
source "drivers/sensor/amg88xx/Kconfig"
|
||||
|
|
9
drivers/sensor/adxl372/CMakeLists.txt
Normal file
9
drivers/sensor/adxl372/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Copyright (c) 2018 Analog Devices Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_ADXL372 adxl372.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_ADXL372_TRIGGER adxl372_trigger.c)
|
330
drivers/sensor/adxl372/Kconfig
Normal file
330
drivers/sensor/adxl372/Kconfig
Normal file
|
@ -0,0 +1,330 @@
|
|||
# Kconfig - Micropower, 3-Axis, +/-200g Digital Accelerometer
|
||||
#
|
||||
# Copyright (c) 2018 Analog Devices Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
menuconfig ADXL372
|
||||
bool "ADXL372 Three Axis High-g I2C/SPI accelerometer"
|
||||
depends on SENSOR && (I2C || SPI)
|
||||
help
|
||||
Enable driver for ADXL372 Three-Axis Digital Accelerometers.
|
||||
|
||||
if ADXL372
|
||||
|
||||
choice ADXL372_BUS_TYPE
|
||||
prompt "Interface type"
|
||||
help
|
||||
Select interface the digital interface type for the ADXL372
|
||||
|
||||
config ADXL372_I2C
|
||||
depends on I2C
|
||||
bool "I2C Interface"
|
||||
|
||||
config ADXL372_SPI
|
||||
depends on SPI
|
||||
bool "SPI Interface"
|
||||
|
||||
endchoice
|
||||
|
||||
if !HAS_DTS_I2C_DEVICE
|
||||
|
||||
config ADXL372_DEV_NAME
|
||||
string "ADXL372 device name"
|
||||
depends on ADXL372_I2C
|
||||
default "ADXL372"
|
||||
|
||||
config ADXL372_I2C_ADDR
|
||||
hex "I2C address for ADXL372"
|
||||
depends on ADXL372_I2C
|
||||
default 0x1D
|
||||
help
|
||||
I2C address of the ADXL372 sensor.
|
||||
|
||||
0x1D: if MISO is pulled low
|
||||
0x53: if MISO is pulled high
|
||||
|
||||
config ADXL372_I2C_MASTER_DEV_NAME
|
||||
string "I2C master where ADXL372 is connected"
|
||||
depends on ADXL372_I2C
|
||||
default "I2C_0"
|
||||
help
|
||||
Specify the device name of the I2C master device to which the
|
||||
ADXL372 chip is connected.
|
||||
|
||||
endif # !HAS_DTS_I2C_DEVICE
|
||||
|
||||
if !HAS_DTS_SPI_DEVICE
|
||||
|
||||
config ADXL372_DEV_NAME
|
||||
string "ADXL372 device name"
|
||||
depends on ADXL372_SPI
|
||||
default "ADXL372"
|
||||
|
||||
config ADXL372_SPI_DEV_NAME
|
||||
string "SPI device where ADXL372 is connected"
|
||||
depends on ADXL372_SPI
|
||||
default "SPI_0"
|
||||
help
|
||||
Specify the device name of the SPI device to which ADXL372 is
|
||||
connected.
|
||||
|
||||
config ADXL372_SPI_DEV_SLAVE
|
||||
int "SPI Slave Select where ADXL372 is connected"
|
||||
depends on ADXL372_SPI
|
||||
default 2
|
||||
help
|
||||
Specify the slave select pin of the SPI to which ADXL372 is
|
||||
connected.
|
||||
|
||||
config ADXL372_SPI_GPIO_CS
|
||||
bool "ADXL372 SPI CS through a GPIO pin"
|
||||
depends on ADXL372_SPI
|
||||
help
|
||||
This option is useful if one needs to manage SPI CS through a GPIO
|
||||
pin to by-pass the SPI controller's CS logic.
|
||||
|
||||
config ADXL372_SPI_BUS_FREQ
|
||||
int "ADXL372 SPI bus speed in Hz"
|
||||
range 10000 10000000
|
||||
default 8000000
|
||||
help
|
||||
This is the maximum supported SPI bus frequency. The chip supports a
|
||||
frequency up to 10MHz.
|
||||
|
||||
endif # !HAS_DTS_SPI_DEVICE
|
||||
|
||||
if !HAS_DTS_SPI_PINS
|
||||
|
||||
config ADXL372_SPI_GPIO_CS_DRV_NAME
|
||||
string "GPIO driver's name to use to drive SPI CS through"
|
||||
default "GPIO_0"
|
||||
depends on ADXL372_SPI_GPIO_CS
|
||||
help
|
||||
This option is mandatory to set which GPIO controller to use in order
|
||||
to actually emulate the SPI CS.
|
||||
|
||||
config ADXL372_SPI_GPIO_CS_PIN
|
||||
int "GPIO PIN to use to drive SPI CS through"
|
||||
default 0
|
||||
depends on ADXL372_SPI_GPIO_CS
|
||||
help
|
||||
This option is mandatory to set which GPIO pin to use in order
|
||||
to actually emulate the SPI CS.
|
||||
|
||||
endif # !HAS_DTS_SPI_PINS
|
||||
|
||||
choice
|
||||
prompt "Operating mode"
|
||||
default ADXL372_PEAK_DETECT_MODE
|
||||
|
||||
config ADXL372_PEAK_DETECT_MODE
|
||||
bool "Max Peak detect mode"
|
||||
help
|
||||
In most high-g applications, a single (3-axis) acceleration sample at
|
||||
the peak of an impact event contains sufficient information
|
||||
about the event, and the full acceleration history is not required.
|
||||
In this mode the device returns only the over threshold
|
||||
Peak Acceleration between two consecutive sample fetches.
|
||||
|
||||
config ADXL372_MEASUREMENT_MODE
|
||||
bool "Measurement Mode"
|
||||
help
|
||||
In this mode, acceleration data is provided continuously at the
|
||||
output data rate (ODR).
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Accelerometer sampling frequency (ODR)"
|
||||
default ADXL372_ODR_6400HZ if ADXL372_PEAK_DETECT_MODE
|
||||
default ADXL372_ODR_400HZ if ADXL372_MEASUREMENT_MODE
|
||||
|
||||
config ADXL372_ODR_400HZ
|
||||
bool "400 Hz"
|
||||
|
||||
config ADXL372_ODR_800HZ
|
||||
bool "800 Hz"
|
||||
|
||||
config ADXL372_ODR_1600HZ
|
||||
bool "1600 Hz"
|
||||
|
||||
config ADXL372_ODR_3200HZ
|
||||
bool "3200 Hz"
|
||||
|
||||
config ADXL372_ODR_6400HZ
|
||||
bool "6400 Hz"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Low-Pass (Antialiasing) Filter corner frequency"
|
||||
default ADXL372_BW_200HZ if ADXL372_ODR_400HZ
|
||||
default ADXL372_BW_400HZ if ADXL372_ODR_800HZ
|
||||
default ADXL372_BW_800HZ if ADXL372_ODR_1600HZ
|
||||
default ADXL372_BW_1600HZ if ADXL372_ODR_3200HZ
|
||||
default ADXL372_BW_3200HZ if ADXL372_ODR_6400HZ
|
||||
help
|
||||
High g events often include acceleration content over a wide range
|
||||
of frequencies. The ADC of the ADXL372 samples the input acceleration
|
||||
at the user selected ODR.
|
||||
In the absence of antialiasing filters, input signals whose frequency
|
||||
is more than half the ODR alias or fold into the measurement bandwidth
|
||||
can lead to inaccurate measurements.
|
||||
|
||||
config ADXL372_LPF_DISABLE
|
||||
bool "Disabled"
|
||||
|
||||
config ADXL372_BW_200HZ
|
||||
bool "200 Hz"
|
||||
|
||||
config ADXL372_BW_400HZ
|
||||
bool "400 Hz"
|
||||
|
||||
config ADXL372_BW_800HZ
|
||||
bool "800 Hz"
|
||||
|
||||
config ADXL372_BW_1600HZ
|
||||
bool "1600 Hz"
|
||||
|
||||
config ADXL372_BW_3200HZ
|
||||
bool "3200 Hz"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "High-Pass Filter corner frequency"
|
||||
default ADXL372_HPF_CORNER0
|
||||
help
|
||||
The ADXL372 offers a one-pole, high-pass filter with a user
|
||||
selectable −3 dB frequency. Applications that do not require dc
|
||||
acceleration measurements can use the high-pass filter to minimize
|
||||
constant or slow varying offset errors including initial bias,
|
||||
bias drift due to temperature, and bias drift due to supply voltage
|
||||
|
||||
config ADXL372_HPF_DISABLE
|
||||
bool "Disabled"
|
||||
|
||||
config ADXL372_HPF_CORNER0
|
||||
bool "ODR/210"
|
||||
|
||||
config ADXL372_HPF_CORNER1
|
||||
bool "ODR/411"
|
||||
|
||||
config ADXL372_HPF_CORNER2
|
||||
bool "ODR/812"
|
||||
|
||||
config ADXL372_HPF_CORNER3
|
||||
bool "ODR/1616"
|
||||
|
||||
endchoice
|
||||
|
||||
|
||||
config ADXL372_ACTIVITY_THRESHOLD
|
||||
int "Activity threshold in mg"
|
||||
range 0 200000
|
||||
default 500
|
||||
help
|
||||
Threshold for activity detection.
|
||||
|
||||
config ADXL372_INACTIVITY_THRESHOLD
|
||||
int "In-activity threshold in mg"
|
||||
range 0 200000
|
||||
default 400
|
||||
help
|
||||
Threshold for in-activity detection.
|
||||
|
||||
config ADXL372_ACTIVITY_TIME
|
||||
int "Activity time"
|
||||
range 0 255
|
||||
default 1
|
||||
help
|
||||
The activity timer implements a robust activity detection that
|
||||
minimizes false positive motion triggers. When the timer is used,
|
||||
only sustained motion can trigger activity detection.
|
||||
Number of multiples of 3.3 ms activity timer for which above threshold
|
||||
acceleration is required to detect activity. It is 3.3 ms per code
|
||||
for 6400 Hz ODR, and it is 6.6 ms per code for 3200 Hz ODR and below.
|
||||
|
||||
config ADXL372_INACTIVITY_TIME
|
||||
int "In-activity time"
|
||||
range 0 255
|
||||
default 2
|
||||
help
|
||||
The time that all enabled axes must be lower than the inactivity
|
||||
threshold for an inactivity event to be detected. Number of multiples
|
||||
of 26 ms inactivity timer for which below threshold acceleration is
|
||||
required to detect inactivity. It is 26 ms per code for 3200 Hz ODR
|
||||
and below, and it is 13 ms per code for 6400 Hz ODR.
|
||||
|
||||
config ADXL372_REFERENCED_ACTIVITY_DETECTION_MODE
|
||||
bool "Use referenced activity/in-activity detection"
|
||||
default y
|
||||
help
|
||||
Activity detection can be configured as referenced or absolute.
|
||||
When using absolute activity detection, acceleration samples are
|
||||
compared directly to a user set threshold to determine whether
|
||||
motion is present. In many applications, it is advantageous for
|
||||
activity detection to be based not on an absolute threshold,
|
||||
but on a deviation from a reference point or orientation.
|
||||
|
||||
choice
|
||||
prompt "Trigger mode"
|
||||
default ADXL372_TRIGGER_NONE
|
||||
help
|
||||
Specify the type of triggering used by the driver.
|
||||
|
||||
config ADXL372_TRIGGER_NONE
|
||||
bool "No trigger"
|
||||
|
||||
config ADXL372_TRIGGER_GLOBAL_THREAD
|
||||
bool "Use global thread"
|
||||
depends on GPIO
|
||||
select ADXL372_TRIGGER
|
||||
|
||||
config ADXL372_TRIGGER_OWN_THREAD
|
||||
bool "Use own thread"
|
||||
depends on GPIO
|
||||
select ADXL372_TRIGGER
|
||||
|
||||
endchoice
|
||||
|
||||
config ADXL372_TRIGGER
|
||||
bool
|
||||
|
||||
if !HAS_DTS_GPIO_DEVICE
|
||||
|
||||
config ADXL372_GPIO_DEV_NAME
|
||||
string "GPIO device"
|
||||
default "GPIO_0"
|
||||
depends on ADXL372_TRIGGER
|
||||
help
|
||||
The GPIO device's name where the ADXL372 interrupt 1 or 2 pin is
|
||||
connected.
|
||||
|
||||
config ADXL372_GPIO_PIN_NUM
|
||||
int "Interrupt GPIO pin number"
|
||||
default 0
|
||||
depends on ADXL372_TRIGGER
|
||||
help
|
||||
The GPIO pin number receiving the interrupt signal from the
|
||||
ADXL372 sensor.
|
||||
|
||||
endif # !HAS_DTS_GPIO_DEVICE
|
||||
|
||||
config ADXL372_THREAD_PRIORITY
|
||||
int "Thread priority"
|
||||
depends on ADXL372_TRIGGER_OWN_THREAD && ADXL372_TRIGGER
|
||||
default 10
|
||||
help
|
||||
Priority of thread used by the driver to handle interrupts.
|
||||
|
||||
config ADXL372_THREAD_STACK_SIZE
|
||||
int "Thread stack size"
|
||||
depends on ADXL372_TRIGGER_OWN_THREAD && ADXL372_TRIGGER
|
||||
default 1024
|
||||
help
|
||||
Stack size of thread used by the driver to handle interrupts.
|
||||
|
||||
endif #ADXL372
|
1012
drivers/sensor/adxl372/adxl372.c
Normal file
1012
drivers/sensor/adxl372/adxl372.c
Normal file
File diff suppressed because it is too large
Load diff
374
drivers/sensor/adxl372/adxl372.h
Normal file
374
drivers/sensor/adxl372/adxl372.h
Normal file
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Analog Devices Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __SENSOR_ADXL372_H__
|
||||
#define __SENSOR_ADXL372_H__
|
||||
|
||||
#include <zephyr/types.h>
|
||||
#include <device.h>
|
||||
#include <gpio.h>
|
||||
#include <spi.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#define GENMASK(h, l) (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (31 - (h))))
|
||||
|
||||
/*
|
||||
* ADXL372 registers definition
|
||||
*/
|
||||
#define ADXL372_DEVID 0x00u /* Analog Devices accelerometer ID */
|
||||
#define ADXL372_DEVID_MST 0x01u /* Analog Devices MEMS device ID */
|
||||
#define ADXL372_PARTID 0x02u /* Device ID */
|
||||
#define ADXL372_REVID 0x03u /* product revision ID*/
|
||||
#define ADXL372_STATUS_1 0x04u /* Status register 1 */
|
||||
#define ADXL372_STATUS_2 0x05u /* Status register 2 */
|
||||
#define ADXL372_FIFO_ENTRIES_2 0x06u /* Valid data samples in the FIFO */
|
||||
#define ADXL372_FIFO_ENTRIES_1 0x07u /* Valid data samples in the FIFO */
|
||||
#define ADXL372_X_DATA_H 0x08u /* X-axis acceleration data [11:4] */
|
||||
#define ADXL372_X_DATA_L 0x09u /* X-axis acceleration data [3:0] */
|
||||
#define ADXL372_Y_DATA_H 0x0Au /* Y-axis acceleration data [11:4] */
|
||||
#define ADXL372_Y_DATA_L 0x0Bu /* Y-axis acceleration data [3:0] */
|
||||
#define ADXL372_Z_DATA_H 0x0Cu /* Z-axis acceleration data [11:4] */
|
||||
#define ADXL372_Z_DATA_L 0x0Du /* Z-axis acceleration data [3:0] */
|
||||
#define ADXL372_X_MAXPEAK_H 0x15u /* X-axis MaxPeak acceleration data */
|
||||
#define ADXL372_X_MAXPEAK_L 0x16u /* X-axis MaxPeak acceleration data */
|
||||
#define ADXL372_Y_MAXPEAK_H 0x17u /* Y-axis MaxPeak acceleration data */
|
||||
#define ADXL372_Y_MAXPEAK_L 0x18u /* Y-axis MaxPeak acceleration data */
|
||||
#define ADXL372_Z_MAXPEAK_H 0x19u /* Z-axis MaxPeak acceleration data */
|
||||
#define ADXL372_Z_MAXPEAK_L 0x1Au /* Z-axis MaxPeak acceleration data */
|
||||
#define ADXL372_OFFSET_X 0x20u /* X axis offset */
|
||||
#define ADXL372_OFFSET_Y 0x21u /* Y axis offset */
|
||||
#define ADXL372_OFFSET_Z 0x22u /* Z axis offset */
|
||||
#define ADXL372_X_THRESH_ACT_H 0x23u /* X axis Activity Threshold [15:8] */
|
||||
#define ADXL372_X_THRESH_ACT_L 0x24u /* X axis Activity Threshold [7:0] */
|
||||
#define ADXL372_Y_THRESH_ACT_H 0x25u /* Y axis Activity Threshold [15:8] */
|
||||
#define ADXL372_Y_THRESH_ACT_L 0x26u /* Y axis Activity Threshold [7:0] */
|
||||
#define ADXL372_Z_THRESH_ACT_H 0x27u /* Z axis Activity Threshold [15:8] */
|
||||
#define ADXL372_Z_THRESH_ACT_L 0x28u /* Z axis Activity Threshold [7:0] */
|
||||
#define ADXL372_TIME_ACT 0x29u /* Activity Time */
|
||||
#define ADXL372_X_THRESH_INACT_H 0x2Au /* X axis Inactivity Threshold */
|
||||
#define ADXL372_X_THRESH_INACT_L 0x2Bu /* X axis Inactivity Threshold */
|
||||
#define ADXL372_Y_THRESH_INACT_H 0x2Cu /* Y axis Inactivity Threshold */
|
||||
#define ADXL372_Y_THRESH_INACT_L 0x2Du /* Y axis Inactivity Threshold */
|
||||
#define ADXL372_Z_THRESH_INACT_H 0x2Eu /* Z axis Inactivity Threshold */
|
||||
#define ADXL372_Z_THRESH_INACT_L 0x2Fu /* Z axis Inactivity Threshold */
|
||||
#define ADXL372_TIME_INACT_H 0x30u /* Inactivity Time [15:8] */
|
||||
#define ADXL372_TIME_INACT_L 0x31u /* Inactivity Time [7:0] */
|
||||
#define ADXL372_X_THRESH_ACT2_H 0x32u /* X axis Activity2 Threshold [15:8] */
|
||||
#define ADXL372_X_THRESH_ACT2_L 0x33u /* X axis Activity2 Threshold [7:0] */
|
||||
#define ADXL372_Y_THRESH_ACT2_H 0x34u /* Y axis Activity2 Threshold [15:8] */
|
||||
#define ADXL372_Y_THRESH_ACT2_L 0x35u /* Y axis Activity2 Threshold [7:0] */
|
||||
#define ADXL372_Z_THRESH_ACT2_H 0x36u /* Z axis Activity2 Threshold [15:8] */
|
||||
#define ADXL372_Z_THRESH_ACT2_L 0x37u /* Z axis Activity2 Threshold [7:0] */
|
||||
#define ADXL372_HPF 0x38u /* High Pass Filter */
|
||||
#define ADXL372_FIFO_SAMPLES 0x39u /* FIFO Samples */
|
||||
#define ADXL372_FIFO_CTL 0x3Au /* FIFO Control */
|
||||
#define ADXL372_INT1_MAP 0x3Bu /* Interrupt 1 mapping control */
|
||||
#define ADXL372_INT2_MAP 0x3Cu /* Interrupt 2 mapping control */
|
||||
#define ADXL372_TIMING 0x3Du /* Timing */
|
||||
#define ADXL372_MEASURE 0x3Eu /* Measure */
|
||||
#define ADXL372_POWER_CTL 0x3Fu /* Power control */
|
||||
#define ADXL372_SELF_TEST 0x40u /* Self Test */
|
||||
#define ADXL372_RESET 0x41u /* Reset */
|
||||
#define ADXL372_FIFO_DATA 0x42u /* FIFO Data */
|
||||
|
||||
#define ADXL372_DEVID_VAL 0xADu /* Analog Devices accelerometer ID */
|
||||
#define ADXL372_MST_DEVID_VAL 0x1Du /* Analog Devices MEMS device ID */
|
||||
#define ADXL372_PARTID_VAL 0xFAu /* Device ID */
|
||||
#define ADXL372_REVID_VAL 0x02u /* product revision ID*/
|
||||
#define ADXL372_RESET_CODE 0x52u /* Writing code 0x52 resets the device */
|
||||
|
||||
#define ADXL372_READ 0x01u
|
||||
#define ADXL372_REG_READ(x) (((x & 0xFF) << 1) | ADXL372_READ)
|
||||
#define ADXL372_REG_WRITE(x) ((x & 0xFF) << 1)
|
||||
#define ADXL372_TO_I2C_REG(x) ((x) >> 1)
|
||||
|
||||
/* ADXL372_POWER_CTL */
|
||||
#define ADXL372_POWER_CTL_INSTANT_ON_TH_MSK BIT(5)
|
||||
#define ADXL372_POWER_CTL_INSTANT_ON_TH_MODE(x) (((x) & 0x1) << 5)
|
||||
#define ADXL372_POWER_CTL_FIL_SETTLE_MSK BIT(4)
|
||||
#define ADXL372_POWER_CTL_FIL_SETTLE_MODE(x) (((x) & 0x1) << 4)
|
||||
#define ADXL372_POWER_CTL_LPF_DIS_MSK BIT(3)
|
||||
#define ADXL372_POWER_CTL_LPF_DIS_MODE(x) (((x) & 0x1) << 3)
|
||||
#define ADXL372_POWER_CTL_HPF_DIS_MSK BIT(2)
|
||||
#define ADXL372_POWER_CTL_HPF_DIS_MODE(x) (((x) & 0x1) << 2)
|
||||
#define ADXL372_POWER_CTL_MODE_MSK GENMASK(1, 0)
|
||||
#define ADXL372_POWER_CTL_MODE(x) (((x) & 0x3) << 0)
|
||||
|
||||
/* ADXL372_MEASURE */
|
||||
#define ADXL372_MEASURE_AUTOSLEEP_MSK BIT(6)
|
||||
#define ADXL372_MEASURE_AUTOSLEEP_MODE(x) (((x) & 0x1) << 6)
|
||||
#define ADXL372_MEASURE_LINKLOOP_MSK GENMASK(5, 4)
|
||||
#define ADXL372_MEASURE_LINKLOOP_MODE(x) (((x) & 0x3) << 4)
|
||||
#define ADXL372_MEASURE_LOW_NOISE_MSK BIT(3)
|
||||
#define ADXL372_MEASURE_LOW_NOISE_MODE(x) (((x) & 0x1) << 3)
|
||||
#define ADXL372_MEASURE_BANDWIDTH_MSK GENMASK(2, 0)
|
||||
#define ADXL372_MEASURE_BANDWIDTH_MODE(x) (((x) & 0x7) << 0)
|
||||
|
||||
/* ADXL372_TIMING */
|
||||
#define ADXL372_TIMING_ODR_MSK GENMASK(7, 5)
|
||||
#define ADXL372_TIMING_ODR_MODE(x) (((x) & 0x7) << 5)
|
||||
#define ADXL372_TIMING_WAKE_UP_RATE_MSK GENMASK(4, 2)
|
||||
#define ADXL372_TIMING_WAKE_UP_RATE_MODE(x) (((x) & 0x7) << 2)
|
||||
#define ADXL372_TIMING_EXT_CLK_MSK BIT(1)
|
||||
#define ADXL372_TIMING_EXT_CLK_MODE(x) (((x) & 0x1) << 1)
|
||||
#define ADXL372_TIMING_EXT_SYNC_MSK BIT(0)
|
||||
#define ADXL372_TIMING_EXT_SYNC_MODE(x) (((x) & 0x1) << 0)
|
||||
|
||||
/* ADXL372_FIFO_CTL */
|
||||
#define ADXL372_FIFO_CTL_FORMAT_MSK GENMASK(5, 3)
|
||||
#define ADXL372_FIFO_CTL_FORMAT_MODE(x) (((x) & 0x7) << 3)
|
||||
#define ADXL372_FIFO_CTL_MODE_MSK GENMASK(2, 1)
|
||||
#define ADXL372_FIFO_CTL_MODE_MODE(x) (((x) & 0x3) << 1)
|
||||
#define ADXL372_FIFO_CTL_SAMPLES_MSK BIT(0)
|
||||
#define ADXL372_FIFO_CTL_SAMPLES_MODE(x) (((x) > 0xFF) ? 1 : 0)
|
||||
|
||||
/* ADXL372_STATUS_1 */
|
||||
#define ADXL372_STATUS_1_DATA_RDY(x) (((x) >> 0) & 0x1)
|
||||
#define ADXL372_STATUS_1_FIFO_RDY(x) (((x) >> 1) & 0x1)
|
||||
#define ADXL372_STATUS_1_FIFO_FULL(x) (((x) >> 2) & 0x1)
|
||||
#define ADXL372_STATUS_1_FIFO_OVR(x) (((x) >> 3) & 0x1)
|
||||
#define ADXL372_STATUS_1_USR_NVM_BUSY(x) (((x) >> 5) & 0x1)
|
||||
#define ADXL372_STATUS_1_AWAKE(x) (((x) >> 6) & 0x1)
|
||||
#define ADXL372_STATUS_1_ERR_USR_REGS(x) (((x) >> 7) & 0x1)
|
||||
|
||||
/* ADXL372_STATUS_2 */
|
||||
#define ADXL372_STATUS_2_INACT(x) (((x) >> 4) & 0x1)
|
||||
#define ADXL372_STATUS_2_ACTIVITY(x) (((x) >> 5) & 0x1)
|
||||
#define ADXL372_STATUS_2_ACTIVITY2(x) (((x) >> 6) & 0x1)
|
||||
|
||||
/* ADXL372_INT1_MAP */
|
||||
#define ADXL372_INT1_MAP_DATA_RDY_MSK BIT(0)
|
||||
#define ADXL372_INT1_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0)
|
||||
#define ADXL372_INT1_MAP_FIFO_RDY_MSK BIT(1)
|
||||
#define ADXL372_INT1_MAP_FIFO_RDY_MODE(x) (((x) & 0x1) << 1)
|
||||
#define ADXL372_INT1_MAP_FIFO_FULL_MSK BIT(2)
|
||||
#define ADXL372_INT1_MAP_FIFO_FULL_MODE(x) (((x) & 0x1) << 2)
|
||||
#define ADXL372_INT1_MAP_FIFO_OVR_MSK BIT(3)
|
||||
#define ADXL372_INT1_MAP_FIFO_OVR_MODE(x) (((x) & 0x1) << 3)
|
||||
#define ADXL372_INT1_MAP_INACT_MSK BIT(4)
|
||||
#define ADXL372_INT1_MAP_INACT_MODE(x) (((x) & 0x1) << 4)
|
||||
#define ADXL372_INT1_MAP_ACT_MSK BIT(5)
|
||||
#define ADXL372_INT1_MAP_ACT_MODE(x) (((x) & 0x1) << 5)
|
||||
#define ADXL372_INT1_MAP_AWAKE_MSK BIT(6)
|
||||
#define ADXL372_INT1_MAP_AWAKE_MODE(x) (((x) & 0x1) << 6)
|
||||
#define ADXL372_INT1_MAP_LOW_MSK BIT(7)
|
||||
#define ADXL372_INT1_MAP_LOW_MODE(x) (((x) & 0x1) << 7)
|
||||
|
||||
/* ADXL372_INT2_MAP */
|
||||
#define ADXL372_INT2_MAP_DATA_RDY_MSK BIT(0)
|
||||
#define ADXL372_INT2_MAP_DATA_RDY_MODE(x) (((x) & 0x1) << 0)
|
||||
#define ADXL372_INT2_MAP_FIFO_RDY_MSK BIT(1)
|
||||
#define ADXL372_INT2_MAP_FIFO_RDY_MODE(x) (((x) & 0x1) << 1)
|
||||
#define ADXL372_INT2_MAP_FIFO_FULL_MSK BIT(2)
|
||||
#define ADXL372_INT2_MAP_FIFO_FULL_MODE(x) (((x) & 0x1) << 2)
|
||||
#define ADXL372_INT2_MAP_FIFO_OVR_MSK BIT(3)
|
||||
#define ADXL372_INT2_MAP_FIFO_OVR_MODE(x) (((x) & 0x1) << 3)
|
||||
#define ADXL372_INT2_MAP_INACT_MSK BIT(4)
|
||||
#define ADXL372_INT2_MAP_INACT_MODE(x) (((x) & 0x1) << 4)
|
||||
#define ADXL372_INT2_MAP_ACT_MSK BIT(5)
|
||||
#define ADXL372_INT2_MAP_ACT_MODE(x) (((x) & 0x1) << 5)
|
||||
#define ADXL372_INT2_MAP_AWAKE_MSK BIT(6)
|
||||
#define ADXL372_INT2_MAP_AWAKE_MODE(x) (((x) & 0x1) << 6)
|
||||
#define ADXL372_INT2_MAP_LOW_MSK BIT(7)
|
||||
#define ADXL372_INT2_MAP_LOW_MODE(x) (((x) & 0x1) << 7)
|
||||
|
||||
/* ADXL372_HPF */
|
||||
#define ADXL372_HPF_CORNER(x) (((x) & 0x3) << 0)
|
||||
|
||||
enum adxl372_axis {
|
||||
ADXL372_X_AXIS,
|
||||
ADXL372_Y_AXIS,
|
||||
ADXL372_Z_AXIS
|
||||
};
|
||||
|
||||
enum adxl372_op_mode {
|
||||
ADXL372_STANDBY,
|
||||
ADXL372_WAKE_UP,
|
||||
ADXL372_INSTANT_ON,
|
||||
ADXL372_FULL_BW_MEASUREMENT
|
||||
};
|
||||
|
||||
enum adxl372_bandwidth {
|
||||
ADXL372_BW_200HZ,
|
||||
ADXL372_BW_400HZ,
|
||||
ADXL372_BW_800HZ,
|
||||
ADXL372_BW_1600HZ,
|
||||
ADXL372_BW_3200HZ,
|
||||
ADXL372_BW_LPF_DISABLED = 0xC,
|
||||
};
|
||||
|
||||
enum adxl372_hpf_corner {
|
||||
ADXL372_HPF_CORNER_0,
|
||||
ADXL372_HPF_CORNER_1,
|
||||
ADXL372_HPF_CORNER_2,
|
||||
ADXL372_HPF_CORNER_3,
|
||||
ADXL372_HPF_DISABLED,
|
||||
};
|
||||
|
||||
enum adxl372_act_proc_mode {
|
||||
ADXL372_DEFAULT,
|
||||
ADXL372_LINKED,
|
||||
ADXL372_LOOPED
|
||||
};
|
||||
|
||||
enum adxl372_odr {
|
||||
ADXL372_ODR_400HZ,
|
||||
ADXL372_ODR_800HZ,
|
||||
ADXL372_ODR_1600HZ,
|
||||
ADXL372_ODR_3200HZ,
|
||||
ADXL372_ODR_6400HZ
|
||||
};
|
||||
|
||||
enum adxl372_instant_on_th_mode {
|
||||
ADXL372_INSTANT_ON_LOW_TH,
|
||||
ADXL372_INSTANT_ON_HIGH_TH
|
||||
};
|
||||
|
||||
enum adxl372_wakeup_rate {
|
||||
ADXL372_WUR_52ms,
|
||||
ADXL372_WUR_104ms,
|
||||
ADXL372_WUR_208ms,
|
||||
ADXL372_WUR_512ms,
|
||||
ADXL372_WUR_2048ms,
|
||||
ADXL372_WUR_4096ms,
|
||||
ADXL372_WUR_8192ms,
|
||||
ADXL372_WUR_24576ms
|
||||
};
|
||||
|
||||
enum adxl372_filter_settle {
|
||||
ADXL372_FILTER_SETTLE_370,
|
||||
ADXL372_FILTER_SETTLE_16
|
||||
};
|
||||
|
||||
enum adxl372_fifo_format {
|
||||
ADXL372_XYZ_FIFO,
|
||||
ADXL372_X_FIFO,
|
||||
ADXL372_Y_FIFO,
|
||||
ADXL372_XY_FIFO,
|
||||
ADXL372_Z_FIFO,
|
||||
ADXL372_XZ_FIFO,
|
||||
ADXL372_YZ_FIFO,
|
||||
ADXL372_XYZ_PEAK_FIFO,
|
||||
};
|
||||
|
||||
enum adxl372_fifo_mode {
|
||||
ADXL372_FIFO_BYPASSED,
|
||||
ADXL372_FIFO_STREAMED,
|
||||
ADXL372_FIFO_TRIGGERED,
|
||||
ADXL372_FIFO_OLD_SAVED
|
||||
};
|
||||
|
||||
struct adxl372_fifo_config {
|
||||
enum adxl372_fifo_mode fifo_mode;
|
||||
enum adxl372_fifo_format fifo_format;
|
||||
u16_t fifo_samples;
|
||||
};
|
||||
|
||||
struct adxl372_activity_threshold {
|
||||
u16_t thresh;
|
||||
bool referenced;
|
||||
bool enable;
|
||||
};
|
||||
|
||||
struct adxl372_xyz_accel_data {
|
||||
s16_t x;
|
||||
s16_t y;
|
||||
s16_t z;
|
||||
};
|
||||
|
||||
struct adxl372_data {
|
||||
struct device *bus;
|
||||
#ifdef CONFIG_ADXL372_SPI
|
||||
struct spi_config spi_cfg;
|
||||
#endif
|
||||
#if defined(CONFIG_ADXL372_SPI_GPIO_CS)
|
||||
struct spi_cs_control adxl372_cs_ctrl;
|
||||
#endif
|
||||
|
||||
struct adxl372_xyz_accel_data sample;
|
||||
struct adxl372_fifo_config fifo_config;
|
||||
|
||||
#ifdef CONFIG_ADXL372_TRIGGER
|
||||
struct device *gpio;
|
||||
struct gpio_callback gpio_cb;
|
||||
|
||||
sensor_trigger_handler_t th_handler;
|
||||
struct sensor_trigger th_trigger;
|
||||
sensor_trigger_handler_t drdy_handler;
|
||||
struct sensor_trigger drdy_trigger;
|
||||
|
||||
#if defined(CONFIG_ADXL372_TRIGGER_OWN_THREAD)
|
||||
K_THREAD_STACK_MEMBER(thread_stack, CONFIG_ADXL372_THREAD_STACK_SIZE);
|
||||
struct k_sem gpio_sem;
|
||||
struct k_thread thread;
|
||||
#elif defined(CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD)
|
||||
struct k_work work;
|
||||
struct device *dev;
|
||||
#endif
|
||||
#endif /* CONFIG_ADXL372_TRIGGER */
|
||||
};
|
||||
|
||||
struct adxl372_dev_config {
|
||||
#ifdef CONFIG_ADXL372_I2C
|
||||
const char *i2c_port;
|
||||
u16_t i2c_addr;
|
||||
#endif
|
||||
#ifdef CONFIG_ADXL372_SPI
|
||||
const char *spi_port;
|
||||
u16_t spi_slave;
|
||||
u32_t spi_max_frequency;
|
||||
#ifdef CONFIG_ADXL372_SPI_GPIO_CS
|
||||
const char *gpio_cs_port;
|
||||
u8_t cs_gpio;
|
||||
#endif
|
||||
#endif /* CONFIG_ADXL372_SPI */
|
||||
#ifdef CONFIG_ADXL372_TRIGGER
|
||||
const char *gpio_port;
|
||||
u8_t int_gpio;
|
||||
#endif
|
||||
bool max_peak_detect_mode;
|
||||
|
||||
/* Device Settings */
|
||||
bool autosleep;
|
||||
|
||||
struct adxl372_activity_threshold activity_th;
|
||||
struct adxl372_activity_threshold activity2_th;
|
||||
struct adxl372_activity_threshold inactivity_th;
|
||||
struct adxl372_fifo_config fifo_config;
|
||||
|
||||
enum adxl372_bandwidth bw;
|
||||
enum adxl372_hpf_corner hpf;
|
||||
enum adxl372_odr odr;
|
||||
enum adxl372_wakeup_rate wur;
|
||||
enum adxl372_act_proc_mode act_proc_mode;
|
||||
enum adxl372_instant_on_th_mode th_mode;
|
||||
enum adxl372_filter_settle filter_settle;
|
||||
enum adxl372_op_mode op_mode;
|
||||
|
||||
u16_t inactivity_time;
|
||||
u8_t activity_time;
|
||||
u8_t int1_config;
|
||||
u8_t int2_config;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ADXL372_TRIGGER
|
||||
int adxl372_get_status(struct device *dev,
|
||||
u8_t *status1, u8_t *status2, u16_t *fifo_entries);
|
||||
|
||||
int adxl372_reg_write_mask(struct device *dev,
|
||||
u8_t reg_addr, u32_t mask, u8_t data);
|
||||
|
||||
int adxl372_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
|
||||
int adxl372_init_interrupt(struct device *dev);
|
||||
#endif /* CONFIG_ADT7420_TRIGGER */
|
||||
|
||||
#define SYS_LOG_DOMAIN "ADXL372"
|
||||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_SENSOR_LEVEL
|
||||
#include <logging/sys_log.h>
|
||||
#endif /* __SENSOR_ADXL372_H__ */
|
171
drivers/sensor/adxl372/adxl372_trigger.c
Normal file
171
drivers/sensor/adxl372/adxl372_trigger.c
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Analog Devices Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <gpio.h>
|
||||
#include <misc/util.h>
|
||||
#include <kernel.h>
|
||||
#include <sensor.h>
|
||||
#include "adxl372.h"
|
||||
|
||||
static void adxl372_thread_cb(void *arg)
|
||||
{
|
||||
struct device *dev = arg;
|
||||
struct adxl372_data *drv_data = dev->driver_data;
|
||||
const struct adxl372_dev_config *cfg = dev->config->config_info;
|
||||
u8_t status1, status2;
|
||||
|
||||
/* Clear the status */
|
||||
if (adxl372_get_status(dev, &status1, &status2, NULL) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drv_data->th_handler != NULL) {
|
||||
/* In max peak mode we wait until we settle below the inactivity
|
||||
* threshold and then call the trigger handler.
|
||||
*/
|
||||
if (cfg->max_peak_detect_mode &&
|
||||
ADXL372_STATUS_2_INACT(status2)) {
|
||||
drv_data->th_handler(dev, &drv_data->th_trigger);
|
||||
} else if (!cfg->max_peak_detect_mode &&
|
||||
(ADXL372_STATUS_2_INACT(status2) ||
|
||||
ADXL372_STATUS_2_ACTIVITY(status2))) {
|
||||
drv_data->th_handler(dev, &drv_data->th_trigger);
|
||||
}
|
||||
}
|
||||
|
||||
if ((drv_data->drdy_handler != NULL) &&
|
||||
ADXL372_STATUS_1_DATA_RDY(status1)) {
|
||||
drv_data->drdy_handler(dev, &drv_data->drdy_trigger);
|
||||
}
|
||||
|
||||
gpio_pin_enable_callback(drv_data->gpio, cfg->int_gpio);
|
||||
}
|
||||
|
||||
static void adxl372_gpio_callback(struct device *dev,
|
||||
struct gpio_callback *cb, u32_t pins)
|
||||
{
|
||||
struct adxl372_data *drv_data =
|
||||
CONTAINER_OF(cb, struct adxl372_data, gpio_cb);
|
||||
const struct adxl372_dev_config *cfg = dev->config->config_info;
|
||||
|
||||
gpio_pin_disable_callback(dev, cfg->int_gpio);
|
||||
|
||||
#if defined(CONFIG_ADXL372_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
#elif defined(CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&drv_data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ADXL372_TRIGGER_OWN_THREAD)
|
||||
static void adxl372_thread(int dev_ptr, int unused)
|
||||
{
|
||||
struct device *dev = INT_TO_POINTER(dev_ptr);
|
||||
struct adxl372_data *drv_data = dev->driver_data;
|
||||
|
||||
ARG_UNUSED(unused);
|
||||
|
||||
while (true) {
|
||||
k_sem_take(&drv_data->gpio_sem, K_FOREVER);
|
||||
adxl372_thread_cb(dev);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD)
|
||||
static void adxl372_work_cb(struct k_work *work)
|
||||
{
|
||||
struct adxl372_data *drv_data =
|
||||
CONTAINER_OF(work, struct adxl372_data, work);
|
||||
|
||||
adxl372_thread_cb(drv_data->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int adxl372_trigger_set(struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct adxl372_data *drv_data = dev->driver_data;
|
||||
const struct adxl372_dev_config *cfg = dev->config->config_info;
|
||||
u8_t int_mask, int_en, status1, status2;
|
||||
int ret;
|
||||
|
||||
gpio_pin_disable_callback(drv_data->gpio, cfg->int_gpio);
|
||||
|
||||
switch (trig->type) {
|
||||
case SENSOR_TRIG_THRESHOLD:
|
||||
drv_data->th_handler = handler;
|
||||
drv_data->th_trigger = *trig;
|
||||
int_mask = ADXL372_INT1_MAP_ACT_MSK |
|
||||
ADXL372_INT1_MAP_INACT_MSK;
|
||||
break;
|
||||
case SENSOR_TRIG_DATA_READY:
|
||||
drv_data->drdy_handler = handler;
|
||||
drv_data->drdy_trigger = *trig;
|
||||
int_mask = ADXL372_INT1_MAP_DATA_RDY_MSK;
|
||||
break;
|
||||
default:
|
||||
SYS_LOG_ERR("Unsupported sensor trigger");
|
||||
ret = -ENOTSUP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (handler) {
|
||||
int_en = int_mask;
|
||||
} else {
|
||||
int_en = 0;
|
||||
};
|
||||
|
||||
ret = adxl372_reg_write_mask(dev, ADXL372_INT1_MAP, int_mask, int_en);
|
||||
|
||||
adxl372_get_status(dev, &status1, &status2, NULL); /* Clear status */
|
||||
out:
|
||||
gpio_pin_enable_callback(drv_data->gpio, cfg->int_gpio);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int adxl372_init_interrupt(struct device *dev)
|
||||
{
|
||||
struct adxl372_data *drv_data = dev->driver_data;
|
||||
const struct adxl372_dev_config *cfg = dev->config->config_info;
|
||||
|
||||
drv_data->gpio = device_get_binding(cfg->gpio_port);
|
||||
if (drv_data->gpio == NULL) {
|
||||
SYS_LOG_ERR("Failed to get pointer to %s device!",
|
||||
cfg->gpio_port);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_pin_configure(drv_data->gpio, cfg->int_gpio,
|
||||
GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
|
||||
GPIO_INT_ACTIVE_HIGH | GPIO_INT_DEBOUNCE);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
adxl372_gpio_callback,
|
||||
BIT(cfg->int_gpio));
|
||||
|
||||
if (gpio_add_callback(drv_data->gpio, &drv_data->gpio_cb) < 0) {
|
||||
SYS_LOG_ERR("Failed to set gpio callback!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ADXL372_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&drv_data->gpio_sem, 0, UINT_MAX);
|
||||
|
||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
||||
CONFIG_ADXL372_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)adxl372_thread, dev,
|
||||
0, NULL, K_PRIO_COOP(CONFIG_ADXL372_THREAD_PRIORITY),
|
||||
0, 0);
|
||||
#elif defined(CONFIG_ADXL372_TRIGGER_GLOBAL_THREAD)
|
||||
drv_data->work.handler = adxl372_work_cb;
|
||||
drv_data->dev = dev;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue