1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #10082 from gschorcht/drivers_l3gd20h

drivers: add driver for L3GD20H 3-axis gyroscope
This commit is contained in:
benpicco 2022-03-18 08:10:24 +01:00 committed by GitHub
commit 82b0e08745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 4731 additions and 8 deletions

View File

@ -28,4 +28,9 @@ config BOARD_STM32F3DISCOVERY
select HAVE_SAUL_GPIO
select HAVE_LSM303DLHC
# L3Gxxxx gyro
select HAVE_L3GXXXX_SPI
select HAVE_I3G4250D
select HAVE_L3GD20
source "$(RIOTBOARD)/common/stm32/Kconfig"

View File

@ -1,4 +1,11 @@
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
USEMODULE += lsm303dlhc
USEMODULE += l3gxxxx
endif
ifneq (,$(filter l3gxxxx,$(USEMODULE)))
USEMODULE += i3g4250d
USEMODULE += l3gd20
USEMODULE += l3gxxxx_spi
endif

View File

@ -92,11 +92,12 @@ e-compass.
An 3-axis gyroscope is soldered on the board.
| Sensor | L3GD20 |
| Sensor | L3GD20/I3G4250D [1] |
|:------------- |:--------------------- |
| Type | Gyroscope |
| Vendor | ST Microelectronics |
| Datasheet | [Datasheet](https://www.mouser.de/datasheet/2/389/l3gd20-954745.pdf) |
| Datasheet L3GD20 | [Datasheet](https://www.mouser.de/datasheet/2/389/l3gd20-954745.pdf) |
| Datasheet I3G4250D | [Datasheet](https://www.st.com/resource/en/datasheet/i3g4250d.pdf) |
| Connected to | SPI_0 |
| Pin Config: | |
| Device | SPI1 |
@ -107,6 +108,8 @@ An 3-axis gyroscope is soldered on the board.
| INT1 | PE0 (IN) |
| INT2/DRDY | PE1 (IN) |
[1] L3GD20 (up to rev. D01), IG34250D (from rev. E02)
The driver detects automatically which sensor variant is on the board.
## Implementation Status
@ -123,7 +126,7 @@ An 3-axis gyroscope is soldered on the board.
| | Inpute Capture| no | |
| Accelerometer | LSM303DLHC | no | planned |
| Magnetometer | LSM303DLHC | no | planned |
| Gyroscope | L3GD20 | no | planned |
| Gyroscope | L3GD20/I3G4250D | yes | |
## Flashing the device

View File

@ -97,6 +97,16 @@ extern "C" {
#define LSM303DLHC_PARAM_MAG_PIN GPIO_PIN(PORT_E, 2)
/** @} */
/**
* @name L3GD20 (Rev. C01, D01), I3G4250D (Rev. E02)
* @{
*/
#define L3GXXXX_SPI_DEV SPI_DEV(0) /**< SPI bus used for L3Gxxxx */
#define L3GXXXX_SPI_CS GPIO_PIN(PORT_E, 3) /**< SPI CS pin used for L3Gxxxx */
#define L3GXXXX_INT1_PIN GPIO_PIN(PORT_E, 0) /**< INT1 pin used for L3Gxxxx */
#define L3GXXXX_INT2_PIN GPIO_PIN(PORT_E, 1) /**< INT2/DRDY pin used for L3Gxxxx */
/** @} */
#ifdef __cplusplus
}
#endif

View File

@ -32,4 +32,9 @@ config BOARD_STM32F429I_DISC1
select HAVE_ILI9341
select HAVE_STMPE811_I2C
# L3Gxxxx gyro
select HAVE_L3GXXXX_SPI
select HAVE_I3G4250D
select HAVE_L3GD20
source "$(RIOTBOARD)/common/stm32/Kconfig"

View File

@ -1,5 +1,6 @@
ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio
USEMODULE += l3gxxxx
endif
ifneq (,$(filter disp_dev,$(USEMODULE)))
@ -9,3 +10,9 @@ endif
ifneq (,$(filter touch_dev,$(USEMODULE)))
USEMODULE += stmpe811_i2c
endif
ifneq (,$(filter l3gxxxx,$(USEMODULE)))
USEMODULE += i3g4250d
USEMODULE += l3gd20
USEMODULE += l3gxxxx_spi
endif

View File

@ -46,13 +46,23 @@ extern "C" {
/** @} */
/**
* @brief User button
* @name User button
* @{
*/
#define BTN0_PIN GPIO_PIN(PORT_A, 0)
#define BTN0_PIN GPIO_PIN(PORT_A, 0) /**< GPIO used for BTN0 */
#define BTN0_MODE GPIO_IN
/** @} */
/**
* @name L3GD20 (Rev. B01, C01), I3G4250D (Rev. D02, E01)
* @{
*/
#define L3GXXXX_SPI_DEV SPI_DEV(0) /**< SPI bus used for L3Gxxxx */
#define L3GXXXX_SPI_CS GPIO_PIN(PORT_C, 1) /**< SPI CS pin used for L3Gxxxx */
#define L3GXXXX_INT1_PIN GPIO_PIN(PORT_A, 1) /**< INT1 pin used for L3Gxxxx */
#define L3GXXXX_INT2_PIN GPIO_PIN(PORT_A, 2) /**< INT2/DRDY pin used for L3Gxxxx */
/** @} */
#ifdef __cplusplus
}
#endif

View File

@ -21,12 +21,14 @@ config CPU_FAM_ESP32
select PACKAGE_ESP32_SDK if TEST_KCONFIG
select PACKAGE_ESP32_SDK_LIBS if TEST_KCONFIG
select MODULE_PERIPH_RTT if HAS_PERIPH_RTT && MODULE_PM_LAYERED
select MODULE_RTT_RTC if HAS_PERIPH_RTT && MODULE_PERIPH_RTC
select MODULE_PS if MODULE_SHELL
select MODULE_ESP_IDF_DRIVER if TEST_KCONFIG
select MODULE_ESP_IDF_ESP32 if TEST_KCONFIG
select MODULE_ESP_IDF_SOC if TEST_KCONFIG
select MODULE_PERIPH_RTT if HAS_PERIPH_RTT && MODULE_PM_LAYERED
select MODULE_RTT_RTC if HAS_PERIPH_RTT && MODULE_PERIPH_RTC
select MODULE_PS if MODULE_SHELL
select MODULE_PTHREAD if MODULE_LIBSTDCPP && TEST_KCONFIG
imply MODULE_NEWLIB_NANO

View File

@ -95,6 +95,7 @@ rsource "isl29125/Kconfig"
rsource "itg320x/Kconfig"
rsource "jc42/Kconfig"
rsource "l3g4200d/Kconfig"
rsource "l3gxxxx/Kconfig"
rsource "lc709203f/Kconfig"
rsource "lis2dh12/Kconfig"
rsource "lis3dh/Kconfig"

View File

@ -76,6 +76,10 @@ ifneq (,$(filter itg320x_%,$(USEMODULE)))
USEMODULE += itg320x
endif
ifneq (,$(filter l3gxxxx_%,$(USEMODULE)))
USEMODULE += l3gxxxx
endif
ifneq (,$(filter lis2dh12%,$(USEMODULE)))
USEMODULE += lis2dh12
endif

1999
drivers/include/l3gxxxx.h Normal file

File diff suppressed because it is too large Load Diff

459
drivers/l3gxxxx/Kconfig Normal file
View File

@ -0,0 +1,459 @@
# Copyright (c) 2021 Gunar Schorcht
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config HAVE_L3GD20H
bool
select MODULE_L3GXXXX if MODULE_SAUL_DEFAULT
help
Indicates that L3GD20H sensor is present.
config HAVE_L3GD20
bool
select MODULE_L3GXXXX if MODULE_SAUL_DEFAULT
help
Indicates that L3GD20 sensor is present.
config HAVE_L3G4200D_NG
bool
select MODULE_L3GXXXX if MODULE_SAUL_DEFAULT
help
Indicates that L3G4200D sensor is present.
config HAVE_A3G4250D
bool
select MODULE_L3GXXXX if MODULE_SAUL_DEFAULT
help
Indicates that A3G4250D sensor is present.
config HAVE_I3G4250D
bool
select MODULE_L3GXXXX if MODULE_SAUL_DEFAULT
help
Indicates that A3G4250D sensor is present.
config HAVE_L3GXXXX_I2C
bool
config HAVE_L3GXXXX_SPI
bool
menuconfig MODULE_L3GXXXX
bool "L3GXXX 3-axis gyroscope sensor"
depends on TEST_KCONFIG
help
Driver for ST L3GXXXX 3-axis gyroscope sensor family.
The driver supports L3GD20H, L3GD20, L3G4200D, I3G4250D and A3G4250D.
if MODULE_L3GXXXX
menu "Sensor variants used"
config MODULE_L3GD20H
bool "L3GD20H"
default y if HAVE_L3GD20H
default y if !MODULE_L3GD20 && !MODULE_L3G4200D_NG && !MODULE_A3G4250D && !MODULE_I3G4250D
help
Enables the support for L3GD20H.
config MODULE_L3GD20
bool "L3GD20"
default y if HAVE_L3GD20
help
Enables the support for L3GD20.
config MODULE_L3G4200D_NG
bool "L3G4200D"
default y if HAVE_L3G4200D_NG
help
Enables the support for L3G4200D.
config MODULE_A3G4250D
bool "A3G4250D"
default y if HAVE_A3G4250D
help
Enables the support for A3G4250D.
config MODULE_I3G4250D
bool "I3G4250D"
default y if HAVE_I3G4250D
help
Enables the support for I3G4250D.
endmenu
choice
bool "Device interface"
default MODULE_L3GXXXX_I2C if HAVE_L3GXXXX_I2C
default MODULE_L3GXXXX_SPI if HAVE_L3GXXXX_SPI
help
The device can be connected via I2C or SPI, select the right one.
config MODULE_L3GXXXX_I2C
bool "I2C"
depends on HAS_PERIPH_I2C
select MODULE_PERIPH_I2C
config MODULE_L3GXXXX_SPI
bool "SPI"
depends on HAS_PERIPH_SPI
depends on HAS_PERIPH_GPIO
select MODULE_PERIPH_SPI
select MODULE_PERIPH_GPIO
endchoice
config MODULE_L3GXXXX_LOW_ODR
bool "Support of low output data rates"
depends on MODULE_L3GD20H
help
Low data rates are only supported on L3GD20H.
choice
bool "Output data rate (ODR)"
default L3GXXXX_ODR_100_25
help
Measurements are performed at a defined output rate (ODR) with a
user selectable bandwidth. Select the ouput data rate of the sensor
an the cutoff frequency of the LPF2 filter. The cutoff frequency of
LPF1 is fix for a given output data rate.
config L3GXXXX_ODR_100_12
bool "High ODR 100 Hz, LPF2 cutoff 12.5 Hz (LPF1 cutoff 32 Hz)"
config L3GXXXX_ODR_100_25
bool "High ODR 100 Hz, LPF2 cutoff 25 Hz (LPF1 cutoff 32 Hz)"
config L3GXXXX_ODR_200_12
bool "High ODR 200 Hz, LPF1 cutoff 63.3 Hz, LPF2 cutoff 12.5 Hz"
config L3GXXXX_ODR_200_25
bool "High ODR 200 Hz, LPF1 cutoff 63.3 Hz, LPF2 cutoff 25 Hz"
config L3GXXXX_ODR_200_50
bool "High ODR 200 Hz, LPF1 cutoff 63.3 Hz, LPF2 cutoff 50 Hz"
config L3GXXXX_ODR_200_70
bool "High ODR 200 Hz, LPF1 cutoff 63.3 Hz, LPF2 cutoff 70 Hz"
config L3GXXXX_ODR_400_20
bool "High ODR 400 Hz, LPF1 cutoff 128 Hz, LPF2 cutoff 20 Hz"
config L3GXXXX_ODR_400_25
bool "High ODR 400 Hz, LPF1 cutoff 128 Hz, LPF2 cutoff 25 Hz"
config L3GXXXX_ODR_400_50
bool "High ODR 400 Hz, LPF1 cutoff 128 Hz, LPF2 cutoff 50 Hz"
config L3GXXXX_ODR_400_110
bool "High ODR 400 Hz, LPF1 cutoff 128 Hz, LPF2 cutoff 110 Hz"
config L3GXXXX_ODR_800_30
bool "High ODR 800 Hz, LPF1 cutoff 211 Hz, LPF2 cutoff 30 Hz"
config L3GXXXX_ODR_800_35
bool "High ODR 800 Hz, LPF1 cutoff 211 Hz, LPF2 cutoff 35 Hz"
config L3GXXXX_ODR_800_50
bool "High ODR 800 Hz, LPF1 cutoff 211 Hz, LPF2 cutoff 50 Hz"
config L3GXXXX_ODR_800_100
bool "High ODR 800 Hz, LPF1 cutoff 211 Hz, LPF2 cutoff 100 Hz"
if MODULE_L3GXXXX_LOW_ODR
config L3GXXXX_ODR_12
bool "Low ODR 12.5 Hz, LPF1 cutoff 3.9 Hz, LPF2 not used"
config L3GXXXX_ODR_25
bool "Low ODR 25 Hz, LPF1 cutoff 7.8 Hz, LPF2 not used"
config L3GXXXX_ODR_50
bool "Low ODR 50 Hz, LPF1 cutoff 16 Hz, LPF2 cutoff 16.6 Hz"
endif # MODULE_L3GXXXX_LOW_ODR
endchoice
choice
bool "Full scale"
default L3GXXXX_SCALE_245_DPS
help
The full scale value determines the sensitivity of the sensor and thus
the range and resolution of the sensor's output data. The resolution
of the output data is about Full Scale/INT16_MAX.
config L3GXXXX_SCALE_245_DPS
bool "±245 dps"
help
The typical sensitivity is 8.75 mdps.
if !MODULE_A3G4250D
config L3GXXXX_SCALE_500_DPS
bool "±500 dps"
help
The Typical sensitivity is 17.5 mdps.
config L3GXXXX_SCALE_2000_DPS
bool "±2000 dps"
help
The typical sensitivity is 70 mdps.
endif # !MODULE_A3G4250D
endchoice
choice
bool "Filters used for output data"
default L3GXXXX_HPF_AND_LPF2
help
L3Gxxxx sensors integrate a combination of two low pass filters (LPF)
and one high pass filter (HPF) which can be used to filter the output
data. First, raw sensor data are always filtered by LPF1 with a cutoff
frequency that is fixed for the selected output data rate (ODR).
The resulting data can then optionally be filtered by HPF and LPF2.
Both filters can be used or bypassed.
Please note: The filter selection for the output data also affects the
filter selection for event interrupt generation. If the HPF is enabled
for filtering the output data, it is also active for filtering the
sensor data used for interrupt generation if the LPF2 is enabled for
interrupt generation.
config L3GXXXX_NO_FILTER
bool "HPF and LPF2 are not used"
config L3GXXXX_HPF_ONLY
bool "only HPF is used"
config L3GXXXX_LPF2_ONLY
bool "only LPF2 used"
config L3GXXXX_HPF_AND_LPF2
bool "HPF and LPF2 are used"
endchoice
if L3GXXXX_HPF_ONLY || L3GXXXX_HPF_AND_LPF2 || L3GXXXX_INT1_HPF_ONLY || L3GXXXX_INT1_HPF_AND_LPF2
choice
bool "HPF mode"
help
The high pass filter (HPF) can be used in different modes. Select
the right one.
config L3GXXXX_HPF_NORMAL
bool "Normal mode"
help
In Normal mode, the HPF is reset by reading REFERENCE register.
config L3GXXXX_HPF_REFERENCE
bool "Reference mode"
help
In Reference mode, the output data are the difference to the
value written to the REFERENCE register.
config L3GXXXX_HPF_AUTORESET
bool "Autoreset mode"
help
In Autoreset mode, the HPF is automatically reset when a configured
interrupt event occurs.
endchoice
config L3GXXXX_HPF_CUTOFF
int "HPF cutoff frequency n = [0...9]"
range 0 9
default 0
help
The cutoff frequency is specified as a value from 0 to 9, which defines
the cutoff frequency depending on the selected sensor mode and the
output data rate. Details can be found in the data sheet for the CTRL2
register field HPCF.
endif # L3GXXXX_HPF_ONLY || L3GXXXX_HPF_AND_LPF2 || L3GXXXX_INT1_HPF_ONLY || L3GXXXX_INT1_HPF_AND_LPF2
config MODULE_L3GXXXX_FIFO
bool "Support for the 32 level FIFO"
help
The 32 level FIFO is used to collect a number of sensor
data samples before the data have to be fetched by the MCU.
if MODULE_L3GXXXX_FIFO
choice
bool "FIFO mode"
default L3GXXXX_FIFO_MODE_FIFO
help
The 32 level FIFO is used to collect a number of sensor
data samples before the data have to be fetched by the MCU. Select
the right mode of the FIFO.
config L3GXXXX_FIFO_MODE_BYPASS
bool "Bypass mode (FIFO is not used)"
help
The FIFO is not used.
config L3GXXXX_FIFO_MODE_FIFO
bool "FIFO mode"
help
Data samples are stored in the FIFO until it is full.
config L3GXXXX_FIFO_MODE_STREAM
bool "Stream mode"
help
The FIFO is used as ring buffer and newest data samples are stored.
continuously
config L3GXXXX_FIFO_MODE_DYNAMIC_STREAM
bool "Dynamic Stream mode"
help
Like the Stream mode, but differs in reading the first data sample
after emptying.
config L3GXXXX_FIFO_MODE_STREAM_TO_FIFO
bool "Stream-to-FIFO mode"
help
The FIFO is used in stream mode until an event interrupt is triggered
and then switches to FIFO mode.
config L3GXXXX_FIFO_MODE_BYPASS_TO_STREAM
bool "Bypass-to-Stream mode"
help
The FIFO is not used until an event interrupt is triggered
and then switches to Stream mode
config L3GXXXX_FIFO_MODE_BYPASS_TO_FIFO
bool "Bypass-to-FIFO mode"
help
The FIFO is not used until an event interrupt is triggered
and then switches to FIFO mode.
endchoice
config L3GXXXX_FIFO_WATERMARK
int "FIFO watermark level (threshold)"
range 1 23
default 31
help
If the number of data samples in FIFO becomes greater than this
watermark level (threshold), the WTM (FTH) flag in FIFO_SRC register
is set and an interrupt can be triggered on signal INT2/DRDY if data
ready and FIFO status interrupts is enabled.
endif # MODULE_L3GXXXX_FIFO
config MODULE_L3GXXXX_IRQ_EVENT
bool "Support for event interrupts on signal INT1"
depends on HAS_PERIPH_GPIO_IRQ
select MODULE_PERIPH_GPIO_IRQ
help
Event interrupts on signal INT2/DRDY can be used to recognize
axes movements or wake-up.
if MODULE_L3GXXXX_IRQ_EVENT
config L3GXXXX_INT1_X_THRESH
int "Threshold for X axis events"
range 0 32767
default 4012
help
Threshold values are defined for raw data values. Their resolution
therefore depends on the selected full range (default ~30 at 245 dps):
254 dps -> LSB value ~7.5 mdps,
500 dps -> LSB value ~15.3 mdps,
2000 dps -> LSB value ~61 mdps
config L3GXXXX_INT1_Y_THRESH
int "Threshold for Y axis events"
range 0 32767
default 4012
help
Threshold values are defined for raw data values. Their resolution
therefore depends on the selected full range (default ~30 at 245 dps):
254 dps -> LSB value ~7.5 mdps,
500 dps -> LSB value ~15.3 mdps,
2000 dps -> LSB value ~61 mdps
config L3GXXXX_INT1_Z_THRESH
int "Threshold for Z axis events"
range 0 32767
default 4012
help
Threshold values are defined for raw data values. Their resolution
therefore depends on the selected full range (default ~30 at 245 dps):
254 dps -> LSB value ~7.5 mdps,
500 dps -> LSB value ~15.3 mdps,
2000 dps -> LSB value ~61 mdps
config L3GXXXX_INT1_X_GT_THRESH
bool "Interrupt generation enabled for |X| > X threshold (X high event)"
default y
config L3GXXXX_INT1_X_LT_THRESH
bool "Interrupt generation enabled for |X| < X threshold (X low event)"
default n
config L3GXXXX_INT1_Y_GT_THRESH
bool "Interrupt generation enabled for |Y| > Y threshold (Y high event)"
default y
config L3GXXXX_INT1_Y_LT_THRESH
bool "Interrupt generation enabled for |Y| < Y threshold (Y low event)"
default n
config L3GXXXX_INT1_Z_GT_THRESH
bool "Interrupt generation enabled for |Z| > Z threshold (Z high event)"
default y
config L3GXXXX_INT1_Z_LT_THRESH
bool "Interrupt generation enabled for |Z| < Z threshold (Z low event)"
default n
choice
bool "Filters used for event interrupt generation"
default L3GXXXX_INT1_HPF_AND_LPF2
help
The combination of high pass filter (HPF) and low pass filter 2 (LPF2)
can also be used to filter the sensor data for event interrupt
generation.
Please note: The filter selection for the interrupt generation also
affects the filter selection for the output data. If the HPF is enabled
for interrupt generation, it is also active for filtering the
output data if the LPF2 is enabled for output data.
config L3GXXXX_INT1_NO_FILTER
bool "HPF and LPF2 are not used"
config L3GXXXX_INT1_HPF_ONLY
bool "only HPF is used"
config L3GXXXX_INT1_LPF2_ONLY
bool "only LPF2 used"
config L3GXXXX_INT1_HPF_AND_LPF2
bool "HPF and LPF2 are used"
endchoice
config L3GXXXX_INT1_AND
bool "Combination of interupt events"
default n
help
y (AND) = all enabled axes passed their tresholds,
n (OR) = at least one axis passed its threshold
config L3GXXXX_INT1_LATCH
bool "Interrupt latch enable"
default n
help
If enabled, the interrupt is latched until the interrupt source has
been read.
endif # MODULE_L3GXXXX_IRQ_EVENT
config MODULE_L3GXXXX_IRQ_DATA
bool "Support for data interrupts on signal INT2/DRDY (Data Ready and FIFO status)"
depends on HAS_PERIPH_GPIO_IRQ
select MODULE_PERIPH_GPIO_IRQ
help
Data ready and FIFO status interrupts on signal INT2/DRDY
can be used to determine when data are ready to be read or when the
status of the FIFO changes.
config MODULE_L3GXXXX_SLEEP
bool "Support for sleep and wake-up function"
config MODULE_L3GXXXX_CONFIG
bool "Support for configuration of the sensor at runtime"
endif # MODULE_L3GXXXX

1
drivers/l3gxxxx/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTMAKE)/driver_with_saul.mk

View File

@ -0,0 +1,25 @@
ifeq (,$(filter l3gd20% l3g4200d_ng %3g4250d,$(USEMODULE)))
# pull in L3GD20H variant by default if no interface is defined
USEMODULE += l3gd20h
endif
ifeq (,$(filter l3gxxxx_spi,$(USEMODULE)))
# pull in I2C variant by default if no interface is defined
USEMODULE += l3gxxxx_i2c
endif
ifneq (,$(filter l3gxxxx_spi,$(USEMODULE)))
FEATURES_REQUIRED += periph_spi
endif
ifneq (,$(filter l3gxxxx_i2c,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif
ifneq (,$(filter l3gxxxx_irq_%,$(USEMODULE)))
USEMODULE += l3gxxxx_irq
endif
ifneq (,$(filter l3gxxxx_irq,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio_irq
endif

View File

@ -0,0 +1,19 @@
# include variants of L3Gxxxx driver as pseudo modules
PSEUDOMODULES += a3g4250d
PSEUDOMODULES += i3g4250d
PSEUDOMODULES += l3g4200d_ng
PSEUDOMODULES += l3gd20
PSEUDOMODULES += l3gd20h
PSEUDOMODULES += l3gxxxx_i2c
PSEUDOMODULES += l3gxxxx_spi
PSEUDOMODULES += l3gxxxx_low_odr
PSEUDOMODULES += l3gxxxx_fifo
PSEUDOMODULES += l3gxxxx_irq
PSEUDOMODULES += l3gxxxx_irq_data
PSEUDOMODULES += l3gxxxx_irq_event
PSEUDOMODULES += l3gxxxx_sleep
PSEUDOMODULES += l3gxxxx_config
USEMODULE_INCLUDES_l3gxxxx := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_l3gxxxx)

View File

@ -0,0 +1,385 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_l3gxxxx
* @brief Default configuration for ST L3Gxxxx 3-axis gyroscope sensor family
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
* @{
*/
#ifndef L3GXXXX_PARAMS_H
#define L3GXXXX_PARAMS_H
#include "board.h"
#include "l3gxxxx.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Default hardware configuration
* @{
*/
#if IS_USED(MODULE_L3GXXXX_I2C) || DOXYGEN
#ifndef L3GXXXX_I2C_DEV
/** Default I2C device, if the I2C interface is used */
#define L3GXXXX_I2C_DEV (I2C_DEV(0))
#endif
#ifndef L3GXXXX_I2C_ADDR
/** Default I2C address, if the I2C interface is used */
#define L3GXXXX_I2C_ADDR (L3GXXXX_I2C_ADDR_2)
#endif
#ifndef L3GXXXX_I2C_IF_PARAMS
/** Default I2C interface parameter set */
#define L3GXXXX_I2C_IF_PARAMS .if_params.type = L3GXXXX_I2C, \
.if_params.i2c.dev = L3GXXXX_I2C_DEV, \
.if_params.i2c.addr = L3GXXXX_I2C_ADDR,
#endif
#endif /* MODULE_L3GXXXX_I2C || DOXYGEN */
#if IS_USED(MODULE_L3GXXXX_SPI) || DOXYGEN
#ifndef L3GXXXX_SPI_DEV
/** Default SPI device, if the SPI interface is used */
#define L3GXXXX_SPI_DEV SPI_DEV(0)
#endif
#ifndef L3GXXXX_SPI_CLK
/** Default SPI clock frequency, if the SPI interface is used */
#define L3GXXXX_SPI_CLK (SPI_CLK_1MHZ)
#endif
#ifndef L3GXXXX_SPI_CS
/** Default SPI CS signal, if the SPI interface is used */
#define L3GXXXX_SPI_CS (GPIO_PIN(0, 0))
#endif
#ifndef L3GXXXX_SPI_IF_PARAMS
/** Default SPI interface parameter set */
#define L3GXXXX_SPI_IF_PARAMS .if_params.type = L3GXXXX_SPI, \
.if_params.spi.dev = L3GXXXX_SPI_DEV, \
.if_params.spi.clk = L3GXXXX_SPI_CLK, \
.if_params.spi.cs = L3GXXXX_SPI_CS,
#endif
#endif /* MODULE_L3GXXXX_SPI || DOXYGEN */
#ifndef L3GXXXX_INT1_PIN
/** Default MCU pin for INT1 signal */
#define L3GXXXX_INT1_PIN (GPIO_PIN(0, 1))
#endif
#ifndef L3GXXXX_INT2_PIN
/** Default MCU pin for INT2/DRDY signal */
#define L3GXXXX_INT2_PIN (GPIO_PIN(0, 2))
#endif
/** @} */
/**
* @name Default sensor configuration
* @{
*/
#if !DOXYGEN
/* Mapping of Kconfig defines to the respective driver enumeration values */
#ifdef CONFIG_L3GXXXX_ODR_100_12
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_100_12)
#elif CONFIG_L3GXXXX_ODR_100_25
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_100_25)
#elif CONFIG_L3GXXXX_ODR_200_12
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_200_12)
#elif CONFIG_L3GXXXX_ODR_200_25
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_200_25)
#elif CONFIG_L3GXXXX_ODR_200_50
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_200_50)
#elif CONFIG_L3GXXXX_ODR_200_70
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_200_70)
#elif CONFIG_L3GXXXX_ODR_400_20
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_400_20)
#elif CONFIG_L3GXXXX_ODR_400_25
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_400_25)
#elif CONFIG_L3GXXXX_ODR_400_50
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_400_50)
#elif CONFIG_L3GXXXX_ODR_400_110
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_400_110)
#elif CONFIG_L3GXXXX_ODR_800_30
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_800_30)
#elif CONFIG_L3GXXXX_ODR_800_35
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_800_35)
#elif CONFIG_L3GXXXX_ODR_800_50
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_800_50)
#elif CONFIG_L3GXXXX_ODR_800_100
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_800_100)
#elif CONFIG_L3GXXXX_ODR_12
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_12)
#elif CONFIG_L3GXXXX_ODR_25
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_25)
#elif CONFIG_L3GXXXX_ODR_50
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_50)
#endif
#ifdef CONFIG_L3GXXXX_SCALE_245_DPS
#define CONFIG_L3GXXXX_SCALE (L3GXXXX_SCALE_245_DPS)
#elif CONFIG_L3GXXXX_SCALE_500_DPS
#define CONFIG_L3GXXXX_SCALE (L3GXXXX_SCALE_500_DPS)
#elif CONFIG_L3GXXXX_SCALE_2000_DPS
#define CONFIG_L3GXXXX_SCALE (L3GXXXX_SCALE_2000_DPS)
#endif
#ifdef CONFIG_L3GXXXX_NO_FILTER
#define CONFIG_L3GXXXX_FILTER_SEL (L3GXXXX_NO_FILTER)
#elif CONFIG_L3GXXXX_HPF_ONLY
#define CONFIG_L3GXXXX_FILTER_SEL (L3GXXXX_HPF_ONLY)
#elif CONFIG_L3GXXXX_LPF2_ONLY
#define CONFIG_L3GXXXX_FILTER_SEL (L3GXXXX_LPF2_ONLY)
#elif CONFIG_L3GXXXX_HPF_AND_LPF2
#define CONFIG_L3GXXXX_FILTER_SEL (L3GXXXX_HPF_AND_LPF2)
#endif
#ifdef CONFIG_L3GXXXX_HPF_NORMAL
#define CONFIG_L3GXXXX_HPF_MODE (L3GXXXX_HPF_NORMAL)
#elif CONFIG_L3GXXXX_HPF_REFERENCE
#define CONFIG_L3GXXXX_HPF_MODE (L3GXXXX_HPF_REFERENCE)
#elif CONFIG_L3GXXXX_HPF_AUTORESET
#define CONFIG_L3GXXXX_HPF_MODE (L3GXXXX_HPF_AUTORESET)
#endif
#ifdef CONFIG_L3GXXXX_FIFO_MODE_BYPASS
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_BYPASS)
#elif CONFIG_L3GXXXX_FIFO_MODE_FIFO
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_FIFO)
#elif CONFIG_L3GXXXX_FIFO_MODE_STREAM
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_STREAM)
#elif CONFIG_L3GXXXX_FIFO_MODE_STREAM_TO_FIFO
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_STREAM_TO_FIFO)
#elif CONFIG_L3GXXXX_FIFO_MODE_BYPASS_TO_STREAM
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_BYPASS_TO_STREAM)
#elif CONFIG_L3GXXXX_FIFO_MODE_DYNAMIC_STREAM
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_DYNAMIC_STREAM
#elif CONFIG_L3GXXXX_FIFO_MODE_BYPASS_TO_FIFO
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_BYPASS_TO_FIFO)
#endif
#ifdef CONFIG_L3GXXXX_INT1_NO_FILTER
#define CONFIG_L3GXXXX_INT1_FILTER (L3GXXXX_NO_FILTER)
#elif CONFIG_L3GXXXX_INT1_HPF_ONLY
#define CONFIG_L3GXXXX_INT1_FILTER (L3GXXXX_HPF_ONLY)
#elif CONFIG_L3GXXXX_INT1_LPF2_ONLY
#define CONFIG_L3GXXXX_INT1_FILTER (L3GXXXX_LPF2_ONLY)
#elif CONFIG_L3GXXXX_INT1_HPF_AND_LPF2
#define CONFIG_L3GXXXX_INT1_FILTER (L3GXXXX_HPF_AND_LPF2)
#endif
#endif /* !DOXYGEN */
#ifndef CONFIG_L3GXXXX_ODR
/** Default ODR and cut-off frequency */
#define CONFIG_L3GXXXX_ODR (L3GXXXX_ODR_100_25)
#endif
#ifndef CONFIG_L3GXXXX_SCALE
/** Default full scale */
#define CONFIG_L3GXXXX_SCALE (L3GXXXX_SCALE_245_DPS)
#endif
#ifndef CONFIG_L3GXXXX_FILTER_SEL
/** Default filter selection used for output data */
#define CONFIG_L3GXXXX_FILTER_SEL (L3GXXXX_HPF_AND_LPF2)
#endif
#ifndef CONFIG_L3GXXXX_HPF_MODE
/** Default HPF mode used for output data */
#define CONFIG_L3GXXXX_HPF_MODE (L3GXXXX_HPF_NORMAL)
#endif
#ifndef CONFIG_L3GXXXX_HPF_CUTOFF
/** Default HPF cutoff frequency 8 Hz */
#define CONFIG_L3GXXXX_HPF_CUTOFF (0)
#endif
#ifndef CONFIG_L3GXXXX_FIFO_MODE
/** Default FIFO mode if FIO is used */
#define CONFIG_L3GXXXX_FIFO_MODE (L3GXXXX_FIFO)
#endif
#ifndef CONFIG_L3GXXXX_FIFO_WATERMARK
/** Default FIFO watermark level (threshold) value if FIO is used */
#define CONFIG_L3GXXXX_FIFO_WATERMARK (23)
#endif
#ifndef CONFIG_L3GXXXX_INT1_X_THRESH
/** Default INT1 threshold for X axis events (~30 dps at fulls scale of ±245 dps) */
#define CONFIG_L3GXXXX_INT1_X_THRESH (4012)
#endif
#ifndef CONFIG_L3GXXXX_INT1_X_GT_THRESH
/** Default INT1 interrupt enable for |X| > X threshold (X high event) */
#define CONFIG_L3GXXXX_INT1_X_GT_THRESH (true)
#endif
#ifndef CONFIG_L3GXXXX_INT1_X_LT_THRESH
/** Default INT1 interrupt enable for |X| < X threshold (X low event) */
#define CONFIG_L3GXXXX_INT1_X_LT_THRESH (false)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Y_THRESH
/** Default INT1 threshold for Y axis events (~30 dps at fulls scale of ±245 dps) */
#define CONFIG_L3GXXXX_INT1_Y_THRESH (4012)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Y_GT_THRESH
/** Default INT1 interrupt enable for |Y| < Y threshold (Y low event) */
#define CONFIG_L3GXXXX_INT1_Y_GT_THRESH (true)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Y_LT_THRESH
/** Default INT1 interrupt enable for |Y| > Y threshold (Y high event) */
#define CONFIG_L3GXXXX_INT1_Y_LT_THRESH (false)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Z_THRESH
/** Default INT1 threshold for Z axis events (~30 dps at fulls scale of ±245 dps) */
#define CONFIG_L3GXXXX_INT1_Z_THRESH (4012)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Z_GT_THRESH
/** Default INT1 interrupt enable for |Z| < Z threshold (Z low event) */
#define CONFIG_L3GXXXX_INT1_Z_GT_THRESH (true)
#endif
#ifndef CONFIG_L3GXXXX_INT1_Z_LT_THRESH
/** Default INT1 interrupt enable for |Z| > Z threshold (Z high event) */
#define CONFIG_L3GXXXX_INT1_Z_LT_THRESH (false)
#endif
#ifndef CONFIG_L3GXXXX_INT1_FILTER
/** Default filter selection used for INT1 interrupt */
#define CONFIG_L3GXXXX_INT1_FILTER (L3GXXXX_HPF_AND_LPF2)
#endif
#ifndef CONFIG_L3GXXXX_INT1_AND
/** Default event interrupt combination is OR */
#define CONFIG_L3GXXXX_INT1_AND (false)
#endif
#ifndef CONFIG_L3GXXXX_INT1_LATCH
/** Default INT1 event interrupt latch enabled */
#define CONFIG_L3GXXXX_INT1_LATCH (true)
#endif
#if IS_USED(MODULE_L3GXXXX_IRQ_EVENT) || DOXYGEN
/** Default INT1 parameter set */
#define L3GXXXX_INT1_PARAMS .int1_pin = L3GXXXX_INT1_PIN, \
.int1_cfg.x_high_enabled = CONFIG_L3GXXXX_INT1_X_GT_THRESH, \
.int1_cfg.y_high_enabled = CONFIG_L3GXXXX_INT1_Y_GT_THRESH, \
.int1_cfg.z_high_enabled = CONFIG_L3GXXXX_INT1_Z_GT_THRESH, \
.int1_cfg.x_low_enabled = CONFIG_L3GXXXX_INT1_X_LT_THRESH, \
.int1_cfg.y_low_enabled = CONFIG_L3GXXXX_INT1_Y_LT_THRESH, \
.int1_cfg.z_low_enabled = CONFIG_L3GXXXX_INT1_Z_LT_THRESH, \
.int1_cfg.x_threshold = CONFIG_L3GXXXX_INT1_X_THRESH, \
.int1_cfg.y_threshold = CONFIG_L3GXXXX_INT1_Y_THRESH, \
.int1_cfg.z_threshold = CONFIG_L3GXXXX_INT1_Z_THRESH, \
.int1_cfg.filter = CONFIG_L3GXXXX_INT1_FILTER, \
.int1_cfg.and_or = CONFIG_L3GXXXX_INT1_AND, \
.int1_cfg.latch = CONFIG_L3GXXXX_INT1_LATCH,
#else
#define L3GXXXX_INT1_PARAMS
#endif
#if IS_USED(MODULE_L3GXXXX_IRQ_DATA) || DOXYGEN
/** Default INT2 parameter set */
#define L3GXXXX_INT2_PARAMS .int2_pin = L3GXXXX_INT2_PIN,
#else
#define L3GXXXX_INT2_PARAMS
#endif
#if IS_USED(MODULE_L3GXXXX_FIFO) || DOXYGEN
/** Default FIFO parameter set */
#define L3GXXXX_FIFO_PARAMS .fifo_mode = CONFIG_L3GXXXX_FIFO_MODE, \
.fifo_watermark = CONFIG_L3GXXXX_FIFO_WATERMARK,
#else
#define L3GXXXX_FIFO_PARAMS
#endif
#if IS_USED(MODULE_L3GXXXX_I2C) || DOXYGEN
#ifndef L3GXXXX_I2C_PARAMS
/** Default I2C device parameter set */
#define L3GXXXX_I2C_PARAMS { \
L3GXXXX_I2C_IF_PARAMS \
.odr = CONFIG_L3GXXXX_ODR, \
.scale = CONFIG_L3GXXXX_SCALE, \
.filter_sel = CONFIG_L3GXXXX_FILTER_SEL, \
.hpf_mode = CONFIG_L3GXXXX_HPF_MODE, \
.hpf_cutoff = CONFIG_L3GXXXX_HPF_CUTOFF, \
L3GXXXX_FIFO_PARAMS \
L3GXXXX_INT1_PARAMS \
L3GXXXX_INT2_PARAMS \
}
#endif
#endif /* MODULE_L3GXXXX_I2C || DOXYGEN */
#if IS_USED(MODULE_L3GXXXX_SPI) || DOXYGEN
#ifndef L3GXXXX_SPI_PARAMS
/** Default SPI device parameter set */
#define L3GXXXX_SPI_PARAMS { \
L3GXXXX_SPI_IF_PARAMS \
.odr = CONFIG_L3GXXXX_ODR, \
.scale = CONFIG_L3GXXXX_SCALE, \
.filter_sel = CONFIG_L3GXXXX_FILTER_SEL, \
.hpf_mode = CONFIG_L3GXXXX_HPF_MODE, \
.hpf_cutoff = CONFIG_L3GXXXX_HPF_CUTOFF, \
L3GXXXX_FIFO_PARAMS \
L3GXXXX_INT1_PARAMS \
L3GXXXX_INT2_PARAMS \
}
#endif
#endif /* MODULE_L3GXXXX_SPI || DOXYGEN */
#ifndef L3GXXXX_SAUL_INFO
/** Default SAUL device info */
#define L3GXXXX_SAUL_INFO { .name = "l3gxxxx" }
#endif
/**@}*/
/**
* @brief Allocate some memory to store the actual configuration
*/
static const l3gxxxx_params_t l3gxxxx_params[] =
{
#if IS_USED(MODULE_L3GXXXX_I2C) || DOXYGEN
L3GXXXX_I2C_PARAMS,
#endif
#if IS_USED(MODULE_L3GXXXX_SPI) || DOXYGEN
L3GXXXX_SPI_PARAMS,
#endif
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t l3gxxxx_saul_info[] =
{
L3GXXXX_SAUL_INFO
};
#ifdef __cplusplus
}
#endif
#endif /* L3GXXXX_PARAMS_H */
/** @} */

