5 Commits

Author SHA1 Message Date
69cf7e9511 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.
2025-07-03 18:17:31 +02:00
8df7aef51b Removed unused lib dir 2025-07-03 17:47:48 +02:00
f6ee0a5122 feat(weact_stm32g431_core): Configure VND7050AJ driver pins in overlay
Updated the weact_stm32g431_core.overlay to define the GPIO and ADC
pin assignments for the VND7050AJ driver. This includes:
- Digital I/O pins (IN0, IN1, RST, S0, S1, SEN) configured as GPIOs.
- Analog input pin (MULTISENSE/PA0) configured for ADC1.
2025-07-03 17:39:04 +02:00
6c1ff0c4df feat(refactor): Restructure project for improved modularity and clarity
This commit introduces a major refactoring of the project structure to align
with Zephyr's recommended multi-application and library organization.

Key changes include:
- Relocation of custom modules from 'software/modules/' to 'software/lib/'.
- Introduction of a central 'software/CMakeLists.txt' to manage application
  and library subdirectories.
- Creation of new Kconfig files for 'software/' and 'software/apps/slave_node/'
  to define project-wide and application-specific configurations.
- Removal of the 'gateway' and 'stm32g431_tests' applications.
- Removal of 'shell_modbus.c' and 'shell_system.c' from 'slave_node' application's
  direct source files, indicating a shift towards library-based shell commands.
- Updates to 'software/apps/slave_node/CMakeLists.txt', 'prj.conf', and
  'boards/bluepill_f103rb.conf' to reflect the new structure and dependencies.
2025-07-03 16:58:43 +02:00
3f0d5a76c6 feat(cdc_acm): Add CDC-ACM support and remove old test applications
- Implemented CDC-ACM (USB Virtual COM Port) support for the slave_node application.
- Removed the now obsolete 'hello_world' and 'stm32g431_tests' applications.
2025-07-03 14:31:17 +02:00
41 changed files with 164 additions and 118 deletions

5
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"files.associations": {
"fwu.h": "c"
}
}

View File

@@ -1,8 +0,0 @@
cmake_minimum_required(VERSION 3.13.1)
project(software)
add_subdirectory(modules/modbus_server)
add_subdirectory(modules/valve)
add_subdirectory(modules/fwu)
add_subdirectory(apps/stm32g431_tests)

1
software/Kconfig Normal file
View File

@@ -0,0 +1 @@
rsource "lib/Kconfig"

View File

@@ -1,6 +0,0 @@
cmake_minimum_required(VERSION 3.20)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(hello_world)
target_sources(app PRIVATE src/main.c)

View File

@@ -1,4 +0,0 @@
CONFIG_CONSOLE=y
CONFIG_LOG=y
CONFIG_UART_CONSOLE=y

View File

@@ -1,9 +0,0 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
int main(void)
{
printk("Hello World! %s\n", CONFIG_BOARD);
return 0;
}

View File

@@ -1,27 +1,8 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
# Point BOARD_ROOT and DTS_ROOT to the 'software' directory, which contains 'boards'.
list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(slave_node)
list(APPEND KCONFIG_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../modules/modbus_server/Kconfig) project(slave_node LANGUAGES C)
list(APPEND KCONFIG_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../modules/valve/Kconfig) zephyr_include_directories(../../include)
list(APPEND KCONFIG_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../modules/fwu/Kconfig) add_subdirectory(../../lib lib)
target_sources(app PRIVATE src/main.c)
target_include_directories(app PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/valve/include
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/modbus_server/include
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/fwu/include
)
# Add the source files from the app and the libraries
target_sources(app PRIVATE
src/main.c
src/shell_modbus.c
src/shell_system.c
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/valve/src/valve.c
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/modbus_server/src/modbus_server.c
${CMAKE_CURRENT_SOURCE_DIR}/../../modules/fwu/src/fwu.c
)

View File

@@ -0,0 +1,2 @@
rsource "../../lib/Kconfig"
source "Kconfig.zephyr"

View File

@@ -4,3 +4,4 @@ CONFIG_UART_CONSOLE=n
# Enable RTT console # Enable RTT console
CONFIG_RTT_CONSOLE=y CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y CONFIG_USE_SEGGER_RTT=y
CONFIG_SHELL_BACKEND_RTT=y

View File

