From 69cf7e95117dae7bac257a74b82f44a83cb89b21 Mon Sep 17 00:00:00 2001 From: Eduard Iten Date: Thu, 3 Jul 2025 18:17:31 +0200 Subject: [PATCH] feat(valve): Implement GPIO control for VND7050AJ This commit implements the real valve control using the GPIOs connected to the VND7050AJ driver. - The `weact_stm32g431_core.overlay` is updated with a specific compatible string and a device tree label for the valve controller. - `valve.h` is extended to include GPIO device specifications. - `valve.c` now initializes and controls the GPIOs for opening and closing the valve, including the reset logic. The IN0 and IN1 pins are interlocked to prevent simultaneous activation. The RST pin is activated before each movement and deactivated afterward. This replaces the previous virtual/simulated valve logic with actual hardware control. --- .../boards/weact_stm32g431_core.overlay | 4 +-- software/include/lib/valve.h | 15 +++++++- software/lib/valve/valve.c | 36 ++++++++++++++++--- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/software/apps/slave_node/boards/weact_stm32g431_core.overlay b/software/apps/slave_node/boards/weact_stm32g431_core.overlay index c29720d..d86e8af 100644 --- a/software/apps/slave_node/boards/weact_stm32g431_core.overlay +++ b/software/apps/slave_node/boards/weact_stm32g431_core.overlay @@ -1,6 +1,6 @@ / { - vnd7050aj { - compatible = "gpio-leds"; // Using generic GPIO compatible + vnd7050aj: vnd7050aj { + compatible = "vnd7050aj-valve-controller"; status = "okay"; // VND7050AJ GPIO pin definitions diff --git a/software/include/lib/valve.h b/software/include/lib/valve.h index ed58220..373215d 100644 --- a/software/include/lib/valve.h +++ b/software/include/lib/valve.h @@ -2,8 +2,21 @@ #define VALVE_H #include +#include -enum valve_state { VALVE_STATE_CLOSED, VALVE_STATE_OPEN }; +struct valve_gpios { + const struct gpio_dt_spec in0; + const struct gpio_dt_spec in1; + const struct gpio_dt_spec rst; + const struct gpio_dt_spec sen; + const struct gpio_dt_spec s0; + const struct gpio_dt_spec s1; +}; + +enum valve_state { + VALVE_STATE_CLOSED, + VALVE_STATE_OPEN, +}; enum valve_movement { VALVE_MOVEMENT_IDLE, VALVE_MOVEMENT_OPENING, VALVE_MOVEMENT_CLOSING, VALVE_MOVEMENT_ERROR }; void valve_init(void); diff --git a/software/lib/valve/valve.c b/software/lib/valve/valve.c index 72c3a92..b0b4e11 100644 --- a/software/lib/valve/valve.c +++ b/software/lib/valve/valve.c @@ -1,10 +1,21 @@ #include #include #include +#include +#include #include LOG_MODULE_REGISTER(valve, LOG_LEVEL_INF); +static const struct valve_gpios valve_gpios = { + .in0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), in0_gpios), + .in1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), in1_gpios), + .rst = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), rst_gpios), + .sen = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), sen_gpios), + .s0 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), s0_gpios), + .s1 = GPIO_DT_SPEC_GET(DT_NODELABEL(vnd7050aj), s1_gpios), +}; + static enum valve_state current_state = VALVE_STATE_CLOSED; static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE; static uint16_t max_opening_time_s = 60; @@ -13,11 +24,15 @@ static struct k_work_delayable valve_work; static void valve_work_handler(struct k_work *work) { + gpio_pin_set_dt(&valve_gpios.in0, 0); + gpio_pin_set_dt(&valve_gpios.in1, 0); + gpio_pin_set_dt(&valve_gpios.rst, 0); + if (current_movement == VALVE_MOVEMENT_OPENING) { - LOG_INF("Virtual valve finished opening"); + LOG_INF("Valve finished opening"); } else if (current_movement == VALVE_MOVEMENT_CLOSING) { current_state = VALVE_STATE_CLOSED; - LOG_INF("Virtual valve finished closing"); + LOG_INF("Valve finished closing"); } current_movement = VALVE_MOVEMENT_IDLE; } @@ -27,22 +42,35 @@ void valve_init(void) k_work_init_delayable(&valve_work, valve_work_handler); settings_load_one("valve/max_open_time", &max_opening_time_s, sizeof(max_opening_time_s)); settings_load_one("valve/max_close_time", &max_closing_time_s, sizeof(max_closing_time_s)); + + gpio_pin_configure_dt(&valve_gpios.in0, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&valve_gpios.in1, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&valve_gpios.rst, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&valve_gpios.sen, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&valve_gpios.s0, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&valve_gpios.s1, GPIO_OUTPUT_INACTIVE); } void valve_open(void) { if (current_state == VALVE_STATE_CLOSED) { + gpio_pin_set_dt(&valve_gpios.rst, 1); + gpio_pin_set_dt(&valve_gpios.in1, 0); + gpio_pin_set_dt(&valve_gpios.in0, 1); current_state = VALVE_STATE_OPEN; current_movement = VALVE_MOVEMENT_OPENING; - k_work_schedule(&valve_work, K_SECONDS(max_opening_time_s)); + k_work_schedule(&valve_work, K_MSEC(max_opening_time_s * 1000 * 0.9)); } } void valve_close(void) { if (current_state == VALVE_STATE_OPEN) { + gpio_pin_set_dt(&valve_gpios.rst, 1); + gpio_pin_set_dt(&valve_gpios.in0, 0); + gpio_pin_set_dt(&valve_gpios.in1, 1); current_movement = VALVE_MOVEMENT_CLOSING; - k_work_schedule(&valve_work, K_SECONDS(max_closing_time_s)); + k_work_schedule(&valve_work, K_MSEC(max_closing_time_s * 1000 * 0.9)); } }