
9 changed files with 851 additions and 0 deletions
@ -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_ */ |
@ -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 */ |
@ -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