@@ -1,9 +1,50 @@
/ {
vnd7050aj: vnd7050aj {
compatible = "vnd7050aj-valve-controller";
status = "okay";
// VND7050AJ GPIO pin definitions
in0-gpios = <&gpiob 7 GPIO_ACTIVE_HIGH>; // IN0 (PB7) - Input 0 control signal
in1-gpios = <&gpiob 9 GPIO_ACTIVE_HIGH>; // IN1 (PB9) - Input 1 control signal
rst-gpios = <&gpiob 3 GPIO_ACTIVE_HIGH>; // RST (PB3) - Reset pin for VND7050AJ
sen-gpios = <&gpiob 4 GPIO_ACTIVE_HIGH>; // SEN (PB4) - Sense Enable for current monitoring
s0-gpios = <&gpiob 6 GPIO_ACTIVE_HIGH>; // S0 (PB6) - Status/Select 0 output from VND7050AJ
s1-gpios = <&gpiob 5 GPIO_ACTIVE_HIGH>; // S1 (PB5) - Status/Select 1 output from VND7050AJ
};
};
&usart1 { &usart1 {
modbus0 { modbus0 {
compatible = "zephyr,modbus-serial"; compatible = "zephyr,modbus-serial";
status = "okay"; status = "okay";
}; };
status = "okay"; status = "okay";
pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pa10>; // PA9=TX, PA10=RX for Modbus communication
pinctrl-names = "default"; pinctrl-names = "default";
}; };
&adc1 { // ADC1 wird für PA0 verwendet
status = "okay"; // ADC1 aktivieren
pinctrl-0 = <&adc1_in1_pa0>; // Pinmux für PA0 als ADC1_IN1
pinctrl-names = "default";
st,adc-clock-source = "SYNC";
st,adc-prescaler = <4>;
#address-cells = <1>;
#size-cells = <0>;
// Definition des ADC-Kanals für MULTISENSE (PA0)
channel@1 { // ADC1_IN1 ist Kanal 1
reg = <1>; // Kanalnummer
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};
};
&pinctrl {
// Pinmux für PA0 als ADC1_IN1 (Analogmodus)
adc1_in1_pa0: adc1_in1_pa0 {
pinmux = <STM32_PINMUX('A', 0, ANALOG)>; // PA0 in den Analogmodus setzen
};
};

View File

@@ -0,0 +1,10 @@
&zephyr_udc0 {
cdc_acm_uart0: cdc_acm_uart0 {
compatible = "zephyr,cdc-acm-uart";
modbus0 {
compatible = "zephyr,modbus-serial";
status = "okay";
};
};
};

View File

@@ -0,0 +1,4 @@
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="Modbus slave node"
CONFIG_UART_LINE_CTRL=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

View File

@@ -4,7 +4,6 @@ CONFIG_LOG=y
# Enable Shell # Enable Shell
CONFIG_SHELL=y CONFIG_SHELL=y
CONFIG_SHELL_BACKEND_RTT=y
CONFIG_REBOOT=y CONFIG_REBOOT=y
# Enable Settings Subsystem # Enable Settings Subsystem

View File

@@ -1,9 +1,9 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/settings/settings.h> #include <zephyr/settings/settings.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <modbus_server.h> #include <lib/modbus_server.h>
#include <valve.h> #include <lib/valve.h>
#include <fwu.h> #include <lib/fwu.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF); LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);

View File

@@ -1,6 +0,0 @@
cmake_minimum_required(VERSION 3.20)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(stm32g431_tests)
target_sources(app PRIVATE src/main.c)

View File

@@ -1,4 +0,0 @@
CONFIG_CONSOLE=y
CONFIG_LOG=y
CONFIG_UART_CONSOLE=y

View File

@@ -1,9 +0,0 @@
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
int main(void)
{
printk("Hello World! %s\n", CONFIG_BOARD);
return 0;
}

View File

@@ -2,8 +2,21 @@
#define VALVE_H #define VALVE_H
#include <stdint.h> #include <stdint.h>
#include <zephyr/drivers/gpio.h>
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 }; enum valve_movement { VALVE_MOVEMENT_IDLE, VALVE_MOVEMENT_OPENING, VALVE_MOVEMENT_CLOSING, VALVE_MOVEMENT_ERROR };
void valve_init(void); void valve_init(void);

View File

@@ -0,0 +1,5 @@
add_subdirectory_ifdef(CONFIG_LIB_FWU fwu)
add_subdirectory_ifdef(CONFIG_LIB_MODBUS_SERVER modbus_server)
add_subdirectory_ifdef(CONFIG_LIB_VALVE valve)
add_subdirectory_ifdef(CONFIG_SHELL_SYSTEM shell_system)
add_subdirectory_ifdef(CONFIG_SHELL_MODBUS shell_modbus)

8
software/lib/Kconfig Normal file
View File

@@ -0,0 +1,8 @@
menu "Irrigation system software libraries"
rsource "fwu/Kconfig"
rsource "modbus_server/Kconfig"
rsource "valve/Kconfig"
rsource "shell_system/Kconfig"
rsource "shell_modbus/Kconfig"
endmenu

View File

@@ -0,0 +1 @@
zephyr_library_sources(fwu.c)

View File

@@ -1,5 +1,5 @@
config FWU config LIB_FWU
bool "Enable Firmware Update Library" bool "Enable Firmware Update Library"
default y default y
help help
Enable the Firmware Update module. Enable the Firmware Update Library.

View File

