Skip to content

Commit 5146ce9

Browse files
committed
drivers: sensor: tmp11x: add trigger function for alert
Allows to configure the alert or therm mode for triggers based on the low/high temperature treshholds Signed-off-by: Tobias Meyer <[email protected]>
1 parent 366d45f commit 5146ce9

File tree

11 files changed

+382
-18
lines changed

11 files changed

+382
-18
lines changed

drivers/sensor/ti/tmp11x/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
zephyr_library()
44

55
zephyr_library_sources(tmp11x.c)
6+
zephyr_library_sources_ifdef(CONFIG_TMP11X_TRIGGER tmp11x_trigger.c)

drivers/sensor/ti/tmp11x/Kconfig

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,46 @@ config TMP11X
1010
select I2C
1111
help
1212
Enable driver for TMP116, TMP117 and TMP119 temperature sensors.
13+
14+
choice
15+
prompt "TMP11X Alert Pin Trigger Mode"
16+
default TMP11X_TRIGGER_GLOBAL_THREAD
17+
depends on TMP11X
18+
19+
config TMP11X_TRIGGER_NONE
20+
bool "No trigger"
21+
22+
config TMP11X_TRIGGER_GLOBAL_THREAD
23+
bool "Use global thread"
24+
depends on GPIO
25+
select TMP11X_TRIGGER
26+
27+
config TMP11X_TRIGGER_OWN_THREAD
28+
bool "Use own thread"
29+
depends on GPIO
30+
select TMP11X_TRIGGER
31+
32+
endchoice
33+
34+
config TMP11X_TRIGGER
35+
bool
36+
depends on GPIO
37+
help
38+
Enable support for the TMP11X alert pin functionality.
39+
The alert pin can be configured to trigger when temperature
40+
exceeds configurable high/low thresholds. This is supported
41+
on TMP116, TMP117, and TMP119 devices.
42+
43+
config TMP11X_THREAD_PRIORITY
44+
int "Thread priority"
45+
depends on TMP11X_TRIGGER_OWN_THREAD
46+
default 10
47+
help
48+
Priority of thread used by the driver to handle interrupts.
49+
50+
config TMP11X_THREAD_STACK_SIZE
51+
int "Thread stack size"
52+
depends on TMP11X_TRIGGER_OWN_THREAD
53+
default 1024
54+
help
55+
Stack size of thread used by the driver to handle interrupts.

drivers/sensor/ti/tmp11x/tmp11x.c

Lines changed: 99 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#define DT_DRV_COMPAT ti_tmp11x
88

99
#include <zephyr/device.h>
10-
#include <zephyr/drivers/i2c.h>
1110
#include <zephyr/drivers/sensor.h>
1211
#include <zephyr/drivers/sensor/tmp11x.h>
1312
#include <zephyr/dt-bindings/sensor/tmp11x.h>
@@ -25,8 +24,7 @@
2524

2625
LOG_MODULE_REGISTER(TMP11X, CONFIG_SENSOR_LOG_LEVEL);
2726

