drivers: sensor: add ti tmp108 driver support
Adding support for the TI TMP108 temperature sensor. This includes over/under temp interrupt support as well as one shot, continuous conversion and power down modes. Signed-off-by: Jimmy Johnson <catch22@fastmail.net>
This commit is contained in:
parent
d170079815
commit
5c28b218fa
11 changed files with 690 additions and 0 deletions
|
@ -89,6 +89,7 @@ add_subdirectory_ifdef(CONFIG_STTS751 stts751)
|
|||
add_subdirectory_ifdef(CONFIG_SX9500 sx9500)
|
||||
add_subdirectory_ifdef(CONFIG_TH02 th02)
|
||||
add_subdirectory_ifdef(CONFIG_TMP007 tmp007)
|
||||
add_subdirectory_ifdef(CONFIG_TMP108 tmp108)
|
||||
add_subdirectory_ifdef(CONFIG_TMP112 tmp112)
|
||||
add_subdirectory_ifdef(CONFIG_TMP116 tmp116)
|
||||
add_subdirectory_ifdef(CONFIG_VCNL4040 vcnl4040)
|
||||
|
|
|
@ -216,6 +216,8 @@ source "drivers/sensor/th02/Kconfig"
|
|||
|
||||
source "drivers/sensor/tmp007/Kconfig"
|
||||
|
||||
source "drivers/sensor/tmp108/Kconfig"
|
||||
|
||||
source "drivers/sensor/tmp112/Kconfig"
|
||||
|
||||
source "drivers/sensor/tmp116/Kconfig"
|
||||
|
|
5
drivers/sensor/tmp108/CMakeLists.txt
Normal file
5
drivers/sensor/tmp108/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(tmp108.c tmp108_trigger.c)
|
20
drivers/sensor/tmp108/Kconfig
Normal file
20
drivers/sensor/tmp108/Kconfig
Normal file
|
@ -0,0 +1,20 @@
|
|||
# TMP108 temperature sensor configuration options
|
||||
|
||||
# Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menuconfig TMP108
|
||||
bool "TMP108 Temperature Sensor"
|
||||
depends on I2C
|
||||
help
|
||||
Enable driver for the TMP108 temperature sensor.
|
||||
|
||||
if TMP108
|
||||
|
||||
config TMP108_ALERT_INTERRUPTS
|
||||
bool "Allow interrupts to service over and under temp alerts"
|
||||
help
|
||||
This will set up interrupts to service under and over temp alerts
|
||||
see TMP108 spec sheet for more information on how these work.
|
||||
|
||||
endif # TMP108
|
401
drivers/sensor/tmp108/tmp108.c
Normal file
401
drivers/sensor/tmp108/tmp108.c
Normal file
|
@ -0,0 +1,401 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ti_tmp108
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/i2c.h>
|
||||
#include <drivers/sensor.h>
|
||||
#include <sys/util.h>
|
||||
#include <sys/byteorder.h>
|
||||
#include <logging/log.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include "tmp108.h"
|
||||
|
||||
LOG_MODULE_REGISTER(TMP108, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
/** TI conversion scale from 16 bit int temp value to float */
|
||||
#define TMP108_TEMP_MULTIPLIER 62500
|
||||
|
||||
/** TMP typical conversion time of 27 ms after waking from sleep */
|
||||
#define TMP108_WAKEUP_TIME_IN_MS 30
|
||||
|
||||
struct tmp108_config {
|
||||
const struct i2c_dt_spec i2c_spec;
|
||||
const struct gpio_dt_spec alert_gpio;
|
||||
};
|
||||
|
||||
int tmp108_reg_read(const struct device *dev, uint8_t reg, uint16_t *val)
|
||||
{
|
||||
const struct tmp108_config *cfg = dev->config;
|
||||
int result;
|
||||
|
||||
result = i2c_burst_read_dt(&cfg->i2c_spec, reg, (uint8_t *) val, 2);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
*val = sys_be16_to_cpu(*val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmp108_reg_write(const struct device *dev, uint8_t reg, uint16_t val)
|
||||
{
|
||||
const struct tmp108_config *cfg = dev->config;
|
||||
uint8_t tx_buf[3];
|
||||
int result;
|
||||
|
||||
tx_buf[0] = reg;
|
||||
sys_put_be16(val, &tx_buf[1]);
|
||||
|
||||
result = i2c_write_dt(&cfg->i2c_spec, tx_buf, sizeof(tx_buf));
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmp108_write_config(const struct device *dev, uint16_t mask, uint16_t conf)
|
||||
{
|
||||
uint16_t config = 0;
|
||||
int result;
|
||||
|
||||
result = tmp108_reg_read(dev, TI_TMP108_REG_CONF, &config);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
config &= mask;
|
||||
config |= conf;
|
||||
|
||||
result = tmp108_reg_write(dev, TI_TMP108_REG_CONF, config);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ti_tmp108_read_temp(const struct device *dev)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
int result;
|
||||
|
||||
/* clear previous temperature readings */
|
||||
|
||||
drv_data->sample = 0U;
|
||||
|
||||
/* Get the most recent temperature measurement */
|
||||
|
||||
result = tmp108_reg_read(dev, TI_TMP108_REG_TEMP, &drv_data->sample);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmp108_sample_fetch(const struct device *dev,
|
||||
enum sensor_channel chan)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
int result;
|
||||
|
||||
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* If one shot mode is set, query chip for reading
|
||||
* should be finished 30 ms later
|
||||
*/
|
||||
if (drv_data->one_shot_mode == true) {
|
||||
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_MODE_MASK,
|
||||
TI_TMP108_MODE_ONE_SHOT);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Schedule read to start in 30 ms if mode change was successful
|
||||
* the typical wakeup time given in the data sheet is 27
|
||||
*/
|
||||
result = k_work_schedule(&drv_data->scheduled_work,
|
||||
K_MSEC(TMP108_WAKEUP_TIME_IN_MS));
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
result = ti_tmp108_read_temp(dev);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmp108_channel_get(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
int32_t uval;
|
||||
|
||||
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
uval = (int32_t)(drv_data->sample >> 4U) * TMP108_TEMP_MULTIPLIER;
|
||||
val->val1 = uval / 1000000U;
|
||||
val->val2 = uval % 1000000U;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmp108_attr_get(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (chan != SENSOR_CHAN_AMBIENT_TEMP && chan != SENSOR_CHAN_ALL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch ((int) attr) {
|
||||
case SENSOR_ATTR_CONFIGURATION:
|
||||
result = tmp108_reg_read(dev,
|
||||
TI_TMP108_REG_CONF,
|
||||
(uint16_t *) &(val->val1));
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int tmp108_attr_set(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
uint16_t mode = 0;
|
||||
uint16_t reg_value = 0;
|
||||
int result = 0;
|
||||
|
||||
if (chan != SENSOR_CHAN_AMBIENT_TEMP && chan != SENSOR_CHAN_ALL) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch ((int) attr) {
|
||||
case SENSOR_ATTR_HYSTERESIS:
|
||||
if (val->val1 < 1) {
|
||||
mode = TI_TMP108_HYSTER_0_C;
|
||||
} else if (val->val1 < 2) {
|
||||
mode = TI_TMP108_HYSTER_1_C;
|
||||
} else if (val->val1 < 4) {
|
||||
mode = TI_TMP108_HYSTER_2_C;
|
||||
} else {
|
||||
mode = TI_TMP108_HYSTER_4_C;
|
||||
}
|
||||
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_HYSTER_MASK,
|
||||
mode);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_ALERT:
|
||||
/* Spec Sheet Errata: TM is set on reset not cleared */
|
||||
if (val->val1 == 1) {
|
||||
mode = TI_TMP108_CONF_TM_INT;
|
||||
} else {
|
||||
mode = TI_TMP108_CONF_TM_CMP;
|
||||
}
|
||||
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_CONF_TM_MASK,
|
||||
mode);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_LOWER_THRESH:
|
||||
reg_value = (val->val1 << 8) | (0x00FF & val->val2);
|
||||
result = tmp108_reg_write(dev,
|
||||
TI_TMP108_REG_LOW_LIMIT,
|
||||
reg_value);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_UPPER_THRESH:
|
||||
reg_value = (val->val1 << 8) | (0x00FF & val->val2);
|
||||
result = tmp108_reg_write(dev,
|
||||
TI_TMP108_REG_HIGH_LIMIT,
|
||||
reg_value);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_SAMPLING_FREQUENCY:
|
||||
if (val->val1 < 1) {
|
||||
mode = TI_TMP108_FREQ_4_SECS;
|
||||
} else if (val->val1 < 4) {
|
||||
mode = TI_TMP108_FREQ_1_HZ;
|
||||
} else if (val->val1 < 16) {
|
||||
mode = TI_TMP108_FREQ_4_HZ;
|
||||
} else {
|
||||
mode = TI_TMP108_FREQ_16_HZ;
|
||||
}
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_FREQ_MASK,
|
||||
mode);
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_TMP108_SHUTDOWN_MODE:
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_MODE_MASK,
|
||||
TI_TMP108_MODE_SHUTDOWN);
|
||||
drv_data->one_shot_mode = false;
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_TMP108_CONTINUOUS_CONVERSION_MODE:
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_MODE_MASK,
|
||||
TI_TMP108_MODE_CONTINUOUS);
|
||||
drv_data->one_shot_mode = false;
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_TMP108_ONE_SHOT_MODE:
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_MODE_MASK,
|
||||
TI_TMP108_MODE_ONE_SHOT);
|
||||
drv_data->one_shot_mode = true;
|
||||
break;
|
||||
|
||||
case SENSOR_ATTR_TMP108_ALERT_POLARITY:
|
||||
if (val->val1 == 1) {
|
||||
mode = TI_TMP108_CONF_POL_HIGH;
|
||||
} else {
|
||||
mode = TI_TMP108_CONF_POL_LOW;
|
||||
}
|
||||
result = tmp108_write_config(dev,
|
||||
TI_TMP108_CONF_POL_MASK,
|
||||
mode);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api tmp108_driver_api = {
|
||||
.attr_set = tmp108_attr_set,
|
||||
.attr_get = tmp108_attr_get,
|
||||
.sample_fetch = tmp108_sample_fetch,
|
||||
.channel_get = tmp108_channel_get,
|
||||
.trigger_set = tmp_108_trigger_set,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TMP108_ALERT_INTERRUPTS
|
||||
static int setup_interrupts(const struct device *dev)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
const struct tmp108_config *config = dev->config;
|
||||
const struct gpio_dt_spec *alert_gpio = &config->alert_gpio;
|
||||
int result;
|
||||
|
||||
if (!device_is_ready(alert_gpio->port)) {
|
||||
LOG_ERR("tmp108: gpio controller %s not ready",
|
||||
alert_gpio->port->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
result = gpio_pin_configure_dt(alert_gpio, GPIO_INPUT);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
gpio_init_callback(&drv_data->temp_alert_gpio_cb,
|
||||
tmp108_trigger_handle_alert,
|
||||
BIT(alert_gpio->pin));
|
||||
|
||||
result = gpio_add_callback(alert_gpio->port,
|
||||
&drv_data->temp_alert_gpio_cb);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = gpio_pin_interrupt_configure_dt(alert_gpio,
|
||||
GPIO_INT_EDGE_BOTH);
|
||||
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tmp108_init(const struct device *dev)
|
||||
{
|
||||
const struct tmp108_config *cfg = dev->config;
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
int result = 0;
|
||||
|
||||
if (!device_is_ready(cfg->i2c_spec.bus)) {
|
||||
LOG_ERR("I2C dev %s not ready", cfg->i2c_spec.bus->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
drv_data->scheduled_work.work.handler = tmp108_trigger_handle_one_shot;
|
||||
|
||||
/* save this driver instance for passing to other functions */
|
||||
drv_data->tmp108_dev = dev;
|
||||
|
||||
#ifdef CONFIG_TMP108_ALERT_INTERRUPTS
|
||||
result = setup_interrupts(dev);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define TMP108_DEFINE(inst) \
|
||||
static struct tmp108_data tmp108_prv_data_##inst; \
|
||||
static const struct tmp108_config tmp108_config_##inst = { \
|
||||
.i2c_spec = I2C_DT_SPEC_INST_GET(inst), \
|
||||
.alert_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, \
|
||||
alert_gpios, { 0 }) \
|
||||
}; \
|
||||
DEVICE_DT_INST_DEFINE(inst, \
|
||||
&tmp108_init, \
|
||||
NULL, \
|
||||
&tmp108_prv_data_##inst, \
|
||||
&tmp108_config_##inst, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_SENSOR_INIT_PRIORITY, \
|
||||
&tmp108_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(TMP108_DEFINE)
|
88
drivers/sensor/tmp108/tmp108.h
Normal file
88
drivers/sensor/tmp108/tmp108.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <drivers/sensor.h>
|
||||
#include <drivers/gpio.h>
|
||||
#include <drivers/sensor/tmp108.h>
|
||||
|
||||
#define TI_TMP108_REG_TEMP 0x00 /** Temperature register */
|
||||
#define TI_TMP108_REG_CONF 0x01 /** Configuration register */
|
||||
#define TI_TMP108_REG_LOW_LIMIT 0x02 /** Low alert set register */
|
||||
#define TI_TMP108_REG_HIGH_LIMIT 0x03 /** High alert set register */
|
||||
|
||||
|
||||
#define TI_TMP108_CONF_M0 0x0100 /** Mode 1 configuration bit */
|
||||
#define TI_TMP108_CONF_M1 0x0200 /** Mode 2 configuration bit */
|
||||
#define TI_TMP108_CONF_CR0 0x2000 /** Conversion rate 1 configuration bit */
|
||||
#define TI_TMP108_CONF_CR1 0x4000 /** Conversion rate 2 configuration bit */
|
||||
#define TI_TMP108_CONF_POL 0x0080 /** Alert pin Polarity configuration bit */
|
||||
#define TI_TMP108_CONF_TM 0x0400 /** Thermostat mode setting bit */
|
||||
#define TI_TMP108_CONF_HYS1 0x0020 /** Temperature hysteresis config 1 bit */
|
||||
#define TI_TMP108_CONF_HYS0 0x0010 /** Temperature hysteresis config 2 bit */
|
||||
#define TI_TMP108_CONF_WFH OVER_TEMP_MASK
|
||||
#define TI_TMP108_CONF_WFL UNDER_TEMP_MASK
|
||||
|
||||
#define TI_TMP108_MODE_SHUTDOWN 0
|
||||
#define TI_TMP108_MODE_ONE_SHOT TI_TMP108_CONF_M0
|
||||
#define TI_TMP108_MODE_CONTINUOUS TI_TMP108_CONF_M1
|
||||
#define TI_TMP108_MODE_MASK ~(TI_TMP108_CONF_M1 | TI_TMP108_CONF_M1)
|
||||
|
||||
#define TI_TMP108_FREQ_4_SECS 0
|
||||
#define TI_TMP108_FREQ_1_HZ TI_TMP108_CONF_CR0
|
||||
#define TI_TMP108_FREQ_4_HZ TI_TMP108_CONF_CR1
|
||||
#define TI_TMP108_FREQ_16_HZ (TI_TMP108_CONF_CR1 | TI_TMP108_CONF_CR0)
|
||||
#define TI_TMP108_FREQ_MASK ~(TI_TMP108_CONF_M1 | TI_TMP108_CONF_M1)
|
||||
|
||||
#define TI_TMP108_CONF_POL_LOW 0
|
||||
#define TI_TMP108_CONF_POL_HIGH TI_TMP108_CONF_POL
|
||||
#define TI_TMP108_CONF_POL_MASK ~(TI_TMP108_CONF_POL)
|
||||
|
||||
#define TI_TMP108_CONF_TM_CMP 0
|
||||
#define TI_TMP108_CONF_TM_INT TI_TMP108_CONF_TM
|
||||
#define TI_TMP108_CONF_TM_MASK ~(TI_TMP108_CONF_TM)
|
||||
|
||||
#define TI_TMP108_HYSTER_0_C 0
|
||||
#define TI_TMP108_HYSTER_1_C TI_TMP108_CONF_HYS0
|
||||
#define TI_TMP108_HYSTER_2_C TI_TMP108_CONF_HYS1
|
||||
#define TI_TMP108_HYSTER_4_C (TI_TMP108_CONF_HYS1 | TI_TMP108_CONF_HYS0)
|
||||
#define TI_TMP108_HYSTER_MASK ~(TI_TMP108_CONF_HYS1 | TI_TMP108_CONF_HYS0)
|
||||
|
||||
struct tmp108_data {
|
||||
const struct device *tmp108_dev;
|
||||
|
||||
uint16_t sample;
|
||||
|
||||
bool one_shot_mode;
|
||||
|
||||
struct k_work_delayable scheduled_work;
|
||||
|
||||
struct sensor_trigger temp_alert_trigger;
|
||||
sensor_trigger_handler_t temp_alert_handler;
|
||||
|
||||
sensor_trigger_handler_t data_ready_handler;
|
||||
struct sensor_trigger data_ready_trigger;
|
||||
|
||||
struct gpio_callback temp_alert_gpio_cb;
|
||||
};
|
||||
|
||||
int tmp_108_trigger_set(const struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
|
||||
int tmp108_reg_read(const struct device *dev, uint8_t reg, uint16_t *val);
|
||||
|
||||
int ti_tmp108_read_temp(const struct device *dev);
|
||||
void tmp108_trigger_handle_one_shot(struct k_work *work);
|
||||
void tmp108_trigger_handle_alert(const struct device *port,
|
||||
struct gpio_callback *cb,
|
||||
gpio_port_pins_t pins);
|
||||
|
||||
#endif /* ZEPHYR_DRIVERS_SENSOR_TMP108_TMP108_H_ */
|
104
drivers/sensor/tmp108/tmp108_trigger.c
Normal file
104
drivers/sensor/tmp108/tmp108_trigger.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <drivers/sensor.h>
|
||||
#include <logging/log.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include "tmp108.h"
|
||||
|
||||
#define TMP108_ONE_SHOT_RETRY_TIME_IN_MS 10
|
||||
|
||||
LOG_MODULE_DECLARE(TMP108, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
void tmp108_trigger_handle_one_shot(struct k_work *work)
|
||||
{
|
||||
struct k_work_delayable *delayable_work = CONTAINER_OF(work,
|
||||
struct k_work_delayable,
|
||||
work);
|
||||
|
||||
struct tmp108_data *drv_data = CONTAINER_OF(delayable_work,
|
||||
struct tmp108_data,
|
||||
scheduled_work);
|
||||
|
||||
struct sensor_trigger sensor_trigger_type = {
|
||||
.chan = SENSOR_CHAN_AMBIENT_TEMP,
|
||||
.type = SENSOR_TRIG_DATA_READY
|
||||
};
|
||||
|
||||
uint16_t config = 0;
|
||||
bool shutdown_mode = false;
|
||||
|
||||
tmp108_reg_read(drv_data->tmp108_dev, TI_TMP108_REG_CONF, &config);
|
||||
|
||||
/* check shutdown mode which indicates a one shot read was successful */
|
||||
|
||||
shutdown_mode = (config & (TI_TMP108_CONF_M1 | TI_TMP108_CONF_M0)) == 0;
|
||||
|
||||
if (shutdown_mode == true) {
|
||||
ti_tmp108_read_temp(drv_data->tmp108_dev);
|
||||
} else {
|
||||
LOG_ERR("Temperature one shot mode read failed, retrying");
|
||||
/* Typical wake up time is 27 ms, retry if the read fails
|
||||
* assuming the chip should wake up and take a reading by the time
|
||||
* 27 ms for the initial wake up time and call of this thread
|
||||
* plus 10 ms time has passed
|
||||
*/
|
||||
k_work_reschedule(&drv_data->scheduled_work,
|
||||
K_MSEC(TMP108_ONE_SHOT_RETRY_TIME_IN_MS));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Successful read, call set callbacks */
|
||||
|
||||
if (drv_data->data_ready_handler) {
|
||||
drv_data->data_ready_handler(drv_data->tmp108_dev,
|
||||
&sensor_trigger_type);
|
||||
}
|
||||
}
|
||||
|
||||
void tmp108_trigger_handle_alert(const struct device *gpio,
|
||||
struct gpio_callback *cb,
|
||||
gpio_port_pins_t pins)
|
||||
{
|
||||
|
||||
struct tmp108_data *drv_data = CONTAINER_OF(cb,
|
||||
struct tmp108_data,
|
||||
temp_alert_gpio_cb);
|
||||
|
||||
struct sensor_trigger sensor_trigger_type = {
|
||||
.chan = SENSOR_CHAN_AMBIENT_TEMP,
|
||||
.type = SENSOR_TRIG_THRESHOLD
|
||||
};
|
||||
|
||||
/* Successful read, call set callbacks */
|
||||
|
||||
if (drv_data->temp_alert_handler) {
|
||||
drv_data->temp_alert_handler(drv_data->tmp108_dev,
|
||||
&sensor_trigger_type);
|
||||
}
|
||||
}
|
||||
|
||||
int tmp_108_trigger_set(const struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct tmp108_data *drv_data = dev->data;
|
||||
|
||||
if (trig->type == SENSOR_TRIG_DATA_READY) {
|
||||
drv_data->data_ready_handler = handler;
|
||||
drv_data->data_ready_trigger = *trig;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (trig->type == SENSOR_TRIG_THRESHOLD) {
|
||||
drv_data->temp_alert_handler = handler;
|
||||
drv_data->temp_alert_trigger = *trig;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOTSUP;
|
||||
}
|
18
dts/bindings/sensor/ti,tmp108.yaml
Normal file
18
dts/bindings/sensor/ti,tmp108.yaml
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (c) 2021 Jimmy Johnson <catch22@fastmail.net>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: |
|
||||
TMP108 Digital Temperature Sensor. See more info at
|
||||
https://www.ti.com/product/TMP108
|
||||
|
||||
compatible: "ti,tmp108"
|
||||
|
||||
include: i2c-device.yaml
|
||||
|
||||
properties:
|
||||
alert-gpios:
|
||||
type: phandle-array
|
||||
required: false
|
||||
description: |
|
||||
Identifies the ALERT signal, which is active-low open drain when
|
||||
produced by the sensor.
|
43
include/drivers/sensor/tmp108.h
Normal file
43
include/drivers/sensor/tmp108.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Jimmy Johnson <catch22@fastmail.net>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Extended public API for TI's TMP108 temperature sensor
|
||||
*
|
||||
* This exposes attributes for the TMP108 which can be used for
|
||||
* setting the on-chip Temperature Mode and alert parameters.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP108_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP108_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum sensor_attribute_tmp_108 {
|
||||
/** Turn on power saving/one shot mode */
|
||||
SENSOR_ATTR_TMP108_ONE_SHOT_MODE = SENSOR_ATTR_PRIV_START,
|
||||
/** Shutdown the sensor */
|
||||
SENSOR_ATTR_TMP108_SHUTDOWN_MODE,
|
||||
/** Turn on continuous conversion */
|
||||
SENSOR_ATTR_TMP108_CONTINUOUS_CONVERSION_MODE,
|
||||
/** Set the alert pin polarity */
|
||||
SENSOR_ATTR_TMP108_ALERT_POLARITY
|
||||
};
|
||||
|
||||
/** a mask for the over temp alert bit in the status word*/
|
||||
#define OVER_TEMP_MASK 0x1000U
|
||||
|
||||
/** a mask for the under temp alert bit in the status word*/
|
||||
#define UNDER_TEMP_MASK 0x0800U
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_TMP108_H_ */
|
|
@ -526,6 +526,13 @@ test_i2c_tmp007: tmp007@44 {
|
|||
int-gpios = <&test_gpio 0 0>;
|
||||
};
|
||||
|
||||
test_i2c_tmp108: tmp108@48 {
|
||||
compatible = "ti,tmp108";
|
||||
label = "TMP108";
|
||||
reg = <0x48>;
|
||||
alert-gpios = <&test_gpio 0 0>;
|
||||
};
|
||||
|
||||
test_i2c_tmp112: tmp112@45 {
|
||||
compatible = "ti,tmp112";
|
||||
label = "TMP112";
|
||||
|
|
|
@ -94,6 +94,7 @@ CONFIG_TH02=y
|
|||
CONFIG_TI_HDC=y
|
||||
CONFIG_TI_HDC20XX=y
|
||||
CONFIG_TMP007=y
|
||||
CONFIG_TMP108=y
|
||||
CONFIG_TMP112=y
|
||||
CONFIG_TMP116=y
|
||||
CONFIG_VCNL4040=y
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue