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 <jordan@embeint.com>
This commit is contained in:
parent
acbc14e767
commit
8f4cf7f6af
2 changed files with 21 additions and 0 deletions
|
|
@ -18,10 +18,12 @@ LOG_MODULE_REGISTER(voltage, CONFIG_SENSOR_LOG_LEVEL);
|
|||
struct voltage_config {
|
||||
struct voltage_divider_dt_spec voltage;
|
||||
struct gpio_dt_spec gpio_power;
|
||||
uint32_t sample_delay_us;
|
||||
};
|
||||
|
||||
struct voltage_data {
|
||||
struct adc_sequence sequence;
|
||||
k_timeout_t earliest_sample;
|
||||
uint16_t raw;
|
||||
};
|
||||
|
||||
|
|
@ -35,6 +37,9 @@ static int fetch(const struct device *dev, enum sensor_channel chan)
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Wait until sampling is valid */
|
||||
k_sleep(data->earliest_sample);
|
||||
|
||||
ret = adc_read(config->voltage.port.dev, &data->sequence);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("adc_read: %d", ret);
|
||||
|
|
@ -90,6 +95,7 @@ static const struct sensor_driver_api voltage_api = {
|
|||
static int pm_action(const struct device *dev, enum pm_device_action action)
|
||||
{
|
||||
const struct voltage_config *config = dev->config;
|
||||
struct voltage_data *data = dev->data;
|
||||
int ret = 0;
|
||||
|
||||
if (config->gpio_power.port == NULL) {
|
||||
|
|
@ -109,6 +115,8 @@ static int pm_action(const struct device *dev, enum pm_device_action action)
|
|||
if (ret != 0) {
|
||||
LOG_ERR("failed to set GPIO for PM resume");
|
||||
}
|
||||
data->earliest_sample = K_TIMEOUT_ABS_TICKS(
|
||||
k_uptime_ticks() + k_us_to_ticks_ceil32(config->sample_delay_us));
|
||||
break;
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
case PM_DEVICE_ACTION_SUSPEND:
|
||||
|
|
@ -133,6 +141,9 @@ static int voltage_init(const struct device *dev)
|
|||
struct voltage_data *data = dev->data;
|
||||
int ret;
|
||||
|
||||
/* Default value to use if `power-gpios` does not exist */
|
||||
data->earliest_sample = K_TIMEOUT_ABS_TICKS(0);
|
||||
|
||||
if (!adc_is_ready_dt(&config->voltage.port)) {
|
||||
LOG_ERR("ADC is not ready");
|
||||
return -ENODEV;
|
||||
|
|
@ -169,6 +180,7 @@ static int voltage_init(const struct device *dev)
|
|||
static const struct voltage_config voltage_##inst##_config = { \
|
||||
.voltage = VOLTAGE_DIVIDER_DT_SPEC_GET(DT_DRV_INST(inst)), \
|
||||
.gpio_power = GPIO_DT_SPEC_INST_GET_OR(inst, power_gpios, {0}), \
|
||||
.sample_delay_us = DT_INST_PROP(inst, power_on_sample_delay_us), \
|
||||
}; \
|
||||
\
|
||||
PM_DEVICE_DT_INST_DEFINE(inst, pm_action); \
|
||||
|
|
|
|||
|
|
@ -36,3 +36,12 @@ properties:
|
|||
|
||||
If present the corresponding GPIO must be set to an active level
|
||||
to enable the divider input.
|
||||
|
||||
power-on-sample-delay-us:
|
||||
type: int
|
||||
default: 100
|
||||
description: |
|
||||
Duration to delay sampling after enabling the circuitry with
|
||||
`power-gpios`. In most cases the switched voltage rail will
|
||||
require some non-zero time to settle to its final value. The
|
||||
default value of 100us should be sufficient in most situations.
|
||||
|
|
|
|||
Loading…
Reference in a new issue