28-
static int tmp11x_reg_read(const struct device *dev, uint8_t reg,
29-
uint16_t *val)
27+
int tmp11x_reg_read(const struct device *dev, uint8_t reg, uint16_t *val)
3028
{
3129
const struct tmp11x_dev_config *cfg = dev->config;
3230

@@ -40,8 +38,7 @@ static int tmp11x_reg_read(const struct device *dev, uint8_t reg,
4038
return 0;
4139
}
4240

43-
static int tmp11x_reg_write(const struct device *dev, uint8_t reg,
44-
uint16_t val)
41+
int tmp11x_reg_write(const struct device *dev, uint8_t reg, uint16_t val)
4542
{
4643
const struct tmp11x_dev_config *cfg = dev->config;
4744
uint8_t tx_buf[3] = {reg, val >> 8, val & 0xFF};
@@ -71,6 +68,31 @@ static inline bool tmp11x_is_offset_supported(const struct tmp11x_data *drv_data
7168
return drv_data->id == TMP117_DEVICE_ID || drv_data->id == TMP119_DEVICE_ID;
7269
}
7370

71+
/**
72+
* @brief Convert sensor_value temperature to TMP11X register format
73+
*
74+
* This function converts a temperature from sensor_value format (val1 in degrees C,
75+
* val2 in micro-degrees C) to the TMP11X register format. It uses 64-bit arithmetic
76+
* to prevent overflow and clamps the result to the valid int16_t range.
77+
*
78+
* @param val Pointer to sensor_value containing temperature
79+
* @return Temperature value in TMP11X register format (int16_t)
80+
*/
81+
static inline int16_t tmp11x_sensor_value_to_reg_format(const struct sensor_value *val)
82+
{
83+
int64_t temp_micro = ((int64_t)val->val1 * 1000000) + val->val2;
84+
int64_t temp_scaled = (temp_micro * 10) / TMP11X_RESOLUTION;
85+
86+
/* Clamp to int16_t range */
87+
if (temp_scaled > INT16_MAX) {
88+
return INT16_MAX;
89+
} else if (temp_scaled < INT16_MIN) {
90+
return INT16_MIN;
91+
} else {
92+
return (int16_t)temp_scaled;
93+
}
94+
}
95+
7496
static bool check_eeprom_bounds(const struct device *dev, off_t offset,
7597
size_t len)
7698
{
@@ -310,8 +332,7 @@ static int tmp11x_attr_set(const struct device *dev,
310332
/*
311333
* The offset is encoded into the temperature register format.
312334
*/
313-
value = (((val->val1) * 10000000) + ((val->val2) * 10))
314-
/ (int32_t)TMP11X_RESOLUTION;
335+
value = tmp11x_sensor_value_to_reg_format(val);
315336

316337
return tmp11x_reg_write(dev, TMP117_REG_TEMP_OFFSET, value);
317338

@@ -347,6 +368,34 @@ static int tmp11x_attr_set(const struct device *dev,
347368
case SENSOR_ATTR_TMP11X_ONE_SHOT_MODE:
348369
return tmp11x_write_config(dev, TMP11X_CFGR_MODE, TMP11X_MODE_ONE_SHOT);
349370

371+
#ifdef CONFIG_TMP11X_TRIGGER
372+
case SENSOR_ATTR_TMP11X_ALERT_PIN_POLARITY:
373+
if (val->val1 == TMP11X_ALERT_PIN_ACTIVE_HIGH) {
374+
return tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_POL,
375+
TMP11X_CFGR_ALERT_PIN_POL);
376+
} else {
377+
return tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_POL, 0);
378+
}
379+
380+
case SENSOR_ATTR_TMP11X_ALERT_PIN_MODE:
381+
if (val->val1 == TMP11X_ALERT_PIN_THERM_MODE) {
382+
return tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_MODE,
383+
TMP11X_CFGR_ALERT_PIN_MODE);
384+
} else {
385+
return tmp11x_write_config(dev, TMP11X_CFGR_ALERT_PIN_MODE, 0);
386+
}
387+
388+
case SENSOR_ATTR_UPPER_THRESH:
389+
/* Convert temperature to register format */
390+
value = tmp11x_sensor_value_to_reg_format(val);
391+
return tmp11x_reg_write(dev, TMP11X_REG_HIGH_LIM, value);
392+
393+
case SENSOR_ATTR_LOWER_THRESH:
394+
/* Convert temperature to register format */
395+
value = tmp11x_sensor_value_to_reg_format(val);
396+
return tmp11x_reg_write(dev, TMP11X_REG_LOW_LIM, value);
397+
#endif /* CONFIG_TMP11X_TRIGGER */
398+
350399
default:
351400
return -ENOTSUP;
352401
}
@@ -385,6 +434,25 @@ static int tmp11x_attr_get(const struct device *dev, enum sensor_channel chan,
385434
}
386435

387436
return rc;
437+
438+
#ifdef CONFIG_TMP11X_TRIGGER
439+
case SENSOR_ATTR_UPPER_THRESH:
440+
rc = tmp11x_reg_read(dev, TMP11X_REG_HIGH_LIM, &data);
441+
if (rc == 0) {
442+
tmp11x_temperature_to_sensor_value(data, val);
443+
}
444+
445+
return rc;
446+
447+
case SENSOR_ATTR_LOWER_THRESH:
448+
rc = tmp11x_reg_read(dev, TMP11X_REG_LOW_LIM, &data);
449+
if (rc == 0) {
450+
tmp11x_temperature_to_sensor_value(data, val);
451+
}
452+
453+
return rc;
454+
#endif /* CONFIG_TMP11X_TRIGGER */
455+
388456
default:
389457
return -ENOTSUP;
390458
}
@@ -394,7 +462,10 @@ static DEVICE_API(sensor, tmp11x_driver_api) = {
394462
.attr_set = tmp11x_attr_set,
395463
.attr_get = tmp11x_attr_get,
396464
.sample_fetch = tmp11x_sample_fetch,
397-
.channel_get = tmp11x_channel_get
465+
.channel_get = tmp11x_channel_get,
466+
#ifdef CONFIG_TMP11X_TRIGGER
467+
.trigger_set = tmp11x_trigger_set,
468+
#endif
398469
};
399470

400471
static int tmp11x_init(const struct device *dev)
@@ -424,18 +495,28 @@ static int tmp11x_init(const struct device *dev)
424495

425496
rc = tmp11x_write_config(dev, TMP11X_CFGR_AVG, cfg->oversampling);
426497

498+
#ifdef CONFIG_TMP11X_TRIGGER
499+
drv_data->dev = dev;
500+
rc = tmp11x_init_interrupt(dev);
501+
if (rc < 0) {
502+
LOG_ERR("%s: Failed to initialize alert pin", dev->name);
503+
return rc;
504+
}
505+
#endif /* CONFIG_TMP11X_TRIGGER */
506+
427507
return rc;
428508
}
429509

