Merge pull request #10695 from aabadie/pr/drivers/lpsxxx
drivers/lpsxxx: refactor lps331ap and add support for lps25hb + lps22hb
This commit is contained in:
commit
14f47bf220
@ -2,5 +2,6 @@ ifneq (,$(filter saul_default,$(USEMODULE)))
|
||||
USEMODULE += saul_gpio
|
||||
USEMODULE += hts221
|
||||
USEMODULE += lis3mdl
|
||||
USEMODULE += lps22hb
|
||||
USEMODULE += lsm6dsl
|
||||
endif
|
||||
|
||||
@ -65,6 +65,13 @@ extern "C" {
|
||||
#define LIS3MDL_PARAM_I2C I2C_DEV(1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS22HB pressure/temperature sensor configuration
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_PARAM_I2C I2C_DEV(1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LSM6DSL accelerometer sensor configuration
|
||||
* @{
|
||||
|
||||
@ -56,7 +56,7 @@ extern "C" {
|
||||
* @name Define the interface to the LPS331AP pressure sensor
|
||||
* @{
|
||||
*/
|
||||
#define LPS331AP_PARAM_ADDR (0x5C)
|
||||
#define LPSXXX_PARAM_ADDR (0x5C)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@ -46,7 +46,7 @@ extern "C" {
|
||||
* @name Define the interface to the LPS331AP pressure sensor
|
||||
* @{
|
||||
*/
|
||||
#define LPS331AP_PARAM_ADDR (0x5C)
|
||||
#define LPSXXX_PARAM_ADDR (0x5C)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
||||
@ -268,7 +268,11 @@ ifneq (,$(filter lpd8808,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_gpio
|
||||
endif
|
||||
|
||||
ifneq (,$(filter lps331ap,$(USEMODULE)))
|
||||
ifneq (,$(filter lps331ap lps2%hb,$(USEMODULE)))
|
||||
USEMODULE += lpsxxx
|
||||
endif
|
||||
|
||||
ifneq (,$(filter lpsxxx,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_i2c
|
||||
endif
|
||||
|
||||
|
||||
@ -158,8 +158,8 @@ ifneq (,$(filter lpd8808,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lpd8808/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter lps331ap,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lps331ap/include
|
||||
ifneq (,$(filter lpsxxx,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lpsxxx/include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter lsm303dlhc,$(USEMODULE)))
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_lps331ap LPS331AP Pressure Sensor Driver
|
||||
* @ingroup drivers_sensors
|
||||
* @ingroup drivers_saul
|
||||
* @brief Device driver for the LPS331AP pressure sensor
|
||||
*
|
||||
* This driver provides @ref drivers_saul capabilities.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver interface for the LPS331AP pressure sensor
|
||||
*
|
||||
* @note This driver uses the sensors I2C interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef LPS331AP_H
|
||||
#define LPS331AP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph/i2c.h"
|
||||
|
||||
/**
|
||||
* @brief The sensors default I2C address
|
||||
*/
|
||||
#define LPS331AP_DEFAULT_ADDRESS (0x5c)
|
||||
|
||||
/**
|
||||
* @brief Possible sampling rates for LPS331AP sensors
|
||||
*/
|
||||
typedef enum {
|
||||
LPS331AP_RATE_1HZ = 1, /**< sample with 1Hz */
|
||||
LPS331AP_RATE_7HZ = 5, /**< sample with 7Hz */
|
||||
LPS331AP_RATE_12HZ5 = 6, /**< sample with 12.5Hz */
|
||||
LPS331AP_RATE_25HZ = 7 /**< sample with 25Hz */
|
||||
} lps331ap_rate_t;
|
||||
|
||||
/**
|
||||
* @brief Struct holding all parameters needed for device initialization
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< I2C bus the sensor is connected to */
|
||||
uint8_t addr; /**< the devices address on the bus */
|
||||
lps331ap_rate_t rate; /**< tell sensor to sample with this rate */
|
||||
} lps331ap_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for LPS331AP sensors
|
||||
*/
|
||||
typedef struct {
|
||||
lps331ap_params_t params; /**< device initialization parameters */
|
||||
} lps331ap_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a given LPS331AP pressure sensor
|
||||
*
|
||||
* @param[out] dev device descriptor of the sensor
|
||||
* @param[in] params initialization parameters
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int lps331ap_init(lps331ap_t *dev, const lps331ap_params_t * params);
|
||||
|
||||
/**
|
||||
* @brief Read a temperature value from the given sensor, returned in m°C
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to read from
|
||||
*
|
||||
* @return temperature value in m°C
|
||||
*/
|
||||
int lps331ap_read_temp(const lps331ap_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Read a pressure value from the given sensor, returned in mbar
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to read from
|
||||
*
|
||||
* @return pressure value in mbar
|
||||
*/
|
||||
int lps331ap_read_pres(const lps331ap_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Enable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to enable
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return <0 on error
|
||||
*/
|
||||
int lps331ap_enable(const lps331ap_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Disable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to disable
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return <0 on error
|
||||
*/
|
||||
int lps331ap_disable(const lps331ap_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPS331AP_H */
|
||||
/** @} */
|
||||
161
drivers/include/lpsxxx.h
Normal file
161
drivers/include/lpsxxx.h
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_lpsxxx LPS331AP/LPS25HB/LPS22HB Pressure Sensors Driver
|
||||
* @ingroup drivers_sensors
|
||||
* @ingroup drivers_saul
|
||||
* @brief Device driver for the LPSXXX pressure sensor family (LPS331AP/LPS25HB/LPS22HB)
|
||||
*
|
||||
* This driver provides @ref drivers_saul capabilities.
|
||||
*
|
||||
* @note This driver uses the sensors I2C interface
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef LPSXXX_H
|
||||
#define LPSXXX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph/i2c.h"
|
||||
|
||||
/**
|
||||
* @brief The sensors default I2C address
|
||||
*
|
||||
* Default address corresponds to SDO/SA0 pad connected to ground. If SDO/SA0
|
||||
* pad is connected to power supply, I2C address is 0x5C.
|
||||
*/
|
||||
#define LPSXXX_DEFAULT_ADDRESS (0x5d)
|
||||
|
||||
/**
|
||||
* @brief Return codes
|
||||
*/
|
||||
enum {
|
||||
LPSXXX_OK, /**< Everything was fine */
|
||||
LPSXXX_ERR_NODEV, /**< No valid device found */
|
||||
LPSXXX_ERR_I2C, /**< An error occurred on the I2C bus */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Possible sampling rates for LPS331AP sensors
|
||||
*/
|
||||
typedef enum {
|
||||
LPSXXX_RATE_1HZ = 1, /**< sample with 1Hz */
|
||||
#if MODULE_LPS331AP
|
||||
LPSXXX_RATE_7HZ = 5, /**< sample with 7Hz, default */
|
||||
LPSXXX_RATE_12HZ5 = 6, /**< sample with 12.5Hz */
|
||||
LPSXXX_RATE_25HZ = 7 /**< sample with 25Hz */
|
||||
#elif MODULE_LPS25HB
|
||||
LPSXXX_RATE_7HZ = 2, /**< sample with 7Hz, default */
|
||||
LPSXXX_RATE_12HZ5 = 3, /**< sample with 12.5Hz */
|
||||
LPSXXX_RATE_25HZ = 4 /**< sample with 25Hz */
|
||||
#elif MODULE_LPS22HB
|
||||
LPSXXX_RATE_10HZ = 2, /**< sample with 10Hz */
|
||||
LPSXXX_RATE_25HZ = 3, /**< sample with 25Hz, default */
|
||||
LPSXXX_RATE_50HZ = 4, /**< sample with 50Hz */
|
||||
LPSXXX_RATE_75HZ = 5 /**< sample with 75Hz */
|
||||
#endif
|
||||
} lpsxxx_rate_t;
|
||||
|
||||
/**
|
||||
* @brief The sensors default output data rate (ODR)
|
||||
*/
|
||||
#if MODULE_LPS331AP || MODULE_LPS25HB
|
||||
#define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_7HZ)
|
||||
#else /* MODULE_LPS22HB */
|
||||
#define LPSXXX_DEFAULT_RATE (LPSXXX_RATE_25HZ)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Struct holding all parameters needed for device initialization
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< I2C bus the sensor is connected to */
|
||||
uint8_t addr; /**< the devices address on the bus */
|
||||
lpsxxx_rate_t rate; /**< tell sensor to sample with this rate */
|
||||
} lpsxxx_params_t;
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for LPSXXX sensors
|
||||
*/
|
||||
typedef struct {
|
||||
lpsxxx_params_t params; /**< device initialization parameters */
|
||||
} lpsxxx_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a given LPSXXX pressure sensor
|
||||
*
|
||||
* @param[out] dev device descriptor of the sensor
|
||||
* @param[in] params initialization parameters
|
||||
*
|
||||
* @return LPSXXX_OK on success
|
||||
* @return -LPSXXX_ERR_NODEV if no valid device found
|
||||
* @return -LPSXXX_ERR_I2C on I2C error
|
||||
*/
|
||||
int lpsxxx_init(lpsxxx_t *dev, const lpsxxx_params_t *params);
|
||||
|
||||
/**
|
||||
* @brief Read a temperature value from the given sensor, returned in c°C
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to read from
|
||||
* @param[out] temp temperature value in c°C
|
||||
*
|
||||
* @return LPSXXX_OK on success
|
||||
* @return -LPSXXX_ERR_I2C on I2C error
|
||||
*/
|
||||
int lpsxxx_read_temp(const lpsxxx_t *dev, int16_t *temp);
|
||||
|
||||
/**
|
||||
* @brief Read a pressure value from the given sensor, returned in hPa
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to read from
|
||||
* @param[out] pres pressure value in hPa
|
||||
*
|
||||
* @return LPSXXX_OK on success
|
||||
* @return -LPSXXX_ERR_I2C on I2C error
|
||||
*/
|
||||
int lpsxxx_read_pres(const lpsxxx_t *dev, uint16_t *pres);
|
||||
|
||||
/**
|
||||
* @brief Enable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to enable
|
||||
*
|
||||
* @return LPSXXX_OK on success
|
||||
* @return -LPSXXX_ERR_I2C on I2C error
|
||||
*/
|
||||
int lpsxxx_enable(const lpsxxx_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Disable the given sensor
|
||||
*
|
||||
* @param[in] dev device descriptor of sensor to disable
|
||||
*
|
||||
* @return LPSXXX_OK on success
|
||||
* @return -LPSXXX_ERR_I2C on I2C error
|
||||
*/
|
||||
int lpsxxx_disable(const lpsxxx_t *dev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPSXXX_H */
|
||||
/** @} */
|
||||
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lps331ap
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Definitions for the LPS331AP pressure sensor
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef LPS331AP_INTERNAL_H
|
||||
#define LPS331AP_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name LPS331AP registers
|
||||
* @{
|
||||
*/
|
||||
#define LPS331AP_AUTO_INC 0x80
|
||||
#define LPS331AP_REG_REF_P_XL 0x08
|
||||
#define LPS331AP_REG_REF_P_L 0x09
|
||||
#define LPS331AP_REG_REF_P_H 0x0a
|
||||
#define LPS331AP_REG_WHO_AM_I 0x0f
|
||||
#define LPS331AP_REG_RES_CONF 0x10
|
||||
#define LPS331AP_REG_CTRL_REG1 0x20
|
||||
#define LPS331AP_REG_CTRL_REG2 0x21
|
||||
#define LPS331AP_REG_CTRL_REG3 0x22
|
||||
#define LPS331AP_REG_INT_CFG_REG 0x23
|
||||
#define LPS331AP_REG_INT_SOURCE_REG 0x24
|
||||
#define LPS331AP_REG_THS_P_LOW_REG 0x25
|
||||
#define LPS331AP_REG_THS_P_HIGH_REG 0x26
|
||||
#define LPS331AP_REG_STATUS_REG 0x27
|
||||
#define LPS331AP_REG_PRESS_OUT_XL 0x28
|
||||
#define LPS331AP_REG_PRESS_OUT_L 0x29
|
||||
#define LPS331AP_REG_PRESS_OUT_H 0x2a
|
||||
#define LPS331AP_REG_TEMP_OUT_L 0x2b
|
||||
#define LPS331AP_REG_TEMP_OUT_H 0x2c
|
||||
#define LPS331AP_REG_AMP_CTRL 0x30
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS331AP CTRL_REG1 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPS331AP_CTRL_REG1_PD 0x80
|
||||
#define LPS331AP_CTRL_REG1_ODR 0x70
|
||||
#define LPS331AP_CTRL_REG1_ODR_POS 4
|
||||
#define LPS331AP_CTRL_REG1_DIFF_EN 0x08
|
||||
#define LPS331AP_CTRL_REG1_DBDU 0x04
|
||||
#define LPS331AP_CTRL_REG1_DELTA_EN 0x02
|
||||
#define LPS331AP_CTRL_REG1_SIM 0x01
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPS331AP_INTERNAL_H */
|
||||
/** @} */
|
||||
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lps331ap
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for LPS331AP devices
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef LPS331AP_PARAMS_H
|
||||
#define LPS331AP_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "lps331ap.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters
|
||||
* @{
|
||||
*/
|
||||
#ifndef LPS331AP_PARAM_I2C
|
||||
#define LPS331AP_PARAM_I2C I2C_DEV(0)
|
||||
#endif
|
||||
#ifndef LPS331AP_PARAM_ADDR
|
||||
#define LPS331AP_PARAM_ADDR (0x44)
|
||||
#endif
|
||||
#ifndef LPS331AP_PARAM_RATE
|
||||
#define LPS331AP_PARAM_RATE (LPS331AP_RATE_7HZ)
|
||||
#endif
|
||||
|
||||
#ifndef LPS331AP_PARAMS
|
||||
#define LPS331AP_PARAMS { .i2c = LPS331AP_PARAM_I2C, \
|
||||
.addr = LPS331AP_PARAM_ADDR, \
|
||||
.rate = LPS331AP_PARAM_RATE }
|
||||
#endif
|
||||
#ifndef LPS331AP_SAUL_INFO
|
||||
#define LPS331AP_SAUL_INFO { .name = "lps331ap" }
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief Allocate some memory to store the actual configuration
|
||||
*/
|
||||
static const lps331ap_params_t lps331ap_params[] =
|
||||
{
|
||||
LPS331AP_PARAMS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Additional meta information to keep in the SAUL registry
|
||||
*/
|
||||
static const saul_reg_info_t lps331ap_saul_info[] =
|
||||
{
|
||||
LPS331AP_SAUL_INFO
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPS331AP_PARAMS_H */
|
||||
/** @} */
|
||||
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lps331ap
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver implementation for the LPS331AP pressure sensor
|
||||
*
|
||||
* @note The current driver implementation is very basic and allows only for polling the
|
||||
* devices temperature and pressure values. Threshold values and interrupts are not
|
||||
* used.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/i2c.h"
|
||||
#include "lps331ap.h"
|
||||
#include "lps331ap-internal.h"
|
||||
|
||||
/**
|
||||
* @brief pressure divider for norming pressure output
|
||||
*/
|
||||
#define PRES_DIVIDER (4096U)
|
||||
|
||||
/**
|
||||
* @brief temperature base value and divider for norming temperature output
|
||||
*/
|
||||
#define TEMP_BASE (42.5f)
|
||||
#define TEMP_DIVIDER (480U)
|
||||
|
||||
#define DEV_I2C (dev->params.i2c)
|
||||
#define DEV_ADDR (dev->params.addr)
|
||||
#define DEV_RATE (dev->params.rate)
|
||||
|
||||
int lps331ap_init(lps331ap_t *dev, const lps331ap_params_t * params)
|
||||
{
|
||||
dev->params = *params;
|
||||
|
||||
uint8_t tmp;
|
||||
|
||||
/* Acquire exclusive access to the bus. */
|
||||
i2c_acquire(DEV_I2C);
|
||||
|
||||
/* configure device, for simple operation only CTRL_REG1 needs to be touched */
|
||||
tmp = LPS331AP_CTRL_REG1_DBDU | LPS331AP_CTRL_REG1_PD |
|
||||
(DEV_RATE << LPS331AP_CTRL_REG1_ODR_POS);
|
||||
if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_CTRL_REG1, tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lps331ap_read_temp(const lps331ap_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int16_t val = 0;
|
||||
float res = TEMP_BASE; /* reference value -> see datasheet */
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_TEMP_OUT_L, &tmp, 0);
|
||||
val |= tmp;
|
||||
i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_TEMP_OUT_H, &tmp, 0);
|
||||
i2c_release(DEV_I2C);
|
||||
val |= ((uint16_t)tmp << 8);
|
||||
|
||||
/* compute actual temperature value in °C */
|
||||
res += ((float)val) / TEMP_DIVIDER;
|
||||
|
||||
/* return temperature in m°C */
|
||||
return (int)(res * 1000);
|
||||
}
|
||||
|
||||
int lps331ap_read_pres(const lps331ap_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int32_t val = 0;
|
||||
float res;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_PRESS_OUT_XL, &tmp, 0);
|
||||
val |= tmp;
|
||||
i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_PRESS_OUT_L, &tmp, 0);
|
||||
val |= ((uint32_t)tmp << 8);
|
||||
i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_PRESS_OUT_H, &tmp, 0);
|
||||
i2c_release(DEV_I2C);
|
||||
val |= ((uint32_t)tmp << 16);
|
||||
/* see if value is negative */
|
||||
if (tmp & 0x80) {
|
||||
val |= ((uint32_t)0xff << 24);
|
||||
}
|
||||
|
||||
/* compute actual pressure value in mbar */
|
||||
res = ((float)val) / PRES_DIVIDER;
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
|
||||
int lps331ap_enable(const lps331ap_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int status;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_CTRL_REG1, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
return -1;
|
||||
}
|
||||
tmp |= (LPS331AP_CTRL_REG1_PD);
|
||||
status = i2c_write_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_CTRL_REG1, tmp, 0);
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int lps331ap_disable(const lps331ap_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int status;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_CTRL_REG1, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
return -1;
|
||||
}
|
||||
tmp &= ~(LPS331AP_CTRL_REG1_PD);
|
||||
status = i2c_write_reg(DEV_I2C, DEV_ADDR, LPS331AP_REG_CTRL_REG1, tmp, 0);
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lps331ap
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief LPS331ap adaption to the RIOT actuator/sensor interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "saul.h"
|
||||
#include "lps331ap.h"
|
||||
|
||||
static int read_pres(const void *dev, phydat_t *res)
|
||||
{
|
||||
res->val[0] = (int16_t)lps331ap_read_pres((const lps331ap_t *)dev);
|
||||
res->unit = UNIT_BAR;
|
||||
res->scale = -3;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_temp(const void *dev, phydat_t *res)
|
||||
{
|
||||
res->val[0] = (int16_t)(lps331ap_read_temp((const lps331ap_t *)dev) / 10);
|
||||
res->unit = UNIT_TEMP_C;
|
||||
/* above division by ten leads to °C * 10^-2*/
|
||||
res->scale = -2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t lps331ap_saul_pres_driver = {
|
||||
.read = read_pres,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_PRESS,
|
||||
};
|
||||
|
||||
const saul_driver_t lps331ap_saul_temp_driver = {
|
||||
.read = read_temp,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_TEMP,
|
||||
};
|
||||
@ -1,3 +1 @@
|
||||
MODULE = lps331ap
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
178
drivers/lpsxxx/include/lpsxxx_internal.h
Normal file
178
drivers/lpsxxx/include/lpsxxx_internal.h
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lpsxxx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Definitions for the LPSXXX family of pressure sensors
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef LPSXXX_INTERNAL_H
|
||||
#define LPSXXX_INTERNAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Common LPS331AP/LPS25HB registers
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_REG_WHO_AM_I (0x0f)
|
||||
#define LPSXXX_REG_STATUS (0x27)
|
||||
#define LPSXXX_REG_PRESS_OUT_XL (0x28)
|
||||
#define LPSXXX_REG_PRESS_OUT_L (0x29)
|
||||
#define LPSXXX_REG_PRESS_OUT_H (0x2a)
|
||||
#define LPSXXX_REG_TEMP_OUT_L (0x2b)
|
||||
#define LPSXXX_REG_TEMP_OUT_H (0x2c)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Common LPS331AP/LPS25HB CTRL_REG1 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_CTRL_REG1_ODR (0x70)
|
||||
#define LPSXXX_CTRL_REG1_ODR_POS (4)
|
||||
#define LPSXXX_CTRL_REG1_SIM (0x01)
|
||||
/** @} */
|
||||
|
||||
#if MODULE_LPS331AP
|
||||
|
||||
/**
|
||||
* @name LPS331AP registers
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_REG_REF_P_XL (0x08)
|
||||
#define LPSXXX_REG_REF_P_L (0x09)
|
||||
#define LPSXXX_REG_REF_P_H (0x0a)
|
||||
#define LPSXXX_REG_RES_CONF (0x10)
|
||||
#define LPSXXX_REG_CTRL_REG1 (0x20)
|
||||
#define LPSXXX_REG_CTRL_REG2 (0x21)
|
||||
#define LPSXXX_REG_CTRL_REG3 (0x22)
|
||||
#define LPSXXX_REG_INT_CFG (0x23)
|
||||
#define LPSXXX_REG_INT_SOURCE (0x24)
|
||||
#define LPSXXX_REG_THS_P_LOW (0x25)
|
||||
#define LPSXXX_REG_THS_P_HIGH (0x26)
|
||||
#define LPSXXX_REG_AMP_CTRL (0x30)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS331AP CTRL_REG1 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_CTRL_REG1_PD (0x80)
|
||||
#define LPSXXX_CTRL_REG1_DIFF_EN (0x08)
|
||||
#define LPSXXX_CTRL_REG1_DBDU (0x04)
|
||||
#define LPSXXX_CTRL_REG1_DELTA_EN (0x02)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief LPS331AP WHO_AM_I register value
|
||||
*/
|
||||
#define LPSXXX_WHO_AM_I (0xbb)
|
||||
|
||||
#elif MODULE_LPS25HB
|
||||
|
||||
/**
|
||||
* @name LPS25HB registers
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_REG_REF_P_XL (0x08)
|
||||
#define LPSXXX_REG_REF_P_L (0x09)
|
||||
#define LPSXXX_REG_REF_P_H (0x0a)
|
||||
#define LPSXXX_REG_RES_CONF (0x10)
|
||||
#define LPSXXX_REG_CTRL_REG1 (0x20)
|
||||
#define LPSXXX_REG_CTRL_REG2 (0x21)
|
||||
#define LPSXXX_REG_CTRL_REG3 (0x22)
|
||||
#define LPSXXX_REG_CTRL_REG4 (0x23)
|
||||
#define LPSXXX_REG_INT_CFG (0x24)
|
||||
#define LPSXXX_REG_INT_SOURCE (0x25)
|
||||
#define LPSXXX_REG_FIFO_CTRL (0x2e)
|
||||
#define LPSXXX_REG_FIFO_STATUS (0x2f)
|
||||
#define LPSXXX_REG_THS_P_LOW (0x30)
|
||||
#define LPSXXX_REG_THS_P_HIGH (0x31)
|
||||
#define LPSXXX_REG_RPDS_L (0x39)
|
||||
#define LPSXXX_REG_RPDS_H (0x3a)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS25HB CTRL_REG1 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_CTRL_REG1_PD (0x80)
|
||||
#define LPSXXX_CTRL_REG1_DIFF_EN (0x08)
|
||||
#define LPSXXX_CTRL_REG1_BDU (0x04)
|
||||
#define LPSXXX_CTRL_REG1_RESET_AZ (0x02)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief LPS25HB WHO_AM_I register value
|
||||
*/
|
||||
#define LPSXXX_WHO_AM_I (0xbd)
|
||||
|
||||
#elif MODULE_LPS22HB
|
||||
|
||||
/**
|
||||
* @name LPS22HB registers
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_REG_INT_CFG (0x0b)
|
||||
#define LPSXXX_REG_THS_P_L (0x0c)
|
||||
#define LPSXXX_REG_THS_P_H (0x0d)
|
||||
#define LPSXXX_REG_REF_P_XL (0x15)
|
||||
#define LPSXXX_REG_RES_CONF (0x1a)
|
||||
#define LPSXXX_REG_CTRL_REG1 (0x10)
|
||||
#define LPSXXX_REG_CTRL_REG2 (0x11)
|
||||
#define LPSXXX_REG_CTRL_REG3 (0x13)
|
||||
#define LPSXXX_REG_FIFO_CTRL (0x2e)
|
||||
#define LPSXXX_REG_REF_P_XL (0x15)
|
||||
#define LPSXXX_REG_REF_P_L (0x16)
|
||||
#define LPSXXX_REG_REF_P_H (0x17)
|
||||
#define LPSXXX_REG_RPDS_L (0x18)
|
||||
#define LPSXXX_REG_RPDS_H (0x19)
|
||||
#define LPSXXX_REG_RES_CONF (0x1a)
|
||||
#define LPSXXX_REG_INT_SOURCE (0x25)
|
||||
#define LPSXXX_REG_FIFO_STATUS (0x26)
|
||||
#define LPSXXX_REG_LPFP_RES (0x33)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS22HB CTRL_REG1 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_CTRL_REG1_EN_LPFP (0x08)
|
||||
#define LPSXXX_CTRL_REG1_LPFP_CFG (0x04)
|
||||
#define LPSXXX_CTRL_REG1_BDU (0x02)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LPS22HB CTRL_REG2 bitfields
|
||||
* @{
|
||||
*/
|
||||
#define LPSXXX_CTRL_REG2_ID_ADD_INC (0x10)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief LPS22HB WHO_AM_I register value
|
||||
*/
|
||||
#define LPSXXX_WHO_AM_I (0xb1)
|
||||
|
||||
#endif /* MODULE_LPS22HB */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPSXXX_INTERNAL_H */
|
||||
/** @} */
|
||||
85
drivers/lpsxxx/include/lpsxxx_params.h
Normal file
85
drivers/lpsxxx/include/lpsxxx_params.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lpsxxx
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief Default configuration for LPSXXX family of devices
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*/
|
||||
|
||||
#ifndef LPSXXX_PARAMS_H
|
||||
#define LPSXXX_PARAMS_H
|
||||
|
||||
#include "board.h"
|
||||
#include "lpsxxx.h"
|
||||
#include "saul_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Set default configuration parameters
|
||||
* @{
|
||||
*/
|
||||
#ifndef LPSXXX_PARAM_I2C
|
||||
#define LPSXXX_PARAM_I2C I2C_DEV(0)
|
||||
#endif
|
||||
#ifndef LPSXXX_PARAM_ADDR
|
||||
#define LPSXXX_PARAM_ADDR (LPSXXX_DEFAULT_ADDRESS)
|
||||
#endif
|
||||
#ifndef LPSXXX_PARAM_RATE
|
||||
#define LPSXXX_PARAM_RATE (LPSXXX_DEFAULT_RATE)
|
||||
#endif
|
||||
|
||||
#ifndef LPSXXX_PARAMS
|
||||
#define LPSXXX_PARAMS { .i2c = LPSXXX_PARAM_I2C, \
|
||||
.addr = LPSXXX_PARAM_ADDR, \
|
||||
.rate = LPSXXX_PARAM_RATE }
|
||||
#endif
|
||||
|
||||
#if MODULE_LPS331AP
|
||||
#define LPSXXX_SAUL_NAME "lps331ap"
|
||||
#elif MODULE_LPS25HB
|
||||
#define LPSXXX_SAUL_NAME "lps25hb"
|
||||
#elif MODULE_LPS22HB
|
||||
#define LPSXXX_SAUL_NAME "lps22hb"
|
||||
#endif
|
||||
#ifndef LPSXXX_SAUL_INFO
|
||||
#define LPSXXX_SAUL_INFO { .name = LPSXXX_SAUL_NAME }
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* @brief Allocate some memory to store the actual configuration
|
||||
*/
|
||||
static const lpsxxx_params_t lpsxxx_params[] =
|
||||
{
|
||||
LPSXXX_PARAMS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Additional meta information to keep in the SAUL registry
|
||||
*/
|
||||
static const saul_reg_info_t lpsxxx_saul_info[] =
|
||||
{
|
||||
LPSXXX_SAUL_INFO
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LPSXXX_PARAMS_H */
|
||||
/** @} */
|
||||
256
drivers/lpsxxx/lpsxxx.c
Normal file
256
drivers/lpsxxx/lpsxxx.c
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lpsxxx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device driver implementation for the LPSXXX family of pressure sensors
|
||||
*
|
||||
* @note The current driver implementation is very basic and allows only for polling the
|
||||
* devices temperature and pressure values. Threshold values and interrupts are not
|
||||
* used.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "periph/i2c.h"
|
||||
#include "lpsxxx.h"
|
||||
#include "lpsxxx_internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief pressure divider for norming pressure output
|
||||
*/
|
||||
#define PRES_DIVIDER (12U)
|
||||
|
||||
/**
|
||||
* @brief temperature base value and divider for norming temperature output
|
||||
*/
|
||||
#if MODULE_LPS331AP || MODULE_LPS25HB
|
||||
#define TEMP_BASE (42.5f)
|
||||
#define TEMP_DIVIDER (480U)
|
||||
#else
|
||||
#define TEMP_BASE (0.0f)
|
||||
#define TEMP_DIVIDER (100U)
|
||||
#endif
|
||||
|
||||
#define DEV_I2C (dev->params.i2c)
|
||||
#define DEV_ADDR (dev->params.addr)
|
||||
#define DEV_RATE (dev->params.rate)
|
||||
|
||||
int lpsxxx_init(lpsxxx_t *dev, const lpsxxx_params_t * params)
|
||||
{
|
||||
dev->params = *params;
|
||||
|
||||
/* Acquire exclusive access to the bus. */
|
||||
i2c_acquire(DEV_I2C);
|
||||
uint8_t id;
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_WHO_AM_I, &id, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] init: cannot read WHO_AM_I register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
|
||||
if (id != LPSXXX_WHO_AM_I) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] init: not a valid device (got %02X, expected %02X)\n",
|
||||
id, LPSXXX_WHO_AM_I);
|
||||
return -LPSXXX_ERR_NODEV;
|
||||
}
|
||||
|
||||
uint8_t tmp;
|
||||
|
||||
#if MODULE_LPS22HB
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG2, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] init: cannot read LPSXXX_REG_CTRL_REG2 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
|
||||
/* Disable automatic increment of register address during byte access
|
||||
(recommanded in datasheet (section 9.6 CTRL_REG2) */
|
||||
tmp &= ~LPSXXX_CTRL_REG2_ID_ADD_INC;
|
||||
|
||||
DEBUG("[lpsxxx] init: update reg2, %02X\n", tmp);
|
||||
|
||||
if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG2, tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] init: cannot write in CTRL_REG2 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* configure device, for simple operation only CTRL_REG1 needs to be touched */
|
||||
#if MODULE_LPS331AP
|
||||
tmp = LPSXXX_CTRL_REG1_DBDU | LPSXXX_CTRL_REG1_PD |
|
||||
(DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS);
|
||||
#elif MODULE_LPS25HB
|
||||
tmp = LPSXXX_CTRL_REG1_BDU | LPSXXX_CTRL_REG1_PD |
|
||||
(DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS);
|
||||
#elif MODULE_LPS22HB
|
||||
tmp = LPSXXX_CTRL_REG1_EN_LPFP | /* Low-pass filter configuration: ODR/9 */
|
||||
LPSXXX_CTRL_REG1_BDU | (DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS);
|
||||
#endif
|
||||
|
||||
DEBUG("[lpsxxx] init: update reg1, value: %02X\n", tmp);
|
||||
|
||||
if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG1, tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] init: cannot write in CTRL_REG1 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
DEBUG("[lpsxxx] initialization successful\n");
|
||||
return LPSXXX_OK;
|
||||
}
|
||||
|
||||
int lpsxxx_read_temp(const lpsxxx_t *dev, int16_t *temp)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int16_t val = 0;
|
||||
float res = TEMP_BASE; /* reference value -> see datasheet */
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_TEMP_OUT_L, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] read_temp: cannot read TEMP_OUT_L register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
val |= tmp;
|
||||
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_TEMP_OUT_H, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] read_temp: cannot read TEMP_OUT_H register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
i2c_release(DEV_I2C);
|
||||
val |= ((uint16_t)tmp << 8);
|
||||
|
||||
DEBUG("[lpsxxx] read_temp: raw data %08" PRIx32 "\n", (uint32_t)val);
|
||||
|
||||
/* compute actual temperature value in °C */
|
||||
res += ((float)val) / TEMP_DIVIDER;
|
||||
|
||||
/* return temperature in c°C */
|
||||
*temp = (int16_t)(res * 100);
|
||||
return LPSXXX_OK;
|
||||
}
|
||||
|
||||
int lpsxxx_read_pres(const lpsxxx_t *dev, uint16_t *pres)
|
||||
{
|
||||
uint8_t tmp;
|
||||
int32_t val = 0;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_PRESS_OUT_XL, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] read_pres: cannot read PRES_OUT_XL register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
val |= tmp;
|
||||
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_PRESS_OUT_L, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] read_pres: cannot read PRES_OUT_L register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
val |= ((uint32_t)tmp << 8);
|
||||
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_PRESS_OUT_H, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] read_pres: cannot read PRES_OUT_H register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
val |= ((uint32_t)tmp << 16);
|
||||
|
||||
DEBUG("[lpsxxx] read_pres: raw data %08" PRIx32 "\n", (uint32_t)val);
|
||||
|
||||
/* see if value is negative */
|
||||
if (tmp & 0x80) {
|
||||
val |= ((uint32_t)0xff << 24);
|
||||
}
|
||||
|
||||
/* compute actual pressure value in hPa */
|
||||
*pres = (uint16_t)(val >> PRES_DIVIDER);
|
||||
|
||||
return LPSXXX_OK;
|
||||
}
|
||||
|
||||
int lpsxxx_enable(const lpsxxx_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG1, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] enable: cannot read CTRL_REG1 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
#if MODULE_LPS331AP || MODULE_LPS25HB
|
||||
tmp |= LPSXXX_CTRL_REG1_PD;
|
||||
#else
|
||||
tmp |= LPSXXX_CTRL_REG1_EN_LPFP | /* Low-pass filter configuration: ODR/9 */
|
||||
LPSXXX_CTRL_REG1_BDU | (DEV_RATE << LPSXXX_CTRL_REG1_ODR_POS);
|
||||
#endif
|
||||
|
||||
|
||||
DEBUG("[lpsxxx] enable: update reg1 with %02X\n", tmp);
|
||||
|
||||
if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG1, tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] enable: cannot write CTRL_REG1 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
return LPSXXX_OK;
|
||||
}
|
||||
|
||||
int lpsxxx_disable(const lpsxxx_t *dev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
i2c_acquire(DEV_I2C);
|
||||
if (i2c_read_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG1, &tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] disable: cannot read CTRL_REG1 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
#if MODULE_LPS331AP || MODULE_LPS25HB
|
||||
tmp &= ~LPSXXX_CTRL_REG1_PD;
|
||||
#else
|
||||
tmp &= ~(7 << LPSXXX_CTRL_REG1_ODR_POS);
|
||||
#endif
|
||||
|
||||
DEBUG("[lpsxxx] disable: update reg1 with %02X\n", tmp);
|
||||
|
||||
if (i2c_write_reg(DEV_I2C, DEV_ADDR, LPSXXX_REG_CTRL_REG1, tmp, 0) < 0) {
|
||||
i2c_release(DEV_I2C);
|
||||
DEBUG("[lpsxxx] disable: cannot write CTRL_REG1 register\n");
|
||||
return -LPSXXX_ERR_I2C;
|
||||
}
|
||||
i2c_release(DEV_I2C);
|
||||
|
||||
return LPSXXX_OK;
|
||||
}
|
||||
60
drivers/lpsxxx/lpsxxx_saul.c
Normal file
60
drivers/lpsxxx/lpsxxx_saul.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup drivers_lpsxxx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief LPSXXX (LPS331ap/LPS25HB/LPS22HB) adaption to SAUL interface
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "saul.h"
|
||||
#include "lpsxxx.h"
|
||||
|
||||
static int read_pres(const void *dev, phydat_t *res)
|
||||
{
|
||||
if (lpsxxx_read_pres((const lpsxxx_t *)dev, (uint16_t *)&res->val[0]) == LPSXXX_OK) {
|
||||
res->unit = UNIT_PA;
|
||||
res->scale = 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
static int read_temp(const void *dev, phydat_t *res)
|
||||
{
|
||||
if (lpsxxx_read_temp((const lpsxxx_t *)dev, &res->val[0]) == LPSXXX_OK) {
|
||||
res->unit = UNIT_TEMP_C;
|
||||
res->scale = -2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -ECANCELED;
|
||||
}
|
||||
|
||||
const saul_driver_t lpsxxx_saul_pres_driver = {
|
||||
.read = read_pres,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_PRESS,
|
||||
};
|
||||
|
||||
const saul_driver_t lpsxxx_saul_temp_driver = {
|
||||
.read = read_temp,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_TEMP,
|
||||
};
|
||||
@ -118,6 +118,11 @@ PSEUDOMODULES += vcnl4010
|
||||
PSEUDOMODULES += vcnl4020
|
||||
PSEUDOMODULES += vcnl4040
|
||||
|
||||
# include variants of lpsxxx drivers as pseudo modules
|
||||
PSEUDOMODULES += lps331ap
|
||||
PSEUDOMODULES += lps22hb
|
||||
PSEUDOMODULES += lps25hb
|
||||
|
||||
# add all pseudo random number generator variants as pseudomodules
|
||||
PSEUDOMODULES += prng_%
|
||||
|
||||
|
||||
@ -409,9 +409,9 @@ void auto_init(void)
|
||||
extern void auto_init_lis3mdl(void);
|
||||
auto_init_lis3mdl();
|
||||
#endif
|
||||
#ifdef MODULE_LPS331AP
|
||||
extern void auto_init_lps331ap(void);
|
||||
auto_init_lps331ap();
|
||||
#ifdef MODULE_LPSXXX
|
||||
extern void auto_init_lpsxxx(void);
|
||||
auto_init_lpsxxx();
|
||||
#endif
|
||||
#ifdef MODULE_LSM303DLHC
|
||||
extern void auto_init_lsm303dlhc(void);
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @ingroup sys_auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization of LPS331AP pressure sensors
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_LPS331AP
|
||||
|
||||
#include "assert.h"
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
#include "lps331ap.h"
|
||||
#include "lps331ap_params.h"
|
||||
|
||||
/**
|
||||
* @brief Define the number of configured sensors
|
||||
*/
|
||||
#define LPS331AP_NUM (sizeof(lps331ap_params) / sizeof(lps331ap_params[0]))
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for the device descriptors
|
||||
*/
|
||||
static lps331ap_t lps331ap_devs[LPS331AP_NUM];
|
||||
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[LPS331AP_NUM * 2];
|
||||
|
||||
/**
|
||||
* @brief Define the number of saul info
|
||||
*/
|
||||
#define LPS331AP_INFO_NUM (sizeof(lps331ap_saul_info) / sizeof(lps331ap_saul_info[0]))
|
||||
|
||||
/**
|
||||
* @brief Reference the driver struct
|
||||
*/
|
||||
extern saul_driver_t lps331ap_saul_pres_driver;
|
||||
extern saul_driver_t lps331ap_saul_temp_driver;
|
||||
|
||||
|
||||
void auto_init_lps331ap(void)
|
||||
{
|
||||
assert(LPS331AP_NUM == LPS331AP_INFO_NUM);
|
||||
|
||||
for (unsigned int i = 0; i < LPS331AP_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing lps331ap #%u\n", i);
|
||||
|
||||
if (lps331ap_init(&lps331ap_devs[i], &lps331ap_params[i]) < 0) {
|
||||
LOG_ERROR("[auto_init_saul] error initializing lps331ap #%u\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
saul_entries[i].dev = &(lps331ap_devs[i]);
|
||||
saul_entries[i].name = lps331ap_saul_info[i].name;
|
||||
saul_entries[i].driver = &lps331ap_saul_pres_driver;
|
||||
saul_reg_add(&(saul_entries[i]));
|
||||
saul_entries[(i * 2) + 1].dev = &(lps331ap_devs[i]);
|
||||
saul_entries[(i * 2) + 1].name = lps331ap_saul_info[i].name;
|
||||
saul_entries[(i * 2) + 1].driver = &lps331ap_saul_temp_driver;
|
||||
saul_reg_add(&(saul_entries[(i * 2) + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_LPS331AP */
|
||||
84
sys/auto_init/saul/auto_init_lpsxxx.c
Normal file
84
sys/auto_init/saul/auto_init_lpsxxx.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @ingroup sys_auto_init_saul
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Auto initialization of LPSXXX family of pressure sensors
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef MODULE_LPSXXX
|
||||
|
||||
#include "assert.h"
|
||||
#include "log.h"
|
||||
#include "saul_reg.h"
|
||||
#include "lpsxxx.h"
|
||||
#include "lpsxxx_params.h"
|
||||
|
||||
/**
|
||||
* @brief Define the number of configured sensors
|
||||
*/
|
||||
#define LPSXXX_NUM (sizeof(lpsxxx_params) / sizeof(lpsxxx_params[0]))
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for the device descriptors
|
||||
*/
|
||||
static lpsxxx_t lpsxxx_devs[LPSXXX_NUM];
|
||||
|
||||
/**
|
||||
* @brief Memory for the SAUL registry entries
|
||||
*/
|
||||
static saul_reg_t saul_entries[LPSXXX_NUM * 2];
|
||||
|
||||
/**
|
||||
* @brief Define the number of saul info
|
||||
*/
|
||||
#define LPSXXX_INFO_NUM (sizeof(lpsxxx_saul_info) / sizeof(lpsxxx_saul_info[0]))
|
||||
|
||||
/**
|
||||
* @brief Reference the driver struct
|
||||
*/
|
||||
extern saul_driver_t lpsxxx_saul_pres_driver;
|
||||
extern saul_driver_t lpsxxx_saul_temp_driver;
|
||||
|
||||
|
||||
void auto_init_lpsxxx(void)
|
||||
{
|
||||
assert(LPSXXX_NUM == LPSXXX_INFO_NUM);
|
||||
|
||||
for (unsigned int i = 0; i < LPSXXX_NUM; i++) {
|
||||
LOG_DEBUG("[auto_init_saul] initializing %s #%u\n",
|
||||
LPSXXX_SAUL_NAME, i);
|
||||
|
||||
if (lpsxxx_init(&lpsxxx_devs[i], &lpsxxx_params[i]) < 0) {
|
||||
LOG_ERROR("[auto_init_saul] error initializing %s #%u\n",
|
||||
LPSXXX_SAUL_NAME, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
saul_entries[i].dev = &(lpsxxx_devs[i]);
|
||||
saul_entries[i].name = lpsxxx_saul_info[i].name;
|
||||
saul_entries[i].driver = &lpsxxx_saul_pres_driver;
|
||||
saul_reg_add(&(saul_entries[i]));
|
||||
saul_entries[(i * 2) + 1].dev = &(lpsxxx_devs[i]);
|
||||
saul_entries[(i * 2) + 1].name = lpsxxx_saul_info[i].name;
|
||||
saul_entries[(i * 2) + 1].driver = &lpsxxx_saul_temp_driver;
|
||||
saul_reg_add(&(saul_entries[(i * 2) + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
typedef int dont_be_pedantic;
|
||||
#endif /* MODULE_LPSXXX */
|
||||
@ -1,9 +0,0 @@
|
||||
# About
|
||||
This is a manual test application for the LPS331AP pressure sensor driver.
|
||||
|
||||
# Usage
|
||||
This test application will initialize the pressure sensor with the following parameters:
|
||||
- Sampling Rate: 7Hz
|
||||
|
||||
After initialization, the sensor reads the pressure and temperature values every 250ms
|
||||
and prints them to the STDOUT.
|
||||
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the LPS331AP pressure sensor
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "lps331ap.h"
|
||||
#include "lps331ap_params.h"
|
||||
|
||||
#define SLEEP (250 * 1000U)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
lps331ap_t dev;
|
||||
|
||||
puts("LPS331AP pressure sensor test application\n");
|
||||
puts("Initializing LPS331AP sensor");
|
||||
if (lps331ap_init(&dev, &lps331ap_params[0]) == 0) {
|
||||
puts("[OK]\n");
|
||||
}
|
||||
else {
|
||||
puts("[Failed]");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int pres = lps331ap_read_pres(&dev);
|
||||
int temp = lps331ap_read_temp(&dev);
|
||||
|
||||
int pres_abs = pres / 1000;
|
||||
pres -= pres_abs * 1000;
|
||||
int temp_abs = temp / 1000;
|
||||
temp -= temp_abs * 1000;
|
||||
|
||||
printf("Pressure value: %2i.%03i bar - Temperature: %2i.%03i °C\n",
|
||||
pres_abs, pres, temp_abs, temp);
|
||||
|
||||
xtimer_usleep(SLEEP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += lps331ap
|
||||
DRIVER ?= lps331ap
|
||||
|
||||
USEMODULE += $(DRIVER)
|
||||
USEMODULE += xtimer
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
17
tests/driver_lpsxxx/README.md
Normal file
17
tests/driver_lpsxxx/README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# About
|
||||
|
||||
This is a manual test application for the LPSXXX family of pressure sensors
|
||||
driver. This driver can be used with LPS331AP, LPS25HB and LPS22HB.
|
||||
|
||||
Default driver is `lps331ap`. To use the LPS25HB driver, set the `DRIVER` when
|
||||
building the application:
|
||||
|
||||
DRIVER=lps25hb make BOARD=<your board>
|
||||
|
||||
# Usage
|
||||
|
||||
This test application will initialize the pressure sensor with a sampling rate
|
||||
of 7Hz (25Hz with lps22hb).
|
||||
|
||||
After initialization, the sensor reads the pressure and temperature values
|
||||
every 250ms and prints them to the STDOUT.
|
||||
58
tests/driver_lpsxxx/main.c
Normal file
58
tests/driver_lpsxxx/main.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* 2018 Inria
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup tests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Test application for the LPS331AP/LPS25HB/LPS22HB pressure sensor
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "xtimer.h"
|
||||
#include "lpsxxx.h"
|
||||
#include "lpsxxx_params.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
lpsxxx_t dev;
|
||||
|
||||
printf("Test application for %s pressure sensor\n\n", LPSXXX_SAUL_NAME);
|
||||
printf("Initializing %s sensor\n", LPSXXX_SAUL_NAME);
|
||||
if (lpsxxx_init(&dev, &lpsxxx_params[0]) != LPSXXX_OK) {
|
||||
puts("Initialization failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t pres;
|
||||
int16_t temp;
|
||||
while (1) {
|
||||
lpsxxx_enable(&dev);
|
||||
xtimer_sleep(1); /* wait a bit for the measurements to complete */
|
||||
|
||||
lpsxxx_read_temp(&dev, &temp);
|
||||
lpsxxx_read_pres(&dev, &pres);
|
||||
lpsxxx_disable(&dev);
|
||||
|
||||
int temp_abs = temp / 100;
|
||||
temp -= temp_abs * 100;
|
||||
|
||||
printf("Pressure value: %ihPa - Temperature: %2i.%02i°C\n",
|
||||
pres, temp_abs, temp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user