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
|
* @brief Available scale values
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LIS2DH12_SCALE_2G = 0x00, /**< +- 2g */
|
LIS2DH12_SCALE_2G = 0x0, /**< +- 2g */
|
||||||
LIS2DH12_SCALE_4G = 0x10, /**< +- 4g */
|
LIS2DH12_SCALE_4G = 0x1, /**< +- 4g */
|
||||||
LIS2DH12_SCALE_8G = 0x20, /**< +- 8g */
|
LIS2DH12_SCALE_8G = 0x2, /**< +- 8g */
|
||||||
LIS2DH12_SCALE_16G = 0x30, /**< +- 16g */
|
LIS2DH12_SCALE_16G = 0x3, /**< +- 16g */
|
||||||
} lis2dh12_scale_t;
|
} lis2dh12_scale_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -74,28 +74,35 @@ typedef enum {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LIS2DH12_RATE_1HZ = 0x1, /**< sample with 1Hz @ all power modes */
|
LIS2DH12_RATE_1HZ = 0x1, /**< sample with 1Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_10HZ = 0x2, /**< sample with 10Hz @ all power modes */
|
LIS2DH12_RATE_10HZ = 0x2, /**< sample with 10Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_25HZ = 0x3, /**< sample with 25Hz @ all power modes */
|
LIS2DH12_RATE_25HZ = 0x3, /**< sample with 25Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_50HZ = 0x4, /**< sample with 50Hz @ all power modes */
|
LIS2DH12_RATE_50HZ = 0x4, /**< sample with 50Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_100HZ = 0x5, /**< sample with 100Hz @ all power modes */
|
LIS2DH12_RATE_100HZ = 0x5, /**< sample with 100Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_200HZ = 0x6, /**< sample with 200Hz @ all power modes */
|
LIS2DH12_RATE_200HZ = 0x6, /**< sample with 200Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_400HZ = 0x7, /**< sample with 400Hz @ all power modes */
|
LIS2DH12_RATE_400HZ = 0x7, /**< sample with 400Hz @ all resolutions */
|
||||||
LIS2DH12_RATE_1620HZ = 0x8, /**< sample with 1620HZ @ Low Power*/
|
LIS2DH12_RATE_1620HZ = 0x8, /**< sample with 1620HZ @ 8-bit */
|
||||||
LIS2DH12_RATE_VERYHIGH = 0x9, /**< sample with 1344Hz @ High resolution or \
|
LIS2DH12_RATE_VERYHIGH = 0x9, /**< sample with 1344Hz @ High resolution or \
|
||||||
5376Hz @ Low Power*/
|
5376Hz @ 8-bit */
|
||||||
} lis2dh12_rate_t;
|
} lis2dh12_rate_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Available power modes
|
* @brief Available resolutions
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LIS2DH12_POWER_DOWN = 0, /**< power down the device */
|
LIS2DH12_POWER_DOWN = 0, /**< power down the device */
|
||||||
LIS2DH12_POWER_LOW = 1, /**< low power mode */
|
LIS2DH12_POWER_LOW = 1, /**< 8-bit mode */
|
||||||
LIS2DH12_POWER_NORMAL = 2, /**< normal mode */
|
LIS2DH12_POWER_NORMAL = 2, /**< 10-bit mode */
|
||||||
LIS2DH12_POWER_HIGH = 3, /**< high resolution */
|
LIS2DH12_POWER_HIGH = 3, /**< 12-bit mode */
|
||||||
} lis2dh12_powermode_t;
|
} 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
|
* @brief LIS2DH12 configuration parameters
|
||||||
@ -114,7 +121,7 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
lis2dh12_scale_t scale; /**< sampling sensitivity used */
|
lis2dh12_scale_t scale; /**< sampling sensitivity used */
|
||||||
lis2dh12_rate_t rate; /**< sampling rate used */
|
lis2dh12_rate_t rate; /**< sampling rate used */
|
||||||
lis2dh12_powermode_t powermode; /**< power mode used*/
|
lis2dh12_resolution_t resolution; /**< resolution used */
|
||||||
} lis2dh12_params_t;
|
} lis2dh12_params_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -170,7 +177,6 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const lis2dh12_params_t *p; /**< device configuration */
|
const lis2dh12_params_t *p; /**< device configuration */
|
||||||
uint8_t comp; /**< scale compensation factor */
|
|
||||||
} lis2dh12_t;
|
} lis2dh12_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,7 +191,6 @@ enum {
|
|||||||
LIS2DH12_NODATA= -4, /**< no data available */
|
LIS2DH12_NODATA= -4, /**< no data available */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if MODULE_LIS2DH12_INT || DOXYGEN
|
|
||||||
/*
|
/*
|
||||||
* @brief Interrupt lines
|
* @brief Interrupt lines
|
||||||
*/
|
*/
|
||||||
@ -204,18 +209,18 @@ typedef struct {
|
|||||||
uint8_t int_duration:7; /**< time between two interrupts ODR section in CTRL_REG1,
|
uint8_t int_duration:7; /**< time between two interrupts ODR section in CTRL_REG1,
|
||||||
duration in range 0-127 */
|
duration in range 0-127 */
|
||||||
uint8_t int_type; /**< values for type of interrupts */
|
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;
|
} lis2dh12_int_params_t;
|
||||||
#endif /* MODULE_LIS2DH12_INT */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief LIS2DH12 FIFO data struct
|
* @brief LIS2DH12 FIFO data struct
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef union {
|
||||||
int16_t X_AXIS; /**< X raw data in FIFO */
|
struct {
|
||||||
int16_t Y_AXIS; /**< Y raw data in FIFO */
|
int16_t x; /**< X data in mili-g */
|
||||||
int16_t Z_AXIS; /**< Z raw data in FIFO */
|
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;
|
} lis2dh12_fifo_data_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -239,33 +244,74 @@ typedef struct {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Export the SAUL interface for this driver
|
* @brief Export the SAUL interface for this driver
|
||||||
|
* @{
|
||||||
*/
|
*/
|
||||||
extern const saul_driver_t lis2dh12_saul_driver;
|
extern const saul_driver_t lis2dh12_saul_driver;
|
||||||
|
extern const saul_driver_t lis2dh12_saul_temp_driver;
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#if MODULE_LIS2DH12_INT || DOXYGEN
|
#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] dev device descriptor
|
||||||
* @param[in] params device interrupt configuration
|
* @param[in] mg acceleration in mg
|
||||||
* @param[in] int_line number of interrupt line (LIS2DH12_INT1 or LIS2DH12_INT2)
|
* @param[in] us time in µs for which the threshold must be exceeded
|
||||||
*
|
* @param[in] axis bitmap of axis / events to be monitored
|
||||||
* @return LIS2DH12_OK on success
|
* @param[in] event Event slot (1 or 2)
|
||||||
* @return LIS2DH12_NOBUS on bus errors
|
* @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] dev device descriptor
|
||||||
* @param[out] data device interrupt data
|
* @param[in] mg acceleration in mg
|
||||||
* @param[in] int_line number of interrupt line (LIS2DH12_INT1 or LIS2DH12_INT2)
|
* @param[in] us_limit upper limit for click duration in µs
|
||||||
*
|
* @param[in] us_latency dead time after click event in µs
|
||||||
* @return LIS2DH12_OK on success
|
* @param[in] us_window time after @p us_latency in which the second click event
|
||||||
* @return LIS2DH12_NOBUS on bus errors
|
* 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)
|
||||||
*/
|
*/
|
||||||
int lis2dh12_read_int_src(const lis2dh12_t *dev, uint8_t *data, uint8_t int_line);
|
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[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 negative error
|
||||||
|
* @return positive LIS2DH12_INT_SRC bit mask on success
|
||||||
|
*/
|
||||||
|
int lis2dh12_wait_event(const lis2dh12_t *dev, uint8_t pin, bool stale_events);
|
||||||
#endif /* MODULE_LIS2DH12_INT */
|
#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);
|
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
|
* @brief This function will read a given number of data from FIFO
|
||||||
* reads amount of data that is available in 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
|
* @brief Read acceleration data from the given device
|
||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @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_OK on success
|
||||||
* @return LIS2DH12_NOBUS on bus error
|
* @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
|
* @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);
|
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] dev device descriptor
|
||||||
* @param[in] scale change to given scale value
|
* @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);
|
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
|
* @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);
|
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
|
* @param[in] dev device descriptor
|
||||||
* @param[in] powermode change to given power mode
|
*
|
||||||
|
* @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] resolution change to given resolution
|
||||||
*
|
*
|
||||||
* @return LIS2DH12_OK on success
|
* @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
|
* @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);
|
int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read the reference value
|
* @brief Power on the given device and resets resolution and sampling rate
|
||||||
*
|
|
||||||
* @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
|
|
||||||
* to default values in the device descriptor parameters
|
* to default values in the device descriptor parameters
|
||||||
*
|
*
|
||||||
* @param[in] dev device descriptor
|
* @param[in] dev device descriptor
|
||||||
|
|||||||
@ -67,8 +67,8 @@ extern "C" {
|
|||||||
#ifndef LIS2DH12_PARAM_RATE
|
#ifndef LIS2DH12_PARAM_RATE
|
||||||
#define LIS2DH12_PARAM_RATE LIS2DH12_RATE_100HZ
|
#define LIS2DH12_PARAM_RATE LIS2DH12_RATE_100HZ
|
||||||
#endif
|
#endif
|
||||||
#ifndef LIS2DH12_PARAM_POWERMODE
|
#ifndef LIS2DH12_PARAM_RESOLUTION
|
||||||
#define LIS2DH12_PARAM_POWERMODE LIS2DH12_POWER_NORMAL
|
#define LIS2DH12_PARAM_RESOLUTION LIS2DH12_POWER_NORMAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LIS2DH12_PARAMS
|
#ifndef LIS2DH12_PARAMS
|
||||||
@ -79,14 +79,14 @@ extern "C" {
|
|||||||
.int2_pin = LIS2DH12_PARAM_INT_PIN2, \
|
.int2_pin = LIS2DH12_PARAM_INT_PIN2, \
|
||||||
.scale = LIS2DH12_PARAM_SCALE, \
|
.scale = LIS2DH12_PARAM_SCALE, \
|
||||||
.rate = LIS2DH12_PARAM_RATE, \
|
.rate = LIS2DH12_PARAM_RATE, \
|
||||||
.powermode = LIS2DH12_PARAM_POWERMODE, \
|
.resolution = LIS2DH12_PARAM_RESOLUTION, \
|
||||||
}
|
}
|
||||||
#else /* MODULE_LIS2DH12_INT */
|
#else /* MODULE_LIS2DH12_INT */
|
||||||
#define LIS2DH12_PARAMS { \
|
#define LIS2DH12_PARAMS { \
|
||||||
LIS2DH12_PARAMS_BUSCFG, \
|
LIS2DH12_PARAMS_BUSCFG, \
|
||||||
.scale = LIS2DH12_PARAM_SCALE, \
|
.scale = LIS2DH12_PARAM_SCALE, \
|
||||||
.rate = LIS2DH12_PARAM_RATE, \
|
.rate = LIS2DH12_PARAM_RATE, \
|
||||||
.powermode = LIS2DH12_PARAM_POWERMODE, \
|
.resolution = LIS2DH12_PARAM_RESOLUTION, \
|
||||||
}
|
}
|
||||||
#endif /* MODULE_LIS2DH12_INT */
|
#endif /* MODULE_LIS2DH12_INT */
|
||||||
#endif /* LIS2DH12_PARAMS */
|
#endif /* LIS2DH12_PARAMS */
|
||||||
|
|||||||
@ -33,6 +33,14 @@ enum {
|
|||||||
LIS2DH12_STATUS_REG_AUX_TOR = 0x40, /**< Temperature data overrun */
|
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
|
* @brief STATUS_REG definitions
|
||||||
*/
|
*/
|
||||||
@ -94,8 +102,36 @@ enum {
|
|||||||
LIS2DH12_INT_TYPE_I2_IA2 = 0x20, /**< IA2 on INT2 */
|
LIS2DH12_INT_TYPE_I2_IA2 = 0x20, /**< IA2 on INT2 */
|
||||||
LIS2DH12_INT_TYPE_I2_IA1 = 0x40, /**< IA1 on INT2 */
|
LIS2DH12_INT_TYPE_I2_IA1 = 0x40, /**< IA1 on INT2 */
|
||||||
LIS2DH12_INT_TYPE_I2_CLICK = 0x80, /**< click interrupt 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
|
* @brief CLICK_SRC definitions
|
||||||
*/
|
*/
|
||||||
@ -169,6 +205,13 @@ typedef union {
|
|||||||
uint8_t reg; /**< Type used for register access */
|
uint8_t reg; /**< Type used for register access */
|
||||||
} LIS2DH12_CTRL_REG1_t;
|
} 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
|
* @brief CTRL_REG2 definitions
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -14,10 +14,16 @@
|
|||||||
* @brief LIS2DH12 accelerometer driver implementation
|
* @brief LIS2DH12 accelerometer driver implementation
|
||||||
*
|
*
|
||||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
* @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 "assert.h"
|
||||||
|
#include "byteorder.h"
|
||||||
|
#include "mutex.h"
|
||||||
|
#include "timex.h"
|
||||||
|
#include "xtimer.h"
|
||||||
|
|
||||||
#include "lis2dh12.h"
|
#include "lis2dh12.h"
|
||||||
#include "lis2dh12_internal.h"
|
#include "lis2dh12_internal.h"
|
||||||
@ -113,8 +119,7 @@ static uint8_t _read(const lis2dh12_t *dev, uint8_t reg)
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _read_burst(const lis2dh12_t *dev, uint8_t reg,
|
static void _read_burst(const lis2dh12_t *dev, uint8_t reg, void *data, size_t len)
|
||||||
void *data, size_t len)
|
|
||||||
{
|
{
|
||||||
i2c_read_regs(BUS, ADDR, (FLAG_AINC | reg), data, len, 0);
|
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 */
|
#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)
|
int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
||||||
{
|
{
|
||||||
assert(dev && params);
|
assert(dev && params);
|
||||||
|
|
||||||
dev->p = params;
|
dev->p = params;
|
||||||
/* calculate shift amount to convert raw acceleration data */
|
|
||||||
dev->comp = 4 - (dev->p->scale >> 4);
|
|
||||||
|
|
||||||
/* initialize the chip select line */
|
/* initialize the chip select line */
|
||||||
if (_init_bus(dev) != LIS2DH12_OK) {
|
if (_init_bus(dev) != LIS2DH12_OK) {
|
||||||
@ -141,6 +150,15 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params)
|
|||||||
return LIS2DH12_NOBUS;
|
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 */
|
/* acquire the bus and verify that our parameters are valid */
|
||||||
if (_acquire(dev) != BUS_OK) {
|
if (_acquire(dev) != BUS_OK) {
|
||||||
DEBUG("[lis2dh12] error: unable to acquire the bus\n");
|
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;
|
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 */
|
/* enable all axes, set sampling rate and scale */
|
||||||
LIS2DH12_CTRL_REG1_t reg1 = {0};
|
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.Yen = 1;
|
||||||
reg1.bit.Zen = 1;
|
reg1.bit.Zen = 1;
|
||||||
|
|
||||||
_write(dev, REG_CTRL_REG4, dev->p->scale);
|
|
||||||
_write(dev, REG_CTRL_REG1, reg1.reg);
|
_write(dev, REG_CTRL_REG1, reg1.reg);
|
||||||
|
|
||||||
_release(dev);
|
/* enable block data update */
|
||||||
|
_write(dev, REG_CTRL_REG4, 0x80);
|
||||||
|
|
||||||
/* set powermode */
|
_release(dev);
|
||||||
lis2dh12_set_powermode(dev, dev->p->powermode);
|
|
||||||
|
|
||||||
DEBUG("[lis2dh12] initialization successful\n");
|
DEBUG("[lis2dh12] initialization successful\n");
|
||||||
return LIS2DH12_OK;
|
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);
|
assert(dev && data);
|
||||||
|
|
||||||
/* allocate 6 byte to save the 6 RAW data registers */
|
|
||||||
uint8_t raw[6];
|
|
||||||
|
|
||||||
/* read sampled data from the device */
|
/* read sampled data from the device */
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
|
|
||||||
|
uint8_t comp = 4 - ((_read(dev, REG_CTRL_REG4) >> 4) & 0x3);
|
||||||
|
|
||||||
/* first check if valid data is available */
|
/* first check if valid data is available */
|
||||||
if ((_read(dev, REG_STATUS_REG) & LIS2DH12_STATUS_REG_ZYXDA) == 0) {
|
if ((_read(dev, REG_STATUS_REG) & LIS2DH12_STATUS_REG_ZYXDA) == 0) {
|
||||||
_release(dev);
|
_release(dev);
|
||||||
return LIS2DH12_NODATA;
|
return LIS2DH12_NODATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
_read_burst(dev, REG_OUT_X_L, raw, 6);
|
_get_fifo_data(dev, data, comp);
|
||||||
_release(dev);
|
_release(dev);
|
||||||
|
|
||||||
/* calculate the actual g-values for the x, y, and z dimension */
|
return LIS2DH12_OK;
|
||||||
for (int i = 0; i < 3; i++) {
|
}
|
||||||
data[i] = (int16_t)((raw[i*2 + 1] << 8) | raw[i*2]) >> dev->comp;
|
|
||||||
|
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
|
#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);
|
mutex_unlock(lock);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
uint32_t int_src = 0;
|
||||||
assert(int_line == LIS2DH12_INT1 || int_line == LIS2DH12_INT2);
|
|
||||||
|
/* 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);
|
_acquire(dev);
|
||||||
|
|
||||||
switch (int_line) {
|
/* find out which events are configured */
|
||||||
/* first interrupt line (INT1) */
|
if (line == LIS2DH12_INT1) {
|
||||||
case LIS2DH12_INT1:
|
events = _read(dev, REG_CTRL_REG3);
|
||||||
*data = _read(dev, REG_INT1_SRC);
|
|
||||||
break;
|
|
||||||
/* second interrupt line (INT2) */
|
|
||||||
case LIS2DH12_INT2:
|
|
||||||
*data = _read(dev, REG_INT2_SRC);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (line == LIS2DH12_INT2) {
|
||||||
|
events = _read(dev, REG_CTRL_REG6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for stale interrupt */
|
||||||
|
int_src = _merge_int_flags(dev, events);
|
||||||
|
|
||||||
_release(dev);
|
_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 */
|
#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);
|
assert(dev && config);
|
||||||
|
|
||||||
LIS2DH12_CTRL_REG5_t reg5 = {0};
|
LIS2DH12_CTRL_REG5_t reg5 = {0};
|
||||||
LIS2DH12_FIFO_CTRL_REG_t fifo_reg = {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) {
|
if (config->FIFO_mode != LIS2DH12_FIFO_MODE_BYPASS) {
|
||||||
reg5.bit.FIFO_EN = 1;
|
reg5.bit.FIFO_EN = 1;
|
||||||
|
} else {
|
||||||
|
reg5.bit.FIFO_EN = 0;
|
||||||
}
|
}
|
||||||
fifo_reg.bit.TR = config->FIFO_set_INT2;
|
fifo_reg.bit.TR = config->FIFO_set_INT2;
|
||||||
fifo_reg.bit.FM = config->FIFO_mode;
|
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;
|
return LIS2DH12_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lis2dh12_restart_fifo(const lis2dh12_t *dev) {
|
int lis2dh12_restart_fifo(const lis2dh12_t *dev)
|
||||||
|
{
|
||||||
|
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
uint8_t reg5 = _read(dev, REG_CTRL_REG5);
|
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);
|
fifo_reg.reg = _read(dev, REG_FIFO_CTRL_REG);
|
||||||
|
|
||||||
uint8_t fifo_mode_old = fifo_reg.bit.FM;
|
uint8_t fifo_mode_old = fifo_reg.bit.FM;
|
||||||
@ -318,45 +536,28 @@ int lis2dh12_restart_fifo(const lis2dh12_t *dev) {
|
|||||||
return LIS2DH12_OK;
|
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 lis2dh12_read_fifo_data(const lis2dh12_t *dev, lis2dh12_fifo_data_t *fifo_data,
|
||||||
uint8_t number) {
|
uint8_t number)
|
||||||
|
{
|
||||||
assert(dev && fifo_data);
|
assert(dev && fifo_data);
|
||||||
/* check max FIFO length */
|
/* check max FIFO length */
|
||||||
assert(number <= 32);
|
assert(number <= 32);
|
||||||
|
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
|
|
||||||
/* check if number is available */
|
/* 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);
|
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;
|
number = src_reg.bit.FSS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src_reg.bit.EMPTY) {
|
uint8_t comp = 4 - ((_read(dev, REG_CTRL_REG4) >> 4) & 0x3);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate X, Y and Z values */
|
/* calculate X, Y and Z values */
|
||||||
for (uint8_t i = 0; i < number; i++){
|
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))
|
_get_fifo_data(dev, &fifo_data[i], comp);
|
||||||
>> 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_release(dev);
|
_release(dev);
|
||||||
@ -364,12 +565,16 @@ uint8_t lis2dh12_read_fifo_data(const lis2dh12_t *dev, lis2dh12_fifo_data_t *fif
|
|||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lis2dh12_clear_data(const lis2dh12_t *dev) {
|
int lis2dh12_clear_data(const lis2dh12_t *dev)
|
||||||
|
{
|
||||||
|
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
LIS2DH12_CTRL_REG5_t ctrl_reg5 = {0};
|
LIS2DH12_CTRL_REG5_t ctrl_reg5 = {
|
||||||
ctrl_reg5.bit.BOOT = 1;
|
.bit.BOOT = 1,
|
||||||
|
.bit.LIR_INT1 = 1,
|
||||||
|
.bit.LIR_INT2 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
_write(dev, REG_CTRL_REG5, ctrl_reg5.reg);
|
_write(dev, REG_CTRL_REG5, ctrl_reg5.reg);
|
||||||
@ -378,7 +583,32 @@ int lis2dh12_clear_data(const lis2dh12_t *dev) {
|
|||||||
return LIS2DH12_OK;
|
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);
|
assert(dev);
|
||||||
|
|
||||||
@ -389,18 +619,8 @@ int lis2dh12_set_reference(const lis2dh12_t *dev, uint8_t reference) {
|
|||||||
return LIS2DH12_OK;
|
return LIS2DH12_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lis2dh12_read_reference(const lis2dh12_t *dev, uint8_t *data) {
|
int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *config)
|
||||||
|
{
|
||||||
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) {
|
|
||||||
|
|
||||||
assert(dev && config);
|
assert(dev && config);
|
||||||
|
|
||||||
@ -420,67 +640,27 @@ int lis2dh12_set_highpass(const lis2dh12_t *dev, const lis2dh12_highpass_t *conf
|
|||||||
return LIS2DH12_OK;
|
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);
|
assert(dev);
|
||||||
|
|
||||||
LIS2DH12_CLICK_CFG_t click_CFG = {0};
|
LIS2DH12_CTRL_REG1_t reg1;
|
||||||
if (config->enable_DOUBLE) {
|
LIS2DH12_CTRL_REG4_t reg4;
|
||||||
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};
|
|
||||||
|
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||||
|
|
||||||
/* set power mode */
|
/* set power mode */
|
||||||
if (powermode == LIS2DH12_POWER_LOW) {
|
if (resolution == LIS2DH12_POWER_LOW) {
|
||||||
reg1.bit.LPen = 1;
|
reg1.bit.LPen = 1;
|
||||||
reg4.bit.HR = 0;
|
reg4.bit.HR = 0;
|
||||||
}
|
}
|
||||||
else if (powermode == LIS2DH12_POWER_HIGH) {
|
else if (resolution == LIS2DH12_POWER_HIGH) {
|
||||||
reg1.bit.LPen = 0;
|
reg1.bit.LPen = 0;
|
||||||
reg4.bit.HR = 1;
|
reg4.bit.HR = 1;
|
||||||
}
|
}
|
||||||
else if (powermode == LIS2DH12_POWER_NORMAL) {
|
else if (resolution == LIS2DH12_POWER_NORMAL) {
|
||||||
reg1.bit.LPen = 0;
|
reg1.bit.LPen = 0;
|
||||||
reg4.bit.HR = 0;
|
reg4.bit.HR = 0;
|
||||||
}
|
}
|
||||||
@ -495,51 +675,125 @@ int lis2dh12_set_powermode(const lis2dh12_t *dev, lis2dh12_powermode_t powermode
|
|||||||
return LIS2DH12_OK;
|
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(dev);
|
||||||
assert(rate <= 0x9);
|
assert(rate <= 0x9);
|
||||||
|
|
||||||
LIS2DH12_CTRL_REG1_t reg1 = {0};
|
LIS2DH12_CTRL_REG1_t reg1;
|
||||||
|
|
||||||
_acquire(dev);
|
_acquire(dev);
|
||||||
reg1.reg = _read(dev, REG_CTRL_REG1);
|
reg1.reg = _read(dev, REG_CTRL_REG1);
|
||||||
|
|
||||||
reg1.bit.ODR = rate;
|
reg1.bit.ODR = rate;
|
||||||
|
|
||||||
_write(dev, REG_CTRL_REG1, reg1.reg);
|
_write(dev, REG_CTRL_REG1, reg1.reg);
|
||||||
_release(dev);
|
_release(dev);
|
||||||
|
|
||||||
return LIS2DH12_OK;
|
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(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);
|
_acquire(dev);
|
||||||
reg4.reg = _read(dev, REG_CTRL_REG4);
|
reg4.reg = _read(dev, REG_CTRL_REG4);
|
||||||
|
reg4.bit.FS = scale;
|
||||||
reg4.bit.FS = scale >> 4;
|
|
||||||
|
|
||||||
_write(dev, REG_CTRL_REG4, reg4.reg);
|
_write(dev, REG_CTRL_REG4, reg4.reg);
|
||||||
_release(dev);
|
_release(dev);
|
||||||
|
|
||||||
dev->comp = 4 - (scale >> 4);
|
|
||||||
|
|
||||||
return LIS2DH12_OK;
|
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)
|
int lis2dh12_poweron(const lis2dh12_t *dev)
|
||||||
{
|
{
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
/* set default param values */
|
/* set default param values */
|
||||||
lis2dh12_set_datarate(dev, dev->p->rate);
|
lis2dh12_set_datarate(dev, dev->p->rate);
|
||||||
lis2dh12_set_powermode(dev, dev->p->powermode);
|
lis2dh12_set_resolution(dev, dev->p->resolution);
|
||||||
|
|
||||||
return LIS2DH12_OK;
|
return LIS2DH12_OK;
|
||||||
}
|
}
|
||||||
@ -551,5 +805,10 @@ int lis2dh12_poweroff(const lis2dh12_t *dev)
|
|||||||
/* set datarate to zero */
|
/* set datarate to zero */
|
||||||
lis2dh12_set_datarate(dev, 0);
|
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;
|
return LIS2DH12_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
static int read_accelerometer(const void *dev, phydat_t *res)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
res->unit = UNIT_G;
|
res->unit = UNIT_G;
|
||||||
@ -31,8 +31,25 @@ static int read_accelerometer(const void *dev, phydat_t *res)
|
|||||||
return 3;
|
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 = {
|
const saul_driver_t lis2dh12_saul_driver = {
|
||||||
.read = read_accelerometer,
|
.read = read_accelerometer,
|
||||||
.write = saul_notsup,
|
.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)
|
#define LIS2DH12_NUM ARRAY_SIZE(lis2dh12_params)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Number of defined SAUL registry info entries
|
* @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
|
* @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)
|
void auto_init_lis2dh12(void)
|
||||||
{
|
{
|
||||||
@ -62,9 +61,14 @@ void auto_init_lis2dh12(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
saul_entries[i].dev = &(lis2dh12_devs[i]);
|
saul_entries[2 * i].dev = &lis2dh12_devs[i];
|
||||||
saul_entries[i].name = lis2dh12_saul_info[i].name;
|
saul_entries[2 * i].name = lis2dh12_saul_info[i].name;
|
||||||
saul_entries[i].driver = &lis2dh12_saul_driver;
|
saul_entries[2 * i].driver = &lis2dh12_saul_driver;
|
||||||
saul_reg_add(&(saul_entries[i]));
|
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 += fmt
|
||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
|
USEMODULE += shell_commands
|
||||||
USEMODULE += $(DRIVER)
|
USEMODULE += $(DRIVER)
|
||||||
|
|
||||||
# for using lis2dh12 with interrupt function
|
# for using lis2dh12 with interrupt function
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
CONFIG_MODULE_FMT=y
|
CONFIG_MODULE_FMT=y
|
||||||
CONFIG_MODULE_XTIMER=y
|
CONFIG_MODULE_XTIMER=y
|
||||||
CONFIG_MODULE_SHELL=y
|
CONFIG_MODULE_SHELL=y
|
||||||
|
CONFIG_MODULE_SHELL_COMMANDS=y
|
||||||
CONFIG_MODULE_LIS2DH12=y
|
CONFIG_MODULE_LIS2DH12=y
|
||||||
CONFIG_MODULE_LIS2DH12_SPI=y
|
CONFIG_MODULE_LIS2DH12_SPI=y
|
||||||
|
|
||||||
|
|||||||
@ -14,13 +14,15 @@
|
|||||||
* @brief Test application for LIS2DH12 accelerometer driver
|
* @brief Test application for LIS2DH12 accelerometer driver
|
||||||
*
|
*
|
||||||
* @author Jan Mohr <jan.mohr@ml-pa.com>
|
* @author Jan Mohr <jan.mohr@ml-pa.com>
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
#include "string.h"
|
#include <string.h>
|
||||||
#include "stdlib.h"
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "xtimer.h"
|
#include "xtimer.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -33,129 +35,12 @@
|
|||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#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 */
|
/* device specific */
|
||||||
#define NUM_AXES 3
|
|
||||||
#define NUM_FIFO_VALUES 32
|
#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 */
|
/* allocate device descriptor */
|
||||||
static lis2dh12_t dev;
|
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) {
|
void lis2dh12_test_init(void) {
|
||||||
|
|
||||||
if (IS_USED(MODULE_LIS2DH12_SPI)) {
|
if (IS_USED(MODULE_LIS2DH12_SPI)) {
|
||||||
@ -173,534 +58,320 @@ void lis2dh12_test_init(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* change LIS settings */
|
/* 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_datarate(&dev, LIS2DH12_RATE_100HZ);
|
||||||
lis2dh12_set_scale(&dev, LIS2DH12_SCALE_4G);
|
lis2dh12_set_scale(&dev, LIS2DH12_SCALE_16G);
|
||||||
|
|
||||||
#ifdef MODULE_LIS2DH12_INT
|
/* configure FIFO */
|
||||||
/* set interrupt pins */
|
lis2dh12_fifo_t fifo_cfg = {
|
||||||
gpio_t pin1 = dev.p->int1_pin;
|
.FIFO_mode = LIS2DH12_FIFO_MODE_STREAM,
|
||||||
gpio_t pin2 = dev.p->int2_pin;
|
};
|
||||||
|
|
||||||
/* 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);
|
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
|
#ifdef MODULE_LIS2DH12_INT
|
||||||
void* lis2dh12_test_process(void* arg) {
|
void* lis2dh12_test_process(void* arg) {
|
||||||
(void) arg;
|
(void) arg;
|
||||||
while (1) {
|
|
||||||
/* start processing */
|
/* start processing */
|
||||||
DEBUG("[Process]: start process\n");
|
DEBUG("[Process]: start process\n");
|
||||||
|
|
||||||
/* read FIFO_src before getting data */
|
while (1) {
|
||||||
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);
|
|
||||||
|
|
||||||
/* get fifo data */
|
/* wait for interrupt */
|
||||||
uint8_t number_read = lis2dh12_read_fifo_data(&dev, data_fifo, NUM_FIFO_VALUES);
|
int int1_src = lis2dh12_wait_event(&dev, LIS2DH12_INT1, false);
|
||||||
|
|
||||||
/* read FIFO_src after getting data */
|
if (int1_src <= 0) {
|
||||||
lis2dh12_read_fifo_src(&dev, &fifo_src);
|
printf("error: %d\n", int1_src);
|
||||||
DEBUG("[Process]: FIFO SRC 0x%x\n", fifo_src.reg);
|
continue;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* After the Interrupt the FIFO needs to be enabled again. */
|
if (LIS2DH12_INT_SRC_1(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||||
lis2dh12_restart_fifo(&dev);
|
puts("event 1");
|
||||||
|
|
||||||
/* 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 (LIS2DH12_INT_SRC_2(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||||
if (max_data_Y <= abs_Y) {
|
puts("event 2");
|
||||||
max_data_Y = abs_Y;
|
|
||||||
Y_shock_pos = (data_fifo[entry].Y_AXIS >= 0);
|
|
||||||
}
|
}
|
||||||
/* check Z shock direction */
|
if (LIS2DH12_INT_SRC_CLICK(int1_src) & LIS2DH12_INT_SRC_IA) {
|
||||||
if (max_data_Z <= abs_Z) {
|
puts("click event");
|
||||||
max_data_Z = abs_Z;
|
|
||||||
Z_shock_pos = (data_fifo[entry].Z_AXIS >= 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* 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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /* MODULE_LIS2DH12_INT */
|
#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] : "",
|
lis2dh12_fifo_data_t data;
|
||||||
(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 */
|
|
||||||
|
|
||||||
/* MISSING command */
|
lis2dh12_read(&dev, &data);
|
||||||
if (argc < 2) {
|
|
||||||
printf("Error: Missing sub-command. %s\n", usage);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enable disable device */
|
/* Memory to print current data */
|
||||||
else if (strncmp(argv[1], "enable", sizeof("enable")) == 0) {
|
char str_out[3][8];
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
/* format data */
|
||||||
for (int i = 0; i < 3; i++) {
|
for (unsigned j = 0; j < 3; ++j) {
|
||||||
size_t len = fmt_s16_dfp(str_out[i], data_lis[i], -3);
|
size_t len = fmt_s16_dfp(str_out[j], data.data[j], -3);
|
||||||
str_out[i][len] = '\0';
|
str_out[j][len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* print data to STDIO */
|
|
||||||
printf("X: %6s Y: %6s Z: %6s\n", str_out[0], str_out[1], str_out[2]);
|
printf("X: %6s Y: %6s Z: %6s\n", str_out[0], str_out[1], str_out[2]);
|
||||||
|
|
||||||
xtimer_msleep(250);
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
static int shell_is2dh12_read_fifo(int argc, char **argv)
|
||||||
else if (strncmp(argv[1], "read_fifo", sizeof("read_fifo")) == 0) {
|
{
|
||||||
uint8_t number = 0;
|
uint8_t num = NUM_FIFO_VALUES;
|
||||||
if ((argc < 3) || (number = atoi(argv[2])) > 32) {
|
lis2dh12_fifo_data_t data[NUM_FIFO_VALUES];
|
||||||
puts("Error: Missing parameter.");
|
|
||||||
puts("The command should contain number of FIFO values to read (max. 32)).");
|
if (argc > 1) {
|
||||||
puts("USAGE: lis read_fifo [number]");
|
num = atoi(argv[1]);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read raw data from FIFO */
|
num = lis2dh12_read_fifo_data(&dev, data, num);
|
||||||
uint8_t number_read = lis2dh12_read_fifo_data(&dev, data_fifo, number);
|
|
||||||
|
|
||||||
DEBUG("[lis_command]: fifo_read %d elements.\n", number_read);
|
|
||||||
|
|
||||||
/* print data */
|
/* print data */
|
||||||
for (int entry = 0; entry < number_read; entry++){
|
for (unsigned i = 0; i < num; ++i) {
|
||||||
|
|
||||||
|
/* Memory to print current data */
|
||||||
|
char str_out[3][8];
|
||||||
|
|
||||||
/* format data */
|
/* format data */
|
||||||
size_t len = fmt_s16_dfp(str_out[0], data_fifo[entry].X_AXIS, -3);
|
for (unsigned j = 0; j < 3; ++j) {
|
||||||
str_out[0][len] = '\0';
|
size_t len = fmt_s16_dfp(str_out[j], data[i].data[j], -3);
|
||||||
len = fmt_s16_dfp(str_out[1], data_fifo[entry].Y_AXIS, -3);
|
str_out[j][len] = '\0';
|
||||||
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 */
|
printf("[%2u] X: %6s Y: %6s Z: %6s\n", i, str_out[0], str_out[1], str_out[2]);
|
||||||
else if (strncmp(argv[1], "clear_data", sizeof("clear_data")) == 0) {
|
|
||||||
|
|
||||||
lis2dh12_clear_data(&dev);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_LIS2DH12_INT
|
return 0;
|
||||||
/* 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;
|
static int shell_is2dh12_threshold(int argc, char **argv)
|
||||||
lis2dh12_set_click(&dev, &click_cfg);
|
{
|
||||||
|
uint8_t slot;
|
||||||
/* enable click interrupt */
|
uint32_t mg;
|
||||||
params_int1.int_type = LIS2DH12_INT_TYPE_I1_CLICK;
|
uint32_t us = 0;
|
||||||
lis2dh12_set_int(&dev, ¶ms_int1, LIS2DH12_INT1);
|
uint8_t axis = LIS2DH12_INT_CFG_XHIE
|
||||||
|
|
||||||
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_YHIE
|
||||||
| LIS2DH12_INT_CFG_ZHIE;
|
| 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);
|
if (argc < 3) {
|
||||||
}
|
printf("usage: %s <slot> <mg> [µs]\n", argv[0]);
|
||||||
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out) {
|
slot = atoi(argv[1]);
|
||||||
/* enable filter for output */
|
mg = atoi(argv[2]);
|
||||||
highpass_cfg.DATA_OUT_enable = 0;
|
|
||||||
|
|
||||||
/* enable HP for interrupt */
|
if (argc > 3) {
|
||||||
if (out == 1) {
|
us = atoi(argv[3]);
|
||||||
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);
|
if (slot < 1 || slot > 2) {
|
||||||
lis2dh12_set_highpass(&dev, &highpass_cfg);
|
puts("event slot must be either 1 or 2");
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* MODULE_LIS2DH12_INT */
|
|
||||||
|
|
||||||
/* change sampling rate */
|
lis2dh12_cfg_threshold_event(&dev, mg, us, axis, slot, LIS2DH12_INT1);
|
||||||
else if (strncmp(argv[1], "change_rate", sizeof("change_rate")) == 0) {
|
|
||||||
uint8_t rate = 0;
|
return 0;
|
||||||
if ((argc < 3) || (rate = atoi(argv[2])) > 9) {
|
}
|
||||||
puts("Error: Missing parameter.");
|
|
||||||
puts("The command should contain a number for sampling rate. "
|
static int shell_is2dh12_click(int argc, char **argv)
|
||||||
"Possible outputs are 1Hz (1), 10Hz (2), 25Hz (3), "
|
{
|
||||||
"50Hz (4), 100Hz (5), 200Hz (6) or 400Hz (7).");
|
uint32_t mg;
|
||||||
puts("USAGE: lis change_rate [samplingrate]");
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lis2dh12_set_datarate(&dev, rate);
|
lis2dh12_set_datarate(&dev, rate);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* change power mode */
|
return 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
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 */
|
/* init lis */
|
||||||
lis2dh12_test_init();
|
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 */
|
/* running shell */
|
||||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user