feat: Add DALI raw frame handling and USB setup bridge

- Introduced DaliRawFrame structure to encapsulate raw frame data.
- Enhanced DaliDomainService to manage raw frame sinks and processing.
- Implemented raw frame task for asynchronous handling of incoming DALI frames.
- Integrated raw frame handling in GatewayBleBridge and GatewayNetworkService.
- Added GatewayUsbSetupBridge to facilitate USB Serial/JTAG communication with DALI.
- Configured ESP-NOW for wireless communication and setup management.
- Updated GatewayRuntime to support clearing wireless credentials on boot button long press.
- Enhanced CMakeLists to include new components and dependencies.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Tony
2026-04-30 04:15:05 +08:00
parent 3d8d00c3dd
commit 4ce3513dd2
20 changed files with 984 additions and 25 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
idf_component_register(
SRCS "app_main.cpp"
REQUIRES gateway_core gateway_controller gateway_network dali_domain gateway_runtime gateway_ble log
REQUIRES gateway_core gateway_controller gateway_network dali_domain gateway_runtime gateway_ble gateway_usb_setup log
)
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
+102
View File
@@ -258,6 +258,90 @@ config GATEWAY_DALI_BAUDRATE
help
Runtime baudrate used when initializing the local DALI bus.
menu "Gateway Startup Services"
config GATEWAY_BLE_SUPPORTED
bool "BLE gateway transport is supported"
default y
help
Builds and starts the BLE gateway bridge. Runtime BLE enable state is controlled separately.
config GATEWAY_START_BLE_ENABLED
bool "Enable BLE at startup"
depends on GATEWAY_BLE_SUPPORTED
default y
help
Default runtime BLE state when no persisted BLE setting exists. Lua gateway behavior starts BLE by default.
config GATEWAY_WIFI_SUPPORTED
bool "Wi-Fi gateway transport is supported"
default y
help
Keeps Wi-Fi control, HTTP/UDP networking, setup AP, and ESP-NOW setup paths available.
config GATEWAY_START_WIFI_STA_ENABLED
bool "Start Wi-Fi STA at startup"
depends on GATEWAY_WIFI_SUPPORTED
default n
help
Connect to persisted Wi-Fi credentials at boot. Disabled by default so wireless stays off until commanded.
config GATEWAY_ESPNOW_SETUP_SUPPORTED
bool "ESP-NOW setup transport is supported"
depends on GATEWAY_WIFI_SUPPORTED
default y
help
Enables ESP-NOW setup ingress when setup AP mode is entered.
config GATEWAY_START_ESPNOW_SETUP_ENABLED
bool "Enter ESP-NOW setup mode at startup"
depends on GATEWAY_ESPNOW_SETUP_SUPPORTED
default n
help
Starts the setup AP and ESP-NOW setup ingress immediately at boot. Disabled by default.
choice GATEWAY_USB_STARTUP_MODE
prompt "USB Serial/JTAG startup mode"
default GATEWAY_USB_STARTUP_DEBUG_JTAG
help
Select whether the built-in USB Serial/JTAG interface remains available for debug or is claimed by the setup bridge.
config GATEWAY_USB_STARTUP_DEBUG_JTAG
bool "USB Serial/JTAG debug interface"
config GATEWAY_USB_STARTUP_SETUP_SERIAL
bool "USB Serial/JTAG setup bridge"
endchoice
config GATEWAY_USB_SETUP_CHANNEL_INDEX
int "USB setup DALI channel index"
depends on GATEWAY_USB_STARTUP_SETUP_SERIAL
range 0 1
default 0
help
Native zero-based DALI channel used for short raw USB setup frames on the single USB stream.
config GATEWAY_USB_SETUP_RX_BUFFER
int "USB setup RX buffer bytes"
depends on GATEWAY_USB_STARTUP_SETUP_SERIAL
range 64 4096
default 256
config GATEWAY_USB_SETUP_TX_BUFFER
int "USB setup TX buffer bytes"
depends on GATEWAY_USB_STARTUP_SETUP_SERIAL
range 64 4096
default 256
config GATEWAY_USB_SETUP_READ_TIMEOUT_MS
int "USB setup read timeout ms"
depends on GATEWAY_USB_STARTUP_SETUP_SERIAL
range 1 1000
default 20
endmenu
menu "Gateway Network Services"
config GATEWAY_NETWORK_HTTP_ENABLED
@@ -296,6 +380,24 @@ config GATEWAY_STATUS_LED_ACTIVE_HIGH
depends on GATEWAY_STATUS_LED_GPIO >= 0
default y
config GATEWAY_BOOT_BUTTON_GPIO
int "BOOT button GPIO"
range -1 48
default 0
help
GPIO used for Lua-compatible setup entry and Wi-Fi credential clearing. Set to -1 to disable.
config GATEWAY_BOOT_BUTTON_ACTIVE_LOW
bool "BOOT button is active low"
depends on GATEWAY_BOOT_BUTTON_GPIO >= 0
default y
config GATEWAY_BOOT_BUTTON_LONG_PRESS_MS
int "BOOT button long press ms"
depends on GATEWAY_BOOT_BUTTON_GPIO >= 0
range 500 10000
default 3000
endmenu
endmenu
+98 -6
View File
@@ -4,6 +4,7 @@
#include "gateway_core.hpp"
#include "gateway_network.hpp"
#include "gateway_runtime.hpp"
#include "gateway_usb_setup.hpp"
#include "esp_log.h"
#include "sdkconfig.h"
@@ -28,16 +29,83 @@
#define CONFIG_GATEWAY_STATUS_LED_GPIO -1
#endif
#ifndef CONFIG_GATEWAY_BOOT_BUTTON_GPIO
#define CONFIG_GATEWAY_BOOT_BUTTON_GPIO -1
#endif
#ifndef CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS
#define CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS 3000
#endif
#ifndef CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX
#define CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX 0
#endif
#ifndef CONFIG_GATEWAY_USB_SETUP_RX_BUFFER
#define CONFIG_GATEWAY_USB_SETUP_RX_BUFFER 256
#endif
#ifndef CONFIG_GATEWAY_USB_SETUP_TX_BUFFER
#define CONFIG_GATEWAY_USB_SETUP_TX_BUFFER 256
#endif
#ifndef CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
#endif
namespace {
constexpr const char* kProjectName = "DALI_485_Gateway";
constexpr const char* kProjectVersion = "0.1.0";
constexpr const char* kTag = "gateway_main";
#ifdef CONFIG_GATEWAY_WIFI_SUPPORTED
constexpr bool kWifiSupported = true;
#else
constexpr bool kWifiSupported = false;
#endif
#ifdef CONFIG_GATEWAY_START_WIFI_STA_ENABLED
constexpr bool kWifiStartupEnabled = true;
#else
constexpr bool kWifiStartupEnabled = false;
#endif
#ifdef CONFIG_GATEWAY_BLE_SUPPORTED
constexpr bool kBleSupported = true;
#else
constexpr bool kBleSupported = false;
#endif
#ifdef CONFIG_GATEWAY_START_BLE_ENABLED
constexpr bool kBleStartupEnabled = true;
#else
constexpr bool kBleStartupEnabled = false;
#endif
#ifdef CONFIG_GATEWAY_ESPNOW_SETUP_SUPPORTED
constexpr bool kEspnowSetupSupported = true;
#else
constexpr bool kEspnowSetupSupported = false;
#endif
#ifdef CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED
constexpr bool kEspnowSetupStartupEnabled = true;
#else
constexpr bool kEspnowSetupStartupEnabled = false;
#endif
#ifdef CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL
constexpr bool kUsbSetupStartupEnabled = true;
#else
constexpr bool kUsbSetupStartupEnabled = false;
#endif
std::unique_ptr<gateway::DaliDomainService> s_dali_domain;
std::unique_ptr<gateway::GatewayRuntime> s_runtime;
std::unique_ptr<gateway::GatewayController> s_controller;
std::unique_ptr<gateway::GatewayNetworkService> s_network;
std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
std::unique_ptr<gateway::GatewayUsbSetupBridge> s_usb_setup_bridge;
[[maybe_unused]] void LogBindError(const char* channel_name, esp_err_t err) {
if (err != ESP_OK) {
@@ -239,11 +307,11 @@ extern "C" void app_main(void) {
const gateway::BootProfile profile{
gateway::AppRole::kGateway,
"gateway",
kWifiSupported,
kBleSupported,
true,
true,
true,
true,
true,
kEspnowSetupSupported,
kUsbSetupStartupEnabled,
};
gateway::GatewayCore core(profile);
@@ -258,6 +326,7 @@ extern "C" void app_main(void) {
kProjectName,
kProjectVersion,
gateway::ReadRuntimeSerialId(),
kBleStartupEnabled,
},
s_dali_domain.get());
ESP_ERROR_CHECK(s_runtime->start());
@@ -278,7 +347,10 @@ extern "C" void app_main(void) {
if (profile.enable_wifi || profile.enable_eth) {
gateway::GatewayNetworkServiceConfig network_config;
network_config.wifi_enabled = profile.enable_wifi;
network_config.wifi_enabled = profile.enable_wifi && kWifiStartupEnabled;
network_config.espnow_setup_enabled = profile.enable_espnow;
network_config.espnow_setup_startup_enabled =
profile.enable_espnow && kEspnowSetupStartupEnabled;
#ifdef CONFIG_GATEWAY_NETWORK_HTTP_ENABLED
network_config.http_enabled = true;
#else
@@ -292,13 +364,20 @@ extern "C" void app_main(void) {
network_config.http_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_HTTP_PORT);
network_config.udp_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_UDP_PORT);
network_config.status_led_gpio = CONFIG_GATEWAY_STATUS_LED_GPIO;
network_config.boot_button_gpio = CONFIG_GATEWAY_BOOT_BUTTON_GPIO;
network_config.boot_button_long_press_ms = CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS;
#ifdef CONFIG_GATEWAY_STATUS_LED_ACTIVE_HIGH
network_config.status_led_active_high = true;
#else
network_config.status_led_active_high = false;
#endif
#ifdef CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW
network_config.boot_button_active_low = true;
#else
network_config.boot_button_active_low = false;
#endif
s_network = std::make_unique<gateway::GatewayNetworkService>(*s_controller, *s_runtime,
network_config);
*s_dali_domain, network_config);
ESP_ERROR_CHECK(s_network->start());
}
@@ -308,6 +387,19 @@ extern "C" void app_main(void) {
ESP_ERROR_CHECK(s_ble_bridge->start());
}
if (profile.enable_usb) {
gateway::GatewayUsbSetupBridgeConfig usb_config;
usb_config.enabled = true;
usb_config.channel_index = static_cast<uint8_t>(CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX);
usb_config.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_RX_BUFFER);
usb_config.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_TX_BUFFER);
usb_config.read_timeout_ms = static_cast<uint32_t>(CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS);
s_usb_setup_bridge = std::make_unique<gateway::GatewayUsbSetupBridge>(*s_controller,
*s_dali_domain,
usb_config);
ESP_ERROR_CHECK(s_usb_setup_bridge->start());
}
const auto device_info = s_runtime->deviceInfo();
std::printf("gateway_main: dali domain implementation=%s bound=%d channels=%u\n",
s_dali_domain->implementationName(), s_dali_domain->isBound(),
+16
View File
@@ -620,6 +620,19 @@ CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED=y
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
#
# Gateway Startup Services
#
CONFIG_GATEWAY_BLE_SUPPORTED=y
CONFIG_GATEWAY_START_BLE_ENABLED=y
CONFIG_GATEWAY_WIFI_SUPPORTED=y
# CONFIG_GATEWAY_START_WIFI_STA_ENABLED is not set
CONFIG_GATEWAY_ESPNOW_SETUP_SUPPORTED=y
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
# end of Gateway Startup Services
#
# Gateway Network Services
#
@@ -628,6 +641,9 @@ CONFIG_GATEWAY_NETWORK_HTTP_PORT=80
CONFIG_GATEWAY_NETWORK_UDP_ROUTER_ENABLED=y
CONFIG_GATEWAY_NETWORK_UDP_PORT=2020
CONFIG_GATEWAY_STATUS_LED_GPIO=-1
CONFIG_GATEWAY_BOOT_BUTTON_GPIO=0
CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW=y
CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS=3000
# end of Gateway Network Services
# end of Gateway App