mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #16328 from benpicco/driver/lis2dh12-cleanup
drivers/lis2dh12: clean up API
This commit is contained in:
commit
41bbafdfe4
@ -63,10 +63,10 @@ extern "C" {
|
||||
* @brief Available scale values
|
||||
*/
|
||||
typedef enum {
|
||||
LIS2DH12_SCALE_2G = 0x00, /**< +- 2g */
|
||||
LIS2DH12_SCALE_4G = 0x10, /**< +- 4g */
|
||||
LIS2DH12_SCALE_8G = 0x20, /**< +- 8g */
|
||||
LIS2DH12_SCALE_16G = 0x30, /**< +- 16g */
|
||||
LIS2DH12_SCALE_2G = 0x0, /**< +- 2g */
|
||||
LIS2DH12_SCALE_4G = 0x1, /**< +- 4g */
|
||||
LIS2DH12_SCALE_8G = 0x2, /**< +- 8g */
|
||||
LIS2DH12_SCALE_16G = 0x3, /**< +- 16g */
|
||||
} lis2dh12_scale_t;
|
||||
|
||||
/**
|
||||
@ -74,28 +74,35 @@ typedef enum {
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
LIS2DH12_RATE_1HZ = 0x1, /**< sample with 1Hz @ all power modes */
|
||||
LIS2DH12_RATE_10HZ = 0x2, /**< sample with 10Hz @ all power modes */
|
||||
LIS2DH12_RATE_25HZ = 0x3, /**< sample with 25Hz @ all power modes */
|
||||
LIS2DH12_RATE_50HZ = 0x4, /**< sample with 50Hz @ all power modes */
|
||||
LIS2DH12_RATE_100HZ = 0x5, /**< sample with 100Hz @ all power modes */
|
||||
LIS2DH12_RATE_200HZ = 0x6, /**< sample with 200Hz @ all power modes */
|
||||
LIS2DH12_RATE_400HZ = 0x7, /**< sample with 400Hz @ all power modes */
|
||||
LIS2DH12_RATE_1620HZ = 0x8, /**< sample with 1620HZ @ Low Power*/
|
||||
LIS2DH12_RATE_1HZ = 0x1, /**< sample with 1Hz @ all resolutions */
|
||||
LIS2DH12_RATE_10HZ = 0x2, /**< sample with 10Hz @ all resolutions */
|
||||
LIS2DH12_RATE_25HZ = 0x3, /**< sample with 25Hz @ all resolutions */
|
||||
LIS2DH12_RATE_50HZ = 0x4, /**< sample with 50Hz @ all resolutions */
|
||||
LIS2DH12_RATE_100HZ = 0x5, /**< sample with 100Hz @ all resolutions */
|
||||
LIS2DH12_RATE_200HZ = 0x6, /**< sample with 200Hz @ all resolutions */
|
||||
LIS2DH12_RATE_400HZ = 0x7, /**< sample with 400Hz @ all resolutions */
|
||||
LIS2DH12_RATE_1620HZ = 0x8, /**< sample with 1620HZ @ 8-bit */
|
||||
LIS2DH12_RATE_VERYHIGH = 0x9, /**< sample with 1344Hz @ High resolution or \
|
||||
5376Hz @ Low Power*/
|
||||
5376Hz @ 8-bit */
|
||||
} lis2dh12_rate_t;
|
||||
|
||||
/**
|
||||
* @brief Available power modes
|
||||
* @brief Available resolutions
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
LIS2DH12_POWER_DOWN = 0, /**< power down the device */
|
||||
LIS2DH12_POWER_LOW = 1, /**< low power mode */
|
||||
LIS2DH12_POWER_NORMAL = 2, /**< normal mode */
|
||||
LIS2DH12_POWER_HIGH = 3, /**< high resolution */
|
||||
} lis2dh12_powermode_t;
|
||||
LIS2DH12_POWER_LOW = 1, /**< 8-bit mode */
|
||||
LIS2DH12_POWER_NORMAL = 2, /**< 10-bit mode */
|
||||
LIS2DH12_POWER_HIGH = 3, /**< 12-bit mode */
|
||||
} lis2dh12_resolution_t;
|
||||
|
||||
#define LIS2DH12_CLICK_X_SINGLE (1 << 0) /**< single click on X axis */
|
||||
#define LIS2DH12_CLICK_X_DOUBLE (1 << 1) /**< double click on X axis */
|
||||
#define LIS2DH12_CLICK_Y_SINGLE (1 << 2) /**< single click on Y axis */
|
||||
#define LIS2DH12_CLICK_Y_DOUBLE (1 << 3) /**< double click on Y axis */
|
||||
#define LIS2DH12_CLICK_Z_SINGLE (1 << 4) /**< single click on Z axis */
|
||||
#define LIS2DH12_CLICK_Z_DOUBLE (1 << 5) /**< double click on Z axis */
|
||||
|
||||
/**
|
||||
* @brief LIS2DH12 configuration parameters
|
||||
@ -114,7 +121,7 @@ typedef struct {
|
||||
#endif
|
||||
lis2dh12_scale_t scale; /**< sampling sensitivity used */
|
||||
lis2dh12_rate_t rate; /**< sampling rate used */
|
||||
lis2dh12_powermode_t powermode; /**< power mode used*/
|
||||
lis2dh12_resolution_t resolution; /**< resolution used */
|
||||
} lis2dh12_params_t;
|
||||
|
||||
/**
|
||||
@ -170,7 +177,6 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
const lis2dh12_params_t *p; /**< device configuration */
|
||||
uint8_t comp; /**< scale compensation factor */
|
||||
} lis2dh12_t;
|
||||
|
||||
/**
|
||||
@ -185,7 +191,6 @@ enum {
|
||||
LIS2DH12_NODATA= -4, /**< no data available */
|
||||
};
|
||||
|
||||
#if MODULE_LIS2DH12_INT || DOXYGEN
|
||||
/*
|
||||
* @brief Interrupt lines
|
||||
*/
|
||||
@ -204,18 +209,18 @@ typedef struct {
|
||||
uint8_t int_duration:7; /**< time between two interrupts ODR section in CTRL_REG1,
|
||||
duration in range 0-127 */
|
||||
uint8_t int_type; /**< values for type of interrupts */
|
||||
gpio_cb_t cb; /**< the callback to execute */
|
||||
void *arg; /**< the callback argument */
|
||||
} lis2dh12_int_params_t;
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/**
|
||||
* @brief LIS2DH12 FIFO data struct
|
||||
*/
|
||||
typedef struct {
|
||||
int16_t X_AXIS; /**< X raw data in FIFO */
|
||||
int16_t Y_AXIS; /**< Y raw data in FIFO */
|
||||
int16_t Z_AXIS; /**< Z raw data in FIFO */
|
||||
typedef union {
|
||||
struct {
|
||||
int16_t x; /**< X data in mili-g */
|
||||
int16_t y; /**< Y data in mili-g */
|
||||
int16_t z; /**< Z data in mili-g */
|
||||
} axis; /**< named axis access */
|
||||
int16_t data[3]; /**< x, y, z data in mili-g */
|
||||
} lis2dh12_fifo_data_t;
|
||||
|
||||
/**
|
||||
@ -239,33 +244,74 @@ typedef struct {
|
||||
|
||||
/**
|
||||
* @brief Export the SAUL interface for this driver
|
||||
* @{
|
||||
*/
|
||||
extern const saul_driver_t lis2dh12_saul_driver;
|
||||
extern const saul_driver_t lis2dh12_saul_temp_driver;
|
||||
/** @} */
|
||||
|
||||
#if MODULE_LIS2DH12_INT || DOXYGEN
|
||||
/**
|
||||
* @brief Set the interrupt values in LIS2DH12 sensor device
|
||||
* @brief Configure a threshold event
|
||||
* An Interrupt will be generated if acceleration exceeds the set threshold
|
||||
* around the current reference value.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] params device interrupt configuration
|
||||
* @param[in] int_line number of interrupt line (LIS2DH12_INT1 or LIS2DH12_INT2)
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
* @return LIS2DH12_NOBUS on bus errors
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] mg acceleration in mg
|
||||
* @param[in] us time in µs for which the threshold must be exceeded
|
||||
* @param[in] axis bitmap of axis / events to be monitored
|
||||
* @param[in] event Event slot (1 or 2)
|
||||
* @param[in] pin Interrupt pin to use (LIS2DH12_INT1/LIS2DH12_INT2)
|
||||
*/
|
||||
int lis2dh12_set_int(const lis2dh12_t *dev, const lis2dh12_int_params_t *params, uint8_t int_line);
|
||||
void lis2dh12_cfg_threshold_event(const lis2dh12_t *dev,
|
||||
uint32_t mg, uint32_t us,
|
||||
uint8_t axis, uint8_t event, uint8_t pin);
|
||||
|
||||
/**
|
||||
* @brief Read an interrupt event on LIS2DH12 sensor device
|
||||
* @brief Configure a click event
|
||||
* A click event is generated when the acceleration exceeds the set threshold
|
||||
* for less than @p us_limit µs.
|
||||
* A double click event is generated if a second click event occurs within
|
||||
* @p us_window µs after the first one.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] mg acceleration in mg
|
||||
* @param[in] us_limit upper limit for click duration in µs
|
||||
* @param[in] us_latency dead time after click event in µs
|
||||
* @param[in] us_window time after @p us_latency in which the second click event
|
||||
* must occur to register as double click
|
||||
* @param[in] click bit map of click axis / types
|
||||
* @param[in] pin Interrupt pin to use (LIS2DH12_INT1/LIS2DH12_INT2)
|
||||
*/
|
||||
void lis2dh12_cfg_click_event(const lis2dh12_t *dev, uint32_t mg,
|
||||
uint32_t us_limit, uint32_t us_latency, uint32_t us_window,
|
||||
uint8_t click, uint8_t pin);
|
||||
|
||||
/**
|
||||
* @brief Disable interrupt generation for an event
|
||||
* This disables an interrupt on @p pin if a previously configured event occurs
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] event Event to disable (LIS2DH12_EVENT_1, LIS2DH12_EVENT_2
|
||||
* or LIS2DH12_EVENT_CLICK)
|
||||
* @param[in] pin Interrupt pin to use (LIS2DH12_INT1/LIS2DH12_INT2)
|
||||
*/
|
||||
void lis2dh12_cfg_disable_event(const lis2dh12_t *dev, uint8_t event, uint8_t pin);
|
||||
|
||||
/**
|
||||
* @brief Wait for an interrupt event
|
||||
* This function will block until an interrupt is received
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data device interrupt data
|
||||
* @param[in] int_line number of interrupt line (LIS2DH12_INT1 or LIS2DH12_INT2)
|
||||
* @param[in] pin Interrupt pin to monitor (LIS2DH12_INT1 or LIS2DH12_INT2)
|
||||
* @param[in] stale_events If true, this also reports events that were generated
|
||||
* before this function was called and which are still in the
|
||||
* fifo buffer.
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
* @return LIS2DH12_NOBUS on bus errors
|
||||
* @return negative error
|
||||
* @return positive LIS2DH12_INT_SRC bit mask on success
|
||||
*/
|
||||
int lis2dh12_read_int_src(const lis2dh12_t *dev, uint8_t *data, uint8_t int_line);
|
||||
int lis2dh12_wait_event(const lis2dh12_t *dev, uint8_t pin, bool stale_events);
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/**
|
||||
@ -291,16 +337,6 @@ int lis2dh12_set_fifo(const lis2dh12_t *dev, const lis2dh12_fifo_t *config);
|
||||
*/
|
||||
int lis2dh12_restart_fifo(const lis2dh12_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Read the FIFO source register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data LIS2DH12_FIFO_SRC_REG_t content, allocate one byte
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
*/
|
||||
int lis2dh12_read_fifo_src(const lis2dh12_t *dev, LIS2DH12_FIFO_SRC_REG_t *data);
|
||||
|
||||
/**
|
||||
* @brief This function will read a given number of data from FIFO
|
||||
* reads amount of data that is available in FIFO
|
||||
@ -330,12 +366,27 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params);
|
||||
* @brief Read acceleration data from the given device
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data acceleration data in mili-g, **MUST** hold 3 values
|
||||
* @param[out] data acceleration data in mili-g
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
* @return LIS2DH12_NOBUS on bus error
|
||||
*/
|
||||
int lis2dh12_read(const lis2dh12_t *dev, int16_t *data);
|
||||
int lis2dh12_read(const lis2dh12_t *dev, lis2dh12_fifo_data_t *data);
|
||||
|
||||
/**
|
||||
* @brief Read temperature data from the given device
|
||||
*
|
||||
* @note The temperature sensor is not calibrated.
|
||||
* Temperature values are only relative to a device specific
|
||||
* reference.
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] temp temperature data in centi-°C
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
* @return LIS2DH12_NOBUS on bus error
|
||||
*/
|
||||
int lis2dh12_read_temperature(const lis2dh12_t *dev, int16_t *temp);
|
||||
|
||||
/**
|
||||
* @brief Clear the LIS2DH12 memory, clears all sampled data
|
||||
@ -347,7 +398,7 @@ int lis2dh12_read(const lis2dh12_t *dev, int16_t *data);
|
||||
int lis2dh12_clear_data(const lis2dh12_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Change device scale value
|
||||
* @brief Change device measuring range
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] scale change to given scale value
|
||||
@ -356,6 +407,15 @@ int lis2dh12_clear_data(const lis2dh12_t *dev);
|
||||
*/
|
||||
int lis2dh12_set_scale(lis2dh12_t *dev, lis2dh12_scale_t scale);
|
||||
|
||||
/**
|
||||
* @brief Get device measuring range
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*
|
||||
* @return Current device range
|
||||
*/
|
||||
lis2dh12_scale_t lis2dh12_get_scale(lis2dh12_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Change device sampling rate
|
||||
*
|
||||
@ -367,14 +427,32 @@ int lis2dh12_set_scale(lis2dh12_t *dev, lis2dh12_scale_t scale);
|
||||
int lis2dh12_set_datarate(const lis2dh12_t *dev, lis2dh12_rate_t rate);
|
||||
|
||||
/**
|
||||
* @brief Change device power mode
|
||||
* @brief Get device sampling rate in Hz
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*
|
||||
* @return current sampling rate in Hz
|
||||
*/
|
||||
uint16_t lis2dh12_get_datarate(const lis2dh12_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Change device resolution
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] powermode change to given power mode
|
||||
* @param[in] resolution change to given resolution
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
*/
|
||||
int lis2dh12_set_powermode(const lis2dh12_t *dev, lis2dh12_powermode_t powermode);
|
||||
int lis2dh12_set_resolution(const lis2dh12_t *dev, lis2dh12_resolution_t resolution);
|
||||
|
||||
/**
|
||||
* @brief Get device resolution
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*
|
||||
* @return Current device resolution settings
|
||||
*/
|
||||
lis2dh12_resolution_t lis2dh12_get_resolution(const lis2dh12_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Configures the high pass filter
|
||||
@ -400,37 +478,7 @@ int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *conf
|
||||
int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference);
|
||||
|
||||
/**
|
||||
* @brief Read the reference value
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data reference value read from device
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
*/
|
||||
int lis2dh12_read_reference(const lis2dh12_t *dev, uint8_t *data);
|
||||
|
||||
/**
|
||||
* @brief Set click configuration
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] config device click configuration
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
*/
|
||||
int lis2dh12_set_click(const lis2dh12_t *dev, const lis2dh12_click_t *config);
|
||||
|
||||
/**
|
||||
* @brief Read click source register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data LIS2DH12_CLICK_SRC_t content, allocate one byte
|
||||
*
|
||||
* @return LIS2DH12_OK on success
|
||||
*/
|
||||
int lis2dh12_read_click_src(const lis2dh12_t *dev, LIS2DH12_CLICK_SRC_t *data);
|
||||
|
||||
/**
|
||||
* @brief Power on the given device and resets power mode and sampling rate
|
||||
* @brief Power on the given device and resets resolution and sampling rate
|
||||
* to default values in the device descriptor parameters
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
|
@ -67,8 +67,8 @@ extern "C" {
|
||||
#ifndef LIS2DH12_PARAM_RATE
|
||||
#define LIS2DH12_PARAM_RATE LIS2DH12_RATE_100HZ
|
||||
#endif
|
||||
#ifndef LIS2DH12_PARAM_POWERMODE
|
||||
#define LIS2DH12_PARAM_POWERMODE LIS2DH12_POWER_NORMAL
|
||||
#ifndef LIS2DH12_PARAM_RESOLUTION
|
||||
#define LIS2DH12_PARAM_RESOLUTION LIS2DH12_POWER_NORMAL
|
||||
#endif
|
||||
|
||||
#ifndef LIS2DH12_PARAMS
|
||||
@ -79,14 +79,14 @@ extern "C" {
|
||||
.int2_pin = LIS2DH12_PARAM_INT_PIN2, \
|
||||
.scale = LIS2DH12_PARAM_SCALE, \
|
||||
.rate = LIS2DH12_PARAM_RATE, \
|
||||
.powermode = LIS2DH12_PARAM_POWERMODE, \
|
||||
.resolution = LIS2DH12_PARAM_RESOLUTION, \
|
||||
}
|
||||
#else /* MODULE_LIS2DH12_INT */
|
||||
#define LIS2DH12_PARAMS { \
|
||||
LIS2DH12_PARAMS_BUSCFG, \
|
||||
.scale = LIS2DH12_PARAM_SCALE, \
|
||||
.rate = LIS2DH12_PARAM_RATE, \
|
||||
.powermode = LIS2DH12_PARAM_POWERMODE, \
|
||||
.resolution = LIS2DH12_PARAM_RESOLUTION, \
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
#endif /* LIS2DH12_PARAMS */
|
||||
|
@ -33,6 +33,14 @@ enum {
|
||||
LIS2DH12_STATUS_REG_AUX_TOR = 0x40, /**< Temperature data overrun */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STATUS_REG_TEMP definitions
|
||||
*/
|
||||
enum {
|
||||
LIS2DH12_TEMP_CFG_REG_DISABLE = 0x00, /**< Temperature sensor disable */
|
||||
LIS2DH12_TEMP_CFG_REG_ENABLE = 0xC0, /**< Temperature sensor enable */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STATUS_REG definitions
|
||||
*/
|
||||
@ -94,8 +102,36 @@ enum {
|
||||
LIS2DH12_INT_TYPE_I2_IA2 = 0x20, /**< IA2 on INT2 */
|
||||
LIS2DH12_INT_TYPE_I2_IA1 = 0x40, /**< IA1 on INT2 */
|
||||
LIS2DH12_INT_TYPE_I2_CLICK = 0x80, /**< click interrupt on INT2 */
|
||||
|
||||
LIS2DH12_INT_TYPE_IA2 = 0x20, /**< Event 2 */
|
||||
LIS2DH12_INT_TYPE_IA1 = 0x40, /**< Event 1 */
|
||||
LIS2DH12_INT_TYPE_CLICK = 0x80, /**< click interrupt */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event slots
|
||||
*/
|
||||
enum {
|
||||
LIS2DH12_EVENT_1 = 0x1, /**< first event slot */
|
||||
LIS2DH12_EVENT_2 = 0x2, /**< second event slot */
|
||||
LIS2DH12_EVENT_CLICK = 0x3, /**< click event */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Extract interrupt flags for Event Slot 1
|
||||
*/
|
||||
#define LIS2DH12_INT_SRC_1(ret) (((uint32_t)(ret) >> 0) & 0x7F)
|
||||
|
||||
/**
|
||||
* @brief Extract interrupt flags for Event Slot 2
|
||||
*/
|
||||
#define LIS2DH12_INT_SRC_2(ret) (((uint32_t)(ret) >> 8) & 0x7F)
|
||||
|
||||
/**
|
||||
* @brief Extract interrupt flags for Click Event
|
||||
*/
|
||||
#define LIS2DH12_INT_SRC_CLICK(ret) (((uint32_t)(ret) >> 16) & 0x7F)
|
||||
|
||||
/**
|
||||
* @brief CLICK_SRC definitions
|
||||
*/
|
||||
@ -169,6 +205,13 @@ typedef union {
|
||||
uint8_t reg; /**< Type used for register access */
|
||||
} LIS2DH12_CTRL_REG1_t;
|
||||
|
||||
#define LIS2DH12_CTRL_REG2_HP_IA1 (1 << 0)
|
||||
#define LIS2DH12_CTRL_REG2_HP_IA2 (1 << 1)
|
||||
#define LIS2DH12_CTRL_REG2_HPCLICK (1 << 2)
|
||||
#define LIS2DH12_CTRL_REG2_FDS (1 << 3)
|
||||
|
||||
#define LIS2DH12_CLICK_THS_LIR (0x80)
|
||||
|
||||
/**
|
||||
* @brief CTRL_REG2 definitions
|
||||
*/
|
||||
|
@ -14,10 +14,16 @@
|
||||
* @brief LIS2DH12 accelerometer driver implementation
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Jan Mohr <jan.mohr@ml-pa.com>
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "assert.h"
|
||||
#include "byteorder.h"
|
||||
#include "mutex.h"
|
||||
#include "timex.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "lis2dh12.h"
|
||||
#include "lis2dh12_internal.h"
|
||||
@ -113,8 +119,7 @@ static uint8_t _read(const lis2dh12_t *dev, uint8_t reg)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void _read_burst(const lis2dh12_t *dev, uint8_t reg,
|
||||
void *data, size_t len)
|
||||
static void _read_burst(const lis2dh12_t *dev, uint8_t reg, void *data, size_t len)
|
||||
{
|
||||
i2c_read_regs(BUS, ADDR, (FLAG_AINC | reg), data, len, 0);
|
||||
}
|
||||
@ -127,13 +132,17 @@ static void _write(const lis2dh12_t *dev, uint8_t reg, uint8_t data)
|
||||
|
||||
#endif /* MODULE_LIS2DH12_SPI */
|
||||
|
||||
static void _write_or(const lis2dh12_t *dev, uint8_t reg, uint8_t data)
|
||||
{
|
||||
data |= _read(dev, reg);
|
||||
_write(dev, reg, data);
|
||||
}
|
||||
|
||||
int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
||||
{
|
||||
assert(dev && params);
|
||||
|
||||
dev->p = params;
|
||||
/* calculate shift amount to convert raw acceleration data */
|
||||
dev->comp = 4 - (dev->p->scale >> 4);
|
||||
|
||||
/* initialize the chip select line */
|
||||
if (_init_bus(dev) != LIS2DH12_OK) {
|
||||
@ -141,6 +150,15 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
||||
return LIS2DH12_NOBUS;
|
||||
}
|
||||
|
||||
/* set resolution */
|
||||
lis2dh12_set_resolution(dev, dev->p->resolution);
|
||||
|
||||
/* clear stale data */
|
||||
lis2dh12_clear_data(dev);
|
||||
|
||||
/* set data range */
|
||||
lis2dh12_set_scale(dev, dev->p->scale);
|
||||
|
||||
/* acquire the bus and verify that our parameters are valid */
|
||||
if (_acquire(dev) != BUS_OK) {
|
||||
DEBUG("[lis2dh12] error: unable to acquire the bus\n");
|
||||
@ -154,6 +172,13 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
||||
return LIS2DH12_NODEV;
|
||||
}
|
||||
|
||||
/* clear events */
|
||||
_write(dev, REG_CTRL_REG3, 0);
|
||||
_write(dev, REG_CTRL_REG6, 0);
|
||||
|
||||
/* disable fifo */
|
||||
_write(dev, REG_FIFO_CTRL_REG, 0);
|
||||
|
||||
/* enable all axes, set sampling rate and scale */
|
||||
LIS2DH12_CTRL_REG1_t reg1 = {0};
|
||||
|
||||
@ -162,125 +187,317 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
||||
reg1.bit.Yen = 1;
|
||||
reg1.bit.Zen = 1;
|
||||
|
||||
_write(dev, REG_CTRL_REG4, dev->p->scale);
|
||||
_write(dev, REG_CTRL_REG1, reg1.reg);
|
||||
|
||||
_release(dev);
|
||||
/* enable block data update */
|
||||
_write(dev, REG_CTRL_REG4, 0x80);
|
||||
|
||||
/* set powermode */
|
||||
lis2dh12_set_powermode(dev, dev->p->powermode);
|
||||
_release(dev);
|
||||
|
||||
DEBUG("[lis2dh12] initialization successful\n");
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_read(const lis2dh12_t *dev, int16_t *data)
|
||||
static void _get_fifo_data(const lis2dh12_t *dev, lis2dh12_fifo_data_t *dst, uint8_t comp)
|
||||
{
|
||||
_read_burst(dev, REG_OUT_X_L, dst, sizeof(*dst));
|
||||
|
||||
for (unsigned i = 0; i < 3; ++i) {
|
||||
dst->data[i] >>= comp;
|
||||
}
|
||||
}
|
||||
|
||||
int lis2dh12_read(const lis2dh12_t *dev, lis2dh12_fifo_data_t *data)
|
||||
{
|
||||
assert(dev && data);
|
||||
|
||||
/* allocate 6 byte to save the 6 RAW data registers */
|
||||
uint8_t raw[6];
|
||||
|
||||
/* read sampled data from the device */
|
||||
_acquire(dev);
|
||||
|
||||
uint8_t comp = 4 - ((_read(dev, REG_CTRL_REG4) >> 4) & 0x3);
|
||||
|
||||
/* first check if valid data is available */
|
||||
if ((_read(dev, REG_STATUS_REG) & LIS2DH12_STATUS_REG_ZYXDA) == 0) {
|
||||
_release(dev);
|
||||
return LIS2DH12_NODATA;
|
||||
}
|
||||
|
||||
_read_burst(dev, REG_OUT_X_L, raw, 6);
|
||||
_get_fifo_data(dev, data, comp);
|
||||
_release(dev);
|
||||
|
||||
/* calculate the actual g-values for the x, y, and z dimension */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
data[i] = (int16_t)((raw[i*2 + 1] << 8) | raw[i*2]) >> dev->comp;
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
static const uint16_t mg_per_bit[] = {
|
||||
16, /* scale = 2g */
|
||||
32, /* scale = 4g */
|
||||
62, /* scale = 8g */
|
||||
186 /* scale = 16g */
|
||||
};
|
||||
|
||||
static const uint16_t hz_per_dr[] = {
|
||||
0, /* power down */
|
||||
1, /* Hz */
|
||||
10, /* Hz */
|
||||
25, /* Hz */
|
||||
50, /* Hz */
|
||||
100, /* Hz */
|
||||
200, /* Hz */
|
||||
400, /* Hz */
|
||||
1620, /* Hz */
|
||||
5376, /* Hz */
|
||||
};
|
||||
|
||||
void lis2dh12_cfg_threshold_event(const lis2dh12_t *dev,
|
||||
uint32_t mg, uint32_t us,
|
||||
uint8_t axis, uint8_t event, uint8_t line)
|
||||
{
|
||||
assert(line == LIS2DH12_INT1 || line == LIS2DH12_INT2);
|
||||
assert(event == LIS2DH12_EVENT_1 || event == LIS2DH12_EVENT_2);
|
||||
|
||||
_acquire(dev);
|
||||
|
||||
LIS2DH12_CTRL_REG2_t reg2;
|
||||
reg2.reg = _read(dev, REG_CTRL_REG2);
|
||||
uint8_t odr = _read(dev, REG_CTRL_REG1) >> 4;
|
||||
uint8_t scale = (_read(dev, REG_CTRL_REG4) >> 4) & 0x3;
|
||||
uint8_t int_reg = 0;
|
||||
|
||||
/* read current interrupt configuration */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
int_reg = _read(dev, REG_CTRL_REG3);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
int_reg = _read(dev, REG_CTRL_REG6);
|
||||
}
|
||||
|
||||
return LIS2DH12_OK;
|
||||
DEBUG("[%u] threshold: %"PRIu32" mg\n", event, mg);
|
||||
|
||||
/* read reference to set it to current data */
|
||||
_read(dev, REG_REFERENCE);
|
||||
|
||||
/* configure interrupt */
|
||||
switch (event) {
|
||||
case LIS2DH12_EVENT_1:
|
||||
/* apply high-pass to interrupt */
|
||||
reg2.bit.HP_IA1 = 1;
|
||||
int_reg |= LIS2DH12_INT_TYPE_IA1;
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_INT1_SRC);
|
||||
|
||||
_write(dev, REG_INT1_CFG, axis);
|
||||
_write(dev, REG_INT1_THS, mg / mg_per_bit[scale]);
|
||||
_write(dev, REG_INT1_DURATION, (us * hz_per_dr[odr]) / US_PER_SEC);
|
||||
break;
|
||||
case LIS2DH12_EVENT_2:
|
||||
/* apply high-pass to interrupt */
|
||||
reg2.bit.HP_IA2 = 1;
|
||||
int_reg |= LIS2DH12_INT_TYPE_IA2;
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_INT2_SRC);
|
||||
|
||||
_write(dev, REG_INT2_CFG, axis);
|
||||
_write(dev, REG_INT2_THS, mg / mg_per_bit[scale]);
|
||||
_write(dev, REG_INT2_DURATION, (us * hz_per_dr[odr]) / US_PER_SEC);
|
||||
break;
|
||||
}
|
||||
|
||||
/* configure high-pass */
|
||||
_write(dev, REG_CTRL_REG2, reg2.reg);
|
||||
|
||||
/* write back configuration */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
_write(dev, REG_CTRL_REG3, int_reg);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
_write(dev, REG_CTRL_REG6, int_reg);
|
||||
}
|
||||
|
||||
_release(dev);
|
||||
}
|
||||
|
||||
void lis2dh12_cfg_click_event(const lis2dh12_t *dev, uint32_t mg,
|
||||
uint32_t us_limit, uint32_t us_latency, uint32_t us_window,
|
||||
uint8_t click, uint8_t line)
|
||||
{
|
||||
_acquire(dev);
|
||||
|
||||
uint8_t odr = _read(dev, REG_CTRL_REG1) >> 4;
|
||||
uint8_t scale = (_read(dev, REG_CTRL_REG4) >> 4) & 0x3;
|
||||
|
||||
DEBUG("click threshold: %"PRIu32" mg\n", mg);
|
||||
|
||||
/* read reference to set it to current data */
|
||||
_read(dev, REG_REFERENCE);
|
||||
|
||||
/* select click axis & mode */
|
||||
_write(dev, REG_CLICK_CFG, click);
|
||||
|
||||
/* enable interrupt latching */
|
||||
_write(dev, REG_CLICK_THS, (mg / mg_per_bit[scale]) | LIS2DH12_CLICK_THS_LIR);
|
||||
|
||||
/* set timing parameters */
|
||||
_write(dev, REG_TIME_LIMIT, (us_limit * hz_per_dr[odr]) / US_PER_SEC);
|
||||
_write(dev, REG_TIME_LATENCY, (us_latency * hz_per_dr[odr]) / US_PER_SEC);
|
||||
_write(dev, REG_TIME_WINDOW, (us_window * hz_per_dr[odr]) / US_PER_SEC);
|
||||
|
||||
/* enable high-pass */
|
||||
_write_or(dev, REG_CTRL_REG2, LIS2DH12_CTRL_REG2_HPCLICK);
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_CLICK_SRC);
|
||||
|
||||
/* configure interrupt */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
_write_or(dev, REG_CTRL_REG3, LIS2DH12_INT_TYPE_CLICK);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
_write_or(dev, REG_CTRL_REG6, LIS2DH12_INT_TYPE_CLICK);
|
||||
}
|
||||
|
||||
_release(dev);
|
||||
}
|
||||
|
||||
void lis2dh12_cfg_disable_event(const lis2dh12_t *dev, uint8_t event, uint8_t line)
|
||||
{
|
||||
uint8_t reg = 0;
|
||||
|
||||
_release(dev);
|
||||
|
||||
/* read current interrupt configuration */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
reg = _read(dev, REG_CTRL_REG3);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
reg = _read(dev, REG_CTRL_REG6);
|
||||
}
|
||||
|
||||
/* remove event */
|
||||
if (event == LIS2DH12_EVENT_1) {
|
||||
reg &= ~LIS2DH12_INT_TYPE_IA1;
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_INT1_SRC);
|
||||
}
|
||||
if (event == LIS2DH12_EVENT_2) {
|
||||
reg &= ~LIS2DH12_INT_TYPE_IA2;
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_INT2_SRC);
|
||||
}
|
||||
if (event == LIS2DH12_EVENT_CLICK) {
|
||||
reg &= ~LIS2DH12_INT_TYPE_CLICK;
|
||||
|
||||
/* clear INT flags */
|
||||
_read(dev, REG_CLICK_SRC);
|
||||
}
|
||||
|
||||
/* write back configuration */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
_write(dev, REG_CTRL_REG3, reg);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
_write(dev, REG_CTRL_REG6, reg);
|
||||
}
|
||||
|
||||
_release(dev);
|
||||
}
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
int lis2dh12_set_int(const lis2dh12_t *dev, const lis2dh12_int_params_t *params, uint8_t int_line)
|
||||
static void _cb(void *lock)
|
||||
{
|
||||
assert (int_line == LIS2DH12_INT1 || int_line == LIS2DH12_INT2);
|
||||
assert (dev && params);
|
||||
assert (params->cb);
|
||||
|
||||
_acquire(dev);
|
||||
|
||||
gpio_t pin = GPIO_UNDEF;
|
||||
|
||||
switch (int_line){
|
||||
/* first interrupt line (INT1) */
|
||||
case LIS2DH12_INT1:
|
||||
pin = dev->p->int1_pin;
|
||||
assert (gpio_is_valid(pin));
|
||||
|
||||
if (gpio_init_int(pin, GPIO_IN, GPIO_RISING, params->cb, params->arg)) {
|
||||
return LIS2DH12_NOINT;
|
||||
}
|
||||
|
||||
_write(dev, REG_CTRL_REG3, params->int_type);
|
||||
_write(dev, REG_INT1_CFG, params->int_config);
|
||||
_write(dev, REG_INT1_THS, params->int_threshold);
|
||||
_write(dev, REG_INT1_DURATION, params->int_duration);
|
||||
break;
|
||||
/* second interrupt line (INT2) */
|
||||
case LIS2DH12_INT2:
|
||||
pin = dev->p->int2_pin;
|
||||
assert (gpio_is_valid(pin));
|
||||
|
||||
if (gpio_init_int(pin, GPIO_IN, GPIO_RISING, params->cb, params->arg)) {
|
||||
return LIS2DH12_NOINT;
|
||||
}
|
||||
|
||||
_write(dev, REG_CTRL_REG6, params->int_type);
|
||||
_write(dev, REG_INT2_CFG, params->int_config);
|
||||
_write(dev, REG_INT2_THS, params->int_threshold);
|
||||
_write(dev, REG_INT2_DURATION, params->int_duration);
|
||||
break;
|
||||
}
|
||||
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
mutex_unlock(lock);
|
||||
}
|
||||
|
||||
int lis2dh12_read_int_src(const lis2dh12_t *dev, uint8_t *data, uint8_t int_line)
|
||||
static uint32_t _merge_int_flags(const lis2dh12_t *dev, uint8_t events)
|
||||
{
|
||||
assert(dev && data);
|
||||
assert(int_line == LIS2DH12_INT1 || int_line == LIS2DH12_INT2);
|
||||
uint32_t int_src = 0;
|
||||
|
||||
/* merge interrupt flags (7 bit per event) into one word */
|
||||
if (events & LIS2DH12_INT_TYPE_IA1) {
|
||||
int_src |= (uint32_t)_read(dev, REG_INT1_SRC);
|
||||
}
|
||||
if (events & LIS2DH12_INT_TYPE_IA2) {
|
||||
int_src |= (uint32_t)_read(dev, REG_INT2_SRC) << 8;
|
||||
}
|
||||
if (events & LIS2DH12_INT_TYPE_CLICK) {
|
||||
int_src |= (uint32_t)_read(dev, REG_CLICK_SRC) << 16;
|
||||
}
|
||||
|
||||
DEBUG("int_src: %"PRIx32"\n", int_src);
|
||||
|
||||
return int_src;
|
||||
}
|
||||
|
||||
#define LIS2DH12_INT_SRC_ANY (((uint32_t)LIS2DH12_INT_SRC_IA << 0) | \
|
||||
((uint32_t)LIS2DH12_INT_SRC_IA << 8) | \
|
||||
((uint32_t)LIS2DH12_INT_SRC_IA << 16))
|
||||
|
||||
int lis2dh12_wait_event(const lis2dh12_t *dev, uint8_t line, bool stale_events)
|
||||
{
|
||||
uint32_t int_src;
|
||||
uint8_t events = 0;
|
||||
mutex_t lock = MUTEX_INIT_LOCKED;
|
||||
gpio_t pin = line == LIS2DH12_INT2
|
||||
? dev->p->int2_pin
|
||||
: dev->p->int1_pin;
|
||||
|
||||
_acquire(dev);
|
||||
|
||||
switch (int_line) {
|
||||
/* first interrupt line (INT1) */
|
||||
case LIS2DH12_INT1:
|
||||
*data = _read(dev, REG_INT1_SRC);
|
||||
break;
|
||||
/* second interrupt line (INT2) */
|
||||
case LIS2DH12_INT2:
|
||||
*data = _read(dev, REG_INT2_SRC);
|
||||
break;
|
||||
/* find out which events are configured */
|
||||
if (line == LIS2DH12_INT1) {
|
||||
events = _read(dev, REG_CTRL_REG3);
|
||||
}
|
||||
if (line == LIS2DH12_INT2) {
|
||||
events = _read(dev, REG_CTRL_REG6);
|
||||
}
|
||||
|
||||
/* check for stale interrupt */
|
||||
int_src = _merge_int_flags(dev, events);
|
||||
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
/* return early if stale interrupt is present */
|
||||
if (stale_events && (int_src & LIS2DH12_INT_SRC_ANY)) {
|
||||
return int_src;
|
||||
}
|
||||
|
||||
/* enable interrupt pin */
|
||||
assert(gpio_is_valid(pin));
|
||||
if (gpio_init_int(pin, GPIO_IN, GPIO_RISING, _cb, &lock)) {
|
||||
return LIS2DH12_NOINT;
|
||||
}
|
||||
|
||||
/* wait for interrupt */
|
||||
mutex_lock(&lock);
|
||||
gpio_irq_disable(pin);
|
||||
|
||||
/* read interrupt source */
|
||||
_acquire(dev);
|
||||
int_src = _merge_int_flags(dev, events);
|
||||
_release(dev);
|
||||
|
||||
return int_src;
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
int lis2dh12_set_fifo(const lis2dh12_t *dev, const lis2dh12_fifo_t *config) {
|
||||
int lis2dh12_set_fifo(const lis2dh12_t *dev, const lis2dh12_fifo_t *config)
|
||||
{
|
||||
|
||||
assert(dev && config);
|
||||
|
||||
LIS2DH12_CTRL_REG5_t reg5 = {0};
|
||||
LIS2DH12_FIFO_CTRL_REG_t fifo_reg = {0};
|
||||
|
||||
reg5.bit.LIR_INT1 = 1;
|
||||
reg5.bit.LIR_INT2 = 1;
|
||||
|
||||
if (config->FIFO_mode != LIS2DH12_FIFO_MODE_BYPASS) {
|
||||
reg5.bit.FIFO_EN = 1;
|
||||
} else {
|
||||
reg5.bit.FIFO_EN = 0;
|
||||
}
|
||||
fifo_reg.bit.TR = config->FIFO_set_INT2;
|
||||
fifo_reg.bit.FM = config->FIFO_mode;
|
||||
@ -294,13 +511,14 @@ int lis2dh12_set_fifo(const lis2dh12_t *dev, const lis2dh12_fifo_t *config) {
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_restart_fifo(const lis2dh12_t *dev) {
|
||||
int lis2dh12_restart_fifo(const lis2dh12_t *dev)
|
||||
{
|
||||
|
||||
assert(dev);
|
||||
|
||||
_acquire(dev);
|
||||
uint8_t reg5 = _read(dev, REG_CTRL_REG5);
|
||||
LIS2DH12_FIFO_CTRL_REG_t fifo_reg = {0};
|
||||
LIS2DH12_FIFO_CTRL_REG_t fifo_reg;
|
||||
fifo_reg.reg = _read(dev, REG_FIFO_CTRL_REG);
|
||||
|
||||
uint8_t fifo_mode_old = fifo_reg.bit.FM;
|
||||
@ -318,45 +536,28 @@ int lis2dh12_restart_fifo(const lis2dh12_t *dev) {
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_read_fifo_src(const lis2dh12_t *dev, LIS2DH12_FIFO_SRC_REG_t *data) {
|
||||
|
||||
assert(dev && data);
|
||||
|
||||
_acquire(dev);
|
||||
data->reg = _read(dev, REG_FIFO_SRC_REG);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
uint8_t lis2dh12_read_fifo_data(const lis2dh12_t *dev, lis2dh12_fifo_data_t *fifo_data,
|
||||
uint8_t number) {
|
||||
|
||||
uint8_t number)
|
||||
{
|
||||
assert(dev && fifo_data);
|
||||
/* check max FIFO length */
|
||||
assert(number <= 32);
|
||||
|
||||
_acquire(dev);
|
||||
|
||||
/* check if number is available */
|
||||
LIS2DH12_FIFO_SRC_REG_t src_reg = {0};
|
||||
LIS2DH12_FIFO_SRC_REG_t src_reg;
|
||||
src_reg.reg = _read(dev, REG_FIFO_SRC_REG);
|
||||
|
||||
if (src_reg.bit.FSS <= number) {
|
||||
if (src_reg.bit.FSS < number) {
|
||||
number = src_reg.bit.FSS;
|
||||
}
|
||||
|
||||
if (src_reg.bit.EMPTY) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t comp = 4 - ((_read(dev, REG_CTRL_REG4) >> 4) & 0x3);
|
||||
|
||||
/* calculate X, Y and Z values */
|
||||
for (uint8_t i = 0; i < number; i++){
|
||||
fifo_data[i].X_AXIS = (int16_t)(_read(dev, REG_OUT_X_L) | (_read(dev, REG_OUT_X_H) << 8))
|
||||
>> dev->comp;
|
||||
fifo_data[i].Y_AXIS = (int16_t)(_read(dev, REG_OUT_Y_L) | (_read(dev, REG_OUT_Y_H) << 8))
|
||||
>> dev->comp;
|
||||
fifo_data[i].Z_AXIS = (int16_t)(_read(dev, REG_OUT_Z_L) | (_read(dev, REG_OUT_Z_H) << 8))
|
||||
>> dev->comp;
|
||||
for (uint8_t i = 0; i < number; i++) {
|
||||
_get_fifo_data(dev, &fifo_data[i], comp);
|
||||
}
|
||||
|
||||
_release(dev);
|
||||
@ -364,12 +565,16 @@ uint8_t lis2dh12_read_fifo_data(const lis2dh12_t *dev, lis2dh12_fifo_data_t *fif
|
||||
return number;
|
||||
}
|
||||
|
||||
int lis2dh12_clear_data(const lis2dh12_t *dev) {
|
||||
int lis2dh12_clear_data(const lis2dh12_t *dev)
|
||||
{
|
||||
|
||||
assert(dev);
|
||||
|
||||
LIS2DH12_CTRL_REG5_t ctrl_reg5 = {0};
|
||||
ctrl_reg5.bit.BOOT = 1;
|
||||
LIS2DH12_CTRL_REG5_t ctrl_reg5 = {
|
||||
.bit.BOOT = 1,
|
||||
.bit.LIR_INT1 = 1,
|
||||
.bit.LIR_INT2 = 1,
|
||||
};
|
||||
|
||||
_acquire(dev);
|
||||
_write(dev, REG_CTRL_REG5, ctrl_reg5.reg);
|
||||
@ -378,7 +583,32 @@ int lis2dh12_clear_data(const lis2dh12_t *dev) {
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference) {
|
||||
int lis2dh12_read_temperature(const lis2dh12_t *dev, int16_t *temp)
|
||||
{
|
||||
uint8_t bytes[2];
|
||||
|
||||
_acquire(dev);
|
||||
|
||||
/* enable temperature sensor */
|
||||
if (!_read(dev, REG_TEMP_CFG_REG)) {
|
||||
uint8_t odr = _read(dev, REG_CTRL_REG1) >> 4;
|
||||
_write(dev, REG_TEMP_CFG_REG, LIS2DH12_TEMP_CFG_REG_ENABLE);
|
||||
if (IS_USED(MODULE_XTIMER)) {
|
||||
xtimer_msleep(MS_PER_SEC / hz_per_dr[odr]);
|
||||
}
|
||||
}
|
||||
|
||||
_read_burst(dev, REG_OUT_TEMP_L, bytes, sizeof(bytes));
|
||||
_release(dev);
|
||||
|
||||
*temp = 100 * (int8_t)bytes[1];
|
||||
*temp += (100 * bytes[0]) >> 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference)
|
||||
{
|
||||
|
||||
assert(dev);
|
||||
|
||||
@ -389,18 +619,8 @@ int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference) {
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_read_reference(const lis2dh12_t *dev, uint8_t *data) {
|
||||
|
||||
assert(dev);
|
||||
|
||||
_acquire(dev);
|
||||
*data = _read(dev, REG_REFERENCE);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *config) {
|
||||
int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *config)
|
||||
{
|
||||
|
||||
assert(dev && config);
|
||||
|
||||
@ -420,67 +640,27 @@ int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *conf
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_click(const lis2dh12_t *dev, const lis2dh12_click_t *config) {
|
||||
int lis2dh12_set_resolution(const lis2dh12_t *dev, lis2dh12_resolution_t resolution)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
LIS2DH12_CLICK_CFG_t click_CFG = {0};
|
||||
if (config->enable_DOUBLE) {
|
||||
click_CFG.bit.XD = config->enable_X_CLICK;
|
||||
click_CFG.bit.YD = config->enable_Y_CLICK;
|
||||
click_CFG.bit.ZD = config->enable_Z_CLICK;
|
||||
}
|
||||
else {
|
||||
click_CFG.bit.XS = config->enable_X_CLICK;
|
||||
click_CFG.bit.YS = config->enable_Y_CLICK;
|
||||
click_CFG.bit.ZS = config->enable_Z_CLICK;
|
||||
}
|
||||
|
||||
LIS2DH12_CLICK_THS_t click_thold = {0};
|
||||
click_thold.bit.LIR_CLICK = config->noINT_latency;
|
||||
click_thold.bit.THS = config->CLICK_thold;
|
||||
|
||||
_acquire(dev);
|
||||
_write(dev, REG_CLICK_CFG, click_CFG.reg);
|
||||
_write(dev, REG_CLICK_THS, click_thold.reg);
|
||||
_write(dev, REG_TIME_LIMIT, config->TIME_limit);
|
||||
_write(dev, REG_TIME_LATENCY, config->TIME_latency);
|
||||
_write(dev, REG_TIME_WINDOW, config->TIME_window);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_read_click_src(const lis2dh12_t *dev, LIS2DH12_CLICK_SRC_t *data) {
|
||||
assert(dev && data);
|
||||
|
||||
_acquire(dev);
|
||||
data->reg = _read(dev, REG_CLICK_SRC);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_powermode(const lis2dh12_t *dev, lis2dh12_powermode_t powermode) {
|
||||
|
||||
assert(dev);
|
||||
|
||||
LIS2DH12_CTRL_REG1_t reg1 = {0};
|
||||
LIS2DH12_CTRL_REG4_t reg4 = {0};
|
||||
LIS2DH12_CTRL_REG1_t reg1;
|
||||
LIS2DH12_CTRL_REG4_t reg4;
|
||||
|
||||
_acquire(dev);
|
||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||
|
||||
/* set power mode */
|
||||
if (powermode == LIS2DH12_POWER_LOW) {
|
||||
if (resolution == LIS2DH12_POWER_LOW) {
|
||||
reg1.bit.LPen = 1;
|
||||
reg4.bit.HR = 0;
|
||||
}
|
||||
else if (powermode == LIS2DH12_POWER_HIGH) {
|
||||
else if (resolution == LIS2DH12_POWER_HIGH) {
|
||||
reg1.bit.LPen = 0;
|
||||
reg4.bit.HR = 1;
|
||||
}
|
||||
else if (powermode == LIS2DH12_POWER_NORMAL) {
|
||||
else if (resolution == LIS2DH12_POWER_NORMAL) {
|
||||
reg1.bit.LPen = 0;
|
||||
reg4.bit.HR = 0;
|
||||
}
|
||||
@ -495,51 +675,125 @@ int lis2dh12_set_powermode(const lis2dh12_t *dev, lis2dh12_powermode_t powermode
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_datarate(const lis2dh12_t *dev, lis2dh12_rate_t rate) {
|
||||
lis2dh12_resolution_t lis2dh12_get_resolution(const lis2dh12_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
LIS2DH12_CTRL_REG1_t reg1;
|
||||
LIS2DH12_CTRL_REG4_t reg4;
|
||||
|
||||
_acquire(dev);
|
||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||
_release(dev);
|
||||
|
||||
if (!reg1.bit.ODR) {
|
||||
return LIS2DH12_POWER_DOWN;
|
||||
}
|
||||
if (reg1.bit.LPen) {
|
||||
return LIS2DH12_POWER_LOW;
|
||||
}
|
||||
if (reg4.bit.HR) {
|
||||
return LIS2DH12_POWER_HIGH;
|
||||
}
|
||||
return LIS2DH12_POWER_NORMAL;
|
||||
}
|
||||
|
||||
int lis2dh12_set_datarate(const lis2dh12_t *dev, lis2dh12_rate_t rate)
|
||||
{
|
||||
|
||||
assert(dev);
|
||||
assert(rate <= 0x9);
|
||||
|
||||
LIS2DH12_CTRL_REG1_t reg1 = {0};
|
||||
LIS2DH12_CTRL_REG1_t reg1;
|
||||
|
||||
_acquire(dev);
|
||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||
|
||||
reg1.bit.ODR = rate;
|
||||
|
||||
_write(dev, REG_CTRL_REG1, reg1.reg);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
int lis2dh12_set_scale(lis2dh12_t *dev, lis2dh12_scale_t scale) {
|
||||
uint16_t lis2dh12_get_datarate(const lis2dh12_t *dev)
|
||||
{
|
||||
const uint16_t rates_hz[] = {
|
||||
0,
|
||||
1,
|
||||
10,
|
||||
25,
|
||||
50,
|
||||
100,
|
||||
200,
|
||||
400,
|
||||
};
|
||||
|
||||
assert(dev);
|
||||
assert((scale>>4) <= 0x3);
|
||||
|
||||
LIS2DH12_CTRL_REG4_t reg4 = {0};
|
||||
LIS2DH12_CTRL_REG1_t reg1;
|
||||
|
||||
_acquire(dev);
|
||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||
_release(dev);
|
||||
|
||||
if (reg1.bit.ODR < ARRAY_SIZE(rates_hz)) {
|
||||
return rates_hz[reg1.bit.ODR];
|
||||
}
|
||||
|
||||
if (reg1.bit.LPen) {
|
||||
if (reg1.bit.ODR == 8) {
|
||||
return 1620;
|
||||
}
|
||||
if (reg1.bit.ODR == 9) {
|
||||
return 5376;
|
||||
}
|
||||
}
|
||||
|
||||
if (reg1.bit.ODR == 9) {
|
||||
return 1344;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lis2dh12_set_scale(lis2dh12_t *dev, lis2dh12_scale_t scale)
|
||||
{
|
||||
|
||||
assert(dev);
|
||||
assert(scale <= LIS2DH12_SCALE_16G);
|
||||
|
||||
LIS2DH12_CTRL_REG4_t reg4;
|
||||
|
||||
_acquire(dev);
|
||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||
|
||||
reg4.bit.FS = scale >> 4;
|
||||
|
||||
reg4.bit.FS = scale;
|
||||
_write(dev, REG_CTRL_REG4, reg4.reg);
|
||||
_release(dev);
|
||||
|
||||
dev->comp = 4 - (scale >> 4);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
||||
lis2dh12_scale_t lis2dh12_get_scale(lis2dh12_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
LIS2DH12_CTRL_REG4_t reg4;
|
||||
|
||||
_acquire(dev);
|
||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||
_release(dev);
|
||||
|
||||
return reg4.bit.FS;
|
||||
}
|
||||
|
||||
int lis2dh12_poweron(const lis2dh12_t *dev)
|
||||
{
|
||||
assert(dev);
|
||||
|
||||
/* set default param values */
|
||||
lis2dh12_set_datarate(dev, dev->p->rate);
|
||||
lis2dh12_set_powermode(dev, dev->p->powermode);
|
||||
lis2dh12_set_resolution(dev, dev->p->resolution);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
@ -551,5 +805,10 @@ int lis2dh12_poweroff(const lis2dh12_t *dev)
|
||||
/* set datarate to zero */
|
||||
lis2dh12_set_datarate(dev, 0);
|
||||
|
||||
/* disable temperature sensor */
|
||||
_acquire(dev);
|
||||
_write(dev, REG_TEMP_CFG_REG, LIS2DH12_TEMP_CFG_REG_DISABLE);
|
||||
_release(dev);
|
||||
|
||||
return LIS2DH12_OK;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
static int read_accelerometer(const void *dev, phydat_t *res)
|
||||
{
|
||||
if (lis2dh12_read((const lis2dh12_t *)dev, res->val) != LIS2DH12_OK) {
|
||||
if (lis2dh12_read(dev, (lis2dh12_fifo_data_t*)res->val) != LIS2DH12_OK) {
|
||||
return 0;
|
||||
}
|
||||
res->unit = UNIT_G;
|
||||
@ -31,8 +31,25 @@ static int read_accelerometer(const void *dev, phydat_t *res)
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int read_temperature(const void *dev, phydat_t *res)
|
||||
{
|
||||
if (lis2dh12_read_temperature(dev, &res->val[0])) {
|
||||
return -ECANCELED;
|
||||
}
|
||||
res->unit = UNIT_TEMP_C;
|
||||
res->scale = -2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t lis2dh12_saul_driver = {
|
||||
.read = read_accelerometer,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_ACCEL
|
||||
.type = SAUL_SENSE_ACCEL,
|
||||
};
|
||||
|
||||
const saul_driver_t lis2dh12_saul_temp_driver = {
|
||||
.read = read_temperature,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_TEMP,
|
||||
};
|
||||
|
@ -30,7 +30,6 @@
|
||||
*/
|
||||
#define LIS2DH12_NUM ARRAY_SIZE(lis2dh12_params)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Number of defined SAUL registry info entries
|
||||
*/
|
||||
@ -45,7 +44,7 @@ static lis2dh12_t lis2dh12_devs[LIS2DH12_NUM];
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[LIS2DH12_NUM];
|
||||
static saul_reg_t saul_entries[LIS2DH12_NUM * 2];
|
||||
|
||||
void auto_init_lis2dh12(void)
|
||||
{
|
||||
@ -62,9 +61,14 @@ void auto_init_lis2dh12(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
saul_entries[i].dev = &(lis2dh12_devs[i]);
|
||||
saul_entries[i].name = lis2dh12_saul_info[i].name;
|
||||
saul_entries[i].driver = &lis2dh12_saul_driver;
|
||||
saul_reg_add(&(saul_entries[i]));
|
||||
saul_entries[2 * i].dev = &lis2dh12_devs[i];
|
||||
saul_entries[2 * i].name = lis2dh12_saul_info[i].name;
|
||||
saul_entries[2 * i].driver = &lis2dh12_saul_driver;
|
||||
saul_reg_add(&saul_entries[2 * i]);
|
||||
|
||||
saul_entries[2 * i + 1].dev = &lis2dh12_devs[i];
|
||||
saul_entries[2 * i + 1].name = lis2dh12_saul_info[i].name;
|
||||
saul_entries[2 * i + 1].driver = &lis2dh12_saul_temp_driver;
|
||||
saul_reg_add(&saul_entries[2 * i + 1]);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ DRIVER ?= lis2dh12_spi
|
||||
USEMODULE += fmt
|
||||
USEMODULE += xtimer
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
USEMODULE += $(DRIVER)
|
||||
|
||||
# for using lis2dh12 with interrupt function
|
||||
|
@ -3,6 +3,7 @@
|
||||
CONFIG_MODULE_FMT=y
|
||||
CONFIG_MODULE_XTIMER=y
|
||||
CONFIG_MODULE_SHELL=y
|
||||
CONFIG_MODULE_SHELL_COMMANDS=y
|
||||
CONFIG_MODULE_LIS2DH12=y
|
||||
CONFIG_MODULE_LIS2DH12_SPI=y
|
||||
|
||||
|
@ -14,13 +14,15 @@
|
||||
* @brief Test application for LIS2DH12 accelerometer driver
|
||||
*
|
||||
* @author Jan Mohr <jan.mohr@ml-pa.com>
|
||||
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "stdlib.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include "xtimer.h"
|
||||
#include "fmt.h"
|
||||
#include "thread.h"
|
||||
@ -33,129 +35,12 @@
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define REFERENCE_DEFAULT 10 /* LSB according to SCALE */
|
||||
|
||||
#define THOLD_SHOCK_MILLIG_DEFAULT 1500
|
||||
#define NUM_DATA_SHOCK_DETECT 7 /* detect shock in NUM last FIFO samples */
|
||||
|
||||
/* device specific */
|
||||
#define NUM_AXES 3
|
||||
#define NUM_FIFO_VALUES 32
|
||||
|
||||
/* axis define for click */
|
||||
#define X_CLICK 1
|
||||
#define Y_CLICK 2
|
||||
#define Z_CLICK 3
|
||||
#define DCLICK_DEFAULT 40 /* default threshold for double click */
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
static kernel_pid_t lis2dh12_process;
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
int __attribute__((weak)) shell_lis2dh12_cmd(int argc, char** argv);
|
||||
|
||||
static const shell_command_t shell_commands[] = {
|
||||
{ "lis", "Command with multiple subcommands.", shell_lis2dh12_cmd },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
char lis2dh12_process_stack[THREAD_STACKSIZE_MAIN];
|
||||
|
||||
/* setting the double click order */
|
||||
static LIS2DH12_CLICK_SRC_t click_src_reg;
|
||||
static lis2dh12_click_t click_cfg = {
|
||||
.enable_DOUBLE = true,
|
||||
.enable_X_CLICK = true,
|
||||
.enable_Y_CLICK = true,
|
||||
.enable_Z_CLICK = true,
|
||||
.noINT_latency = true,
|
||||
.CLICK_thold = DCLICK_DEFAULT,
|
||||
.TIME_limit = 4, /* 4 ODR cycles -> 40ms */
|
||||
.TIME_latency = 16, /* 16 ODR cycles -> 160ms */
|
||||
.TIME_window = 10, /* 10 ODR cycles -> 100ms */
|
||||
};
|
||||
|
||||
/* allocate device descriptor */
|
||||
static lis2dh12_t dev;
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
/* Interrupt lines */
|
||||
static uint8_t line1 = 1;
|
||||
static uint8_t line2 = 2;
|
||||
|
||||
/* Interrupt params */
|
||||
static lis2dh12_int_params_t params_int1 = {0};
|
||||
static lis2dh12_int_params_t params_int2 = {0};
|
||||
|
||||
/* Interrupt source register */
|
||||
static uint8_t int1_src;
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/* FIFO data memory */
|
||||
static lis2dh12_fifo_data_t data_fifo[NUM_FIFO_VALUES];
|
||||
/* FIFO configuration */
|
||||
static lis2dh12_fifo_t fifo_cfg = {
|
||||
.FIFO_set_INT2 = false,
|
||||
.FIFO_watermark = 10,
|
||||
.FIFO_mode = LIS2DH12_FIFO_MODE_STREAMtoFIFO,
|
||||
};
|
||||
|
||||
/* Memory to print current data */
|
||||
static char str_out[3][8];
|
||||
|
||||
/* current lis acceleration data */
|
||||
static int16_t data_lis[3];
|
||||
|
||||
/* highpass configuration */
|
||||
lis2dh12_highpass_t highpass_cfg = {
|
||||
.Highpass_mode = LIS2DH12_HP_MODE_REFERENCE,
|
||||
.Highpass_freq = LIS2DH12_HP_FREQ_DIV100,
|
||||
.CLICK_enable = false,
|
||||
.INT1_enable = false,
|
||||
.INT2_enable = false,
|
||||
.DATA_OUT_enable = false,
|
||||
};
|
||||
|
||||
/* reference data */
|
||||
static uint8_t reference_value;
|
||||
|
||||
/* shock threshold */
|
||||
static int16_t shock_thold;
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
/* previous values */
|
||||
static int16_t old_data_lis[3];
|
||||
static uint8_t int1_src_old;
|
||||
|
||||
/* lis2dh12 interrupt callback function. */
|
||||
static void lis2dh12_int_cb(void* l) {
|
||||
|
||||
/* disable IRQ until lis_process is done */
|
||||
gpio_irq_disable(dev.p->int1_pin);
|
||||
gpio_irq_disable(dev.p->int2_pin);
|
||||
|
||||
/* reset click source */
|
||||
lis2dh12_read_click_src(&dev, &click_src_reg);
|
||||
DEBUG("[INT]: CLICK_SRC 0x%x\n", click_src_reg.reg);
|
||||
|
||||
uint8_t line = *(uint8_t*)l;
|
||||
printf("Info: INT_line: %d\n", line);
|
||||
|
||||
lis2dh12_read_reference(&dev, &reference_value);
|
||||
DEBUG("[INT]: REF: 0x%x\n", reference_value);
|
||||
|
||||
lis2dh12_read_int_src(&dev, &int1_src, 1);
|
||||
DEBUG("[INT]: INT_SRC 0x%x\n", int1_src);
|
||||
DEBUG("[INT]: INT_SRC - IA %d; ZH %d; ZL %d; YH %d; YL %d; XH %d; XL %d.\n",
|
||||
int1_src & LIS2DH12_INT_SRC_IA,
|
||||
int1_src & LIS2DH12_INT_SRC_ZH, int1_src & LIS2DH12_INT_SRC_ZL,
|
||||
int1_src & LIS2DH12_INT_SRC_YH, int1_src & LIS2DH12_INT_SRC_YL,
|
||||
int1_src & LIS2DH12_INT_SRC_XH, int1_src & LIS2DH12_INT_SRC_XL);
|
||||
|
||||
thread_wakeup(lis2dh12_process);
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
void lis2dh12_test_init(void) {
|
||||
|
||||
if (IS_USED(MODULE_LIS2DH12_SPI)) {
|
||||
@ -173,534 +58,320 @@ void lis2dh12_test_init(void) {
|
||||
}
|
||||
|
||||
/* change LIS settings */
|
||||
lis2dh12_set_powermode(&dev, LIS2DH12_POWER_LOW);
|
||||
lis2dh12_set_resolution(&dev, LIS2DH12_POWER_LOW);
|
||||
lis2dh12_set_datarate(&dev, LIS2DH12_RATE_100HZ);
|
||||
lis2dh12_set_scale(&dev, LIS2DH12_SCALE_4G);
|
||||
lis2dh12_set_scale(&dev, LIS2DH12_SCALE_16G);
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
/* set interrupt pins */
|
||||
gpio_t pin1 = dev.p->int1_pin;
|
||||
gpio_t pin2 = dev.p->int2_pin;
|
||||
/* configure FIFO */
|
||||
lis2dh12_fifo_t fifo_cfg = {
|
||||
.FIFO_mode = LIS2DH12_FIFO_MODE_STREAM,
|
||||
};
|
||||
|
||||
/* set Interrupt params */
|
||||
if (gpio_is_valid(pin1)) {
|
||||
/* enables interrupt on all axes above the threshold value */
|
||||
params_int1.int_config = LIS2DH12_INT_CFG_XHIE
|
||||
| LIS2DH12_INT_CFG_YHIE
|
||||
| LIS2DH12_INT_CFG_ZHIE;
|
||||
params_int1.int_duration = 1;
|
||||
params_int1.cb = lis2dh12_int_cb;
|
||||
params_int1.arg = &line1;
|
||||
}
|
||||
if (gpio_is_valid(pin2)) {
|
||||
/* enables interrupt on Y-axis below the threshold value */
|
||||
params_int2.int_config = LIS2DH12_INT_CFG_YLIE;
|
||||
params_int2.int_duration = 1;
|
||||
params_int2.cb = lis2dh12_int_cb;
|
||||
params_int2.arg = &line2;
|
||||
}
|
||||
|
||||
if (gpio_init_int(pin1, GPIO_IN, GPIO_RISING, lis2dh12_int_cb, &line1)) {
|
||||
DEBUG("[lis_init]: INT1 failed\n");
|
||||
}
|
||||
else {
|
||||
DEBUG("[lis_init]: INT1 done\n");
|
||||
}
|
||||
|
||||
if (gpio_init_int(pin2, GPIO_IN, GPIO_RISING, lis2dh12_int_cb, &line2)) {
|
||||
DEBUG("[lis_init]: INT2 failed\n");
|
||||
}
|
||||
else {
|
||||
DEBUG("[lis_init]: INT2 done\n");
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/* enable FIFO */
|
||||
lis2dh12_set_fifo(&dev, &fifo_cfg);
|
||||
|
||||
/* enable click detection */
|
||||
lis2dh12_set_click(&dev, &click_cfg);
|
||||
|
||||
/* set default shock value */
|
||||
shock_thold = THOLD_SHOCK_MILLIG_DEFAULT;
|
||||
|
||||
/* read registers to reset device */
|
||||
lis2dh12_read_click_src(&dev, &click_src_reg);
|
||||
lis2dh12_read_reference(&dev, &reference_value);
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
lis2dh12_read_int_src(&dev, &int1_src, 1);
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
}
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
void* lis2dh12_test_process(void* arg) {
|
||||
(void) arg;
|
||||
|
||||
/* start processing */
|
||||
DEBUG("[Process]: start process\n");
|
||||
|
||||
while (1) {
|
||||
/* start processing */
|
||||
DEBUG("[Process]: start process\n");
|
||||
|
||||
/* read FIFO_src before getting data */
|
||||
LIS2DH12_FIFO_SRC_REG_t fifo_src;
|
||||
lis2dh12_read_fifo_src(&dev, &fifo_src);
|
||||
DEBUG("[Process]: FIFO SRC 0x%x\n", fifo_src.reg);
|
||||
DEBUG("[Process]: WTM %x, OVRN %d, EMPTY %d, FSS %d\n", fifo_src.bit.WTM,
|
||||
fifo_src.bit.OVRN_FIFO, fifo_src.bit.EMPTY, fifo_src.bit.FSS);
|
||||
/* wait for interrupt */
|
||||
int int1_src = lis2dh12_wait_event(&dev, LIS2DH12_INT1, false);
|
||||
|
||||
/* get fifo data */
|
||||
uint8_t number_read = lis2dh12_read_fifo_data(&dev, data_fifo, NUM_FIFO_VALUES);
|
||||
|
||||
/* read FIFO_src after getting data */
|
||||
lis2dh12_read_fifo_src(&dev, &fifo_src);
|
||||
DEBUG("[Process]: FIFO SRC 0x%x\n", fifo_src.reg);
|
||||
DEBUG("[Process]: WTM %x, OVRN %d, EMPTY %d, FSS %d\n", fifo_src.bit.WTM,
|
||||
fifo_src.bit.OVRN_FIFO, fifo_src.bit.EMPTY, fifo_src.bit.FSS);
|
||||
|
||||
/* display FIFO data */
|
||||
if (ENABLE_DEBUG) {
|
||||
for (int i = 0; i < number_read; i++){
|
||||
printf("[Process]: X[%2d] %d\n", i, data_fifo[i].X_AXIS);
|
||||
printf("[Process]: Y[%2d] %d\n", i, data_fifo[i].Y_AXIS);
|
||||
printf("[Process]: Z[%2d] %d\n", i, data_fifo[i].Z_AXIS);
|
||||
}
|
||||
if (int1_src <= 0) {
|
||||
printf("error: %d\n", int1_src);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* After the Interrupt the FIFO needs to be enabled again. */
|
||||
lis2dh12_restart_fifo(&dev);
|
||||
|
||||
/* check if shock occurred*/
|
||||
uint16_t max_data_X = 0;
|
||||
uint16_t max_data_Y = 0;
|
||||
uint16_t max_data_Z = 0;
|
||||
|
||||
bool X_shock_pos = false;
|
||||
bool Y_shock_pos = false;
|
||||
bool Z_shock_pos = false;
|
||||
|
||||
for (uint8_t entry = NUM_FIFO_VALUES - NUM_DATA_SHOCK_DETECT; entry < NUM_FIFO_VALUES;
|
||||
entry++) {
|
||||
uint16_t abs_X = data_fifo[entry].X_AXIS >= 0 ? data_fifo[entry].X_AXIS :
|
||||
-1*data_fifo[entry].X_AXIS;
|
||||
uint16_t abs_Y = data_fifo[entry].Y_AXIS >= 0 ? data_fifo[entry].Y_AXIS :
|
||||
-1*data_fifo[entry].Y_AXIS;
|
||||
uint16_t abs_Z = data_fifo[entry].Z_AXIS >= 0 ? data_fifo[entry].Z_AXIS :
|
||||
-1*data_fifo[entry].Z_AXIS;
|
||||
|
||||
/* check X shock direction */
|
||||
if (max_data_X <= abs_X) {
|
||||
max_data_X = abs_X;
|
||||
X_shock_pos = (data_fifo[entry].X_AXIS >= 0);
|
||||
}
|
||||
/* check Y shock direction */
|
||||
if (max_data_Y <= abs_Y) {
|
||||
max_data_Y = abs_Y;
|
||||
Y_shock_pos = (data_fifo[entry].Y_AXIS >= 0);
|
||||
}
|
||||
/* check Z shock direction */
|
||||
if (max_data_Z <= abs_Z) {
|
||||
max_data_Z = abs_Z;
|
||||
Z_shock_pos = (data_fifo[entry].Z_AXIS >= 0);
|
||||
}
|
||||
if (LIS2DH12_INT_SRC_1(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||
puts("event 1");
|
||||
}
|
||||
|
||||
DEBUG("[Process]: oldX %d, oldY %d, oldZ %d\n", old_data_lis[0], old_data_lis[1],
|
||||
old_data_lis[2]);
|
||||
DEBUG("[Process]: maxX %d, maxY %d, maxZ %d\n", max_data_X, max_data_Y, max_data_Z);
|
||||
|
||||
/* X shock */
|
||||
int16_t diff_value = max_data_X - old_data_lis[0];
|
||||
if (diff_value >= shock_thold) {
|
||||
if (X_shock_pos) {
|
||||
puts("positive X shock detected.");
|
||||
}
|
||||
else {
|
||||
puts("negative X shock detected.");
|
||||
}
|
||||
if (LIS2DH12_INT_SRC_2(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||
puts("event 2");
|
||||
}
|
||||
/* Y shock */
|
||||
diff_value = max_data_Y - old_data_lis[1];
|
||||
if (diff_value >= shock_thold) {
|
||||
if (Y_shock_pos) {
|
||||
puts("positive Y shock detected.");
|
||||
}
|
||||
else {
|
||||
puts("negative Y shock detected.");
|
||||
}
|
||||
if (LIS2DH12_INT_SRC_CLICK(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||
puts("click event");
|
||||
}
|
||||
/* Z shock */
|
||||
diff_value = max_data_Z - old_data_lis[2];
|
||||
if (diff_value >= shock_thold) {
|
||||
if (Z_shock_pos) {
|
||||
puts("positive Z shock detected.");
|
||||
}
|
||||
else {
|
||||
puts("negative Z shock detected.");
|
||||
}
|
||||
}
|
||||
|
||||
/* check for roll */
|
||||
/* roll conditions
|
||||
*
|
||||
* only 180°, changes can be detected with 6D reg in INT1_SRC
|
||||
* change in ZH and ZL -> X-roll (device flipped from top to bottom)
|
||||
* change in YH and YL -> Z-roll
|
||||
* change in XH and XL -> Y-roll
|
||||
*/
|
||||
DEBUG("[Process]: OLD - IA %d; ZH %d; ZL %d; YH %d; YL %d; XH %d; XL %d.\n",
|
||||
int1_src_old & LIS2DH12_INT_SRC_IA,
|
||||
int1_src_old & LIS2DH12_INT_SRC_ZH, int1_src_old & LIS2DH12_INT_SRC_ZL,
|
||||
int1_src_old & LIS2DH12_INT_SRC_YH, int1_src_old & LIS2DH12_INT_SRC_YL,
|
||||
int1_src_old & LIS2DH12_INT_SRC_XH, int1_src_old & LIS2DH12_INT_SRC_XL);
|
||||
|
||||
DEBUG("[Process]: NEW - IA %d; ZH %d; ZL %d; YH %d; YL %d; XH %d; XL %d.\n",
|
||||
int1_src & LIS2DH12_INT_SRC_IA,
|
||||
int1_src & LIS2DH12_INT_SRC_ZH, int1_src & LIS2DH12_INT_SRC_ZL,
|
||||
int1_src & LIS2DH12_INT_SRC_YH, int1_src & LIS2DH12_INT_SRC_YL,
|
||||
int1_src & LIS2DH12_INT_SRC_XH, int1_src & LIS2DH12_INT_SRC_XL);
|
||||
|
||||
if (((int1_src_old & LIS2DH12_INT_SRC_ZH) != (int1_src & LIS2DH12_INT_SRC_ZH))
|
||||
&& ((int1_src_old & LIS2DH12_INT_SRC_ZL) != (int1_src & LIS2DH12_INT_SRC_ZL))) {
|
||||
printf("X roll detected.\n");
|
||||
}
|
||||
if (((int1_src_old & LIS2DH12_INT_SRC_XH) != (int1_src & LIS2DH12_INT_SRC_XH))
|
||||
&& ((int1_src_old & LIS2DH12_INT_SRC_YL) != (int1_src & LIS2DH12_INT_SRC_YL))) {
|
||||
printf("Z roll detected.\n");
|
||||
}
|
||||
if (((int1_src_old & LIS2DH12_INT_SRC_YH) != (int1_src & LIS2DH12_INT_SRC_YH))
|
||||
&& ((int1_src_old & LIS2DH12_INT_SRC_XL) != (int1_src & LIS2DH12_INT_SRC_XL))) {
|
||||
printf("Y roll detected.\n");
|
||||
}
|
||||
|
||||
int1_src_old = int1_src;
|
||||
|
||||
/* check click order */
|
||||
/*
|
||||
* idea is to do a sequence of double clicks, to enable the device
|
||||
*
|
||||
*/
|
||||
/* click_src read during interrupt callback */
|
||||
DEBUG("[Process]: clickSRC 0x%x\n", click_src_reg.reg);
|
||||
|
||||
if (click_src_reg.bit.IA && click_src_reg.bit.DClick) {
|
||||
/* X-Double */
|
||||
if (click_src_reg.bit.X_AXIS && !click_src_reg.bit.Y_AXIS
|
||||
&& !click_src_reg.bit.Z_AXIS) {
|
||||
int8_t sign = click_src_reg.bit.Sign ? -1 : 1;
|
||||
printf("got X-DCLICK, sign %d\n", sign);
|
||||
}
|
||||
/* Y-Double */
|
||||
if (!click_src_reg.bit.X_AXIS && click_src_reg.bit.Y_AXIS
|
||||
&& !click_src_reg.bit.Z_AXIS) {
|
||||
int8_t sign = click_src_reg.bit.Sign ? -1 : 1;
|
||||
printf("got Y-DCLICK, sign %d\n", sign);
|
||||
}
|
||||
/* Z-Double */
|
||||
if (!click_src_reg.bit.X_AXIS && !click_src_reg.bit.Y_AXIS
|
||||
&& click_src_reg.bit.Z_AXIS) {
|
||||
int8_t sign = click_src_reg.bit.Sign ? -1 : 1;
|
||||
printf("got Z-DCLICK, sign %d\n", sign);
|
||||
}
|
||||
}
|
||||
|
||||
/* enable IRQ again */
|
||||
gpio_irq_enable(dev.p->int1_pin);
|
||||
gpio_irq_enable(dev.p->int2_pin);
|
||||
|
||||
/* thread will sleep until next wokeup_lis */
|
||||
thread_sleep();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
int shell_lis2dh12_cmd(int argc, char **argv) {
|
||||
static int shell_is2dh12_read(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
printf("Command: lis %s %s\n", (argc > 1) ? argv[1] : "",
|
||||
(argc > 2) ? argv[2] : "");
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
const char * usage = "USAGE: lis <subcommand> [arg], with subcommand "
|
||||
"in (enable, disable, read, read_fifo, clear_data, "
|
||||
"set-click, set-thold-shock, set-thold-inter, "
|
||||
"set-highpass, change_rate, change_power, change_scale).";
|
||||
#else
|
||||
const char * usage = "USAGE: lis <subcommand> [arg], with subcommand "
|
||||
"in (enable, disable, read, read_fifo, clear_data, "
|
||||
"change_rate, change_power, change_scale).";
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
lis2dh12_fifo_data_t data;
|
||||
|
||||
/* MISSING command */
|
||||
if (argc < 2) {
|
||||
printf("Error: Missing sub-command. %s\n", usage);
|
||||
return -1;
|
||||
lis2dh12_read(&dev, &data);
|
||||
|
||||
/* Memory to print current data */
|
||||
char str_out[3][8];
|
||||
|
||||
/* format data */
|
||||
for (unsigned j = 0; j < 3; ++j) {
|
||||
size_t len = fmt_s16_dfp(str_out[j], data.data[j], -3);
|
||||
str_out[j][len] = '\0';
|
||||
}
|
||||
|
||||
/* enable disable device */
|
||||
else if (strncmp(argv[1], "enable", sizeof("enable")) == 0) {
|
||||
if (lis2dh12_poweron(&dev) != LIS2DH12_OK) {
|
||||
puts("unable to poweron device.");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp(argv[1], "disable", sizeof("disable")) == 0) {
|
||||
if (lis2dh12_poweroff(&dev) != LIS2DH12_OK) {
|
||||
puts("unable to poweroff device.");
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
printf("X: %6s Y: %6s Z: %6s\n", str_out[0], str_out[1], str_out[2]);
|
||||
|
||||
/* read acceleration data */
|
||||
else if (strncmp(argv[1], "read", sizeof("read")) == 0) {
|
||||
uint8_t amount = (argc < 3) ? 1 : atoi(argv[2]);
|
||||
uint8_t amt = 0;
|
||||
|
||||
/* read sensor data */
|
||||
for (amt = 0; amt < amount; amt++){
|
||||
if (lis2dh12_read(&dev, data_lis) != LIS2DH12_OK) {
|
||||
puts("error: no data from sensor");
|
||||
return -1;
|
||||
}
|
||||
/* format data */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
size_t len = fmt_s16_dfp(str_out[i], data_lis[i], -3);
|
||||
str_out[i][len] = '\0';
|
||||
}
|
||||
|
||||
/* print data to STDIO */
|
||||
printf("X: %6s Y: %6s Z: %6s\n", str_out[0], str_out[1], str_out[2]);
|
||||
|
||||
xtimer_msleep(250);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp(argv[1], "read_fifo", sizeof("read_fifo")) == 0) {
|
||||
uint8_t number = 0;
|
||||
if ((argc < 3) || (number = atoi(argv[2])) > 32) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain number of FIFO values to read (max. 32)).");
|
||||
puts("USAGE: lis read_fifo [number]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read raw data from FIFO */
|
||||
uint8_t number_read = lis2dh12_read_fifo_data(&dev, data_fifo, number);
|
||||
|
||||
DEBUG("[lis_command]: fifo_read %d elements.\n", number_read);
|
||||
|
||||
/* print data */
|
||||
for (int entry = 0; entry < number_read; entry++){
|
||||
|
||||
/* format data */
|
||||
size_t len = fmt_s16_dfp(str_out[0], data_fifo[entry].X_AXIS, -3);
|
||||
str_out[0][len] = '\0';
|
||||
len = fmt_s16_dfp(str_out[1], data_fifo[entry].Y_AXIS, -3);
|
||||
str_out[1][len] = '\0';
|
||||
len = fmt_s16_dfp(str_out[2], data_fifo[entry].Z_AXIS, -3);
|
||||
str_out[2][len] = '\0';
|
||||
|
||||
printf("[%2d] X: %6s Y: %6s Z: %6s\n", entry, str_out[0], str_out[1], str_out[2]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* clear memory */
|
||||
else if (strncmp(argv[1], "clear_data", sizeof("clear_data")) == 0) {
|
||||
|
||||
lis2dh12_clear_data(&dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
/* set commands */
|
||||
else if (strncmp(argv[1], "set-click", sizeof("set-click")) == 0) {
|
||||
uint8_t thold = 0;
|
||||
if ((argc < 3) || (thold = atoi(argv[2])) > 127) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain a threshold value below 128. "
|
||||
"The LSB changes according to selected SCALE "
|
||||
"(@2G LSB=16mg; @4G LSB=32mg; @8G LSB=62mg: @16G LSB=186mg).");
|
||||
puts("USAGE: lis set-click [thold]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
click_cfg.CLICK_thold = thold;
|
||||
lis2dh12_set_click(&dev, &click_cfg);
|
||||
|
||||
/* enable click interrupt */
|
||||
params_int1.int_type = LIS2DH12_INT_TYPE_I1_CLICK;
|
||||
lis2dh12_set_int(&dev, ¶ms_int1, LIS2DH12_INT1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp(argv[1], "set-thold-shock", sizeof("set-thold-shock")) == 0) {
|
||||
uint16_t thold = 0;
|
||||
if ((argc < 3) || !(thold = atoi(argv[2]))) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain a threshold value in [mg] below the max SCALE. "
|
||||
"(@2G below 2000; @4G below 4000; and so on)");
|
||||
puts("USAGE: lis set-thold-shock [thold]");
|
||||
return -1;
|
||||
}
|
||||
shock_thold = thold;
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp(argv[1], "set-thold-inter", sizeof("set-thold-inter")) == 0) {
|
||||
uint8_t line = 0;
|
||||
if ((argc < 4) || (line = atoi(argv[3])) > 2) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain threshold value and interrupt line (1 or 2). "
|
||||
"The threshold LSB changes according to selected SCALE "
|
||||
"(@2G LSB=16mg; @4G LSB=32mg; @8G LSB=62mg: @16G LSB=186mg).");
|
||||
puts("To disable interrupt set thold to 0.");
|
||||
puts("USAGE: lis set-thold-inter [thold] [line]");
|
||||
return -1;
|
||||
}
|
||||
uint8_t thold = atoi(argv[2]);
|
||||
if (line == 1) {
|
||||
if (!thold) {
|
||||
params_int1.int_config = 0;
|
||||
}
|
||||
else {
|
||||
/* enables all axes for acceleration above threshold */
|
||||
params_int1.int_config = LIS2DH12_INT_CFG_XHIE
|
||||
| LIS2DH12_INT_CFG_YHIE
|
||||
| LIS2DH12_INT_CFG_ZHIE;
|
||||
}
|
||||
params_int1.int_type = LIS2DH12_INT_TYPE_I1_IA1;
|
||||
params_int1.int_threshold = thold;
|
||||
|
||||
lis2dh12_set_int(&dev, ¶ms_int1, LIS2DH12_INT1);
|
||||
}
|
||||
else if (line == 2){
|
||||
if (!thold) {
|
||||
params_int2.int_config = 0;
|
||||
}
|
||||
else {
|
||||
/* enables Y-axis for acceleration under the threshold */
|
||||
params_int2.int_config = LIS2DH12_INT_CFG_YLIE;
|
||||
}
|
||||
params_int2.int_type = LIS2DH12_INT_TYPE_I2_IA2;
|
||||
params_int2.int_threshold = thold;
|
||||
lis2dh12_set_int(&dev, ¶ms_int2, LIS2DH12_INT2);
|
||||
}
|
||||
if (thold) {
|
||||
printf("Info: Interrupt thold = %d on line %d.\n", thold, line);
|
||||
}
|
||||
else {
|
||||
printf("Info: Interrupt disabled.\n");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
else if (strncmp(argv[1], "set-highpass", sizeof("set-highpass")) == 0) {
|
||||
uint8_t out = 0;
|
||||
uint8_t reference = atoi(argv[2]);
|
||||
if ((argc < 4) || (out = atoi(argv[3])) > 3) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contains the number of an output which gets filtered "
|
||||
"and the reference value less than 255. "
|
||||
"Possible outputs are IA1 (1) or IA2 (2) or CLICK (3) "
|
||||
"or (0) to disable the filter.");
|
||||
puts("USAGE: lis set-highpass [reference] [out_number]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (out) {
|
||||
/* enable filter for output */
|
||||
highpass_cfg.DATA_OUT_enable = 0;
|
||||
|
||||
/* enable HP for interrupt */
|
||||
if (out == 1) {
|
||||
highpass_cfg.INT1_enable = 1;
|
||||
}
|
||||
else if (out == 2) {
|
||||
highpass_cfg.INT2_enable = 1;
|
||||
}
|
||||
else {
|
||||
/* enable filter for click function */
|
||||
highpass_cfg.CLICK_enable = 1;
|
||||
}
|
||||
printf("Info: Filter set to %d on output %d.\n", reference, out);
|
||||
}
|
||||
else {
|
||||
printf("Info: Filter disabled.\n");
|
||||
}
|
||||
|
||||
lis2dh12_set_reference(&dev, reference);
|
||||
lis2dh12_set_highpass(&dev, &highpass_cfg);
|
||||
return 1;
|
||||
}
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/* change sampling rate */
|
||||
else if (strncmp(argv[1], "change_rate", sizeof("change_rate")) == 0) {
|
||||
uint8_t rate = 0;
|
||||
if ((argc < 3) || (rate = atoi(argv[2])) > 9) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain a number for sampling rate. "
|
||||
"Possible outputs are 1Hz (1), 10Hz (2), 25Hz (3), "
|
||||
"50Hz (4), 100Hz (5), 200Hz (6) or 400Hz (7).");
|
||||
puts("USAGE: lis change_rate [samplingrate]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_datarate(&dev, rate);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* change power mode */
|
||||
else if (strncmp(argv[1], "change_power", sizeof("change_power")) == 0) {
|
||||
uint8_t power = 0;
|
||||
if ((argc < 3) || (power = atoi(argv[2])) > 9) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain a number for power mode. "
|
||||
"Possible outputs are POWER_DOWN (0), POWER_LOW (1), "
|
||||
"POWER_NORMAL (2) or POWER_HIGH (3).");
|
||||
puts("USAGE: lis change_power [powermode]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_powermode(&dev, power);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* change scale value */
|
||||
else if (strncmp(argv[1], "change_scale", sizeof("change_scale")) == 0) {
|
||||
uint8_t scale = 0;
|
||||
if ((argc < 3) || (scale = atoi(argv[2])) > 3) {
|
||||
puts("Error: Missing parameter.");
|
||||
puts("The command should contain a number for scale value. "
|
||||
"Possible values are SCALE_2G (0), SCALE_4G (1), "
|
||||
"SCALE_8G (2) or SCALE_16G (3).");
|
||||
puts("USAGE: lis change_scale [scale]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_scale(&dev, scale<<4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* UNKNOWN */
|
||||
else {
|
||||
printf("Error: Unknown sub-command. %s\n", usage);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_read_fifo(int argc, char **argv)
|
||||
{
|
||||
uint8_t num = NUM_FIFO_VALUES;
|
||||
lis2dh12_fifo_data_t data[NUM_FIFO_VALUES];
|
||||
|
||||
if (argc > 1) {
|
||||
num = atoi(argv[1]);
|
||||
}
|
||||
|
||||
num = lis2dh12_read_fifo_data(&dev, data, num);
|
||||
|
||||
/* print data */
|
||||
for (unsigned i = 0; i < num; ++i) {
|
||||
|
||||
/* Memory to print current data */
|
||||
char str_out[3][8];
|
||||
|
||||
/* format data */
|
||||
for (unsigned j = 0; j < 3; ++j) {
|
||||
size_t len = fmt_s16_dfp(str_out[j], data[i].data[j], -3);
|
||||
str_out[j][len] = '\0';
|
||||
}
|
||||
|
||||
printf("[%2u] X: %6s Y: %6s Z: %6s\n", i, str_out[0], str_out[1], str_out[2]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_threshold(int argc, char **argv)
|
||||
{
|
||||
uint8_t slot;
|
||||
uint32_t mg;
|
||||
uint32_t us = 0;
|
||||
uint8_t axis = LIS2DH12_INT_CFG_XHIE
|
||||
| LIS2DH12_INT_CFG_YHIE
|
||||
| LIS2DH12_INT_CFG_ZHIE;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s <slot> <mg> [µs]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
slot = atoi(argv[1]);
|
||||
mg = atoi(argv[2]);
|
||||
|
||||
if (argc > 3) {
|
||||
us = atoi(argv[3]);
|
||||
}
|
||||
|
||||
if (slot < 1 || slot > 2) {
|
||||
puts("event slot must be either 1 or 2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_cfg_threshold_event(&dev, mg, us, axis, slot, LIS2DH12_INT1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_click(int argc, char **argv)
|
||||
{
|
||||
uint32_t mg;
|
||||
uint32_t us = 0;
|
||||
uint32_t us_delay = 0;
|
||||
uint32_t us_double = 0;
|
||||
uint8_t clicks = LIS2DH12_CLICK_X_SINGLE
|
||||
| LIS2DH12_CLICK_Y_SINGLE
|
||||
| LIS2DH12_CLICK_Z_SINGLE;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s <mg> [µs] [dead time µs] [double click µs]\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mg = atoi(argv[1]);
|
||||
|
||||
if (argc > 2) {
|
||||
us = atoi(argv[2]);
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
us_delay = atoi(argv[3]);
|
||||
}
|
||||
|
||||
if (argc > 4) {
|
||||
us_double = atoi(argv[4]);
|
||||
clicks |= clicks << 1;
|
||||
}
|
||||
|
||||
lis2dh12_cfg_click_event(&dev, mg, us, us_delay, us_double, clicks, LIS2DH12_INT1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_power(int argc, char **argv)
|
||||
{
|
||||
bool on;
|
||||
|
||||
if (argc > 1 && (!strcmp(argv[1], "on") || !strcmp(argv[1], "1"))) {
|
||||
on = true;
|
||||
} else if (argc > 1 && (!strcmp(argv[1], "off") || !strcmp(argv[1], "0"))) {
|
||||
on = false;
|
||||
} else {
|
||||
printf("usage: %s <on|off>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (on) {
|
||||
lis2dh12_poweron(&dev);
|
||||
} else {
|
||||
lis2dh12_poweroff(&dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_set_resolution(int argc, char **argv)
|
||||
{
|
||||
unsigned resolution = UINT_MAX;
|
||||
|
||||
const char* resolutions[4] = {
|
||||
"off",
|
||||
"8-bit",
|
||||
"10-bit",
|
||||
"12-bit",
|
||||
};
|
||||
|
||||
if (argc > 1) {
|
||||
resolution = atoi(argv[1]);
|
||||
} else {
|
||||
printf("current resolution: %s\n", resolutions[lis2dh12_get_resolution(&dev)]);
|
||||
}
|
||||
|
||||
if (resolution > LIS2DH12_POWER_HIGH) {
|
||||
printf("usage: %s <mode>\n", argv[0]);
|
||||
puts("where <mode> is:");
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(resolutions); ++i) {
|
||||
printf("\t%u: %s\n", i, resolutions[i]);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_resolution(&dev, resolution);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_set_rate(int argc, char **argv)
|
||||
{
|
||||
unsigned rate = UINT_MAX;
|
||||
|
||||
if (argc > 1) {
|
||||
rate = atoi(argv[1]);
|
||||
} else {
|
||||
printf("Current sampling rate: %u Hz\n", lis2dh12_get_datarate(&dev));
|
||||
}
|
||||
|
||||
if (rate > LIS2DH12_RATE_VERYHIGH) {
|
||||
printf("usage: %s <rate>\n", argv[0]);
|
||||
puts("where <rate> is:");
|
||||
puts("\t1: 1 Hz");
|
||||
puts("\t2: 10 Hz");
|
||||
puts("\t3: 25 Hz");
|
||||
puts("\t4: 50 Hz");
|
||||
puts("\t5: 100 Hz");
|
||||
puts("\t6: 200 Hz");
|
||||
puts("\t7: 400 Hz");
|
||||
puts("\t8: 1620 Hz");
|
||||
puts("\t9: 5376 Hz");
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_datarate(&dev, rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_set_scale(int argc, char **argv)
|
||||
{
|
||||
unsigned scale = UINT_MAX;
|
||||
|
||||
const uint8_t scales[] = {
|
||||
2, 4, 8, 16
|
||||
};
|
||||
|
||||
if (argc > 1) {
|
||||
scale = atoi(argv[1]);
|
||||
} else {
|
||||
printf("current range: ± %ug\n", scales[lis2dh12_get_scale(&dev)]);
|
||||
}
|
||||
|
||||
if (scale > LIS2DH12_SCALE_16G) {
|
||||
printf("usage: %s <scale>\n", argv[0]);
|
||||
puts("where <scale> is:");
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(scales); ++i) {
|
||||
printf("\t%u: ± %ug\n", i, scales[i]);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
lis2dh12_set_scale(&dev, scale);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_is2dh12_read_temp(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
int16_t temp;
|
||||
lis2dh12_read_temperature(&dev, &temp);
|
||||
|
||||
printf("%d.%02d °C\n", temp / 100, temp % 100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const shell_command_t shell_commands[] = {
|
||||
{ "read", "Read acceleration data", shell_is2dh12_read },
|
||||
{ "read_fifo", "Read acceleration data from fifo", shell_is2dh12_read_fifo },
|
||||
{ "threshold", "Configure threshold event", shell_is2dh12_threshold },
|
||||
{ "click", "Configure click event", shell_is2dh12_click },
|
||||
{ "power", "Enable / Disable the sensor", shell_is2dh12_power },
|
||||
{ "resolution", "Get/Set resolution", shell_is2dh12_set_resolution },
|
||||
{ "rate", "Get/Set sampline rate", shell_is2dh12_set_rate },
|
||||
{ "scale", "Get/Set measuring range", shell_is2dh12_set_scale },
|
||||
{ "temp", "Read temperature data", shell_is2dh12_read_temp },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
/* processing lis2dh12 acceleration data */
|
||||
lis2dh12_process = thread_create(lis2dh12_process_stack, sizeof(lis2dh12_process_stack),
|
||||
THREAD_PRIORITY_MAIN - 1, THREAD_CREATE_SLEEPING,
|
||||
lis2dh12_test_process, NULL, "lis2dh12_process");
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/* init lis */
|
||||
lis2dh12_test_init();
|
||||
|
||||
#ifdef MODULE_LIS2DH12_INT
|
||||
static char lis2dh12_process_stack[THREAD_STACKSIZE_MAIN];
|
||||
|
||||
/* processing lis2dh12 acceleration data */
|
||||
thread_create(lis2dh12_process_stack, sizeof(lis2dh12_process_stack),
|
||||
THREAD_PRIORITY_MAIN - 1, THREAD_CREATE_STACKTEST,
|
||||
lis2dh12_test_process, NULL, "lis2dh12_process");
|
||||
#endif /* MODULE_LIS2DH12_INT */
|
||||
|
||||
/* running shell */
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
Loading…
Reference in New Issue
Block a user