drivers: sensor: introduce driver for TCN75A temperature sensor
Add driver for TCN75A temperature sensor. The following features are supported: - TCN75A oneshot mode, which allows single shot conversions with lower power consumtion - Resolution selection, up to 12 bit resolution (9 bit default) - Triggering based on temperatue thresholds. If the TCN75A exits a set threshold range, the application can be notified via a callback. Signed-off-by: Daniel DeGrasse <daniel@degrasse.com>
This commit is contained in:
parent
47e3c5386a
commit
6c10da7957
8 changed files with 521 additions and 0 deletions
|
@ -120,6 +120,7 @@ add_subdirectory_ifdef(CONFIG_SX9500 sx9500)
|
|||
add_subdirectory_ifdef(CONFIG_TACH_IT8XXX2 ite_tach_it8xxx2)
|
||||
add_subdirectory_ifdef(CONFIG_TACH_NPCX nuvoton_tach_npcx)
|
||||
add_subdirectory_ifdef(CONFIG_TACH_XEC mchp_tach_xec)
|
||||
add_subdirectory_ifdef(CONFIG_TCN75A tcn75a)
|
||||
add_subdirectory_ifdef(CONFIG_TCS3400 tcs3400)
|
||||
add_subdirectory_ifdef(CONFIG_TEMP_KINETIS nxp_kinetis_temp)
|
||||
add_subdirectory_ifdef(CONFIG_TEMP_NRF5 nrf5)
|
||||
|
|
|
@ -178,6 +178,7 @@ source "drivers/sensor/stm32_vbat/Kconfig"
|
|||
source "drivers/sensor/stm32_vref/Kconfig"
|
||||
source "drivers/sensor/stts751/Kconfig"
|
||||
source "drivers/sensor/sx9500/Kconfig"
|
||||
source "drivers/sensor/tcn75a/Kconfig"
|
||||
source "drivers/sensor/tcs3400/Kconfig"
|
||||
source "drivers/sensor/th02/Kconfig"
|
||||
source "drivers/sensor/ti_hdc/Kconfig"
|
||||
|
|
6
drivers/sensor/tcn75a/CMakeLists.txt
Normal file
6
drivers/sensor/tcn75a/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_sources(tcn75a.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_TCN75A_TRIGGER tcn75a_trigger.c)
|
50
drivers/sensor/tcn75a/Kconfig
Normal file
50
drivers/sensor/tcn75a/Kconfig
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config TCN75A
|
||||
bool "TCN75A Ambient Temperature Sensor"
|
||||
default y
|
||||
depends on DT_HAS_MICROCHIP_TCN75A_ENABLED
|
||||
select I2C
|
||||
help
|
||||
Enable TCN75A ambient temperature to digital converter
|
||||
|
||||
if TCN75A
|
||||
|
||||
choice
|
||||
prompt "TCN75A Trigger mode"
|
||||
default TCN75A_TRIGGER_NONE
|
||||
|
||||
config TCN75A_TRIGGER_NONE
|
||||
bool "No trigger"
|
||||
|
||||
config TCN75A_TRIGGER_OWN_THREAD
|
||||
bool "Use own thread"
|
||||
select TCN75A_TRIGGER
|
||||
|
||||
config TCN75A_TRIGGER_GLOBAL_THREAD
|
||||
bool "Use global thread"
|
||||
select TCN75A_TRIGGER
|
||||
|
||||
endchoice
|
||||
|
||||
config TCN75A_TRIGGER
|
||||
bool
|
||||
help
|
||||
Enable interrupt based trigger support for TCN75A. Requires that
|
||||
the sensor be set to continuous sample mode.
|
||||
|
||||
if TCN75A_TRIGGER_OWN_THREAD
|
||||
|
||||
config TCN75A_THREAD_PRIORITY
|
||||
int "Own thread priority"
|
||||
default 10
|
||||
|
||||
config TCN75A_THREAD_STACK_SIZE
|
||||
int "Own thread stack size"
|
||||
default 1024
|
||||
|
||||
endif # TCN75A_TRIGGER_OWN_THREAD
|
||||
|
||||
|
||||
endif # TCN75A
|
135
drivers/sensor/tcn75a/tcn75a.c
Normal file
135
drivers/sensor/tcn75a/tcn75a.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT microchip_tcn75a
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(tcn75a, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
#include "tcn75a.h"
|
||||
|
||||
int tcn75a_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
struct tcn75a_data *data = dev->data;
|
||||
int ret;
|
||||
uint8_t temp_reg = TCN75A_TEMP_REG;
|
||||
uint8_t rx_buf[2];
|
||||
uint8_t adc_conf[2] = {TCN75A_CONFIG_REG, 0x0};
|
||||
/* This sensor only supports ambient temperature */
|
||||
if ((chan != SENSOR_CHAN_ALL) && (chan != SENSOR_CHAN_AMBIENT_TEMP)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (config->oneshot_mode) {
|
||||
/* Oneshot mode, requires one shot bit to be set in config register */
|
||||
adc_conf[1] = TCN75A_CONFIG_ONEDOWN;
|
||||
ret = i2c_write_dt(&config->i2c_spec, adc_conf, 2);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch a sample from the 2 byte ambient temperature register */
|
||||
ret = i2c_write_read_dt(&config->i2c_spec, &temp_reg, sizeof(temp_reg),
|
||||
rx_buf, sizeof(rx_buf));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
data->temp_sample = sys_get_be16(rx_buf);
|
||||
LOG_DBG("Raw sample: 0x%04x", data->temp_sample);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tcn75a_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
struct tcn75a_data *data = dev->data;
|
||||
uint32_t temp_lsb;
|
||||
|
||||
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Convert fixed point to sensor value */
|
||||
val->val1 = data->temp_sample >> TCN75A_TEMP_MSB_POS;
|
||||
temp_lsb = (data->temp_sample & TCN75A_TEMP_LSB_MASK);
|
||||
val->val2 = TCN75A_FIXED_PT_TO_SENSOR(temp_lsb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sensor_driver_api tcn75a_api = {
|
||||
.sample_fetch = &tcn75a_sample_fetch,
|
||||
.channel_get = &tcn75a_channel_get,
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
.attr_get = &tcn75a_attr_get,
|
||||
.attr_set = &tcn75a_attr_set,
|
||||
.trigger_set = &tcn75a_trigger_set,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int tcn75a_init(const struct device *dev)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
uint8_t adc_conf[2] = {TCN75A_CONFIG_REG, 0x0};
|
||||
|
||||
if (!i2c_is_ready_dt(&config->i2c_spec)) {
|
||||
LOG_ERR("I2C bus is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Set user selected resolution */
|
||||
adc_conf[1] |= TCN75A_CONFIG_RES(config->resolution);
|
||||
|
||||
if (config->oneshot_mode) {
|
||||
if (adc_conf[1] != 0) {
|
||||
/* Oneshot mode only supports 9 bit resolution */
|
||||
LOG_ERR("Oneshot mode requires 9 bit resolution");
|
||||
return -ENODEV;
|
||||
}
|
||||
adc_conf[1] |= TCN75A_CONFIG_SHUTDOWN;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
/* If user supplies an ALERT gpio, assume they want trigger support. */
|
||||
if (config->alert_gpios.port != NULL) {
|
||||
int ret;
|
||||
|
||||
if (config->oneshot_mode) {
|
||||
LOG_ERR("Oneshot mode not supported with trigger");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = tcn75a_trigger_init(dev);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return i2c_write_dt(&config->i2c_spec, adc_conf, 2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
#define TCN75A_TRIGGER(n) .alert_gpios = GPIO_DT_SPEC_INST_GET_OR(n, alert_gpios, {}),
|
||||
#else
|
||||
#define TCN75A_TRIGGER(n)
|
||||
#endif
|
||||
|
||||
#define TCN75A_INIT(n) \
|
||||
static struct tcn75a_data tcn75a_data_##n; \
|
||||
static const struct tcn75a_config tcn75a_config_##n = { \
|
||||
.i2c_spec = I2C_DT_SPEC_INST_GET(n), \
|
||||
.resolution = DT_INST_ENUM_IDX(n, resolution), \
|
||||
.oneshot_mode = DT_INST_PROP(n, oneshot_mode), \
|
||||
TCN75A_TRIGGER(n) \
|
||||
}; \
|
||||
SENSOR_DEVICE_DT_INST_DEFINE(n, &tcn75a_init, NULL, &tcn75a_data_##n, &tcn75a_config_##n, \
|
||||
POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, &tcn75a_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(TCN75A_INIT)
|
83
drivers/sensor/tcn75a/tcn75a.h
Normal file
83
drivers/sensor/tcn75a/tcn75a.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _DRIVERS_SENSOR_TCN75A_H_
|
||||
#define _DRIVERS_SENSOR_TCN75A_H_
|
||||
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
|
||||
#define TCN75A_TEMP_REG 0x0
|
||||
#define TCN75A_CONFIG_REG 0x1
|
||||
#define TCN75A_THYST_REG 0x2
|
||||
#define TCN75A_TSET_REG 0x3
|
||||
|
||||
/* TCN75A TEMP register constants */
|
||||
#define TCN75A_TEMP_MSB_POS 8
|
||||
#define TCN75A_TEMP_MSB_MASK 0xFF00
|
||||
#define TCN75A_TEMP_LSB_MASK 0xFF
|
||||
#define TCN75A_TEMP_LSB_POS 0
|
||||
|
||||
/* TCN75A CONFIG register constants */
|
||||
#define TCN75A_CONFIG_ONEDOWN BIT(7)
|
||||
#define TCN75A_CONFIG_RES(x) (((x) & 0x3) << 5)
|
||||
#define TCN75A_CONFIG_INT_EN 0x2
|
||||
#define TCN75A_CONFIG_SHUTDOWN 0x1
|
||||
|
||||
struct tcn75a_config {
|
||||
struct i2c_dt_spec i2c_spec;
|
||||
bool oneshot_mode;
|
||||
uint8_t resolution;
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
struct gpio_dt_spec alert_gpios;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct tcn75a_data {
|
||||
uint16_t temp_sample;
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
const struct device *dev;
|
||||
struct gpio_callback gpio_cb;
|
||||
sensor_trigger_handler_t sensor_cb;
|
||||
const struct sensor_trigger *sensor_trig;
|
||||
#endif
|
||||
#ifdef CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD
|
||||
struct k_work work;
|
||||
#endif
|
||||
#ifdef CONFIG_TCN75A_TRIGGER_OWN_THREAD
|
||||
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_TCN75A_THREAD_STACK_SIZE);
|
||||
struct k_thread thread;
|
||||
struct k_sem trig_sem;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Helpers to convert from TCN75A temperature fixed point format
|
||||
* to sensor val2 format. When the LSB of the TCN75A temperature sample
|
||||
* is treated as an integer, the format to convert to sensor val2 is
|
||||
* FIXED_POINT_VAL * 3906.25
|
||||
*/
|
||||
#define TCN75A_FIXED_PT_TO_SENSOR(x) (((x)*3906) + ((x) >> 2))
|
||||
/* This conversion is imprecise, but because the 4 least significant bits
|
||||
* of the temperature register aren't used, it doesn't matter.
|
||||
*/
|
||||
#define TCN75A_SENSOR_TO_FIXED_PT(x) ((x) / 3906)
|
||||
|
||||
#ifdef CONFIG_TCN75A_TRIGGER
|
||||
|
||||
int tcn75a_trigger_init(const struct device *dev);
|
||||
int tcn75a_attr_get(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
|
||||
struct sensor_value *val);
|
||||
|
||||
int tcn75a_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
|
||||
const struct sensor_value *val);
|
||||
int tcn75a_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler);
|
||||
#endif
|
||||
int tcn75a_sample_fetch(const struct device *dev, enum sensor_channel chan);
|
||||
|
||||
#endif /* _DRIVERS_SENSOR_TCN75A_H_ */
|
203
drivers/sensor/tcn75a/tcn75a_trigger.c
Normal file
203
drivers/sensor/tcn75a/tcn75a_trigger.c
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(tcn75a, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
#include "tcn75a.h"
|
||||
|
||||
int tcn75a_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
struct tcn75a_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
if (trig->type != SENSOR_TRIG_THRESHOLD) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if ((trig->chan != SENSOR_CHAN_ALL) && (trig->chan != SENSOR_CHAN_AMBIENT_TEMP)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
data->sensor_cb = handler;
|
||||
data->sensor_trig = trig;
|
||||
|
||||
/* TCN75A starts in comparator mode by default, switch it to
|
||||
* use interrupt mode.
|
||||
*/
|
||||
ret = i2c_reg_update_byte_dt(&config->i2c_spec, TCN75A_CONFIG_REG, TCN75A_CONFIG_INT_EN,
|
||||
TCN75A_CONFIG_INT_EN);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpio_pin_interrupt_configure_dt(&config->alert_gpios, GPIO_INT_EDGE_TO_ACTIVE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tcn75a_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
uint8_t tx_buf[3];
|
||||
|
||||
if ((chan != SENSOR_CHAN_AMBIENT_TEMP) && (chan != SENSOR_CHAN_ALL)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_LOWER_THRESH:
|
||||
tx_buf[0] = TCN75A_THYST_REG;
|
||||
break;
|
||||
case SENSOR_ATTR_UPPER_THRESH:
|
||||
tx_buf[0] = TCN75A_TSET_REG;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Convert sensor val to fixed point */
|
||||
tx_buf[1] = (uint8_t)val->val1;
|
||||
tx_buf[2] = TCN75A_SENSOR_TO_FIXED_PT(val->val2);
|
||||
|
||||
LOG_DBG("Writing 0x%02X to limit reg %s", *(uint16_t *)(tx_buf + 1),
|
||||
tx_buf[0] == TCN75A_THYST_REG ? "THYST" : "TSET");
|
||||
|
||||
return i2c_write_dt(&config->i2c_spec, tx_buf, 3);
|
||||
}
|
||||
|
||||
int tcn75a_attr_get(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
|
||||
struct sensor_value *val)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
uint8_t config_reg;
|
||||
uint8_t rx_buf[2];
|
||||
uint16_t limit, temp_lsb;
|
||||
int ret;
|
||||
|
||||
if ((chan != SENSOR_CHAN_AMBIENT_TEMP) && (chan != SENSOR_CHAN_ALL)) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
switch (attr) {
|
||||
case SENSOR_ATTR_LOWER_THRESH:
|
||||
config_reg = TCN75A_THYST_REG;
|
||||
break;
|
||||
case SENSOR_ATTR_UPPER_THRESH:
|
||||
config_reg = TCN75A_TSET_REG;
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
ret = i2c_write_read_dt(&config->i2c_spec, &config_reg, 1, rx_buf, 2);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
limit = sys_get_be16(rx_buf);
|
||||
|
||||
LOG_DBG("Read 0x%02X from %s", limit, config_reg == TCN75A_THYST_REG ? "THYST" : "TSET");
|
||||
|
||||
/* Convert fixed point to sensor value */
|
||||
val->val1 = limit >> TCN75A_TEMP_MSB_POS;
|
||||
temp_lsb = (limit & TCN75A_TEMP_LSB_MASK);
|
||||
val->val2 = TCN75A_FIXED_PT_TO_SENSOR(temp_lsb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tcn75a_handle_int(const struct device *dev)
|
||||
{
|
||||
struct tcn75a_data *data = dev->data;
|
||||
/* Note that once the temperature rises
|
||||
* above T_SET, the sensor will not trigger another interrupt until
|
||||
* it falls below T_HYST (or vice versa for falling below T_HYST).
|
||||
*
|
||||
* Reading from any register will de-assert the interrupt.
|
||||
*/
|
||||
|
||||
if (data->sensor_cb) {
|
||||
data->sensor_cb(dev, data->sensor_trig);
|
||||
}
|
||||
}
|
||||
|
||||
static void tcn75a_gpio_callback(const struct device *dev, struct gpio_callback *cb,
|
||||
uint32_t pin_mask)
|
||||
{
|
||||
struct tcn75a_data *data = CONTAINER_OF(cb, struct tcn75a_data, gpio_cb);
|
||||
const struct tcn75a_config *config = data->dev->config;
|
||||
|
||||
if ((pin_mask & BIT(config->alert_gpios.pin)) == 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TCN75A_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&data->trig_sem);
|
||||
#elif defined(CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCN75A_TRIGGER_OWN_THREAD
|
||||
static void tcn75a_thread_main(struct tcn75a_data *data)
|
||||
{
|
||||
while (true) {
|
||||
k_sem_take(&data->trig_sem, K_FOREVER);
|
||||
tcn75a_handle_int(data->dev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD
|
||||
static void tcn75a_work_handler(struct k_work *work)
|
||||
{
|
||||
struct tcn75a_data *data = CONTAINER_OF(work, struct tcn75a_data, work);
|
||||
|
||||
tcn75a_handle_int(data->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int tcn75a_trigger_init(const struct device *dev)
|
||||
{
|
||||
const struct tcn75a_config *config = dev->config;
|
||||
struct tcn75a_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
/* Save config pointer */
|
||||
data->dev = dev;
|
||||
|
||||
if (!gpio_is_ready_dt(&config->alert_gpios)) {
|
||||
LOG_ERR("alert GPIO device is not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = gpio_pin_configure_dt(&config->alert_gpios, GPIO_INPUT);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpio_init_callback(&data->gpio_cb, tcn75a_gpio_callback, BIT(config->alert_gpios.pin));
|
||||
|
||||
ret = gpio_add_callback(config->alert_gpios.port, &data->gpio_cb);
|
||||
|
||||
#if defined(CONFIG_TCN75A_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&data->trig_sem, 0, K_SEM_MAX_LIMIT);
|
||||
k_thread_create(&data->thread, data->thread_stack, CONFIG_TCN75A_THREAD_STACK_SIZE,
|
||||
(k_thread_entry_t)tcn75a_thread_main, data, NULL, NULL,
|
||||
K_PRIO_COOP(CONFIG_TCN75A_THREAD_PRIORITY), 0, K_NO_WAIT);
|
||||
#elif defined(CONFIG_TCN75A_TRIGGER_GLOBAL_THREAD)
|
||||
data->work.handler = tcn75a_work_handler;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
42
dts/bindings/sensor/microchip,tcn75a.yaml
Normal file
42
dts/bindings/sensor/microchip,tcn75a.yaml
Normal file
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2023 Daniel DeGrasse <daniel@degrasse.com>
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: TCN75A ambient temperature sensor
|
||||
|
||||
compatible: "microchip,tcn75a"
|
||||
|
||||
include: [sensor-device.yaml, i2c-device.yaml]
|
||||
|
||||
properties:
|
||||
alert-gpios:
|
||||
type: phandle-array
|
||||
description: |
|
||||
ALERT pin
|
||||
This pin defaults to active low when produced by the sensor.
|
||||
The property value should ensure the gpio flags properly describe
|
||||
the signal that is presented to the driver. Required in order to use
|
||||
triggering support.
|
||||
|
||||
resolution:
|
||||
type: string
|
||||
default: "9-bit"
|
||||
enum:
|
||||
- "9-bit"
|
||||
- "10-bit"
|
||||
- "11-bit"
|
||||
- "12-bit"
|
||||
description: |
|
||||
Sensor resolution. Higher resolutions will result in longer conversion
|
||||
times. Note: datasheet's claim about the ambient temperature register:
|
||||
> When the 0.5°C, 0.25°C or 0.125°C resolutions are selected,
|
||||
> bit 6, bit 7 or bit 8 will remain clear <0>,
|
||||
> respectively.
|
||||
appears to be incorrect. Only conversion times seem to be affected by
|
||||
resolution selection.
|
||||
|
||||
oneshot-mode:
|
||||
type: boolean
|
||||
description: |
|
||||
Oneshot sampling mode. Reduces power consumption, but disables triggering
|
||||
feature as well as high resolution sampling. Only supported with 9 bit
|
||||
resolution.
|
Loading…
Add table
Add a link
Reference in a new issue