Skip to content

Commit ec7a814

Browse files
Jaakko-Bitmaxd-nordic
authored andcommitted
[nrf fromtree] drivers: sensor: ti: tmp435: added driver for TMP435
The TMP435 is a remote temperature sensor monitor with a built-in local temperature sensor. Signed-off-by: Jaakko Rautiainen <[email protected]> (cherry picked from commit 516e5d6)
1 parent c95fb4e commit ec7a814

File tree

8 files changed

+322
-1
lines changed

8 files changed

+322
-1
lines changed

drivers/sensor/ti/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ add_subdirectory_ifdef(CONFIG_TMP108 tmp108)
2020
add_subdirectory_ifdef(CONFIG_TMP112 tmp112)
2121
add_subdirectory_ifdef(CONFIG_TMP114 tmp114)
2222
add_subdirectory_ifdef(CONFIG_TMP116 tmp116)
23+
add_subdirectory_ifdef(CONFIG_TMP435 tmp435)
2324
# zephyr-keep-sorted-stop

drivers/sensor/ti/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ source "drivers/sensor/ti/tmp108/Kconfig"
2020
source "drivers/sensor/ti/tmp112/Kconfig"
2121
source "drivers/sensor/ti/tmp114/Kconfig"
2222
source "drivers/sensor/ti/tmp116/Kconfig"
23+
source "drivers/sensor/ti/tmp435/Kconfig"
2324
# zephyr-keep-sorted-stop
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Copyright (c) 2024 Bittium Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
5+
zephyr_library()
6+
7+
zephyr_library_sources(tmp435.c)

drivers/sensor/ti/tmp435/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2024 Bittium Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
5+
config TMP435
6+
bool "TMP435 temperature sensor"
7+
default y
8+
depends on DT_HAS_TI_TMP435_ENABLED
9+
select I2C
10+
help
11+
Enable the driver for the TMP435 temperature sensor

