Just saving

This commit is contained in:
2025-07-10 17:23:22 +02:00
parent 222ffea568
commit c1622bb01c
11 changed files with 352 additions and 104 deletions

View File

@@ -22,30 +22,40 @@ LOG_MODULE_REGISTER(adc_sensor, LOG_LEVEL_INF);
// Devicetree node checks
#define VOLTAGE_SENSOR_NODE DT_NODELABEL(supply_voltage)
#define CURRENT_SENSOR_NODE DT_NODELABEL(motor_current)
#define SENSOR_MUX_NODE DT_NODELABEL(vnd7050aj_mux)
#define CURRENT_OPEN_SENSOR_NODE DT_NODELABEL(motor_current_open)
#define CURRENT_CLOSE_SENSOR_NODE DT_NODELABEL(motor_current_close)
#define VND7050AJ_NODE DT_NODELABEL(vnd7050aj)
#ifndef CONFIG_ADC_SENSOR_SIMULATED
// ADC device reference from centralized mux node
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
#define ADC_NODE DT_PHANDLE(SENSOR_MUX_NODE, io_channels)
#define ADC_CHANNEL DT_PHA(SENSOR_MUX_NODE, io_channels, input)
#define ADC_RESOLUTION 12
#define ADC_REFERENCE_MV DT_PROP(SENSOR_MUX_NODE, reference_mv)
// ADC device reference from voltage sensor node (all sensors use same ADC)
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
#define ADC_NODE DT_PHANDLE(VOLTAGE_SENSOR_NODE, io_channels)
#define ADC_REFERENCE_MV DT_PROP(VOLTAGE_SENSOR_NODE, reference_mv)
#endif
#define ADC_CHANNEL 1 /* ADC1 channel 1 as defined in overlay */
// Sensor-specific properties
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
#define VOLTAGE_DIVIDER_RATIO \
DT_PROP(VOLTAGE_SENSOR_NODE, voltage_divider_ratio)
#define VOLTAGE_MUX_CHANNEL DT_PROP(VOLTAGE_SENSOR_NODE, mux_channel)
#define VOLTAGE_DELAY_MS DT_PROP(VOLTAGE_SENSOR_NODE, measurement_delay_ms)
#endif
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
#define CURRENT_SENSE_RESISTOR_MOHM \
DT_PROP(CURRENT_SENSOR_NODE, current_sense_resistor_mohm)
#define CURRENT_MUX_CHANNEL DT_PROP(CURRENT_SENSOR_NODE, mux_channel)
#define CURRENT_DELAY_MS DT_PROP(CURRENT_SENSOR_NODE, measurement_delay_ms)
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
#define CURRENT_OPEN_SENSE_RESISTOR_MOHM \
DT_PROP(CURRENT_OPEN_SENSOR_NODE, current_sense_resistor_mohm)
#define CURRENT_OPEN_K_FACTOR DT_PROP(CURRENT_OPEN_SENSOR_NODE, k_factor)
#define CURRENT_OPEN_DELAY_MS \
DT_PROP(CURRENT_OPEN_SENSOR_NODE, measurement_delay_ms)
#endif
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
#define CURRENT_CLOSE_SENSE_RESISTOR_MOHM \
DT_PROP(CURRENT_CLOSE_SENSOR_NODE, current_sense_resistor_mohm)
#define CURRENT_CLOSE_K_FACTOR DT_PROP(CURRENT_CLOSE_SENSOR_NODE, k_factor)
#define CURRENT_CLOSE_DELAY_MS \
DT_PROP(CURRENT_CLOSE_SENSOR_NODE, measurement_delay_ms)
#endif
static const struct device *adc_dev;
@@ -59,24 +69,23 @@ static struct adc_channel_cfg adc_channel_cfg = {
static struct adc_sequence adc_sequence = {
.channels = BIT(ADC_CHANNEL),
.buffer_size = sizeof(uint16_t),
.resolution = ADC_RESOLUTION,
.resolution = 12,
};
static uint16_t adc_buffer;
#endif
#endif
static bool initialized = false;
#ifndef CONFIG_ADC_SENSOR_SIMULATED
// GPIO specs from centralized mux node
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
// GPIO specs from VND7050AJ node
#if DT_NODE_EXISTS(VND7050AJ_NODE)
static const struct gpio_dt_spec sen_gpio =
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, sen_gpios);
GPIO_DT_SPEC_GET(VND7050AJ_NODE, sen_gpios);
static const struct gpio_dt_spec s0_gpio =
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, s0_gpios);
GPIO_DT_SPEC_GET(VND7050AJ_NODE, s0_gpios);
static const struct gpio_dt_spec s1_gpio =
GPIO_DT_SPEC_GET(SENSOR_MUX_NODE, s1_gpios);
GPIO_DT_SPEC_GET(VND7050AJ_NODE, s1_gpios);
#endif
/**
@@ -85,7 +94,7 @@ static const struct gpio_dt_spec s1_gpio =
static int configure_sensor_gpios(void) {
int ret = 0;
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
#if DT_NODE_EXISTS(VND7050AJ_NODE)
// Configure sensor multiplexer GPIOs
if (gpio_is_ready_dt(&sen_gpio)) {
ret = gpio_pin_configure_dt(&sen_gpio, GPIO_OUTPUT_INACTIVE);
@@ -122,7 +131,7 @@ static int configure_sensor_gpios(void) {
* @param delay_ms Delay after setting GPIOs
*/
static int set_mux_channel(bool enable, uint8_t channel, uint32_t delay_ms) {
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
#if DT_NODE_EXISTS(VND7050AJ_NODE)
if (gpio_is_ready_dt(&sen_gpio)) {
gpio_pin_set_dt(&sen_gpio, enable ? 1 : 0);
}
@@ -148,7 +157,7 @@ static int set_mux_channel(bool enable, uint8_t channel, uint32_t delay_ms) {
* @return ADC reading in millivolts, or 0 on error
*/
static uint16_t read_adc_voltage_mv(void) {
#if DT_NODE_EXISTS(SENSOR_MUX_NODE) && DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
int ret = adc_read(adc_dev, &adc_sequence);
if (ret < 0) {
LOG_ERR("ADC read failed: %d", ret);
@@ -172,11 +181,11 @@ static uint16_t read_adc_voltage_mv(void) {
}
/**
* @brief Read ADC value and convert to milliamps (for current sensor)
* @brief Read ADC value and convert to milliamps for opening current
* @return ADC reading in milliamps, or 0 on error
*/
static uint16_t read_adc_current_ma(void) {
#if DT_NODE_EXISTS(SENSOR_MUX_NODE) && DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
static uint16_t read_adc_current_open_ma(void) {
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
int ret = adc_read(adc_dev, &adc_sequence);
if (ret < 0) {
LOG_ERR("ADC read failed: %d", ret);
@@ -187,12 +196,45 @@ static uint16_t read_adc_current_ma(void) {
uint32_t adc_value = adc_buffer;
uint32_t voltage_mv = (adc_value * ADC_REFERENCE_MV) / 4095;
// Convert voltage to current based on sense resistor
// I = V / R, where R is in milliohms and V is in millivolts
// VND7050AJ current calculation: I = V_sense * K / R_sense
// Where: V_sense in mV, K is the current sense factor, R_sense in mΩ
// Result is in milliamps
uint32_t current_ma = (voltage_mv * 1000) / CURRENT_SENSE_RESISTOR_MOHM;
uint32_t current_ma = (voltage_mv * CURRENT_OPEN_K_FACTOR * 1000) /
CURRENT_OPEN_SENSE_RESISTOR_MOHM;
LOG_DBG("ADC raw: %u, current: %u mA", adc_value, (uint16_t)current_ma);
LOG_DBG("Open current - ADC raw: %u, voltage: %u mV, current: %u mA",
adc_value, voltage_mv, (uint16_t)current_ma);
return (uint16_t)current_ma;
#else
return 0;
#endif
}
/**
* @brief Read ADC value and convert to milliamps for closing current
* @return ADC reading in milliamps, or 0 on error
*/
static uint16_t read_adc_current_close_ma(void) {
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
int ret = adc_read(adc_dev, &adc_sequence);
if (ret < 0) {
LOG_ERR("ADC read failed: %d", ret);
return 0;
}
// Convert ADC reading to millivolts first
uint32_t adc_value = adc_buffer;
uint32_t voltage_mv = (adc_value * ADC_REFERENCE_MV) / 4095;
// VND7050AJ current calculation: I = V_sense * K / R_sense
// Where: V_sense in mV, K is the current sense factor, R_sense in mΩ
// Result is in milliamps
uint32_t current_ma = (voltage_mv * CURRENT_CLOSE_K_FACTOR * 1000) /
CURRENT_CLOSE_SENSE_RESISTOR_MOHM;
LOG_DBG("Close current - ADC raw: %u, voltage: %u mV, current: %u mA",
adc_value, voltage_mv, (uint16_t)current_ma);
return (uint16_t)current_ma;
#else
@@ -219,7 +261,7 @@ int adc_sensor_init(void) {
}
// Initialize ADC hardware
#if DT_NODE_EXISTS(SENSOR_MUX_NODE)
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
adc_dev = DEVICE_DT_GET(ADC_NODE);
if (!device_is_ready(adc_dev)) {
LOG_ERR("ADC device not ready");
@@ -237,15 +279,18 @@ int adc_sensor_init(void) {
LOG_INF("ADC device ready: %s", adc_dev->name);
#endif
LOG_INF("ADC sensor initialized (real ADC mode with centralized mux)");
LOG_INF("ADC sensor initialized (real ADC mode)");
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
LOG_INF("Voltage sensor: channel %d, divider ratio %d", VOLTAGE_MUX_CHANNEL,
VOLTAGE_DIVIDER_RATIO);
LOG_INF("Voltage sensor: divider ratio %d", VOLTAGE_DIVIDER_RATIO);
#endif
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
LOG_INF("Current sensor: channel %d, sense resistor %d mOhm",
CURRENT_MUX_CHANNEL, CURRENT_SENSE_RESISTOR_MOHM);
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
LOG_INF("Open current sensor: K-factor %d, sense resistor %d mΩ",
CURRENT_OPEN_K_FACTOR, CURRENT_OPEN_SENSE_RESISTOR_MOHM);
#endif
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
LOG_INF("Close current sensor: K-factor %d, sense resistor %d mΩ",
CURRENT_CLOSE_K_FACTOR, CURRENT_CLOSE_SENSE_RESISTOR_MOHM);
#endif
#endif
@@ -262,9 +307,9 @@ uint16_t adc_sensor_get_voltage_mv(void) {
#ifdef CONFIG_ADC_SENSOR_SIMULATED
return SIMULATED_VOLTAGE_MV;
#else
// Set multiplexer to voltage channel
// Set multiplexer to voltage channel (channel 3: VCC sense)
#if DT_NODE_EXISTS(VOLTAGE_SENSOR_NODE)
set_mux_channel(true, VOLTAGE_MUX_CHANNEL, VOLTAGE_DELAY_MS);
set_mux_channel(true, 3, VOLTAGE_DELAY_MS);
// Read real ADC value for voltage
uint16_t voltage = read_adc_voltage_mv();
@@ -280,6 +325,11 @@ uint16_t adc_sensor_get_voltage_mv(void) {
}
uint16_t adc_sensor_get_current_ma(void) {
// Legacy function - redirect to opening current for backward compatibility
return adc_sensor_get_current_open_ma();
}
uint16_t adc_sensor_get_current_open_ma(void) {
if (!initialized) {
LOG_WRN("ADC sensor not initialized, calling adc_sensor_init()");
adc_sensor_init();
@@ -288,12 +338,38 @@ uint16_t adc_sensor_get_current_ma(void) {
#ifdef CONFIG_ADC_SENSOR_SIMULATED
return SIMULATED_CURRENT_MA;
#else
// Set multiplexer to current channel
#if DT_NODE_EXISTS(CURRENT_SENSOR_NODE)
set_mux_channel(true, CURRENT_MUX_CHANNEL, CURRENT_DELAY_MS);
// Set multiplexer to IN0 current sense channel (channel 0)
#if DT_NODE_EXISTS(CURRENT_OPEN_SENSOR_NODE)
set_mux_channel(true, 0, CURRENT_OPEN_DELAY_MS);
// Read real ADC value for current
uint16_t current = read_adc_current_ma();
uint16_t current = read_adc_current_open_ma();
// Disable sensor after measurement to save power
set_mux_channel(false, 0, 0);
return current;
#else
return 0;
#endif
#endif
}
uint16_t adc_sensor_get_current_close_ma(void) {
if (!initialized) {
LOG_WRN("ADC sensor not initialized, calling adc_sensor_init()");
adc_sensor_init();
}
#ifdef CONFIG_ADC_SENSOR_SIMULATED
return SIMULATED_CURRENT_MA;
#else
// Set multiplexer to IN1 current sense channel (channel 1)
#if DT_NODE_EXISTS(CURRENT_CLOSE_SENSOR_NODE)
set_mux_channel(true, 1, CURRENT_CLOSE_DELAY_MS);
// Read real ADC value for current
uint16_t current = read_adc_current_close_ma();
// Disable sensor after measurement to save power
set_mux_channel(false, 0, 0);