View File

@ -0,0 +1,196 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_l3gxxxx
* @brief Register definitions for ST L3Gxxxx 3-axis gyroscope sensor family
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
* @{
*/
#ifndef L3GXXXX_REGS_H
#define L3GXXXX_REGS_H
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @name Register addresses
* @{
*/
#define L3GXXXX_REG_WHO_AM_I (0x0f) /**< Register address WHO_AM_I */
#define L3GXXXX_REG_CTRL1 (0x20) /**< Register address CTRL1 */
#define L3GXXXX_REG_CTRL2 (0x21) /**< Register address CTRL2 */
#define L3GXXXX_REG_CTRL3 (0x22) /**< Register address CTRL3 */
#define L3GXXXX_REG_CTRL4 (0x23) /**< Register address CTRL4 */
#define L3GXXXX_REG_CTRL5 (0x24) /**< Register address CTRL5 */
#define L3GXXXX_REG_REFERENCE (0x25) /**< Register address REFERENCE */
#define L3GXXXX_REG_OUT_TEMP (0x26) /**< Register address OUT_TEMP */
#define L3GXXXX_REG_STATUS (0x27) /**< Register address STATUS */
#define L3GXXXX_REG_OUT_X_L (0x28) /**< Register address OUT_X_L */
#define L3GXXXX_REG_OUT_X_H (0x29) /**< Register address OUT_X_H */
#define L3GXXXX_REG_OUT_Y_L (0x2a) /**< Register address OUT_Y_L */
#define L3GXXXX_REG_OUT_Y_H (0x2b) /**< Register address OUT_Y_H */
#define L3GXXXX_REG_OUT_Z_L (0x2c) /**< Register address OUT_Z_L */
#define L3GXXXX_REG_OUT_Z_H (0x2d) /**< Register address OUT_Z_H */
#define L3GXXXX_REG_FIFO_CTRL (0x2e) /**< Register address FIFO_CTRL */
#define L3GXXXX_REG_FIFO_SRC (0x2f) /**< Register address FIFO_SRC */
#define L3GXXXX_REG_IG_CFG (0x30) /**< Register address IG_CFG */
#define L3GXXXX_REG_IG_SRC (0x31) /**< Register address IG_SRC */
#define L3GXXXX_REG_IG_THS_XH (0x32) /**< Register address IG_THS_XH */
#define L3GXXXX_REG_IG_THS_XL (0x33) /**< Register address IG_THS_XL */
#define L3GXXXX_REG_IG_THS_YH (0x34) /**< Register address IG_THS_YH */
#define L3GXXXX_REG_IG_THS_YL (0x35) /**< Register address IG_THS_YL */
#define L3GXXXX_REG_IG_THS_ZH (0x36) /**< Register address IG_THS_ZH */
#define L3GXXXX_REG_IG_THS_ZL (0x37) /**< Register address IG_THS_ZL */
#define L3GXXXX_REG_IG_DURATION (0x38) /**< Register address IG_DURATION */
#define L3GXXXX_REG_LOW_ODR (0x39) /**< Register address LOW_ODR */
/** @} */
/**
* @name Register structure definitions
* @{
*/
#define L3GXXXX_ZYXOR (0x80) /**< L3GXXXX_REG_STATUS<7> */
#define L3GXXXX_ZOR (0x40) /**< L3GXXXX_REG_STATUS<6> */
#define L3GXXXX_YOR (0x20) /**< L3GXXXX_REG_STATUS<5> */
#define L3GXXXX_XOR (0x10) /**< L3GXXXX_REG_STATUS<4> */
#define L3GXXXX_ZYXDA (0x08) /**< L3GXXXX_REG_STATUS<3> */
#define L3GXXXX_ZDA (0x04) /**< L3GXXXX_REG_STATUS<2> */
#define L3GXXXX_YDA (0x02) /**< L3GXXXX_REG_STATUS<1> */
#define L3GXXXX_XDA (0x01) /**< L3GXXXX_REG_STATUS<0> */
#define L3GXXXX_ANY_DATA_READY (0x07) /**< L3GXXXX_REG_STATUS<2:0> */
#define L3GXXXX_ANY_DATA_READY_S (0) /**< L3GXXXX_REG_STATUS<2:0> */
#define L3GXXXX_ODR (0xc0) /**< L3GXXXX_REG_CTRL1<7:6> */
#define L3GXXXX_BW (0x30) /**< L3GXXXX_REG_CTRL1<5:4> */
#define L3GXXXX_ODR_BW (0xf0) /**< L3GXXXX_REG_CTRL1<7:4> */
#define L3GXXXX_POWER_MODE (0x08) /**< L3GXXXX_REG_CTRL1<3> */
#define L3GXXXX_Z_ENABLED (0x04) /**< L3GXXXX_REG_CTRL1<2> */
#define L3GXXXX_Y_ENABLED (0x02) /**< L3GXXXX_REG_CTRL1<1> */
#define L3GXXXX_X_ENABLED (0x01) /**< L3GXXXX_REG_CTRL1<0> */
#define L3GXXXX_XYZ_ENABLED (0x07) /**< L3GXXXX_REG_CTRL1<2:0> */
#define L3GXXXX_ODR_S (6) /**< L3GXXXX_REG_CTRL1<7:6> */
#define L3GXXXX_BW_S (4) /**< L3GXXXX_REG_CTRL1<5:4> */
#define L3GXXXX_ODR_BW_S (4) /**< L3GXXXX_REG_CTRL1<7:4> */
#define L3GXXXX_POWER_MODE_S (3) /**< L3GXXXX_REG_CTRL1<3> */
#define L3GXXXX_Z_ENABLED_S (2) /**< L3GXXXX_REG_CTRL1<2> */
#define L3GXXXX_Y_ENABLED_S (1) /**< L3GXXXX_REG_CTRL1<1> */
#define L3GXXXX_X_ENABLED_S (1) /**< L3GXXXX_REG_CTRL1<0> */
#define L3GXXXX_XYZ_ENABLED_S (0) /**< L3GXXXX_REG_CTRL1<2:0> */
#define L3GXXXX_EXTR_EN (0x80) /**< L3GXXXX_REG_CTRL2<7> */
#define L3GXXXX_LVL_EN (0x40) /**< L3GXXXX_REG_CTRL2<6> */
#define L3GXXXX_HPF_MODE (0x30) /**< L3GXXXX_REG_CTRL2<5:4> */
#define L3GXXXX_HPF_CUTOFF (0x0f) /**< L3GXXXX_REG_CTRL2<3:0> */
#define L3GXXXX_EXTR_EN_S (7) /**< L3GXXXX_REG_CTRL2<7> */
#define L3GXXXX_LVL_EN_S (6) /**< L3GXXXX_REG_CTRL2<6> */
#define L3GXXXX_HPF_MODE_S (4) /**< L3GXXXX_REG_CTRL2<5:4> */
#define L3GXXXX_INT1_IG (0x80) /**< L3GXXXX_REG_CTRL3<7> */
#define L3GXXXX_INT1_BOOT (0x40) /**< L3GXXXX_REG_CTRL3<6> */
#define L3GXXXX_HL_ACTIVE (0x20) /**< L3GXXXX_REG_CTRL3<5> */
#define L3GXXXX_PP_OD (0x10) /**< L3GXXXX_REG_CTRL3<4> */
#define L3GXXXX_INT2_DRDY (0x08) /**< L3GXXXX_REG_CTRL3<3> */
#define L3GXXXX_INT2_WTM (0x04) /**< L3GXXXX_REG_CTRL3<2> */
#define L3GXXXX_INT2_ORUN (0x02) /**< L3GXXXX_REG_CTRL3<1> */
#define L3GXXXX_INT2_EMPTY (0x01) /**< L3GXXXX_REG_CTRL3<0> */
#define L3GXXXX_INT1_IG_S (7) /**< L3GXXXX_REG_CTRL3<7> */
#define L3GXXXX_INT1_BOOT_S (6) /**< L3GXXXX_REG_CTRL3<6> */
#define L3GXXXX_HL_ACTIVE_S (5) /**< L3GXXXX_REG_CTRL3<5> */
#define L3GXXXX_PP_OD_S (4) /**< L3GXXXX_REG_CTRL3<4> */
#define L3GXXXX_INT2_DRDY_S (3) /**< L3GXXXX_REG_CTRL3<3> */
#define L3GXXXX_INT2_WTM_S (2) /**< L3GXXXX_REG_CTRL3<2> */
#define L3GXXXX_INT2_ORUN_S (1) /**< L3GXXXX_REG_CTRL3<1> */
#define L3GXXXX_INT2_EMPTY_S (0) /**< L3GXXXX_REG_CTRL3<0> */
#define L3GXXXX_BLOCK_DATA_UPDATE (0x80) /**< L3GXXXX_REG_CTRL4<7> */
#define L3GXXXX_BIG_LITTLE_ENDIAN (0x40) /**< L3GXXXX_REG_CTRL4<6> */
#define L3GXXXX_FULL_SCALE (0x30) /**< L3GXXXX_REG_CTRL4<5:4> */
#define L3GXXXX_FULL_SCALE_S (4) /**< L3GXXXX_REG_CTRL4<5:4> */
#define L3GXXXX_BOOT (0x80) /**< L3GXXXX_REG_CTRL5<7> */
#define L3GXXXX_FIFO_EN (0x40) /**< L3GXXXX_REG_CTRL5<6> */
#define L3GXXXX_STOP_ON_WTM (0x20) /**< L3GXXXX_REG_CTRL5<5> */
#define L3GXXXX_HP_ENABLED (0x10) /**< L3GXXXX_REG_CTRL5<4> */
#define L3GXXXX_IG_SEL (0x0c) /**< L3GXXXX_REG_CTRL5<3:2> */
#define L3GXXXX_OUT_SEL (0x03) /**< L3GXXXX_REG_CTRL5<1:0> */
#define L3GXXXX_BOOT_S (7) /**< L3GXXXX_REG_CTRL5<7> */
#define L3GXXXX_FIFO_EN_S (6) /**< L3GXXXX_REG_CTRL5<6> */
#define L3GXXXX_STOP_ON_WTM_S (5) /**< L3GXXXX_REG_CTRL5<5> */
#define L3GXXXX_HP_ENABLED_S (4) /**< L3GXXXX_REG_CTRL5<4> */
#define L3GXXXX_IG_SEL_S (2) /**< L3GXXXX_REG_CTRL5<3:2> */
#define L3GXXXX_OUT_SEL_S (0) /**< L3GXXXX_REG_CTRL5<1:0> */
#define L3GXXXX_FIFO_MODE (0xe0) /**< L3GXXXX_REG_FIFO_CTRL<7:5> */
#define L3GXXXX_FIFO_WATERMARK (0x1f) /**< L3GXXXX_REG_FIFO_CTRL<4:0> */
#define L3GXXXX_FIFO_MODE_S (5) /**< L3GXXXX_REG_FIFO_CTRL<7:5> */
#define L3GXXXX_FIFO_WATERMARK_S (0) /**< L3GXXXX_REG_FIFO_CTRL<4:0> */
#define L3GXXXX_FIFO_WTM (0x80) /**< L3GXXXX_REG_FIFO_SRC<7> */
#define L3GXXXX_FIFO_OVR (0x40) /**< L3GXXXX_REG_FIFO_SRC<6> */
#define L3GXXXX_FIFO_EMPTY (0x20) /**< L3GXXXX_REG_FIFO_SRC<5> */
#define L3GXXXX_FIFO_FFS (0x1f) /**< L3GXXXX_REG_FIFO_SRC<4:0> */
#define L3GXXXX_FIFO_WTM_S (7) /**< L3GXXXX_REG_FIFO_SRC<7> */
#define L3GXXXX_FIFO_OVR_S (6) /**< L3GXXXX_REG_FIFO_SRC<6> */
#define L3GXXXX_FIFO_EMPTY_S (5) /**< L3GXXXX_REG_FIFO_SRC<5> */
#define L3GXXXX_FIFO_FFS_S (0) /**< L3GXXXX_REG_FIFO_SRC<4:0> */
#define L3GXXXX_INT1_AND_OR (0x80) /**< L3GXXXX_REG_IG_CFG<7> */
#define L3GXXXX_INT1_LATCH (0x40) /**< L3GXXXX_REG_IG_CFG<6> */
#define L3GXXXX_INT1_Z_HIGH (0x20) /**< L3GXXXX_REG_IG_CFG<5>, L3GXXXX_REG_IG_SRC<5> */
#define L3GXXXX_INT1_Z_LOW (0x10) /**< L3GXXXX_REG_IG_CFG<4>, L3GXXXX_REG_IG_SRC<4> */
#define L3GXXXX_INT1_Y_HIGH (0x08) /**< L3GXXXX_REG_IG_CFG<3>, L3GXXXX_REG_IG_SRC<3> */
#define L3GXXXX_INT1_Y_LOW (0x04) /**< L3GXXXX_REG_IG_CFG<2>, L3GXXXX_REG_IG_SRC<2> */
#define L3GXXXX_INT1_X_HIGH (0x02) /**< L3GXXXX_REG_IG_CFG<1>, L3GXXXX_REG_IG_SRC<1> */
#define L3GXXXX_INT1_X_LOW (0x01) /**< L3GXXXX_REG_IG_CFG<0>, L3GXXXX_REG_IG_SRC<0> */
#define L3GXXXX_INT1_AND_OR_S (7) /**< L3GXXXX_REG_IG_CFG<7> */
#define L3GXXXX_INT1_LATCH_S (6) /**< L3GXXXX_REG_IG_CFG<6> */
#define L3GXXXX_INT1_Z_HIGH_S (5) /**< L3GXXXX_REG_IG_CFG<5>, L3GXXXX_REG_IG_SRC<5> */
#define L3GXXXX_INT1_Z_LOW_S (4) /**< L3GXXXX_REG_IG_CFG<4>, L3GXXXX_REG_IG_SRC<4> */
#define L3GXXXX_INT1_Y_HIGH_S (3) /**< L3GXXXX_REG_IG_CFG<3>, L3GXXXX_REG_IG_SRC<3> */
#define L3GXXXX_INT1_Y_LOW_S (2) /**< L3GXXXX_REG_IG_CFG<2>, L3GXXXX_REG_IG_SRC<2> */
#define L3GXXXX_INT1_X_HIGH_S (1) /**< L3GXXXX_REG_IG_CFG<1>, L3GXXXX_REG_IG_SRC<1> */
#define L3GXXXX_INT1_X_LOW_S (0) /**< L3GXXXX_REG_IG_CFG<0>, L3GXXXX_REG_IG_SRC<0> */
#define L3GXXXX_INT1_ACTIVE (0x40) /**< L3GXXXX_REG_IG_SRC<6> */
#define L3GXXXX_INT1_WAIT (0x80) /**< L3GXXXX_REG_IG_DURATION<7> */
#define L3GXXXX_INT1_DURATION (0x3f) /**< L3GXXXX_REG_IG_DURATION<6:0> */
#define L3GXXXX_INT1_WAIT_S (7) /**< L3GXXXX_REG_IG_DURATION<7> */
#define L3GXXXX_INT1_DURATION_S (0) /**< L3GXXXX_REG_IG_DURATION<6:0> */
#define L3GXXXX_DRDY_HL (0x20) /**< L3GXXXX_REG_LOW_ODR<5> */
#define L3GXXXX_SW_RESET (0x04) /**< L3GXXXX_REG_LOW_ODR<2> */
#define L3GXXXX_LOW_ODR (0x01) /**< L3GXXXX_REG_LOW_ODR<0> */
#define L3GXXXX_DRDY_HL_S (5) /**< L3GXXXX_REG_LOW_ODR<5> */
#define L3GXXXX_SW_RESET_S (2) /**< L3GXXXX_REG_LOW_ODR<2> */
#define L3GXXXX_LOW_ODR_S (0) /**< L3GXXXX_REG_LOW_ODR<0> */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* L3GXXXX_REGS_H */
/** @} */

1143
drivers/l3gxxxx/l3gxxxx.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_l3gxxxx
* @brief L3Gxxxx adaption to the RIOT actuator/sensor interface
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
*/
#include <string.h>
#include "saul.h"
#include "l3gxxxx.h"
static int read(const void *dev, phydat_t *res)
{
l3gxxxx_data_t data;
int ret = l3gxxxx_read((const l3gxxxx_t *)dev, &data);
if (ret < 0) {
return -ECANCELED;
}
res->val[0] = data.x / 100;
res->val[1] = data.y / 100;
res->val[2] = data.z / 100;
res->unit = UNIT_DPS;
res->scale = -1;
return 3;
}
const saul_driver_t l3gxxxx_saul_driver = {
.read = read,
.write = saul_notsup,
.type = SAUL_SENSE_GYRO,
};

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/*
* @ingroup sys_auto_init_saul
* @brief Auto initialization of ST L3Gxxxx 3-axis gyroscope sensor
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
*/
#include "assert.h"
#include "log.h"
#include "saul_reg.h"
#include "l3gxxxx.h"
#include "l3gxxxx_params.h"
/**
* @brief Define the number of configured sensors
*/
#define L3GXXXX_NUM ARRAY_SIZE(l3gxxxx_params)
/**
* @brief Allocate memory for the device descriptors
*/
static l3gxxxx_t l3gxxxx_devs[L3GXXXX_NUM];
/**
* @brief Memory for the SAUL registry entries
*/
static saul_reg_t saul_entries[L3GXXXX_NUM];
/**
* @brief Define the number of saul info
*/
#define L3GXXXX_INFO_NUM ARRAY_SIZE(l3gxxxx_saul_info)
/**
* @brief Reference the driver struct
*/
extern saul_driver_t l3gxxxx_saul_driver;
void auto_init_l3gxxxx(void)
{
assert(L3GXXXX_NUM == L3GXXXX_INFO_NUM);
for (unsigned int i = 0; i < L3GXXXX_NUM; i++) {
LOG_DEBUG("[auto_init_saul] initializing l3gd20h #%u\n", i);
if (l3gxxxx_init(&l3gxxxx_devs[i], &l3gxxxx_params[i]) < 0) {
LOG_ERROR("[auto_init_saul] error initializing l3gd20h #%u\n", i);
continue;
}
saul_entries[i].dev = &(l3gxxxx_devs[i]);
saul_entries[i].name = l3gxxxx_saul_info[i].name;
saul_entries[i].driver = &l3gxxxx_saul_driver;
saul_reg_add(&(saul_entries[i]));
}
}

View File

@ -163,6 +163,10 @@ void saul_init_devs(void)
extern void auto_init_l3g4200d(void);
auto_init_l3g4200d();
}
if (IS_USED(MODULE_L3GXXXX)) {
extern void auto_init_l3gxxxx(void);
auto_init_l3gxxxx();
}
if (IS_USED(MODULE_LIS2DH12)) {
extern void auto_init_lis2dh12(void);
auto_init_lis2dh12();

View File

@ -0,0 +1,15 @@
include ../Makefile.tests_common
# define the driver to be used for selected boards
ifneq (,$(filter stm32f429i-disc1 stm32f429i-disco stm32f3discovery,$(BOARD)))
DRIVER := i3g4250d
endif
DRIVER ?= l3gd20h
USEMODULE += $(DRIVER)
USEMODULE += l3gxxxx
USEMODULE += ztimer
USEMODULE += ztimer_msec
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,74 @@
# About
This is a manual test application for the driver of the L3GXXXX 3-axis
gyroscope sensor family. It demonstrates the use of a L3Gxxxx sensor.
The different functionalities of the driver are enabled and tested by
using different modules.
# Usage
The used sensor must be specified by setting the variable DRIVER to
`l3gd20h`, `l3gd20`, `l3g4200d_ng`, `i3g4250d` or `a3g4250d` which enables
the corresponding pseudomodule:
```
DRIVER=l3gd20h BOARD=... make -C tests/driver_l3gxxxx
```
If the DRIVER variable is not set, `l3gd20h` is used.
By default, the application will initialize the gyroscope with the default
configuration parameter set as defined in the `l3gxxxx_params.h` file:
Configuration Parameter | Default value
:---------------------------|:----------------------
Output data rate | 100 Hz
LPF2 cutoff frequency | 25 Hz
Full scale | 245 dps
Filter selection | HPF and LPF2 are used
HPF mode | Normal with autoreset
HPF cutoff frequency | 8 Hz
The default configuration uses the I2C interface (module `l3gxxxx_i2c`)
of the sensor and polls the data periodically every 200 ms. If the SPI
interface of the sensor should be used, the module `l3gxxxx_spi` has to
be used:
```
DRIVER=l3gd20h USEMODULE=l3gxxxx_spi BOARD=... make -C tests/driver_l3gxxxx
```
The application is configurable by using different pseudomodules to test
most of the functionalities of the L3Gxxxx driver.
- Module `l3gxxxx_irq_drdy`:
Instead of polling the sensor regularly for data, the data ready interrupt
on signal `INT2/DRDY` is used to read the data. If module `l3gxxxx_fifo`
is used at the same time, the FIFO status interrupts are enabled instead
of the data ready interrupt. The GPIO pin used for the interrupt signal
can be overridden, for example:
```
DRIVER=l3gd20h USEMODULE=l3gxxxx_irq_drdy \
CFLAGS='-DL3GXXXX_INT2_PIN=GPIO_PIN\(0,5\) BOARD=... make -C tests/driver_l3gxxxx
```
- Module `l3gxxxx_irq_event`:
Event interrupt generation is configured according to default
configuration parameters in the `l3gxxxx_params.h` file to generate
interrupts on signal `INT1` when the absolute value of the angular rate
of any axis exceeds the default threshold. The GPIO pin used for the
interrupt signal can be overridden, for example:
```
DRIVER=l3gd20h USEMODULE=l3gxxxx_irq_event \
CFLAGS='-DL3GXXXX_INT1_PIN=GPIO_PIN\(0,6\) BOARD=... make -C tests/driver_l3gxxxx
```
- Module `l3gxxxx_fifo`:
Instead of fetching single data samples from the sensor, the FIFO of
the sensor is enabled. Depending on the use of module `l3gxxxx_irq_drdy`,
the FIFO state is either polled regularly or FIFO status interrupts on
signal `INT2/DRDY` are used. All available data samples are read from
the FIFO with a single burst access.
- Module `l3gxxxx_config`:
The configuration of the event interrupt generation is changed at
runtime.

View File

@ -0,0 +1,4 @@
# application configuration. This is only needed during migration.
CONFIG_MODULE_L3GXXXX=y
CONFIG_MODULE_ZTIMER=y
CONFIG_MODULE_ZTIMER_MSEC=y

238
tests/driver_l3gxxxx/main.c Normal file
View File

@ -0,0 +1,238 @@
/*
* Copyright (C) 2018 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @brief Test application for the L3Gxxxx 3-axis gyroscope sensor family driver
* @author Gunar Schorcht <gunar@schorcht.net>
* @file
*
* # About
*
* This is a manual test application for the driver of the L3GXXXX 3-axis
* gyroscope sensor family. It demonstrates the use of a L3Gxxxx sensor.
* The different functionalities of the driver are enabled and tested by
* using different modules.
*
* # Usage
*
* The used sensor must be specified by setting the variable DRIVER to
* `l3gd20h`, `l3gd20`, `l3g4200d_ng`, `i3g4250d` or `a3g4250d` which enables
* the corresponding pseudomodule:
* ```
* DRIVER=l3gd20h BOARD=... make -C tests/driver_l3gxxxx
* ```
* If the DRIVER variable is not set, `l3gd20h` is used.
*
* By default, the application will initialize the gyroscope with the default
* configuration parameter set as defined in the `l3gxxxx_params.h` file:
*
* Configuration Parameter | Default value
* :---------------------------|:----------------------
* Output data rate | 100 Hz
* LPF2 cutoff frequency | 25 Hz
* Full scale | 245 dps
* Filter selection | HPF and LPF2 are used
* HPF mode | Normal with autoreset
* HPF cutoff frequency | 8 Hz
*
* The default configuration uses the I2C interface (module `l3gxxxx_i2c`)
* of the sensor and polls the data periodically every 200 ms. If the SPI
* interface of the sensor should be used, the module `l3gxxxx_spi` has to
* be used:
* ```
* DRIVER=l3gd20h USEMODULE=l3gxxxx_spi BOARD=... make -C tests/driver_l3gxxxx
* ```
*
* The application is configurable by using different pseudomodules to test
* most of the functionalities of the L3Gxxxx driver.
*
* - Module `l3gxxxx_irq_drdy`:
* Instead of polling the sensor regularly for data, the data ready interrupt
* on signal `INT2/DRDY` is used to read the data. If module `l3gxxxx_fifo`
* is used at the same time, the FIFO status interrupts are enabled instead
* of the data ready interrupt. The GPIO pin used for the interrupt signal
* can be overridden, for example:
*
* ```
* DRIVER=l3gd20h USEMODULE=l3gxxxx_irq_drdy \
* CFLAGS='-DL3GXXXX_INT2_PIN=GPIO_PIN\(0,5\) BOARD=... make -C tests/driver_l3gxxxx
* ```
*
* - Module `l3gxxxx_irq_event`:
* Event interrupt generation is configured according to default
* configuration parameters in the `l3gxxxx_params.h` file to generate
* interrupts on signal `INT1` when the absolute value of the angular rate
* of any axis exceeds the default threshold. The GPIO pin used for the
* interrupt signal can be overridden, for example:
*
* ```
* DRIVER=l3gd20h USEMODULE=l3gxxxx_irq_event \
* CFLAGS='-DL3GXXXX_INT1_PIN=GPIO_PIN\(0,6\) BOARD=... make -C tests/driver_l3gxxxx
* ```
*
* - Module `l3gxxxx_fifo`:
* Instead of fetching single data samples from the sensor, the FIFO of
* the sensor is enabled. Depending on the use of module `l3gxxxx_irq_drdy`,
* the FIFO state is either polled regularly or FIFO status interrupts on
* signal `INT2/DRDY` are used. All available data samples are read from
* the FIFO with a single burst access.
*
* - Module `l3gxxxx_config`:
* The configuration of the event interrupt generation is changed at
* runtime.
*/
#include <stdio.h>
#include "thread.h"
#include "ztimer.h"
#include "l3gxxxx.h"
#include "l3gxxxx_params.h"
#define TESTS_DRIVER_L3GXXXX_SLEEP (200) /* 200 ms */
#if IS_USED(MODULE_L3GXXXX_IRQ)
int handle_event(const l3gxxxx_t *dev, l3gxxxx_int_event_src_t source)
{
(void)dev;
/* display the event */
if (!source.active) {
return -1;
}
if (source.x_low) {
printf("|x| below ");
}
if (source.y_low) {
printf("|y| below ");
}
if (source.z_low) {
printf("|z| below ");
}
if (source.x_high) {
printf("|x| above ");
}
if (source.y_high) {
printf("|y| above ");
}
if (source.z_high) {
printf("|z| above ");
}
printf("defined thresholds: ");
return 0;
}
#endif /* IS_USED(MODULE_L3GXXXX_IRQ) */
int read_data(const l3gxxxx_t *dev)
{
#if IS_USED(MODULE_L3GXXXX_FIFO)
l3gxxxx_data_fifo_t data;
int num = l3gxxxx_read_fifo(dev, data);
printf("FIFO samples num=%d\n", num);
for (int i = 0; i < num; i++) {
printf("gyro [dps] x: %+5" PRIi32 ", y: %+5" PRIi32 ", z: %+5" PRIi32 "\n",
data[i].x / 1000, data[i].y / 1000, data[i].z / 1000);
}
return num;
#else /* IS_USED(MODULE_L3GXXXX_FIFO) */
l3gxxxx_data_t data;
l3gxxxx_read(dev, &data);
printf("gyro [dps] x: %+5" PRIi32 ", y: %+5" PRIi32 ", z: %+5" PRIi32 "\n",
data.x / 1000, data.y / 1000, data.z / 1000);
return 1;
#endif /* IS_USED(MODULE_L3GXXXX_FIFO) */
}
int main(void)
{
l3gxxxx_t dev;
puts("L3GXXXX gyroscope driver test application\n");
puts("Initializing L3GXXXX sensor");
/* initialize the sensor with default configuration parameters */
if (l3gxxxx_init(&dev, &l3gxxxx_params[0]) == L3GXXXX_OK) {
puts("[OK]\n");
}
else {
puts("[Failed]");
return 1;
}
#if IS_USED(MODULE_L3GXXXX_CONFIG)
/* select LPF2 and HPF, configure HPF and reset REFERENCE by dummy read */
int8_t ref;
l3gxxxx_select_output_filter(&dev, L3GXXXX_HPF_ONLY);
l3gxxxx_config_hpf(&dev, L3GXXXX_HPF_NORMAL, 0);
l3gxxxx_get_hpf_ref(&dev, &ref);
#endif /* IS_USED(MODULE_L3GXXXX_CONFIG) */
#if IS_USED(MODULE_L3GXXXX_FIFO) && IS_USED(MODULE_L3GXXXX_CONFIG)
/* clear FIFO and activate FIFO Stream mode */
l3gxxxx_set_fifo_mode(&dev, L3GXXXX_BYPASS, 0);
l3gxxxx_set_fifo_mode(&dev, L3GXXXX_STREAM, 10);
#endif
#if IS_USED(MODULE_L3GXXXX_IRQ_EVENT) && IS_USED(MODULE_L3GXXXX_CONFIG)
/* enable event interrupts (axis movement and wake-up) */
l3gxxxx_int_event_cfg_t int_cfg;
l3gxxxx_get_int_event_cfg(&dev, &int_cfg);
int_cfg.x_high_enabled = true;
int_cfg.y_high_enabled = true;
int_cfg.z_high_enabled = true;
int_cfg.x_low_enabled = false;
int_cfg.y_low_enabled = false;
int_cfg.z_low_enabled = false;
int_cfg.x_threshold = 1000;
int_cfg.y_threshold = 1000;
int_cfg.z_threshold = 1000;
int_cfg.filter = L3GXXXX_HPF_ONLY;
int_cfg.and_or = false;
int_cfg.duration = 0;
int_cfg.latch = true;
l3gxxxx_set_int_event_cfg(&dev, &int_cfg);
#endif /* IS_USED(MODULE_L3GXXXX_CONFIG) && IS_USED(MODULE_L3GXXXX_IRQ_EVENT) */
while (1) {
#if IS_USED(MODULE_L3GXXXX_IRQ)
/* wait for next interrupt */
l3gxxxx_int_src_t int_src = l3gxxxx_wait_int(&dev);
(void)int_src;
/* in case of event we determine the source */
if (int_src.event.active) {
handle_event(&dev, int_src.event);
}
/* read and print data in any case */
read_data(&dev);
#else
/* read and print data */
read_data(&dev);
ztimer_sleep(ZTIMER_MSEC, TESTS_DRIVER_L3GXXXX_SLEEP);
#endif /* IS_USED(MODULE_L3GXXXX_IRQ) */
}
return 0;
}