drivers/sensor/ti/tmp435/tmp435.c

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
* Copyright (c) 2024 Bittium Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT ti_tmp435
8+
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
12+
#include <zephyr/device.h>
13+
#include <zephyr/devicetree.h>
14+
#include <zephyr/drivers/i2c.h>
15+
#include <zephyr/drivers/sensor.h>
16+
#include <zephyr/logging/log.h>
17+
#include "tmp435.h"
18+
19+
LOG_MODULE_REGISTER(TMP435, CONFIG_SENSOR_LOG_LEVEL);
20+
21+
static inline int tmp435_reg_read(const struct tmp435_config *cfg, uint8_t reg, uint8_t *buf,
22+
uint32_t size)
23+
{
24+
return i2c_burst_read_dt(&cfg->i2c, reg, buf, size);
25+
}
26+
27+
static inline int tmp435_reg_write(const struct tmp435_config *cfg, uint8_t reg, uint8_t *buf,
28+
uint32_t size)
29+
{
30+
return i2c_burst_write_dt(&cfg->i2c, reg, buf, size);
31+
}
32+
33+
static inline int tmp435_get_status(const struct tmp435_config *cfg, uint8_t *status)
34+
{
35+
return tmp435_reg_read(cfg, TMP435_STATUS_REG, status, 1);
36+
}
37+
38+
static int tmp435_one_shot(const struct device *dev)
39+
{
40+
uint8_t data = 0;
41+
uint8_t status = 0;
42+
int ret = 0;
43+
const struct tmp435_config *cfg = dev->config;
44+
45+
data = 1; /* write anything to start */
46+
ret = tmp435_reg_write(cfg, TMP435_ONE_SHOT_START_REG, &data, 1);
47+
for (uint16_t i = 0; i < TMP435_CONV_LOOP_LIMIT; i++) {
48+
ret = tmp435_get_status(cfg, &status);
49+
if (ret < 0) {
50+
LOG_DBG("Failed to read TMP435_STATUS_REG, ret:%d", ret);
51+
} else {
52+
if (status & TMP435_STATUS_REG_BUSY) {
53+
/* conversion not ready */
54+
k_msleep(10);
55+
} else {
56+
LOG_DBG("conv over, loops:%d status:%x", i, status);
57+
break;
58+
}
59+
}
60+
}
61+
return ret;
62+
}
63+
64+
static int tmp435_sample_fetch(const struct device *dev, enum sensor_channel chan)
65+
{
66+
int ret = 0;
67+
uint8_t value = 0;
68+
int32_t temp = 0;
69+
const struct tmp435_config *cfg = dev->config;
70+
struct tmp435_data *data = dev->data;
71+
72+
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP &&
73+
chan != SENSOR_CHAN_AMBIENT_TEMP) {
74+
return -ENOTSUP;
75+
}
76+
tmp435_one_shot(dev); /* start conversion */
77+
if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_DIE_TEMP)) {
78+
ret = tmp435_reg_read(cfg, TMP435_LOCAL_TEMP_H_REG, &value, sizeof(value));
79+
if (ret < 0) {
80+
LOG_ERR("Failed to read TMP435_LOCAL_TEMP_H_REG, ret:%d", ret);
81+
return ret;
82+
}
83+
temp = value;
84+
ret = tmp435_reg_read(cfg, TMP435_LOCAL_TEMP_L_REG, &value, sizeof(value));
85+
if (ret < 0) {
86+
LOG_ERR("Failed to read TMP435_LOCAL_TEMP_L_REG, ret:%d", ret);
87+
return ret;
88+
}
89+
if (value > TMP435_FRACTION_INC) {
90+
temp++;
91+
}
92+
data->temp_die = temp + tmp435_temp_offset;
93+
}
94+
95+
if ((chan == SENSOR_CHAN_ALL) || (chan == SENSOR_CHAN_AMBIENT_TEMP)) {
96+
if (!(cfg->external_channel)) {
97+
return 0; /* not enabled, just return */
98+
}
99+
ret = tmp435_reg_read(cfg, TMP435_REMOTE_TEMP_H_REG, &value, sizeof(value));
100+
if (ret < 0) {
101+
LOG_ERR("Failed to read TMP435_REMOTE_TEMP_H_REG ret:%d", ret);
102+
return ret;
103+
}
104+
temp = value;
105+
ret = tmp435_reg_read(cfg, TMP435_REMOTE_TEMP_L_REG, &value, sizeof(value));
106+
if (ret < 0) {
107+
LOG_ERR("Failed to read TMP435_REMOTE_TEMP_L_REG, ret:%d", ret);
108+
return ret;
109+
}
110+
if (value > TMP435_FRACTION_INC) {
111+
temp++;
112+
}
113+
data->temp_ambient = temp + tmp435_temp_offset;
114+
}
115+
return 0;
116+
}
117+
118+
static int tmp435_channel_get(const struct device *dev, enum sensor_channel chan,
119+
struct sensor_value *val)
120+
{
121+
int ret = 0;
122+
struct tmp435_data *data = dev->data;
123+
const struct tmp435_config *cfg = dev->config;
124+
125+
switch (chan) {
126+
127+
case SENSOR_CHAN_DIE_TEMP:
128+
val->val1 = data->temp_die;
129+
val->val2 = 0;
130+
break;
131+
case SENSOR_CHAN_AMBIENT_TEMP:
132+
if (cfg->external_channel) {
133+
val->val1 = data->temp_ambient;
134+
val->val2 = 0;
135+
} else {
136+
ret = -ENOTSUP;
137+
}
138+
break;
139+
default:
140+
ret = -ENOTSUP;
141+
break;
142+
}
143+
return ret;
144+
}
145+
146+
static const struct sensor_driver_api tmp435_driver_api = {
147+
.sample_fetch = tmp435_sample_fetch,
148+
.channel_get = tmp435_channel_get,
149+
};
150+
151+
static int tmp435_init(const struct device *dev)
152+
{
153+
uint8_t data = 0;
154+
int ret = 0;
155+
const struct tmp435_config *cfg = dev->config;
156+
157+
if (!(i2c_is_ready_dt(&cfg->i2c))) {
158+
LOG_ERR("I2C dev not ready");
159+
return -ENODEV;
160+
}
161+
162+
data = 1; /* write anything to reset */
163+
ret = tmp435_reg_write(cfg, TMP435_SOFTWARE_RESET_REG, &data, 1);
164+
if (ret < 0) {
165+
LOG_ERR("Failed to write TMP435_SOFTWARE_RESET_REG ret:%d", ret);
166+
return ret;
167+
}
168+
169+
data = TMP435_CONF_REG_1_DATA;
170+
ret = tmp435_reg_write(cfg, TMP435_CONF_REG_1, &data, 1);
171+
if (ret < 0) {
172+
LOG_ERR("Failed to write TMP435_CONF_REG_1 ret:%d", ret);
173+
return ret;
174+
}
175+
176+
data = TMP435_CONF_REG_2_DATA;
177+
if (cfg->external_channel) {
178+
data = data + TMP435_CONF_REG_2_REN;
179+
}
180+
if (cfg->resistance_correction) {
181+
data = data + TMP435_CONF_REG_2_RC;
182+
}
183+
ret = tmp435_reg_write(cfg, TMP435_CONF_REG_2, &data, 1);
184+
if (ret < 0) {
185+
LOG_ERR("Failed to write TMP435_CONF_REG_2 ret:%d", ret);
186+
return ret;
187+
}
188+
189+
data = cfg->beta_compensation;
190+
ret = tmp435_reg_write(cfg, TMP435_BETA_RANGE_REG, &data, 1);
191+
if (ret < 0) {
192+
LOG_ERR("Failed to write TMP435_BETA_RANGE_REG ret:%d", ret);
193+
return ret;
194+
}
195+
return 0;
196+
}
197+
198+
/*
199+
* Device creation macros
200+
*/
201+
202+
#define TMP435_INST(inst) \
203+
static struct tmp435_data tmp435_data_##inst; \
204+
static const struct tmp435_config tmp435_config_##inst = { \
205+
.i2c = I2C_DT_SPEC_INST_GET(inst), \
206+
.external_channel = DT_INST_PROP(inst, external_channel), \
207+
.resistance_correction = DT_INST_PROP(inst, resistance_correction), \
208+
.beta_compensation = DT_INST_PROP(inst, beta_compensation), \
209+
}; \
210+
SENSOR_DEVICE_DT_INST_DEFINE(inst, tmp435_init, NULL, &tmp435_data_##inst, \
211+
&tmp435_config_##inst, POST_KERNEL, \
212+
CONFIG_SENSOR_INIT_PRIORITY, &tmp435_driver_api);
213+
214+
DT_INST_FOREACH_STATUS_OKAY(TMP435_INST)

drivers/sensor/ti/tmp435/tmp435.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2024 Bittium Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_DRIVERS_SENSOR_TMP435_H_
8+
#define ZEPHYR_DRIVERS_SENSOR_TMP435_H_
9+
10+
#define TMP435_CONF_REG_1 0x03
11+
#define TMP435_CONF_REG_1_DATA 0xc4
12+
/* [7]=1 ALERT Masked, [6]=1 Shut Down (one shot mode), [2]=1 −55 C to +150 C */
13+
#define TMP435_CONF_REG_2 0x1a
14+
#define TMP435_CONF_REG_2_REN 0x10 /* [4]=1 External channel 1 enabled */
15+
#define TMP435_CONF_REG_2_RC 0x04 /* [2]=1 Resistance correction enabled */
16+
#define TMP435_CONF_REG_2_DATA 0x08 /* [3]=1 Local channel enabled */
17+
#define TMP435_BETA_RANGE_REG 0x25
18+
#define TMP435_STATUS_REG 0x02
19+
#define TMP435_STATUS_REG_BUSY 0x80 /* conv not ready */
20+
#define TMP435_SOFTWARE_RESET_REG 0xfc
21+
#define TMP435_ONE_SHOT_START_REG 0x0f
22+
#define TMP435_LOCAL_TEMP_H_REG 0x00
23+
#define TMP435_LOCAL_TEMP_L_REG 0x15
24+
#define TMP435_REMOTE_TEMP_H_REG 0x01
25+
#define TMP435_REMOTE_TEMP_L_REG 0x10
26+
27+
#define TMP435_CONV_LOOP_LIMIT 50 /* max 50*10 ms */
28+
#define TMP435_FRACTION_INC 0x80 /* 0.5000 */
29+
30+
static const int32_t tmp435_temp_offset = -64;
31+
32+
struct tmp435_data {
33+
int32_t temp_die; /* Celsius degrees */
34+
int32_t temp_ambient; /* Celsius degrees */
35+
};
36+
37+
struct tmp435_config {
38+
struct i2c_dt_spec i2c;
39+
bool external_channel;
40+
bool resistance_correction;
41+
uint8_t beta_compensation;
42+
};
43+
44+
#endif /* ZEPHYR_DRIVERS_SENSOR_TMP435_H_ */

dts/bindings/sensor/ti,tmp435.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#
2+
# Copyright (c) 2024 Bittium Corporation
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
description: Texas Instruments TMP435 temperature sensor
8+
9+
compatible: "ti,tmp435"
10+
11+
bus: tmp435
12+
13+
include: [sensor-device.yaml, i2c-device.yaml]
14+
15+
properties:
16+
external-channel:
17+
description: External temperature measurement is enabled
18+
type: boolean
19+
resistance-correction:
20+
description: |
21+
Resistance correction feature for the external
22+
temperature channel. If not enabled then conversion
23+
is faster but with lower accuracy.
24+
type: boolean
25+
beta-compensation:
26+
description: |
27+
Beta Compensation Configuration, see Table 8
28+
from TMP435 data sheet, some common values.
29+
0x0f, Automatically selected range 7 (beta > 27.0) or
30+
Automatically detected diode connected sensor
31+
0x07, Manually disabled beta correction
32+
Default is common value for general purpose transistors.
33+
type: int
34+
default: 0x0f
35+
enum: [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
36+
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]

tests/drivers/build_all/sensor/i2c.dtsi

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,14 @@ test_i2c_tmag3001: tmag3001@a8 {
12071207
status = "okay";
12081208
reg = <0xa8>;
12091209
int-gpios = <&test_gpio 15 1>;
1210-
12111210
operation-mode = <TMAG5273_DT_OPER_MODE_CONTINUOUS>;
12121211
angle-magnitude-axis = <TMAG5273_DT_ANGLE_MAG_XY>;
12131212
};
1213+
1214+
test_i2c_tmp435: tmp435@a9 {
1215+
compatible = "ti,tmp435";
1216+
reg = <0xa9>;
1217+
external-channel;
1218+
resistance-correction;
1219+
beta-compensation = <0x0f>;
1220+
};

0 commit comments

Comments
 (0)