feat: Add ADC sensor device tree bindings and configuration

Introduces device tree bindings for custom ADC voltage and current sensors,
allowing for flexible configuration of sensor inputs and associated GPIOs.
This enables proper hardware abstraction for ADC measurements.

The example overlay file
has been removed as its content is now integrated or superseded by the new
binding definitions.
This commit is contained in:
2025-07-08 16:43:27 +02:00
parent 2e8a86bc54
commit b11f844415
7 changed files with 333 additions and 7 deletions

View File

@@ -8,7 +8,7 @@ if ADC_SENSOR
config ADC_SENSOR_SIMULATED
bool "Use simulated ADC readings"
default y
default n
help
Use simulated values instead of real ADC readings.
Voltage: 12000mV, Current: 45mA

View File

@@ -4,10 +4,13 @@
*
* This file contains the implementation for initializing and reading from ADC
* sensors. It currently provides simulated values for voltage and current, with
* placeholders for real hardware ADC implementation.
* placeholders for real hardware ADC implementation including GPIO control.
*/
#include <lib/adc_sensor.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
@@ -17,8 +20,150 @@ LOG_MODULE_REGISTER(adc_sensor, LOG_LEVEL_INF);
#define SIMULATED_VOLTAGE_MV 12000
#define SIMULATED_CURRENT_MA 45
static bool initialized =
false; // Flag to indicate if the ADC sensor is initialized
// Devicetree node checks
#define VOLTAGE_SENSOR_NODE DT_NODELABEL(supply_voltage)
#define CURRENT_SENSOR_NODE DT_NODELABEL(motor_current)
static bool initialized = false;
#ifndef CONFIG_ADC_SENSOR_SIMULATED
// GPIO specs for voltage sensor (if devicetree nodes exist)
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
static const struct gpio_dt_spec voltage_sen_gpio =
GPIO_DT_SPEC_GET(VOLTAGE_SENSOR_NODE, sen_gpios);
static const struct gpio_dt_spec voltage_s0_gpio =
GPIO_DT_SPEC_GET(VOLTAGE_SENSOR_NODE, s0_gpios);
static const struct gpio_dt_spec voltage_s1_gpio =
GPIO_DT_SPEC_GET(VOLTAGE_SENSOR_NODE, s1_gpios);
#endif
// GPIO specs for current sensor (if devicetree nodes exist)
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
static const struct gpio_dt_spec current_sen_gpio =
GPIO_DT_SPEC_GET(CURRENT_SENSOR_NODE, sen_gpios);
static const struct gpio_dt_spec current_s0_gpio =
GPIO_DT_SPEC_GET(CURRENT_SENSOR_NODE, s0_gpios);
static const struct gpio_dt_spec current_s1_gpio =
GPIO_DT_SPEC_GET(CURRENT_SENSOR_NODE, s1_gpios);
#endif
/**
* @brief Configure GPIO pins for ADC sensor control
*/
static int configure_sensor_gpios(void) {
int ret = 0;
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
// Configure voltage sensor GPIOs
if (gpio_is_ready_dt(&voltage_sen_gpio)) {
ret = gpio_pin_configure_dt(&voltage_sen_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure voltage sen GPIO: %d", ret);
return ret;
}
}
if (gpio_is_ready_dt(&voltage_s0_gpio)) {
ret = gpio_pin_configure_dt(&voltage_s0_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure voltage s0 GPIO: %d", ret);
return ret;
}
}
if (gpio_is_ready_dt(&voltage_s1_gpio)) {
ret = gpio_pin_configure_dt(&voltage_s1_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure voltage s1 GPIO: %d", ret);
return ret;
}
}
#endif
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
// Configure current sensor GPIOs
if (gpio_is_ready_dt(&current_sen_gpio)) {
ret = gpio_pin_configure_dt(&current_sen_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure current sen GPIO: %d", ret);
return ret;
}
}
if (gpio_is_ready_dt(&current_s0_gpio)) {
ret = gpio_pin_configure_dt(&current_s0_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure current s0 GPIO: %d", ret);
return ret;
}
}
if (gpio_is_ready_dt(&current_s1_gpio)) {
ret = gpio_pin_configure_dt(&current_s1_gpio, GPIO_OUTPUT_INACTIVE);
if (ret < 0) {
LOG_ERR("Failed to configure current s1 GPIO: %d", ret);
return ret;
}
}
#endif
return 0;
}
/**
* @brief Set GPIO pins for voltage measurement
* @param s0_state State for S0 pin (multiplexer bit 0)
* @param s1_state State for S1 pin (multiplexer bit 1)
*/
static int set_voltage_sensor_gpios(bool enable, bool s0_state, bool s1_state) {
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
if (gpio_is_ready_dt(&voltage_sen_gpio)) {
gpio_pin_set_dt(&voltage_sen_gpio, enable ? 1 : 0);
}
if (gpio_is_ready_dt(&voltage_s0_gpio)) {
gpio_pin_set_dt(&voltage_s0_gpio, s0_state ? 1 : 0);
}
if (gpio_is_ready_dt(&voltage_s1_gpio)) {
gpio_pin_set_dt(&voltage_s1_gpio, s1_state ? 1 : 0);
}
// Delay for GPIO settling (from devicetree or default)
#if DT_NODE_HAS_PROP(VOLTAGE_SENSOR_NODE, measurement_delay_ms)
k_msleep(DT_PROP(VOLTAGE_SENSOR_NODE, measurement_delay_ms));
#else
k_msleep(5); // Default 5ms delay
#endif
#endif
return 0;
}
/**
* @brief Set GPIO pins for current measurement
* @param s0_state State for S0 pin (multiplexer bit 0)
* @param s1_state State for S1 pin (multiplexer bit 1)
*/
static int set_current_sensor_gpios(bool enable, bool s0_state, bool s1_state) {
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
if (gpio_is_ready_dt(&current_sen_gpio)) {
gpio_pin_set_dt(&current_sen_gpio, enable ? 1 : 0);
}
if (gpio_is_ready_dt(&current_s0_gpio)) {
gpio_pin_set_dt(&current_s0_gpio, s0_state ? 1 : 0);
}
if (gpio_is_ready_dt(&current_s1_gpio)) {
gpio_pin_set_dt(&current_s1_gpio, s1_state ? 1 : 0);
}
// Delay for GPIO settling (from devicetree or default)
#if DT_NODE_HAS_PROP(CURRENT_SENSOR_NODE, measurement_delay_ms)
k_msleep(DT_PROP(CURRENT_SENSOR_NODE, measurement_delay_ms));
#else
k_msleep(10); // Default 10ms delay
#endif
#endif
return 0;
}
#endif /* !CONFIG_ADC_SENSOR_SIMULATED */
int adc_sensor_init(void) {
if (initialized) {
@@ -30,8 +175,22 @@ int adc_sensor_init(void) {
LOG_INF("Simulated values: %dmV, %dmA", SIMULATED_VOLTAGE_MV,
SIMULATED_CURRENT_MA);
#else
// Initialize GPIO pins for sensor control
int ret = configure_sensor_gpios();
if (ret < 0) {
LOG_ERR("Failed to configure sensor GPIOs: %d", ret);
return ret;
}
// TODO: Initialize real ADC hardware
LOG_INF("ADC sensor initialized (real ADC mode - not yet implemented)");
LOG_INF("ADC sensor initialized (real ADC mode with GPIO control)");
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
LOG_INF("Voltage sensor found in devicetree");
#endif
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
LOG_INF("Current sensor found in devicetree");
#endif
#endif
initialized = true;
@@ -47,9 +206,17 @@ uint16_t adc_sensor_get_voltage_mv(void) {
#ifdef CONFIG_ADC_SENSOR_SIMULATED
return SIMULATED_VOLTAGE_MV;
#else
// Set GPIOs for voltage measurement (example: s0=0, s1=0 for channel 0)
set_voltage_sensor_gpios(true, false, false);
// TODO: Read real ADC value for voltage
// For now return simulated value
return SIMULATED_VOLTAGE_MV;
uint16_t voltage = SIMULATED_VOLTAGE_MV;
// Disable sensor after measurement to save power
set_voltage_sensor_gpios(false, false, false);
return voltage;
#endif
}
@@ -62,8 +229,16 @@ uint16_t adc_sensor_get_current_ma(void) {
#ifdef CONFIG_ADC_SENSOR_SIMULATED
return SIMULATED_CURRENT_MA;
#else
// Set GPIOs for current measurement (example: s0=1, s1=0 for channel 1)
set_current_sensor_gpios(true, true, false);
// TODO: Read real ADC value for current
// For now return simulated value
return SIMULATED_CURRENT_MA;
uint16_t current = SIMULATED_CURRENT_MA;
// Disable sensor after measurement to save power
set_current_sensor_gpios(false, false, false);
return current;
#endif
}