drivers/at30tse75x: add device driver for AT30TSE75x temperature sensor
This commit is contained in:
parent
be8f63769c
commit
396b76c039
|
@ -425,6 +425,10 @@ ifneq (,$(filter ltc4150,$(USEMODULE)))
|
|||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
USEMODULE += vtimer
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include $(RIOTBASE)/Makefile.base
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Copyright (C) Daniel Krebs
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Driver for the AT30TSE75x temperature sensor with serial EEPROM
|
||||
*
|
||||
* @author Daniel Krebs <github@daniel-krebs.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "periph/i2c.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#include "at30tse75x.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static inline float temperature_to_float(uint16_t temp)
|
||||
{
|
||||
/* Integer part is 8-bit signed */
|
||||
int8_t temp_int = (temp & AT30TSE75X_INTEGER_MASK) >>
|
||||
AT30TSE75X_INTEGER_SHIFT;
|
||||
/* Fractional part is multiple of 0.0625 */
|
||||
uint8_t frac_multiplier = (temp & AT30TSE75X_FRACTIONAL_MASK) >>
|
||||
AT30TSE75X_FRACTIONAL_SHIFT;
|
||||
|
||||
return temp_int + (frac_multiplier * AT30TSE75X_FRACTIONAL_BASE);
|
||||
}
|
||||
|
||||
static int at30tse75x_get_register(at30tse75x_t* dev, uint8_t reg, uint16_t* data)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_read_regs(dev->i2c, dev->addr, reg, (char*) data, 2) <= 0) {
|
||||
DEBUG("[at30tse75x] Can't read register 0x%x\n", reg);
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at30tse75x_set_register(at30tse75x_t* dev, uint8_t reg, uint16_t* data)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_write_regs(dev->i2c, dev->addr, reg, (char*) data, 2) <= 0) {
|
||||
DEBUG("[at30tse75x] Can't write to register 0x%x\n", reg);
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int at30tse75x_reset(at30tse75x_t* dev)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_write_byte(dev->i2c, 0x00, AT30TSE75X_CMD__GENERAL_CALL_RESET) != 1) {
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
/* Wait for reset to complete */
|
||||
xtimer_usleep(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_get_config(at30tse75x_t* dev, uint8_t* data)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_read_reg(dev->i2c, dev->addr, AT30TSE75X_REG__CONFIG, (char*) data) <= 0) {
|
||||
DEBUG("[at30tse75x] Can't read CONFIG register\n");
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_config(at30tse75x_t* dev, uint8_t data)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_write_reg(dev->i2c, dev->addr, AT30TSE75X_REG__CONFIG, (char) data) <= 0) {
|
||||
DEBUG("[at30tse75x] Can't write to CONFIG register\n");
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_resolution(at30tse75x_t* dev, at30tse75x_resolution_t resolution)
|
||||
{
|
||||
uint8_t config;
|
||||
|
||||
if(resolution < AT30TSE75X_RESOLUTION_9BIT ||
|
||||
resolution > AT30TSE75X_RESOLUTION_12BIT) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
config &= ~(AT30TSE75X_CONFIG__RESOLUTION_MASK);
|
||||
config |= resolution << AT30TSE75X_CONFIG__RESOLUTION_SHIFT;
|
||||
|
||||
if(at30tse75x_set_config(dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_mode(at30tse75x_t* dev, at30tse75x_mode_t mode)
|
||||
{
|
||||
uint8_t config;
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case AT30TSE75X_MODE_ONE_SHOT:
|
||||
config |= AT30TSE75X_CONFIG__SHUTDOWN_BIT;
|
||||
/* Don't touch alarm mode */
|
||||
break;
|
||||
case AT30TSE75X_MODE_COMPARATOR:
|
||||
config &= ~(AT30TSE75X_CONFIG__SHUTDOWN_BIT);
|
||||
config &= ~(AT30TSE75X_CONFIG__ALARM_MODE_BIT);
|
||||
break;
|
||||
case AT30TSE75X_MODE_INTERRUPT:
|
||||
config &= ~(AT30TSE75X_CONFIG__SHUTDOWN_BIT);
|
||||
config |= AT30TSE75X_CONFIG__ALARM_MODE_BIT;
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(at30tse75x_set_config(dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_alarm_polarity(at30tse75x_t* dev, at30tse75x_alarm_polatity_t polarity)
|
||||
{
|
||||
uint8_t config;
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(polarity) {
|
||||
case AT30TSE75X_ALARM_ACTIVE_HIGH:
|
||||
config |= AT30TSE75X_CONFIG__ALERT_POL_BIT;
|
||||
break;
|
||||
case AT30TSE75X_ALARM_ACTIVE_LOW:
|
||||
config &= ~(AT30TSE75X_CONFIG__ALERT_POL_BIT);
|
||||
break;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(at30tse75x_set_config(dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_fault_tolerance(at30tse75x_t* dev, at30tse75x_fault_tolerance_t tolerance)
|
||||
{
|
||||
if(tolerance < AT30TSE75X_ALARM_AFTER_1 ||
|
||||
tolerance > AT30TSE75X_ALARM_AFTER_6) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
uint8_t config;
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
config &= ~(AT30TSE75X_CONFIG__FTQ_MASK);
|
||||
config |= tolerance << AT30TSE75X_CONFIG__FTQ_SHIFT;
|
||||
|
||||
if(at30tse75x_set_config(dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_set_limit_low(at30tse75x_t* dev, int8_t t_low)
|
||||
{
|
||||
uint16_t tmp = (t_low << 8) | (0x00);
|
||||
return at30tse75x_set_register(dev, AT30TSE75X_REG__LIMIT_LOW, &tmp);
|
||||
}
|
||||
|
||||
int at30tse75x_set_limit_high(at30tse75x_t* dev, int8_t t_high)
|
||||
{
|
||||
uint16_t tmp = (t_high << 8) | (0x00);
|
||||
return at30tse75x_set_register(dev, AT30TSE75X_REG__LIMIT_HIGH, &tmp);
|
||||
}
|
||||
|
||||
int at30tse75x_save_config(at30tse75x_t* dev)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_write_byte(dev->i2c, dev->addr, AT30TSE75X_CMD__SAVE_TO_NVRAM) != 1) {
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
/* Wait for copy to complete */
|
||||
xtimer_usleep(5000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_restore_config(at30tse75x_t* dev)
|
||||
{
|
||||
i2c_acquire(dev->i2c);
|
||||
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
|
||||
if(i2c_write_byte(dev->i2c, dev->addr, AT30TSE75X_CMD__RESTORE_FROM_NVRAM) != 1) {
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
/* Wait for copy to complete */
|
||||
xtimer_usleep(200);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_get_temperature(at30tse75x_t* dev, float* temperature)
|
||||
{
|
||||
uint16_t tmp;
|
||||
uint8_t config;
|
||||
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If sensor is shutdown trigger One-Shot mode*/
|
||||
if(config & AT30TSE75X_CONFIG__SHUTDOWN_BIT) {
|
||||
|
||||
config |= AT30TSE75X_CONFIG__OS_BIT;
|
||||
if(at30tse75x_set_config(dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Use resolution to calculate conversion time */
|
||||
uint8_t resolution = (config & AT30TSE75X_CONFIG__RESOLUTION_MASK) >>
|
||||
AT30TSE75X_CONFIG__RESOLUTION_SHIFT;
|
||||
|
||||
/* Wait until conversion is finished */
|
||||
xtimer_usleep((uint32_t)(25000 << resolution));
|
||||
}
|
||||
|
||||
/* Read temperature */
|
||||
if(at30tse75x_get_register(dev, AT30TSE75X_REG__TEMPERATURE, &tmp) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Convert fixed point to float */
|
||||
*temperature = temperature_to_float(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int at30tse75x_init(at30tse75x_t* dev, i2c_t i2c, i2c_speed_t speed, uint8_t addr)
|
||||
{
|
||||
uint8_t config;
|
||||
|
||||
dev->i2c = i2c;
|
||||
|
||||
if( (addr < 0x48) || (addr > 0x4f) ) {
|
||||
DEBUG("[at30tse75x] Invalid address\n");
|
||||
return -2;
|
||||
}
|
||||
dev->addr = addr;
|
||||
|
||||
i2c_acquire(dev->i2c);
|
||||
if(i2c_init_master(dev->i2c, speed) != 0) {
|
||||
DEBUG("[at30tse75x] Can't initialize I2C master\n");
|
||||
i2c_release(dev->i2c);
|
||||
return -1;
|
||||
}
|
||||
i2c_release(dev->i2c);
|
||||
|
||||
/* Reset the device */
|
||||
if(at30tse75x_reset(dev) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Poll the device, fail if unavailable */
|
||||
if(at30tse75x_get_config(dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG("[at30tse75x] Config: 0x%x\n", config);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* Copyright (C) Daniel Krebs
|
||||
*
|
||||
* 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 at30tse75x AT30TSE75x temperature sensor with EEPROM
|
||||
* @ingroup drivers
|
||||
*
|
||||
* The connection between the MCU and the AT30TSE75x is based on the
|
||||
* I2C-interface. There are 3 versions of this IC, with either 2/4/8 Kb of
|
||||
* EEPROM.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Driver for the AT30TSE75x temperature sensor with serial EEPROM
|
||||
*
|
||||
* @author Daniel Krebs <github@daniel-krebs.net>
|
||||
*/
|
||||
|
||||
#ifndef AT30TSE75X_H_
|
||||
#define AT30TSE75X_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "periph/i2c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x I2C addresses
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_TEMP_ADDR (0x48)
|
||||
#define AT30TSE75X_EEPROM_ADDR (0x50)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x register addresses
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_REG__TEMPERATURE (0x00)
|
||||
#define AT30TSE75X_REG__CONFIG (0x01)
|
||||
#define AT30TSE75X_REG__LIMIT_LOW (0x02)
|
||||
#define AT30TSE75X_REG__LIMIT_HIGH (0x03)
|
||||
#define AT30TSE75X_REG__NV_CONFIG (0x11)
|
||||
#define AT30TSE75X_REG__NV_LIMIT_LOW (0x12)
|
||||
#define AT30TSE75X_REG__NV_LIMIR_HIGH (0x13)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x number formatting
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_INTEGER_MASK (0x00ff)
|
||||
#define AT30TSE75X_INTEGER_SHIFT (0)
|
||||
#define AT30TSE75X_FRACTIONAL_MASK (0xf000)
|
||||
#define AT30TSE75X_FRACTIONAL_SHIFT (12)
|
||||
#define AT30TSE75X_FRACTIONAL_BASE (0.0625f)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x configuration register
|
||||
*
|
||||
* Only upper byte can be read/written, so treat as 8-bit register.
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_CONFIG__OS_BIT (1 << 7)
|
||||
#define AT30TSE75X_CONFIG__RESOLUTION_MASK (0x60)
|
||||
#define AT30TSE75X_CONFIG__RESOLUTION_SHIFT (5)
|
||||
#define AT30TSE75X_CONFIG__FTQ_MASK (0x18)
|
||||
#define AT30TSE75X_CONFIG__FTQ_SHIFT (3)
|
||||
#define AT30TSE75X_CONFIG__ALERT_POL_BIT (1 << 2)
|
||||
#define AT30TSE75X_CONFIG__ALARM_MODE_BIT (1 << 1)
|
||||
#define AT30TSE75X_CONFIG__SHUTDOWN_BIT (1 << 0)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x commands
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_CMD__SAVE_TO_NVRAM (0x48)
|
||||
#define AT30TSE75X_CMD__RESTORE_FROM_NVRAM (0xb8)
|
||||
#define AT30TSE75X_CMD__GENERAL_CALL_RESET (0x06)
|
||||
#define AT30TSE75X_CMD__GENERAL_CALL_RELATCH (0x04)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x constants
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define AT30TSE75X_BUS_FREE_TIME_US (1U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name AT30TSE75x configuration types
|
||||
*
|
||||
* @brief Temperature resolution
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
AT30TSE75X_RESOLUTION_9BIT = 0,
|
||||
AT30TSE75X_RESOLUTION_10BIT = 1,
|
||||
AT30TSE75X_RESOLUTION_11BIT = 2,
|
||||
AT30TSE75X_RESOLUTION_12BIT = 3
|
||||
} at30tse75x_resolution_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Operation mode
|
||||
*
|
||||
* The device can run in continous or one-shot mode. While in one-shot mode it
|
||||
* is effectively shutdown and only wakes up to perform a single measurement.
|
||||
* When in comparator or interrupt mode, the device samples contiously the
|
||||
* temperature and sets the ALERT pin according to the chosen mode.
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
AT30TSE75X_MODE_COMPARATOR,
|
||||
AT30TSE75X_MODE_INTERRUPT,
|
||||
AT30TSE75X_MODE_ONE_SHOT
|
||||
} at30tse75x_mode_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief After how many limit exceeding measurements the ALERT pin is set
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
AT30TSE75X_ALARM_AFTER_1 = 0,
|
||||
AT30TSE75X_ALARM_AFTER_2 = 1,
|
||||
AT30TSE75X_ALARM_AFTER_4 = 2,
|
||||
AT30TSE75X_ALARM_AFTER_6 = 3
|
||||
} at30tse75x_fault_tolerance_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Polarity of the ALERT pin
|
||||
* @{
|
||||
*/
|
||||
typedef enum {
|
||||
AT30TSE75X_ALARM_ACTIVE_LOW,
|
||||
AT30TSE75X_ALARM_ACTIVE_HIGH
|
||||
} at30tse75x_alarm_polatity_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for a AT30TSE75x device
|
||||
* @{
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< I2C device that sensor is connected to */
|
||||
uint8_t addr; /**< I2C address of this particular sensor */
|
||||
} at30tse75x_t;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Initialize a AT30TSE75x device
|
||||
*
|
||||
* @param[out] dev device descriptor
|
||||
* @param[in] i2c I2C bus the device is connected to
|
||||
* @param[in] speed I2C speed to use
|
||||
* @param[in] addr I2C address of the device
|
||||
*
|
||||
* The valid address range is 0x48 - 0x4f depending on the configuration of the
|
||||
* address pins A0-A2.
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
* @return -2 on invalid address
|
||||
*/
|
||||
int at30tse75x_init(at30tse75x_t* dev, i2c_t i2c, i2c_speed_t speed, uint8_t addr);
|
||||
|
||||
/**
|
||||
* @brief Save configuration register to non-volatile backup register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_save_config(at30tse75x_t* dev);
|
||||
|
||||
/**
|
||||
* @brief Restore configuration register from non-volatile backup register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_restore_config(at30tse75x_t* dev);
|
||||
|
||||
/**
|
||||
* @brief Get content of configuration register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] data buffer where config register will be written to
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_get_config(at30tse75x_t* dev, uint8_t* data);
|
||||
|
||||
/**
|
||||
* @brief Set content of configuration register
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] data new value for configuration register
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_set_config(at30tse75x_t* dev, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Set temperature resolution
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] resolution temperature resolution
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
* @return -2 on bad user input
|
||||
*/
|
||||
int at30tse75x_set_resolution(at30tse75x_t* dev, at30tse75x_resolution_t resolution);
|
||||
|
||||
/**
|
||||
* @brief Set operation mode
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] mode operation mode
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on device error
|
||||
* @return -2 on bad user input
|
||||
*/
|
||||
int at30tse75x_set_mode(at30tse75x_t* dev, at30tse75x_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set polarity of ALERT pin
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] polarity polarity of ALERT pin
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on device error
|
||||
* @return -2 on bad user input
|
||||
*/
|
||||
int at30tse75x_set_alarm_polarity(at30tse75x_t* dev, at30tse75x_alarm_polatity_t polarity);
|
||||
|
||||
/**
|
||||
* @brief Set tolerance to outlying measurements
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] tolerance tolerance
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on device error
|
||||
* @return -2 on bad user input
|
||||
*/
|
||||
int at30tse75x_set_fault_tolerance(at30tse75x_t* dev, at30tse75x_fault_tolerance_t tolerance);
|
||||
|
||||
/**
|
||||
* @brief Set T_Low limit
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] t_low lower temperature limit
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on device error
|
||||
* @return -2 on bad user input
|
||||
*/
|
||||
int at30tse75x_set_limit_low(at30tse75x_t* dev, int8_t t_low);
|
||||
|
||||
/**
|
||||
* @brief Set T_High limit
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[in] t_high upper temperature limit
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_set_limit_high(at30tse75x_t* dev, int8_t t_high);
|
||||
|
||||
/**
|
||||
* @brief Get measured temperature
|
||||
*
|
||||
* @param[in] dev device descriptor
|
||||
* @param[out] temperature float buffer where temperature will be written to
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int at30tse75x_get_temperature(at30tse75x_t* dev, float* temperature);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* AT30TSE75X_H_ */
|
|
@ -38,6 +38,9 @@ endif
|
|||
ifneq (,$(filter lsm303dlhc,$(USEMODULE)))
|
||||
SRC += sc_lsm303dlhc.c
|
||||
endif
|
||||
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
||||
SRC += sc_at30tse75x.c
|
||||
endif
|
||||
ifneq (,$(filter gnrc_netif,$(USEMODULE)))
|
||||
SRC += sc_netif.c
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Daniel Krebs
|
||||
*
|
||||
* 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_shell_commands
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Provides shell commands to test AT30TSE75x temperature sensor
|
||||
*
|
||||
* @author Daniel Krebs <github@daniel-krebs.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "at30tse75x.h"
|
||||
|
||||
#ifdef MODULE_AT30TSE75X
|
||||
|
||||
static bool initialized = false;
|
||||
static at30tse75x_t dev;
|
||||
|
||||
int _at30tse75x_handler(int argc, char **argv)
|
||||
{
|
||||
if(argc <= 1) {
|
||||
printf("Usage: %s init|read|mode|resolution|save|restore|config\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1], "init") == 0) {
|
||||
if(argc == 2) {
|
||||
printf("Usage: %s init #I2C [addr]\n"
|
||||
" e.g. %s init 0\n", argv[0], argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int error;
|
||||
unsigned addr = 0x48; /* default to A0-A2 connected to GND */
|
||||
|
||||
/* Try to parse i2c dev */
|
||||
i2c_t i2c_dev = (i2c_t) strtol(argv[2], &argv[1] + 1, 10);
|
||||
|
||||
/* Address given */
|
||||
if(argc == 4) {
|
||||
char* hex = strstr(argv[3], "0x");
|
||||
if(hex) {
|
||||
addr = strtoul(hex+2, NULL, 16);
|
||||
}
|
||||
}
|
||||
|
||||
error = at30tse75x_init(&dev, i2c_dev, I2C_SPEED_NORMAL, addr);
|
||||
if (error) {
|
||||
printf("Error initializing AT30TSE75x sensor on I2C #%u @ 0x%x\n", i2c_dev, addr);
|
||||
initialized = false;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
printf("Initialized AT30TSE75x sensor on I2C #%u @ 0x%x\n", i2c_dev, addr);
|
||||
initialized = true;
|
||||
}
|
||||
} else {
|
||||
if(!initialized) {
|
||||
puts("Please initialize first");
|
||||
return -1;
|
||||
}
|
||||
if(strcmp(argv[1], "read") == 0) {
|
||||
float temperature;
|
||||
if(at30tse75x_get_temperature(&dev, &temperature) != 0) {
|
||||
puts("Reading temperature failed");
|
||||
return -1;
|
||||
}
|
||||
printf("Temperature: %i.%03u °C\n",
|
||||
(int)temperature,
|
||||
(unsigned)((temperature - (int)temperature) * 1000));
|
||||
} else if(strcmp(argv[1], "mode") == 0) {
|
||||
if(argc == 2) {
|
||||
printf("Usage: %s mode one-shot|comparator|interrupt\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
at30tse75x_mode_t mode;
|
||||
if(strcmp(argv[2], "one-shot") == 0) {
|
||||
mode = AT30TSE75X_MODE_ONE_SHOT;
|
||||
} else if(strcmp(argv[2], "comparator") == 0) {
|
||||
mode = AT30TSE75X_MODE_COMPARATOR;
|
||||
} else if(strcmp(argv[2], "interrupt") == 0) {
|
||||
mode = AT30TSE75X_MODE_INTERRUPT;
|
||||
} else {
|
||||
puts("Invalid mode");
|
||||
return -1;
|
||||
}
|
||||
if(at30tse75x_set_mode(&dev, mode) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Mode set to %s\n", argv[2]);
|
||||
} else if(strcmp(argv[1], "resolution") == 0) {
|
||||
if(argc == 2) {
|
||||
printf("Usage: %s resolution 9|10|11|12\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
unsigned resolution = strtoul(argv[2], NULL, 10);
|
||||
if(at30tse75x_set_resolution(&dev, resolution - 9) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Resolution set to %u bits\n", resolution);
|
||||
} else if(strcmp(argv[1], "save") == 0) {
|
||||
uint8_t config;
|
||||
if(at30tse75x_get_config(&dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if(at30tse75x_save_config(&dev) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Config (0x%x) saved\n", config);
|
||||
} else if(strcmp(argv[1], "restore") == 0) {
|
||||
uint8_t config;
|
||||
if(at30tse75x_restore_config(&dev) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if(at30tse75x_get_config(&dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Config restored to 0x%x\n", config);
|
||||
|
||||
} else if(strcmp(argv[1], "config") == 0) {
|
||||
if(argc == 2) {
|
||||
uint8_t config;
|
||||
if(at30tse75x_get_config(&dev, &config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Config: 0x%x\n", config);
|
||||
} else {
|
||||
/* Try to parse config in hex format */
|
||||
uint8_t config;
|
||||
char* hex = strstr(argv[2], "0x");
|
||||
if(!hex) {
|
||||
printf("Usage: %s config 0x__"
|
||||
" to set config\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
config = strtoul(hex+2, NULL, 16);
|
||||
if(at30tse75x_set_config(&dev, config) != 0) {
|
||||
return -1;
|
||||
}
|
||||
printf("Config set to: 0x%x\n", config);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* MODULE_AT30TSE75X */
|
|
@ -69,6 +69,10 @@ extern int _get_current_handler(int argc, char **argv);
|
|||
extern int _reset_current_handler(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#ifdef MODULE_AT30TSE75X
|
||||
extern int _at30tse75x_handler(int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#if FEATURE_PERIPH_RTC
|
||||
extern int _rtc_handler(int argc, char **argv);
|
||||
#endif
|
||||
|
@ -167,6 +171,9 @@ const shell_command_t _shell_command_list[] = {
|
|||
{"cur", "Prints current and average power consumption.", _get_current_handler},
|
||||
{"rstcur", "Resets coulomb counter.", _reset_current_handler},
|
||||
#endif
|
||||
#ifdef MODULE_AT30TSE75X
|
||||
{"at30tse75x", "Test AT30TSE75X temperature sensor", _at30tse75x_handler},
|
||||
#endif
|
||||
#ifdef MODULE_MCI
|
||||
{DISK_READ_SECTOR_CMD, "Reads the specified sector of inserted memory card", _read_sector},
|
||||
{DISK_READ_BYTES_CMD, "Reads the specified bytes from inserted memory card", _read_bytes},
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
APPLICATION = driver_at30tse75x
|
||||
include ../Makefile.tests_common
|
||||
|
||||
FEATURES_REQUIRED = periph_i2c
|
||||
|
||||
USEMODULE += at30tse75x
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
|
||||
CFLAGS += -DDEVELHELP
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Daniel Krebs
|
||||
*
|
||||
* 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 AT30TSE75x temperature sensor
|
||||
*
|
||||
* @author Daniel Krebs <github@daniel-krebs.net>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "shell.h"
|
||||
#include "shell_commands.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("AT30TSE75x device driver test");
|
||||
|
||||
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
|
||||
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue