sensor: Generic driver for NTC Thermistor
Driver for NTC Thermistors attached to ADC Signed-off-by: Al Semjonovs <asemjonovs@google.com>
This commit is contained in:
parent
fb8d8c5773
commit
5d4352f322
12 changed files with 531 additions and 1 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <zephyr/dt-bindings/adc/adc.h>
|
#include <zephyr/dt-bindings/adc/adc.h>
|
||||||
#include "tdk_robokit1-pinctrl.dtsi"
|
#include "tdk_robokit1-pinctrl.dtsi"
|
||||||
|
#include "tdk_robokit1-thermistor.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
aliases {
|
||||||
|
@ -42,6 +43,17 @@
|
||||||
label = "User LED";
|
label = "User LED";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
temp_sensor: ambient_temp_sensor {
|
||||||
|
compatible = "zephyr,ntc-thermistor";
|
||||||
|
io-channels = <&spi_adc 0>;
|
||||||
|
zephyr,rt-table = <&thermistor_R25_10000_B_3974>;
|
||||||
|
r25-ohm = <10000>;
|
||||||
|
pullup-uv = <3300000>;
|
||||||
|
pullup-ohm = <0>;
|
||||||
|
pulldown-ohm = <10000>;
|
||||||
|
connection-type = "NTC_CONNECTED_POSITIVE";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&cpu0 {
|
&cpu0 {
|
||||||
|
@ -219,3 +231,6 @@ zephyr_udc0: &usbhs {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&thermistor_R25_10000_B_3974 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
31
boards/arm/tdk_robokit1/tdk_robokit1-thermistor.dtsi
Normal file
31
boards/arm/tdk_robokit1/tdk_robokit1-thermistor.dtsi
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* NTC Thermistor Table Generated with ntc_thermistor_table.py */
|
||||||
|
|
||||||
|
/ {
|
||||||
|
thermistor_R25_10000_B_3974: thermistor-R25-10000-B-3974 {
|
||||||
|
status = "disabled";
|
||||||
|
compatible = "zephyr,ntc-thermistor-rt-table";
|
||||||
|
/* Format <temp resistance> */
|
||||||
|
tr-table = <(-25) 146676>,
|
||||||
|
<(-15) 78875>,
|
||||||
|
<(-5) 44424>,
|
||||||
|
<(5) 26075>,
|
||||||
|
<(15) 15881>,
|
||||||
|
<(25) 10000>,
|
||||||
|
<(35) 6488>,
|
||||||
|
<(45) 4326>,
|
||||||
|
<(55) 2956>,
|
||||||
|
<(65) 2066>,
|
||||||
|
<(75) 1474>,
|
||||||
|
<(85) 1072>,
|
||||||
|
<(95) 793>,
|
||||||
|
<(105) 596>,
|
||||||
|
<(115) 454>,
|
||||||
|
<(125) 351>;
|
||||||
|
};
|
||||||
|
};
|
|
@ -127,6 +127,7 @@ add_subdirectory_ifdef(CONFIG_ESP32_TEMP esp32_temp)
|
||||||
add_subdirectory_ifdef(CONFIG_RPI_PICO_TEMP rpi_pico_temp)
|
add_subdirectory_ifdef(CONFIG_RPI_PICO_TEMP rpi_pico_temp)
|
||||||
add_subdirectory_ifdef(CONFIG_XMC4XXX_TEMP xmc4xxx_temp)
|
add_subdirectory_ifdef(CONFIG_XMC4XXX_TEMP xmc4xxx_temp)
|
||||||
add_subdirectory_ifdef(CONFIG_TMD2620 tmd2620)
|
add_subdirectory_ifdef(CONFIG_TMD2620 tmd2620)
|
||||||
|
add_subdirectory_ifdef(CONFIG_ZEPHYR_NTC_THERMISTOR zephyr_thermistor)
|
||||||
|
|
||||||
if(CONFIG_USERSPACE OR CONFIG_SENSOR_SHELL OR CONFIG_SENSOR_SHELL_BATTERY)
|
if(CONFIG_USERSPACE OR CONFIG_SENSOR_SHELL OR CONFIG_SENSOR_SHELL_BATTERY)
|
||||||
# The above if() is needed or else CMake would complain about
|
# The above if() is needed or else CMake would complain about
|
||||||
|
|
|
@ -293,4 +293,6 @@ source "drivers/sensor/xmc4xxx_temp/Kconfig"
|
||||||
|
|
||||||
source "drivers/sensor/tmd2620/Kconfig"
|
source "drivers/sensor/tmd2620/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/sensor/zephyr_thermistor/Kconfig"
|
||||||
|
|
||||||
endif # SENSOR
|
endif # SENSOR
|
||||||
|
|
8
drivers/sensor/zephyr_thermistor/CMakeLists.txt
Normal file
8
drivers/sensor/zephyr_thermistor/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
zephyr_library()
|
||||||
|
|
||||||
|
zephyr_library_sources(
|
||||||
|
zephyr_ntc_thermistor.c
|
||||||
|
zephyr_ntc_thermistor_rt_table.c
|
||||||
|
)
|
14
drivers/sensor/zephyr_thermistor/Kconfig
Normal file
14
drivers/sensor/zephyr_thermistor/Kconfig
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Zephyr Generic NTC Thermistor
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023 Google LLC
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
config ZEPHYR_NTC_THERMISTOR
|
||||||
|
bool "Zephyr Generic NTC Thermistor"
|
||||||
|
default y
|
||||||
|
depends on DT_HAS_ZEPHYR_NTC_THERMISTOR_ENABLED
|
||||||
|
depends on DT_HAS_ZEPHYR_NTC_THERMISTOR_RT_TABLE_ENABLED
|
||||||
|
select ADC
|
||||||
|
help
|
||||||
|
Enable driver for Zephyr NTC Thermistor.
|
125
drivers/sensor/zephyr_thermistor/zephyr_ntc_thermistor.c
Normal file
125
drivers/sensor/zephyr_thermistor/zephyr_ntc_thermistor.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DT_DRV_COMPAT zephyr_ntc_thermistor
|
||||||
|
|
||||||
|
#include <zephyr/drivers/adc.h>
|
||||||
|
#include <zephyr/drivers/sensor.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
#include "zephyr_ntc_thermistor.h"
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(ZEPHYR_NTC_THERMISTOR, CONFIG_SENSOR_LOG_LEVEL);
|
||||||
|
|
||||||
|
struct zephyr_ntc_thermistor_data {
|
||||||
|
struct k_mutex mutex;
|
||||||
|
int16_t raw;
|
||||||
|
int16_t sample_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct zephyr_ntc_thermistor_config {
|
||||||
|
const struct adc_dt_spec adc_channel;
|
||||||
|
const struct ntc_config ntc_cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zephyr_ntc_thermistor_sample_fetch(const struct device *dev, enum sensor_channel chan)
|
||||||
|
{
|
||||||
|
struct zephyr_ntc_thermistor_data *data = dev->data;
|
||||||
|
const struct zephyr_ntc_thermistor_config *cfg = dev->config;
|
||||||
|
int32_t val_mv;
|
||||||
|
int res;
|
||||||
|
struct adc_sequence sequence = {
|
||||||
|
.options = NULL,
|
||||||
|
.buffer = &data->raw,
|
||||||
|
.buffer_size = sizeof(data->raw),
|
||||||
|
.calibrate = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
k_mutex_lock(&data->mutex, K_FOREVER);
|
||||||
|
|
||||||
|
adc_sequence_init_dt(&cfg->adc_channel, &sequence);
|
||||||
|
res = adc_read(cfg->adc_channel.dev, &sequence);
|
||||||
|
if (res) {
|
||||||
|
val_mv = data->raw;
|
||||||
|
res = adc_raw_to_millivolts_dt(&cfg->adc_channel, &val_mv);
|
||||||
|
data->sample_val = val_mv;
|
||||||
|
}
|
||||||
|
|
||||||
|
k_mutex_unlock(&data->mutex);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int zephyr_ntc_thermistor_channel_get(const struct device *dev, enum sensor_channel chan,
|
||||||
|
struct sensor_value *val)
|
||||||
|
{
|
||||||
|
struct zephyr_ntc_thermistor_data *data = dev->data;
|
||||||
|
const struct zephyr_ntc_thermistor_config *cfg = dev->config;
|
||||||
|
uint32_t ohm, max_adc;
|
||||||
|
int32_t temp;
|
||||||
|
|
||||||
|
switch (chan) {
|
||||||
|
case SENSOR_CHAN_AMBIENT_TEMP:
|
||||||
|
max_adc = (1 << (cfg->adc_channel.resolution - 1)) - 1;
|
||||||
|
ohm = ntc_get_ohm_of_thermistor(&cfg->ntc_cfg, max_adc, data->raw);
|
||||||
|
temp = ntc_get_temp_mc(cfg->ntc_cfg.type, ohm);
|
||||||
|
val->val1 = temp / 1000;
|
||||||
|
val->val2 = (temp % 1000) * 1000;
|
||||||
|
LOG_INF("ntc temp says %u", val->val1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sensor_driver_api zephyr_ntc_thermistor_driver_api = {
|
||||||
|
.sample_fetch = zephyr_ntc_thermistor_sample_fetch,
|
||||||
|
.channel_get = zephyr_ntc_thermistor_channel_get,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int zephyr_ntc_thermistor_init(const struct device *dev)
|
||||||
|
{
|
||||||
|
const struct zephyr_ntc_thermistor_config *cfg = dev->config;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!device_is_ready(cfg->adc_channel.dev)) {
|
||||||
|
LOG_ERR("ADC controller device is not ready\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = adc_channel_setup_dt(&cfg->adc_channel);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Could not setup channel err(%d)\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZEPHYR_NTC_THERMISTOR_DEV_INIT(inst) \
|
||||||
|
static struct zephyr_ntc_thermistor_data zephyr_ntc_thermistor_driver_##inst; \
|
||||||
|
\
|
||||||
|
extern const struct ntc_type NTC_TYPE_NAME(DT_INST_PROP(inst, zephyr_rt_table)); \
|
||||||
|
\
|
||||||
|
static const struct zephyr_ntc_thermistor_config zephyr_ntc_thermistor_cfg_##inst = { \
|
||||||
|
.adc_channel = ADC_DT_SPEC_INST_GET(inst), \
|
||||||
|
.ntc_cfg = \
|
||||||
|
{ \
|
||||||
|
.r25_ohm = DT_INST_PROP(inst, r25_ohm), \
|
||||||
|
.pullup_uv = DT_INST_PROP(inst, pullup_uv), \
|
||||||
|
.pullup_ohm = DT_INST_PROP(inst, pullup_ohm), \
|
||||||
|
.pulldown_ohm = DT_INST_PROP(inst, pulldown_ohm), \
|
||||||
|
.connection_type = DT_INST_STRING_TOKEN(inst, connection_type), \
|
||||||
|
.type = &NTC_TYPE_NAME(DT_INST_PROP(inst, zephyr_rt_table)), \
|
||||||
|
}, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
SENSOR_DEVICE_DT_INST_DEFINE( \
|
||||||
|
inst, zephyr_ntc_thermistor_init, NULL, &zephyr_ntc_thermistor_driver_##inst, \
|
||||||
|
&zephyr_ntc_thermistor_cfg_##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
|
||||||
|
&zephyr_ntc_thermistor_driver_api);
|
||||||
|
|
||||||
|
DT_INST_FOREACH_STATUS_OKAY(ZEPHYR_NTC_THERMISTOR_DEV_INIT)
|
73
drivers/sensor/zephyr_thermistor/zephyr_ntc_thermistor.h
Normal file
73
drivers/sensor/zephyr_thermistor/zephyr_ntc_thermistor.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZEPHYR_NTC_THERMISTOR_H
|
||||||
|
#define ZEPHYR_NTC_THERMISTOR_H
|
||||||
|
|
||||||
|
#include <zephyr/types.h>
|
||||||
|
|
||||||
|
struct ntc_compensation {
|
||||||
|
const int32_t temp_c;
|
||||||
|
const uint32_t ohm;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ntc_type_e {
|
||||||
|
NTC_CONNECTED_POSITIVE,
|
||||||
|
NTC_CONNECTED_GROUND
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ntc_type {
|
||||||
|
const struct ntc_compensation *comp;
|
||||||
|
int n_comp;
|
||||||
|
int (*ohm_cmp)(const void *key, const void *element);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ntc_config {
|
||||||
|
enum ntc_type_e connection_type;
|
||||||
|
uint32_t r25_ohm;
|
||||||
|
uint32_t pullup_uv;
|
||||||
|
uint32_t pullup_ohm;
|
||||||
|
uint32_t pulldown_ohm;
|
||||||
|
const struct ntc_type *type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NTC_TYPE_NAME(node_id) DT_CAT(node_id, _type)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper comparison function for bsearch for specific
|
||||||
|
* ntc_type
|
||||||
|
*
|
||||||
|
* Ohms are sorted in descending order, perform comparison to find
|
||||||
|
* interval indexes where key falls between
|
||||||
|
*
|
||||||
|
* @param type: Pointer to ntc_type table info
|
||||||
|
* @param key: Key value bsearch is looking for
|
||||||
|
* @param element: Array element bsearch is searching
|
||||||
|
*/
|
||||||
|
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts ohm to temperature in milli centigrade
|
||||||
|
*
|
||||||
|
* @param type: Pointer to ntc_type table info
|
||||||
|
* @param ohm: Read resistance of NTC thermistor
|
||||||
|
*
|
||||||
|
* @return temperature in milli centigrade
|
||||||
|
*/
|
||||||
|
int32_t ntc_get_temp_mc(const struct ntc_type *type, unsigned int ohm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculate the resistance read from NTC Thermistor
|
||||||
|
*
|
||||||
|
* @param cfg: NTC Thermistor configuration
|
||||||
|
* @param max_adc: Max ADC value
|
||||||
|
* @param raw_adc: Raw ADC value read
|
||||||
|
*
|
||||||
|
* @return resistance from raw ADC value
|
||||||
|
*/
|
||||||
|
uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, uint32_t max_adc, int16_t raw_adc);
|
||||||
|
|
||||||
|
#endif /* ZEPHYR_NTC_THERMISTOR_H */
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Google LLC
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <zephyr/devicetree.h>
|
||||||
|
#include "zephyr_ntc_thermistor.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fixp_linear_interpolate() - interpolates a value from two known points
|
||||||
|
*
|
||||||
|
* @x0: x value of point 0
|
||||||
|
* @y0: y value of point 0
|
||||||
|
* @x1: x value of point 1
|
||||||
|
* @y1: y value of point 1
|
||||||
|
* @x: the linear interpolant
|
||||||
|
*/
|
||||||
|
static int ntc_fixp_linear_interpolate(int x0, int y0, int x1, int y1, int x)
|
||||||
|
{
|
||||||
|
if (y0 == y1 || x == x0) {
|
||||||
|
return y0;
|
||||||
|
}
|
||||||
|
if (x1 == x0 || x == x1) {
|
||||||
|
return y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ntc_compensation_compare_ohm() - Helper comparison function for bsearch
|
||||||
|
*
|
||||||
|
* Ohms are sorted in descending order, perform comparison to find
|
||||||
|
* interval indexes where key falls between
|
||||||
|
*
|
||||||
|
* @type: Pointer to ntc_type table info
|
||||||
|
* @key: Key value bsearch is looking for
|
||||||
|
* @element: Array element bsearch is searching
|
||||||
|
*/
|
||||||
|
int ntc_compensation_compare_ohm(const struct ntc_type *type, const void *key, const void *element)
|
||||||
|
{
|
||||||
|
int sgn = 0;
|
||||||
|
const struct ntc_compensation *ntc_key = key;
|
||||||
|
const struct ntc_compensation *element_val = element;
|
||||||
|
int element_idx = element_val - type->comp;
|
||||||
|
|
||||||
|
if (ntc_key->ohm > element_val->ohm) {
|
||||||
|
if (element_idx == 0) {
|
||||||
|
sgn = 0;
|
||||||
|
} else {
|
||||||
|
sgn = -1;
|
||||||
|
}
|
||||||
|
} else if (ntc_key->ohm == element_val->ohm) {
|
||||||
|
sgn = 0;
|
||||||
|
} else if (ntc_key->ohm < element_val->ohm) {
|
||||||
|
if (element_idx == type->n_comp - 1) {
|
||||||
|
sgn = 0;
|
||||||
|
} else {
|
||||||
|
if (element_idx != type->n_comp - 1 &&
|
||||||
|
ntc_key->ohm > type->comp[element_idx + 1].ohm) {
|
||||||
|
sgn = 0;
|
||||||
|
} else {
|
||||||
|
sgn = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sgn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ntc_lookup_comp() - Finds indicies where ohm falls between
|
||||||
|
*
|
||||||
|
* @ohm: key value search is looking for
|
||||||
|
* @i_low: return Lower interval index value
|
||||||
|
* @i_high: return Higher interval index value
|
||||||
|
*/
|
||||||
|
static void ntc_lookup_comp(const struct ntc_type *type, unsigned int ohm, int *i_low, int *i_high)
|
||||||
|
{
|
||||||
|
const struct ntc_compensation *ptr;
|
||||||
|
struct ntc_compensation search_ohm_key = {.ohm = ohm};
|
||||||
|
|
||||||
|
ptr = bsearch(&search_ohm_key, type->comp, type->n_comp, sizeof(type->comp[0]),
|
||||||
|
type->ohm_cmp);
|
||||||
|
if (ptr) {
|
||||||
|
*i_low = ptr - type->comp;
|
||||||
|
*i_high = *i_low + 1;
|
||||||
|
} else {
|
||||||
|
*i_low = 0;
|
||||||
|
*i_high = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ntc_get_ohm_of_thermistor() - Calculate the resistance read from NTC Thermistor
|
||||||
|
*
|
||||||
|
* @cfg: NTC Thermistor configuration
|
||||||
|
* @max_adc: Max ADC value
|
||||||
|
* @raw_adc: Raw ADC value read
|
||||||
|
*/
|
||||||
|
uint32_t ntc_get_ohm_of_thermistor(const struct ntc_config *cfg, uint32_t max_adc, int16_t raw_adc)
|
||||||
|
{
|
||||||
|
uint32_t ohm;
|
||||||
|
|
||||||
|
if (cfg->connection_type == NTC_CONNECTED_POSITIVE) {
|
||||||
|
ohm = cfg->pulldown_ohm * max_adc / (raw_adc - 1);
|
||||||
|
} else {
|
||||||
|
ohm = cfg->pullup_ohm * (raw_adc - 1) / max_adc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ohm;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ntc_get_temp_mc(const struct ntc_type *type, unsigned int ohm)
|
||||||
|
{
|
||||||
|
int low, high;
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
ntc_lookup_comp(type, ohm, &low, &high);
|
||||||
|
/*
|
||||||
|
* First multiplying the table temperatures with 1000 to get to
|
||||||
|
* millicentigrades (which is what we want) and then interpolating
|
||||||
|
* will give the best precision.
|
||||||
|
*/
|
||||||
|
temp = ntc_fixp_linear_interpolate(type->comp[low].ohm, type->comp[low].temp_c * 1000,
|
||||||
|
type->comp[high].ohm, type->comp[high].temp_c * 1000,
|
||||||
|
ohm);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define THERMISTOR_DATA_NAME(node_id) DT_CAT(node_id, _thermistor_data)
|
||||||
|
|
||||||
|
#define DEFINE_THERMISTOR_TYPE(node_id) \
|
||||||
|
static int node_id##_compare_ohm(const void *key, const void *element); \
|
||||||
|
BUILD_ASSERT(DT_PROP_LEN(node_id, tr_table) % 2 == 0, "T/R Table needs to be even size"); \
|
||||||
|
static const uint32_t node_id##_tr_table[] = DT_PROP(node_id, tr_table); \
|
||||||
|
\
|
||||||
|
const struct ntc_type NTC_TYPE_NAME(node_id) = { \
|
||||||
|
.comp = (struct ntc_compensation *)node_id##_tr_table, \
|
||||||
|
.n_comp = (ARRAY_SIZE(node_id##_tr_table) / 2), \
|
||||||
|
.ohm_cmp = node_id##_compare_ohm, \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
static int node_id##_compare_ohm(const void *key, const void *element) \
|
||||||
|
{ \
|
||||||
|
return ntc_compensation_compare_ohm(&NTC_TYPE_NAME(node_id), key, element); \
|
||||||
|
}
|
||||||
|
|
||||||
|
DT_FOREACH_STATUS_OKAY(zephyr_ntc_thermistor_rt_table, DEFINE_THERMISTOR_TYPE)
|
18
dts/bindings/sensor/zephyr,ntc-thermistor-rt-table.yaml
Normal file
18
dts/bindings/sensor/zephyr,ntc-thermistor-rt-table.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright 2023 Google LLC
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Common properties for NTC thermistors
|
||||||
|
For more information: https://www.electronics-tutorials.ws/io/thermistors.html
|
||||||
|
|
||||||
|
compatible: "zephyr,ntc-thermistor-rt-table"
|
||||||
|
|
||||||
|
properties:
|
||||||
|
tr-table:
|
||||||
|
required: true
|
||||||
|
type: array
|
||||||
|
description: |
|
||||||
|
NTC Thermistor Temp/Resistance Table formatted as an array like follows
|
||||||
|
<temp0 resistance0 temp1 resistance1 ...>
|
||||||
|
See `scripts/utils/ntc_thermistor_table.py` to help generate node.
|
47
dts/bindings/sensor/zephyr,ntc-thermistor.yaml
Normal file
47
dts/bindings/sensor/zephyr,ntc-thermistor.yaml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# Copyright (c) 2022 Google LLC
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
description: Generic NTC Thermistor
|
||||||
|
|
||||||
|
compatible: "zephyr,ntc-thermistor"
|
||||||
|
|
||||||
|
include: [sensor-device.yaml]
|
||||||
|
|
||||||
|
properties:
|
||||||
|
io-channels:
|
||||||
|
required: true
|
||||||
|
description: |
|
||||||
|
ADC IO channel connected to this NTC thermistor.
|
||||||
|
|
||||||
|
zephyr,rt-table:
|
||||||
|
type: phandle
|
||||||
|
required: true
|
||||||
|
description: R/T table for NTC thermistor.
|
||||||
|
|
||||||
|
r25-ohm:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
The resistance value of the thermistor at 25 C.
|
||||||
|
|
||||||
|
pullup-uv:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
The pullup voltage microvoltage in the circuit.
|
||||||
|
|
||||||
|
pullup-ohm:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
The pullup resistance in the circuit.
|
||||||
|
|
||||||
|
pulldown-ohm:
|
||||||
|
type: int
|
||||||
|
description: |
|
||||||
|
The pulldown resistance in the circuit.
|
||||||
|
|
||||||
|
connection-type:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
The connection type of the circuit model used.
|
||||||
|
enum:
|
||||||
|
- NTC_CONNECTED_POSITIVE
|
||||||
|
- NTC_CONNECTED_GROUND
|
|
@ -1,14 +1,59 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023 FTP Technologies
|
* Copyright (c) 2023 FTP Technologies
|
||||||
|
* Copyright (c) 2023, Google LLC
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
* Application overlay for ADC devices
|
* Application overlay for ADC devices
|
||||||
*/
|
*/
|
||||||
|
|
||||||
test_adc_mcp9700a: mcp9700a {
|
#include <zephyr/dt-bindings/adc/adc.h>
|
||||||
|
|
||||||
|
test_adc_mcp9700a: mcp9700a {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
compatible = "microchip,mcp970x";
|
compatible = "microchip,mcp970x";
|
||||||
family = "MCP9700/9700A";
|
family = "MCP9700/9700A";
|
||||||
io-channels = <&test_adc 0>;
|
io-channels = <&test_adc 0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
adc0: adc {
|
||||||
|
compatible = "zephyr,adc-emul";
|
||||||
|
nchannels = <2>;
|
||||||
|
ref-internal-mv = <3300>;
|
||||||
|
ref-external1-mv = <5000>;
|
||||||
|
#io-channel-cells = <1>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
thermistor_R25_10000_B_3974: thermistor-R25-10000-B-3974 {
|
||||||
|
compatible = "zephyr,ntc-thermistor-rt-table";
|
||||||
|
/* Format <temp resistance> */
|
||||||
|
tr-table = <(-25) 146676>,
|
||||||
|
<(-15) 78875>,
|
||||||
|
<(-5) 44424>,
|
||||||
|
<(5) 26075>,
|
||||||
|
<(15) 15881>,
|
||||||
|
<(25) 10000>,
|
||||||
|
<(35) 6488>,
|
||||||
|
<(45) 4326>,
|
||||||
|
<(55) 2956>,
|
||||||
|
<(65) 2066>,
|
||||||
|
<(75) 1474>,
|
||||||
|
<(85) 1072>,
|
||||||
|
<(95) 793>,
|
||||||
|
<(105) 596>,
|
||||||
|
<(115) 454>,
|
||||||
|
<(125) 351>;
|
||||||
|
};
|
||||||
|
|
||||||
|
test_adc_b57861s: b57861s@0 {
|
||||||
|
compatible = "zephyr,ntc-thermistor";
|
||||||
|
reg = <0x0 0x1000>;
|
||||||
|
io-channels = <&adc0 0>;
|
||||||
|
zephyr,rt-table = <&thermistor_R25_10000_B_3974>;
|
||||||
|
r25-ohm = <10000>;
|
||||||
|
pullup-uv = <3300000>;
|
||||||
|
pullup-ohm = <0>;
|
||||||
|
pulldown-ohm = <10000>;
|
||||||
|
connection-type = "NTC_CONNECTED_POSITIVE";
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue