Skip to content

Commit 05d798e

Browse files
Delsiangalak
authored andcommitted
drivers: sensor: STM32 die temperature driver
STM32 internal temperature sensor driver. This sensor can be used to measure the temperature of the CPU and its surroundings. Signed-off-by: Eug Krashtan <[email protected]>
1 parent c045cbd commit 05d798e

File tree

7 files changed

+207
-0
lines changed

7 files changed

+207
-0
lines changed

drivers/sensor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ add_subdirectory_ifdef(CONFIG_SI7055 si7055)
7474
add_subdirectory_ifdef(CONFIG_SI7060 si7060)
7575
add_subdirectory_ifdef(CONFIG_SM351LT sm351lt)
7676
add_subdirectory_ifdef(CONFIG_HAS_STMEMSC stmemsc)
77+
add_subdirectory_ifdef(CONFIG_STM32_TEMP stm32_temp)
7778
add_subdirectory_ifdef(CONFIG_STTS751 stts751)
7879
add_subdirectory_ifdef(CONFIG_SX9500 sx9500)
7980
add_subdirectory_ifdef(CONFIG_TH02 th02)

drivers/sensor/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ source "drivers/sensor/si7060/Kconfig"
186186

187187
source "drivers/sensor/sm351lt/Kconfig"
188188

189+
source "drivers/sensor/stm32_temp/Kconfig"
190+
189191
source "drivers/sensor/stts751/Kconfig"
190192

191193
source "drivers/sensor/sx9500/Kconfig"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_library()
4+
5+
zephyr_library_sources_ifdef(CONFIG_STM32_TEMP stm32_temp.c)

drivers/sensor/stm32_temp/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# STM32 temperature sensor configuration options
2+
3+
# Copyright (c) 2021 Eug Krashtan
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config STM32_TEMP
7+
bool "STM32 Temperature Sensor"
8+
depends on (ADC && SOC_FAMILY_STM32)
9+
help
10+
Enable driver for STM32 temperature sensor.
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/*
2+
* Copyright (c) 2021 Eug Krashtan
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <device.h>
8+
#include <drivers/sensor.h>
9+
#include <drivers/adc.h>
10+
#include <logging/log.h>
11+
12+
LOG_MODULE_REGISTER(stm32_temp, CONFIG_SENSOR_LOG_LEVEL);
13+
14+
#define DT_DRV_COMPAT st_stm32_temp
15+
16+
struct stm32_temp_data {
17+
const struct device *adc;
18+
uint8_t channel;
19+
struct adc_channel_cfg adc_cfg;
20+
struct adc_sequence adc_seq;
21+
struct k_mutex mutex;
22+
int16_t sample_buffer;
23+
int32_t mv; /* Sensor value in millivolts */
24+
};
25+
26+
struct stm32_temp_config {
27+
int avgslope;
28+
int v25_mv;
29+
int tsv_mv;
30+
bool is_ntc;
31+
};
32+
33+
static int stm32_temp_sample_fetch(const struct device *dev,
34+
enum sensor_channel chan)
35+
{
36+
const struct stm32_temp_config *cfg = dev->config;
37+
struct stm32_temp_data *data = dev->data;
38+
struct adc_sequence *sp = &data->adc_seq;
39+
int rc;
40+
41+
if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) {
42+
return -ENOTSUP;
43+
}
44+
45+
k_mutex_lock(&data->mutex, K_FOREVER);
46+
47+
rc = adc_read(data->adc, sp);
48+
sp->calibrate = false;
49+
if (rc == 0) {
50+
data->mv = data->sample_buffer * cfg->tsv_mv / 0x0FFF;
51+
}
52+
53+
k_mutex_unlock(&data->mutex);
54+
55+
return 0;
56+
}
57+
58+
static int stm32_temp_channel_get(const struct device *dev,
59+
enum sensor_channel chan,
60+
struct sensor_value *val)
61+
{
62+
struct stm32_temp_data *data = dev->data;
63+
const struct stm32_temp_config *cfg = dev->config;
64+
float temp;
65+
66+
if (chan != SENSOR_CHAN_DIE_TEMP) {
67+
return -ENOTSUP;
68+
}
69+
70+
if (cfg->is_ntc) {
71+
temp = (float)(cfg->v25_mv - data->mv);
72+
} else {
73+
temp = (float)(data->mv - cfg->v25_mv);
74+
}
75+
temp = (temp/cfg->avgslope)*10;
76+
temp += 25;
77+
sensor_value_from_double(val, temp);
78+
79+
return 0;
80+
}
81+
82+
static const struct sensor_driver_api stm32_temp_driver_api = {
83+
.sample_fetch = stm32_temp_sample_fetch,
84+
.channel_get = stm32_temp_channel_get,
85+
};
86+
87+
static int stm32_temp_init(const struct device *dev)
88+
{
89+
struct stm32_temp_data *data = dev->data;
90+
struct adc_channel_cfg *accp = &data->adc_cfg;
91+
struct adc_sequence *asp = &data->adc_seq;
92+
int rc;
93+
94+
k_mutex_init(&data->mutex);
95+
96+
if (!device_is_ready(data->adc)) {
97+
LOG_ERR("Device %s is not ready", data->adc->name);
98+
return -ENODEV;
99+
}
100+
101+
*accp = (struct adc_channel_cfg){
102+
.gain = ADC_GAIN_1,
103+
.reference = ADC_REF_INTERNAL,
104+
.acquisition_time = ADC_ACQ_TIME_MAX,
105+
.channel_id = data->channel,
106+
.differential = 0
107+
};
108+
rc = adc_channel_setup(data->adc, accp);
109+
LOG_DBG("Setup AIN%u got %d", data->channel, rc);
110+
111+
*asp = (struct adc_sequence){
112+
.channels = BIT(data->channel),
113+
.buffer = &data->sample_buffer,
114+
.buffer_size = sizeof(data->sample_buffer),
115+
.resolution = 12,
116+
.calibrate = true,
117+
};
118+
119+
return 0;
120+
}
121+
122+
#define STM32_TEMP_INST(idx) \
123+
static struct stm32_temp_data inst_##idx##_data = { \
124+
.adc = DEVICE_DT_GET(DT_IO_CHANNELS_CTLR( \
125+
DT_INST(idx, st_stm32_temp))), \
126+
.channel = DT_IO_CHANNELS_INPUT( \
127+
DT_INST(idx, st_stm32_temp)) \
128+
}; \
129+
static const struct stm32_temp_config inst_##idx##_config = { \
130+
.avgslope = DT_INST_PROP(idx, avgslope), \
131+
.v25_mv = DT_INST_PROP(idx, v25), \
132+
.tsv_mv = DT_INST_PROP(idx, ts_voltage_mv), \
133+
.is_ntc = DT_INST_PROP(idx, ntc) \
134+
}; \
135+
DEVICE_DT_INST_DEFINE(idx, \
136+
stm32_temp_init, \
137+
NULL, \
138+
&inst_##idx##_data, \
139+
&inst_##idx##_config, \
140+
POST_KERNEL, \
141+
CONFIG_SENSOR_INIT_PRIORITY, \
142+
&stm32_temp_driver_api);
143+
144+
DT_INST_FOREACH_STATUS_OKAY(STM32_TEMP_INST)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) 2021, Eug Krashtan
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: STM32 family TEMP node
5+
6+
compatible: "st,stm32-temp"
7+
8+
include: base.yaml
9+
10+
properties:
11+
label:
12+
required: true
13+
14+
io-channels:
15+
required: true
16+
description: ADC channel for temperature sensor
17+
18+
ts-voltage-mv:
19+
type: int
20+
default: 3300
21+
description: Temperature sensor voltage in millivolts
22+
23+
avgslope:
24+
type: int
25+
default: 25
26+
description: >
27+
Average slope of T-V chart (in mV/C x10) according to
28+
datasheet "Electrical characteristics/Operating conditions"
29+
STM32F1 Table 5.3.19 (min 4 mV/C, max 4.6, default 4.3)
30+
STM32F4 Table 6.3.21 default 2.5
31+
32+
v25:
33+
type: int
34+
default: 760
35+
description: >
36+
Voltage of temperature sensor at 25C in mV according to
37+
datasheet "Electrical characteristics/Operating conditions"
38+
STM32F1 Table 5.3.19 (min 1340, max 1520, default 1430)
39+
STM32F4 Table 6.3.21 default 760
40+
41+
ntc:
42+
type: boolean
43+
description: >
44+
Negative Temperature Coefficient. True if STM32F1

tests/drivers/build_all/sensors_i_z.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ CONFIG_SI7006=y
3737
CONFIG_SI7055=y
3838
CONFIG_SI7060=y
3939
CONFIG_SM351LT=y
40+
CONFIG_STM32_TEMP=y
4041
CONFIG_SX9500=y
4142
CONFIG_TACH_NPCX=y
4243
CONFIG_TEMP_NRF5=y

0 commit comments

Comments
 (0)