

6 changed files with 322 additions and 0 deletions
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 driver_lps331ap LPS331AP Pressure Sensor Driver |
||||
* @ingroup drivers |
||||
* @brief Device driver for the LPS331AP pressure sensor |
||||
* @{ |
||||
* |
||||
* @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" |
||||
|
||||
/**
|
||||
* @name The sensors default I2C address |
||||
*/ |
||||
#define LPS331AP_DEFAULT_ADDRESS 0x5c |
||||
|
||||
/**
|
||||
* @brief Device descriptor for LPS331AP sensors |
||||
*/ |
||||
typedef struct { |
||||
i2c_t i2c; /**< I2C device the sensor is connected to */ |
||||
uint8_t address; /**< I2C bus address of the sensor */ |
||||
} lps331ap_t; |
||||
|
||||
/**
|
||||
* @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 Initialize a given LPS331AP pressure sensor |
||||
* |
||||
* @param[out] dev device descriptor of the sensor |
||||
* @param[in] i2c I2C bus the sensor is connected to |
||||
* @param[in] address the sensor's address on the I2C bus |
||||
* @param[in] rate internal sampling rate of the sensor |
||||
* |
||||
* @return 0 on success |
||||
* @return -1 on error |
||||
*/ |
||||
int lps331ap_init(lps331ap_t *dev, i2c_t i2c, uint8_t address, lps331ap_rate_t rate); |
||||
|
||||
/**
|
||||
* @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(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(lps331ap_t *dev); |
||||
|
||||
/**
|
||||
* @brief Enable the given sensor |
||||
* |
||||
* @param[in] dev device descriptor of sensor to enable |
||||
* |
||||
* @return 0 on success |
||||
* @return -1 on error |
||||
*/ |
||||
int lps331ap_enable(lps331ap_t *dev); |
||||
|
||||
/**
|
||||
* @brief Disable the given sensor |
||||
* |
||||
* @param[in] dev device descriptor of sensor to disable |
||||
* |
||||
* @return 0 on success |
||||
* @return -1 on error |
||||
*/ |
||||
int lps331ap_disable(lps331ap_t *dev); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __LPS331AP_H */ |
||||
/** @} */ |
@ -0,0 +1,3 @@
|
||||
MODULE = lps331ap
|
||||
|
||||
include $(RIOTBASE)/Makefile.base |
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 driver_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 */ |
||||
/** @} */ |
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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 driver_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> |
||||
* |
||||
* @} |
||||
*/ |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "periph/i2c.h" |
||||
#include "lps331ap.h" |
||||
#include "lps331ap-internal.h" |
||||
|
||||
/**
|
||||
* @brief default I2C bus speed for this sensor |
||||
*/ |
||||
#define BUS_SPEED I2C_SPEED_FAST |
||||
|
||||
/**
|
||||
* @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) |
||||
|
||||
|
||||
int lps331ap_init(lps331ap_t *dev, i2c_t i2c, uint8_t address, lps331ap_rate_t rate) |
||||
{ |
||||
char tmp; |
||||
|
||||
/* save device specifics */ |
||||
dev->i2c = i2c; |
||||
dev->address = address; |
||||
|
||||
/* initialize underlying I2C bus */ |
||||
if (i2c_init_master(dev->i2c, BUS_SPEED) < 0) { |
||||
return -1; |
||||
} |
||||
|
||||
/* configure device, for simple operation only CTRL_REG1 needs to be touched */ |
||||
tmp = LPS331AP_CTRL_REG1_DBDU | LPS331AP_CTRL_REG1_PD | |
||||
(rate << LPS331AP_CTRL_REG1_ODR_POS); |
||||
if (i2c_write_reg(dev->i2c, dev->address, LPS331AP_REG_CTRL_REG1, tmp) != 1) { |
||||
return -1; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int lps331ap_read_temp(lps331ap_t *dev) |
||||
{ |
||||
char tmp; |
||||
int16_t val = 0; |
||||
float res = TEMP_BASE; /* reference value -> see datasheet */ |
||||
|
||||
i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_TEMP_OUT_L, &tmp); |
||||
val |= tmp; |
||||
i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_TEMP_OUT_H, &tmp); |
||||
val |= (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(lps331ap_t *dev) |
||||
{ |
||||
char tmp; |
||||
int32_t val = 0; |
||||
float res; |
||||
|
||||
i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_PRESS_OUT_XL, &tmp); |
||||
val |= tmp; |
||||
i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_PRESS_OUT_L, &tmp); |
||||
val |= (tmp << 8); |
||||
i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_PRESS_OUT_H, &tmp); |
||||
val |= (tmp << 16); |
||||
/* see if value is negative */ |
||||
if (tmp & 0x80) { |
||||
val |= (0xff << 24); |
||||
} |
||||
|
||||
/* compute actual pressure value in mbar */ |
||||
res = ((float)val) / PRES_DIVIDER; |
||||
|
||||
return (int)res; |
||||
} |
||||
|
||||
|
||||
int lps331ap_enable(lps331ap_t *dev) |
||||
{ |
||||
char tmp; |
||||
if (i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_CTRL_REG1, &tmp) != 1) { |
||||
return -1; |
||||
} |
||||
tmp |= (LPS331AP_CTRL_REG1_PD); |
||||
return i2c_write_reg(dev->i2c, dev->address, LPS331AP_REG_CTRL_REG1, tmp); |
||||
} |
||||
|
||||
int lps331ap_disable(lps331ap_t *dev) |
||||
{ |
||||
char tmp; |
||||
if (i2c_read_reg(dev->i2c, dev->address, LPS331AP_REG_CTRL_REG1, &tmp) != 1) { |
||||
return -1; |
||||
} |
||||
tmp &= ~(LPS331AP_CTRL_REG1_PD); |
||||
return i2c_write_reg(dev->i2c, dev->address, LPS331AP_REG_CTRL_REG1, tmp); |
||||
} |
Loading…
Reference in new issue