430-
#define DEFINE_TMP11X(_num) \
431-
static struct tmp11x_data tmp11x_data_##_num; \
432-
static const struct tmp11x_dev_config tmp11x_config_##_num = { \
433-
.bus = I2C_DT_SPEC_INST_GET(_num), \
434-
.odr = DT_INST_PROP(_num, odr), \
435-
.oversampling = DT_INST_PROP(_num, oversampling), \
436-
}; \
437-
SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp11x_init, NULL, \
438-
&tmp11x_data_##_num, &tmp11x_config_##_num, POST_KERNEL, \
439-
CONFIG_SENSOR_INIT_PRIORITY, &tmp11x_driver_api);
510+
#define DEFINE_TMP11X(_num) \
511+
static struct tmp11x_data tmp11x_data_##_num; \
512+
static const struct tmp11x_dev_config tmp11x_config_##_num = { \
513+
.bus = I2C_DT_SPEC_INST_GET(_num), \
514+
.odr = DT_INST_PROP(_num, odr), \
515+
.oversampling = DT_INST_PROP(_num, oversampling), \
516+
IF_ENABLED(CONFIG_TMP11X_TRIGGER, \
517+
(.alert_gpio = GPIO_DT_SPEC_INST_GET_OR(_num, alert_gpios, {}),)) }; \
518+
SENSOR_DEVICE_DT_INST_DEFINE(_num, tmp11x_init, NULL, &tmp11x_data_##_num, \
519+
&tmp11x_config_##_num, POST_KERNEL, \
520+
CONFIG_SENSOR_INIT_PRIORITY, &tmp11x_driver_api);
440521

441522
DT_INST_FOREACH_STATUS_OKAY(DEFINE_TMP11X)

drivers/sensor/ti/tmp11x/tmp11x.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#define ZEPHYR_DRIVERS_SENSOR_TMP11X_TMP11X_H_
99

1010
#include <zephyr/sys/util_macro.h>
11+
#include <zephyr/drivers/gpio.h>
12+
#include <zephyr/drivers/i2c.h>
1113

1214
#define TMP11X_REG_TEMP 0x0
1315
#define TMP11X_REG_CFGR 0x1
@@ -35,6 +37,10 @@
3537
#define TMP11X_EEPROM_UL_UNLOCK BIT(15)
3638
#define TMP11X_EEPROM_UL_BUSY BIT(14)
3739

40+
/* Alert pin configuration bits */
41+
#define TMP11X_CFGR_ALERT_PIN_POL BIT(3) /* Alert pin polarity */
42+
#define TMP11X_CFGR_ALERT_PIN_MODE BIT(4) /* Alert pin mode (1=therm, 0=alert) */
43+
3844
#define TMP11X_AVG_1_SAMPLE 0
3945
#define TMP11X_AVG_8_SAMPLES BIT(5)
4046
#define TMP11X_AVG_32_SAMPLES BIT(6)
@@ -46,12 +52,39 @@
4652
struct tmp11x_data {
4753
uint16_t sample;
4854
uint16_t id;
55+
#ifdef CONFIG_TMP11X_TRIGGER
56+
const struct device *dev;
57+
struct gpio_callback alert_cb;
58+
sensor_trigger_handler_t alert_handler;
59+
const struct sensor_trigger *alert_trigger;
60+
61+
#if defined(CONFIG_TMP11X_TRIGGER_OWN_THREAD)
62+
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_TMP11X_THREAD_STACK_SIZE);
63+
struct k_thread thread;
64+
struct k_sem gpio_sem;
65+
#elif defined(CONFIG_TMP11X_TRIGGER_GLOBAL_THREAD)
66+
struct k_work work;
67+
#endif /* CONFIG_TMP11X_TRIGGER_OWN_THREAD */
68+
#endif /* CONFIG_TMP11X_TRIGGER */
4969
};
5070

5171
struct tmp11x_dev_config {
5272
struct i2c_dt_spec bus;
5373
uint16_t odr;
5474
uint16_t oversampling;
75+
#ifdef CONFIG_TMP11X_TRIGGER
76+
struct gpio_dt_spec alert_gpio;
77+
#endif
5578
};
5679

80+
/* Function declarations */
81+
int tmp11x_write_config(const struct device *dev, uint16_t mask, uint16_t conf);
82+
int tmp11x_reg_read(const struct device *dev, uint8_t reg, uint16_t *val);
83+
84+
#ifdef CONFIG_TMP11X_TRIGGER
85+
int tmp11x_trigger_set(const struct device *dev, const struct sensor_trigger *trig,
86+
sensor_trigger_handler_t handler);
87+
int tmp11x_init_interrupt(const struct device *dev);
88+
#endif
89+
5790
#endif /* ZEPHYR_DRIVERS_SENSOR_TMP11X_TMP11X_H_ */

0 commit comments

Comments
 (0)