@@ -1,8 +1,8 @@
#include "fwu.h"
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/sys/crc.h> #include <zephyr/sys/crc.h>
#include <zephyr/sys/byteorder.h> #include <zephyr/sys/byteorder.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <lib/fwu.h>
LOG_MODULE_REGISTER(fwu, LOG_LEVEL_INF); LOG_MODULE_REGISTER(fwu, LOG_LEVEL_INF);

View File

@@ -0,0 +1 @@
zephyr_library_sources(modbus_server.c)

View File

@@ -0,0 +1,5 @@
config LIB_MODBUS_SERVER
bool "Enable Modbus Server Library"
default y
help
Enable the Modbus Server Library.

View File

@@ -5,9 +5,9 @@
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <zephyr/settings/settings.h> #include <zephyr/settings/settings.h>
#include <zephyr/sys/reboot.h> #include <zephyr/sys/reboot.h>
#include "modbus_server.h" #include <lib/modbus_server.h>
#include "valve.h" #include <lib/valve.h>
#include "fwu.h" #include <lib/fwu.h>
#include <zephyr/usb/usb_device.h> #include <zephyr/usb/usb_device.h>
@@ -135,7 +135,7 @@ static int input_reg_rd(uint16_t addr, uint16_t *reg)
*reg = (0 << 8) | 0; *reg = (0 << 8) | 0;
break; break;
case REG_INPUT_FIRMWARE_VERSION_PATCH: case REG_INPUT_FIRMWARE_VERSION_PATCH:
*reg = 1; *reg = 2;
break; break;
default: default:
*reg = 0; *reg = 0;

View File

@@ -0,0 +1 @@
zephyr_library_sources(shell_modbus.c)

View File

@@ -0,0 +1,5 @@
config SHELL_MODBUS
bool "Enable Shell Modbus"
default y
help
Enable the modnbus shell commands.

View File

@@ -1,7 +1,7 @@
#include <zephyr/shell/shell.h> #include <zephyr/shell/shell.h>
#include <stdlib.h> #include <stdlib.h>
#include <modbus_server.h> #include <lib/modbus_server.h>
#include <valve.h> #include <lib/valve.h>
static int cmd_modbus_set_baud(const struct shell *sh, size_t argc, char **argv) static int cmd_modbus_set_baud(const struct shell *sh, size_t argc, char **argv)
{ {

View File

@@ -0,0 +1 @@
zephyr_library_sources(shell_system.c)

View File

@@ -0,0 +1,5 @@
config SHELL_SYSTEM
bool "Enable Shell System"
default y
help
Enable the system commands.

View File

@@ -0,0 +1 @@
zephyr_library_sources(valve.c)

View File

@@ -1,5 +1,5 @@
config VALVE config LIB_VALVE
bool "Enable Valve Library" bool "Enable Valve Library"
default y default y
help help
Enable the Valve module. Enable the Valve Library.

View File

@@ -1,10 +1,21 @@
#include "valve.h"
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/settings/settings.h> #include <zephyr/settings/settings.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <lib/valve.h>
LOG_MODULE_REGISTER(valve, LOG_LEVEL_INF); 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_state current_state = VALVE_STATE_CLOSED;
static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE; static enum valve_movement current_movement = VALVE_MOVEMENT_IDLE;
static uint16_t max_opening_time_s = 60; 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) 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) { if (current_movement == VALVE_MOVEMENT_OPENING) {
LOG_INF("Virtual valve finished opening"); LOG_INF("Valve finished opening");
} else if (current_movement == VALVE_MOVEMENT_CLOSING) { } else if (current_movement == VALVE_MOVEMENT_CLOSING) {
current_state = VALVE_STATE_CLOSED; current_state = VALVE_STATE_CLOSED;
LOG_INF("Virtual valve finished closing"); LOG_INF("Valve finished closing");
} }
current_movement = VALVE_MOVEMENT_IDLE; current_movement = VALVE_MOVEMENT_IDLE;
} }
@@ -27,22 +42,35 @@ void valve_init(void)
k_work_init_delayable(&valve_work, valve_work_handler); 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_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)); 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) void valve_open(void)
{ {
if (current_state == VALVE_STATE_CLOSED) { 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_state = VALVE_STATE_OPEN;
current_movement = VALVE_MOVEMENT_OPENING; 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) void valve_close(void)
{ {
if (current_state == VALVE_STATE_OPEN) { 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; 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));
} }
} }

View File

@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(fwu)
target_sources(app PRIVATE src/fwu.c)
target_include_directories(app PUBLIC include)

View File

@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(modbus_server)
target_sources(app PRIVATE src/modbus_server.c)
target_include_directories(app PUBLIC include)

View File

@@ -1,5 +0,0 @@
config MODBUS_SERVER
bool "Enable Modbus Server Library"
default y
help
Enable the Modbus Server module.

View File

@@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 3.13.1)
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(valve)
target_sources(app PRIVATE src/valve.c)
target_include_directories(app PUBLIC include)