Skip to content

Commit 8f4cf7f

Browse files
JordanYatesnashif
authored andcommitted
sensor: voltage_divider: delay sampling after power-on
Enforce some minimum delay between enabling the voltage divider with a GPIO and sampling the analog voltage. Without this delay the ADC can easily sample the transient power up curve instead of the steady state output. Signed-off-by: Jordan Yates <[email protected]>
1 parent acbc14e commit 8f4cf7f

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

drivers/sensor/voltage_divider/voltage.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ LOG_MODULE_REGISTER(voltage, CONFIG_SENSOR_LOG_LEVEL);
1818
struct voltage_config {
1919
struct voltage_divider_dt_spec voltage;
2020
struct gpio_dt_spec gpio_power;
21+
uint32_t sample_delay_us;
2122
};
2223

2324
struct voltage_data {
2425
struct adc_sequence sequence;
26+
k_timeout_t earliest_sample;
2527
uint16_t raw;
2628
};
2729

@@ -35,6 +37,9 @@ static int fetch(const struct device *dev, enum sensor_channel chan)
3537
return -ENOTSUP;
3638
}
3739

40+
/* Wait until sampling is valid */
41+
k_sleep(data->earliest_sample);
42+
3843
ret = adc_read(config->voltage.port.dev, &data->sequence);
3944
if (ret != 0) {
4045
LOG_ERR("adc_read: %d", ret);
@@ -90,6 +95,7 @@ static const struct sensor_driver_api voltage_api = {
9095
static int pm_action(const struct device *dev, enum pm_device_action action)
9196
{
9297
const struct voltage_config *config = dev->config;
98+
struct voltage_data *data = dev->data;
9399
int ret = 0;
94100

95101
if (config->gpio_power.port == NULL) {
@@ -109,6 +115,8 @@ static int pm_action(const struct device *dev, enum pm_device_action action)
109115
if (ret != 0) {
110116
LOG_ERR("failed to set GPIO for PM resume");
111117
}
118+
data->earliest_sample = K_TIMEOUT_ABS_TICKS(
119+
k_uptime_ticks() + k_us_to_ticks_ceil32(config->sample_delay_us));
112120
break;
113121
#ifdef CONFIG_PM_DEVICE
114122
case PM_DEVICE_ACTION_SUSPEND:
@@ -133,6 +141,9 @@ static int voltage_init(const struct device *dev)
133141
struct voltage_data *data = dev->data;
134142
int ret;
135143

144+
/* Default value to use if `power-gpios` does not exist */
145+
data->earliest_sample = K_TIMEOUT_ABS_TICKS(0);
146+
136147
if (!adc_is_ready_dt(&config->voltage.port)) {
137148
LOG_ERR("ADC is not ready");
138149
return -ENODEV;
@@ -169,6 +180,7 @@ static int voltage_init(const struct device *dev)
169180
static const struct voltage_config voltage_##inst##_config = { \
170181
.voltage = VOLTAGE_DIVIDER_DT_SPEC_GET(DT_DRV_INST(inst)), \
171182
.gpio_power = GPIO_DT_SPEC_INST_GET_OR(inst, power_gpios, {0}), \
183+
.sample_delay_us = DT_INST_PROP(inst, power_on_sample_delay_us), \
172184
}; \
173185
\
174186
PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \

dts/bindings/iio/afe/voltage-divider.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,12 @@ properties:
3636
3737
If present the corresponding GPIO must be set to an active level
3838
to enable the divider input.
39+
40+
power-on-sample-delay-us:
41+
type: int
42+
default: 100
43+
description: |
44+
Duration to delay sampling after enabling the circuitry with
45+
`power-gpios`. In most cases the switched voltage rail will
46+
require some non-zero time to settle to its final value. The
47+
default value of 100us should be sufficient in most situations.

0 commit comments

Comments
 (0)