feat(gateway): Update SDK configuration and add 485 control bridge
- Changed flash size configuration from 16MB to 4MB and updated partition table filename. - Introduced two gateway channels with UART configurations for communication. - Added support for gateway cache and startup services including BLE and Wi-Fi. - Enabled SPI RAM and configured its parameters for better memory management. - Enhanced the gateway bridge service to handle generated Modbus points more efficiently. - Refactored the gateway Modbus component to improve point management and added new methods for point description and generation. - Implemented a new Gateway485ControlBridge for handling 485 control communication with UART. - Added necessary files for the 485 control bridge including configuration and implementation. Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -18,11 +18,12 @@ This folder hosts the native ESP-IDF C++ rewrite of the Lua DALI gateway.
|
|||||||
- `gateway_controller/`: Lua-compatible gateway command dispatcher, internal scene/group state, and notification fan-out.
|
- `gateway_controller/`: Lua-compatible gateway command dispatcher, internal scene/group state, and notification fan-out.
|
||||||
- `gateway_network/`: HTTP `/info`, `/dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP port `2020` command/notify routing, Wi-Fi STA lifecycle, ESP-Touch smartconfig, setup AP mode, ESP-NOW setup ingress, and BOOT-button Wi-Fi reset for the native gateway.
|
- `gateway_network/`: HTTP `/info`, `/dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP port `2020` command/notify routing, Wi-Fi STA lifecycle, ESP-Touch smartconfig, setup AP mode, ESP-NOW setup ingress, and BOOT-button Wi-Fi reset for the native gateway.
|
||||||
- `gateway_runtime/`: persistent runtime state, command queueing, and device info services.
|
- `gateway_runtime/`: persistent runtime state, command queueing, and device info services.
|
||||||
|
- `gateway_485_control/`: optional 485 Lua control bridge for framed `0x28 0x01` commands and `0x22 ... checksum` notifications at `9600 8N1`; disabled by default because UART0 must be moved off the ESP-IDF console first.
|
||||||
- `gateway_usb_setup/`: optional USB Serial/JTAG setup bridge; disabled by default so USB remains available for debug at boot.
|
- `gateway_usb_setup/`: optional USB Serial/JTAG setup bridge; disabled by default so USB remains available for debug at boot.
|
||||||
|
|
||||||
## Current status
|
## Current status
|
||||||
|
|
||||||
The native rewrite now wires a shared `gateway_core` bootstrap component, a multi-channel `dali_domain` wrapper over `dali_cpp`, a local vendored `dali` hardware backend from the LuatOS ESP-IDF port with raw receive fan-out, an initial `gateway_runtime` service that provides persistent settings, device info, Lua-compatible command framing helpers, and Lua-style query command deduplication, plus a `gateway_controller` service that starts the gateway command task, dispatches core Lua gateway opcodes, and owns internal scene/group state. The gateway app also includes a `gateway_ble` NimBLE bridge that advertises a Lua-compatible GATT service and forwards `FFF3` framed notifications, incoming `FFF1`/`FFF2`/`FFF3` writes, and native raw DALI frame notifications into the matching raw channel, and a `gateway_network` service that provides the native HTTP `/info`, `GET`/`POST /dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP control-plane router on port `2020`, Wi-Fi STA lifecycle, ESP-Touch smartconfig credential provisioning, the Lua-style `LAMMIN_Gateway` setup AP on `192.168.3.1`, ESP-NOW setup ingress for Lua-compatible `connReq`/`connAck`/`echo`/`cmd`/`data`/`uart` packets, native raw DALI frame forwarding back to connected setup peers, and BOOT-button Wi-Fi credential clearing. Startup behavior is configured in `main/Kconfig.projbuild`: BLE is enabled by default, Wi-Fi STA, smartconfig, and ESP-NOW setup mode are disabled by default, and the built-in USB Serial/JTAG interface stays in debug mode unless the optional USB setup bridge mode is selected. Runtime settings and internal scene/group data are cached in RAM after load, skip unchanged flash writes, and batch Wi-Fi credential commits to reduce flash stalls on ESP32-S3 boards where flash and PSRAM share the SPI bus. The gateway app exposes per-channel PHY selection through `main/Kconfig.projbuild`; each channel can be disabled, bound to the native DALI GPIO HAL, or bound to a UART1/UART2 serial PHY. The checked-in `sdkconfig` is aligned with the app's custom 16 MB partition table so the Wi-Fi/BLE/network-enabled image fits the OTA app slots.
|
The native rewrite now wires a shared `gateway_core` bootstrap component, a multi-channel `dali_domain` wrapper over `dali_cpp`, a local vendored `dali` hardware backend from the LuatOS ESP-IDF port with raw receive fan-out, an initial `gateway_runtime` service that provides persistent settings, device info, Lua-compatible command framing helpers, and Lua-style query command deduplication, plus a `gateway_controller` service that starts the gateway command task, dispatches core Lua gateway opcodes, and owns internal scene/group state. The gateway app also includes a `gateway_ble` NimBLE bridge that advertises a Lua-compatible GATT service and forwards `FFF3` framed notifications, incoming `FFF1`/`FFF2`/`FFF3` writes, and native raw DALI frame notifications into the matching raw channel, a `gateway_network` service that provides the native HTTP `/info`, `GET`/`POST /dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP control-plane router on port `2020`, Wi-Fi STA lifecycle, ESP-Touch smartconfig credential provisioning, the Lua-style `LAMMIN_Gateway` setup AP on `192.168.3.1`, ESP-NOW setup ingress for Lua-compatible `connReq`/`connAck`/`echo`/`cmd`/`data`/`uart` packets, native raw DALI frame forwarding back to connected setup peers, and BOOT-button Wi-Fi credential clearing, and an optional `gateway_485_control` bridge that claims UART0 for Lua-compatible framed command ingress plus `0x22` notification egress when the console is moved off UART0. Startup behavior is configured in `main/Kconfig.projbuild`: BLE is enabled by default, Wi-Fi STA, smartconfig, and ESP-NOW setup mode are disabled by default, the built-in USB Serial/JTAG interface stays in debug mode unless the optional USB setup bridge mode is selected, and the UART0 control bridge stays disabled unless the deployment explicitly repurposes UART0 away from the ESP-IDF console. Runtime settings and internal scene/group data are cached in RAM after load, skip unchanged flash writes, and batch Wi-Fi credential commits to reduce flash stalls on ESP32-S3 boards where flash and PSRAM share the SPI bus. The gateway app exposes per-channel PHY selection through `main/Kconfig.projbuild`; each channel can be disabled, bound to the native DALI GPIO HAL, or bound to a UART1/UART2 serial PHY. The checked-in `sdkconfig` is aligned with the app's custom 16 MB partition table so the Wi-Fi/BLE/network-enabled image fits the OTA app slots.
|
||||||
|
|
||||||
## Modbus
|
## Modbus
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "app_main.cpp"
|
SRCS "app_main.cpp"
|
||||||
REQUIRES gateway_core gateway_controller gateway_network gateway_bridge gateway_cache dali_domain gateway_runtime gateway_ble gateway_usb_setup log
|
REQUIRES gateway_core gateway_controller gateway_network gateway_bridge gateway_cache dali_domain gateway_runtime gateway_ble gateway_usb_setup gateway_485_control log
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||||
@@ -579,6 +579,72 @@ config GATEWAY_USB_SETUP_READ_TIMEOUT_MS
|
|||||||
range 1 1000
|
range 1 1000
|
||||||
default 20
|
default 20
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_ENABLED
|
||||||
|
bool "Enable UART0 Lua control bridge"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Claims UART0 for the Lua-compatible framed gateway control channel at boot.
|
||||||
|
This requires moving the ESP-IDF console away from UART0 and prevents Modbus
|
||||||
|
serial from using UART0 at runtime.
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_BAUDRATE
|
||||||
|
int "UART0 control baudrate"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 1200 921600
|
||||||
|
default 9600
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_TX_PIN
|
||||||
|
int "UART0 control TX pin"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range -1 48
|
||||||
|
default -1
|
||||||
|
help
|
||||||
|
Leave at -1 to keep the current UART0 TX routing.
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_RX_PIN
|
||||||
|
int "UART0 control RX pin"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range -1 48
|
||||||
|
default -1
|
||||||
|
help
|
||||||
|
Leave at -1 to keep the current UART0 RX routing.
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_RX_BUFFER
|
||||||
|
int "UART0 control RX buffer bytes"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 64 4096
|
||||||
|
default 256
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_TX_BUFFER
|
||||||
|
int "UART0 control TX buffer bytes"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 64 4096
|
||||||
|
default 256
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_READ_TIMEOUT_MS
|
||||||
|
int "UART0 control read timeout ms"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 1 1000
|
||||||
|
default 20
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS
|
||||||
|
int "UART0 control write timeout ms"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 1 1000
|
||||||
|
default 20
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_TASK_STACK_SIZE
|
||||||
|
int "UART0 control task stack bytes"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 2048 16384
|
||||||
|
default 4096
|
||||||
|
|
||||||
|
config GATEWAY_485_CONTROL_TASK_PRIORITY
|
||||||
|
int "UART0 control task priority"
|
||||||
|
depends on GATEWAY_485_CONTROL_ENABLED
|
||||||
|
range 1 10
|
||||||
|
default 4
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
||||||
menu "Gateway Network Services"
|
menu "Gateway Network Services"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "gateway_core.hpp"
|
#include "gateway_core.hpp"
|
||||||
#include "gateway_network.hpp"
|
#include "gateway_network.hpp"
|
||||||
#include "gateway_runtime.hpp"
|
#include "gateway_runtime.hpp"
|
||||||
|
#include "gateway_485_control.hpp"
|
||||||
#include "gateway_usb_setup.hpp"
|
#include "gateway_usb_setup.hpp"
|
||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
@@ -55,6 +56,42 @@
|
|||||||
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
|
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_BAUDRATE
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_BAUDRATE 9600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_TX_PIN
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_TX_PIN -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_RX_PIN
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_RX_PIN -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_RX_BUFFER
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_RX_BUFFER 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_TX_BUFFER
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_TX_BUFFER 256
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY
|
||||||
|
#define CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY 4
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC
|
#ifndef CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC
|
||||||
#define CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC 60
|
#define CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC 60
|
||||||
#endif
|
#endif
|
||||||
@@ -257,6 +294,20 @@ constexpr bool kModbusAllowUart0 = true;
|
|||||||
constexpr bool kModbusAllowUart0 = false;
|
constexpr bool kModbusAllowUart0 = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_GATEWAY_485_CONTROL_ENABLED
|
||||||
|
constexpr bool k485ControlEnabled = true;
|
||||||
|
#else
|
||||||
|
constexpr bool k485ControlEnabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_ESP_CONSOLE_UART) && defined(CONFIG_ESP_CONSOLE_UART_NUM) && CONFIG_ESP_CONSOLE_UART_NUM == 0
|
||||||
|
constexpr bool kConsoleOnUart0 = true;
|
||||||
|
#elif defined(CONFIG_CONSOLE_UART) && defined(CONFIG_CONSOLE_UART_NUM) && CONFIG_CONSOLE_UART_NUM == 0
|
||||||
|
constexpr bool kConsoleOnUart0 = true;
|
||||||
|
#else
|
||||||
|
constexpr bool kConsoleOnUart0 = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_GATEWAY_MODBUS_SERIAL_RS485_ENABLED
|
#ifdef CONFIG_GATEWAY_MODBUS_SERIAL_RS485_ENABLED
|
||||||
constexpr bool kModbusSerialRs485Enabled = true;
|
constexpr bool kModbusSerialRs485Enabled = true;
|
||||||
#else
|
#else
|
||||||
@@ -270,6 +321,7 @@ std::unique_ptr<gateway::GatewayController> s_controller;
|
|||||||
std::unique_ptr<gateway::GatewayBridgeService> s_bridge;
|
std::unique_ptr<gateway::GatewayBridgeService> s_bridge;
|
||||||
std::unique_ptr<gateway::GatewayNetworkService> s_network;
|
std::unique_ptr<gateway::GatewayNetworkService> s_network;
|
||||||
std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
|
std::unique_ptr<gateway::GatewayBleBridge> s_ble_bridge;
|
||||||
|
std::unique_ptr<gateway::Gateway485ControlBridge> s_uart0_control_bridge;
|
||||||
std::unique_ptr<gateway::GatewayUsbSetupBridge> s_usb_setup_bridge;
|
std::unique_ptr<gateway::GatewayUsbSetupBridge> s_usb_setup_bridge;
|
||||||
|
|
||||||
[[maybe_unused]] void LogBindError(const char* channel_name, esp_err_t err) {
|
[[maybe_unused]] void LogBindError(const char* channel_name, esp_err_t err) {
|
||||||
@@ -289,6 +341,11 @@ struct ChannelBindingConfig {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool ValidateChannelBindings() {
|
bool ValidateChannelBindings() {
|
||||||
|
if (k485ControlEnabled && kConsoleOnUart0) {
|
||||||
|
ESP_LOGE(kTag, "485 control bridge requires moving the ESP-IDF console off UART0");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ChannelBindingConfig channels[CONFIG_GATEWAY_CHANNEL_COUNT] = {};
|
ChannelBindingConfig channels[CONFIG_GATEWAY_CHANNEL_COUNT] = {};
|
||||||
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
||||||
@@ -375,6 +432,10 @@ bool ValidateChannelBindings() {
|
|||||||
|
|
||||||
if (kModbusBridgeSupported && kModbusDefaultSerialTransport) {
|
if (kModbusBridgeSupported && kModbusDefaultSerialTransport) {
|
||||||
const int modbus_uart = CONFIG_GATEWAY_MODBUS_SERIAL_UART_PORT;
|
const int modbus_uart = CONFIG_GATEWAY_MODBUS_SERIAL_UART_PORT;
|
||||||
|
if (k485ControlEnabled && modbus_uart == 0) {
|
||||||
|
ESP_LOGE(kTag, "Modbus serial UART0 conflicts with the UART0 control bridge");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (modbus_uart == 0 && !kModbusAllowUart0) {
|
if (modbus_uart == 0 && !kModbusAllowUart0) {
|
||||||
ESP_LOGE(kTag, "Modbus serial is configured on UART0, but UART0 is reserved for console");
|
ESP_LOGE(kTag, "Modbus serial is configured on UART0, but UART0 is reserved for console");
|
||||||
return false;
|
return false;
|
||||||
@@ -429,10 +490,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
|||||||
channel1.query_timeout_ms =
|
channel1.query_timeout_ms =
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
|
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
|
||||||
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
||||||
esp_err_t err = dali_domain.bindSerialBus(channel1);
|
esp_err_t err1 = dali_domain.bindSerialBus(channel1);
|
||||||
LogBindError("channel1 serial DALI", err);
|
LogBindError("channel1 serial DALI", err1);
|
||||||
if (err != ESP_OK) {
|
if (err1 != ESP_OK) {
|
||||||
return err;
|
return err1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -446,10 +507,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
|||||||
channel2.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN);
|
channel2.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN);
|
||||||
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
||||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
||||||
esp_err_t err = dali_domain.bindHardwareBus(channel2);
|
esp_err_t err2 = dali_domain.bindHardwareBus(channel2);
|
||||||
LogBindError("channel2 native DALI", err);
|
LogBindError("channel2 native DALI", err2);
|
||||||
if (err != ESP_OK) {
|
if (err2 != ESP_OK) {
|
||||||
return err;
|
return err2;
|
||||||
}
|
}
|
||||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
||||||
gateway::DaliSerialBusConfig channel2{};
|
gateway::DaliSerialBusConfig channel2{};
|
||||||
@@ -468,10 +529,10 @@ esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
|||||||
channel2.query_timeout_ms =
|
channel2.query_timeout_ms =
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
|
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
|
||||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
||||||
esp_err_t err = dali_domain.bindSerialBus(channel2);
|
esp_err_t err2 = dali_domain.bindSerialBus(channel2);
|
||||||
LogBindError("channel2 serial DALI", err);
|
LogBindError("channel2 serial DALI", err2);
|
||||||
if (err != ESP_OK) {
|
if (err2 != ESP_OK) {
|
||||||
return err;
|
return err2;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -535,7 +596,27 @@ extern "C" void app_main(void) {
|
|||||||
s_controller = std::make_unique<gateway::GatewayController>(*s_runtime, *s_dali_domain,
|
s_controller = std::make_unique<gateway::GatewayController>(*s_runtime, *s_dali_domain,
|
||||||
*s_cache,
|
*s_cache,
|
||||||
controller_config);
|
controller_config);
|
||||||
ESP_ERROR_CHECK(s_controller->start());
|
if (k485ControlEnabled) {
|
||||||
|
gateway::Gateway485ControlBridgeConfig gateway485_config;
|
||||||
|
gateway485_config.enabled = true;
|
||||||
|
gateway485_config.tx_pin = CONFIG_GATEWAY_485_CONTROL_TX_PIN;
|
||||||
|
gateway485_config.rx_pin = CONFIG_GATEWAY_485_CONTROL_RX_PIN;
|
||||||
|
gateway485_config.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_BAUDRATE);
|
||||||
|
gateway485_config.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_485_CONTROL_RX_BUFFER);
|
||||||
|
gateway485_config.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_485_CONTROL_TX_BUFFER);
|
||||||
|
gateway485_config.read_timeout_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS);
|
||||||
|
gateway485_config.write_timeout_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS);
|
||||||
|
gateway485_config.task_stack_size =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE);
|
||||||
|
gateway485_config.task_priority =
|
||||||
|
static_cast<UBaseType_t>(CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY);
|
||||||
|
s_uart0_control_bridge = std::make_unique<gateway::Gateway485ControlBridge>(*s_controller,
|
||||||
|
gateway485_config);
|
||||||
|
ESP_ERROR_CHECK(s_uart0_control_bridge->start());
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(s_controller->start());
|
||||||
|
|
||||||
if (kBridgeSupported) {
|
if (kBridgeSupported) {
|
||||||
gateway::GatewayBridgeServiceConfig bridge_config;
|
gateway::GatewayBridgeServiceConfig bridge_config;
|
||||||
@@ -552,8 +633,8 @@ extern "C" void app_main(void) {
|
|||||||
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE);
|
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE);
|
||||||
bridge_config.modbus_task_priority =
|
bridge_config.modbus_task_priority =
|
||||||
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
|
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
|
||||||
bridge_config.allow_modbus_uart0 = kModbusAllowUart0;
|
bridge_config.allow_modbus_uart0 = kModbusAllowUart0 && !k485ControlEnabled;
|
||||||
if (!kModbusAllowUart0) {
|
if (!bridge_config.allow_modbus_uart0) {
|
||||||
bridge_config.reserved_uart_ports.push_back(0);
|
bridge_config.reserved_uart_ports.push_back(0);
|
||||||
}
|
}
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x6000,
|
||||||
|
otadata, data, ota, 0xf000, 0x2000,
|
||||||
|
phy_init, data, phy, 0x11000, 0x1000,
|
||||||
|
factory, app, factory, 0x20000, 0x200000,
|
||||||
|
storage, data, spiffs, 0x220000, 0x180000,
|
||||||
|
+86
-25
@@ -562,13 +562,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
|||||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
|
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||||
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
||||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||||
@@ -587,8 +587,8 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
|||||||
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
||||||
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
|
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4M-single.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions-4M-single.csv"
|
||||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||||
CONFIG_PARTITION_TABLE_MD5=y
|
CONFIG_PARTITION_TABLE_MD5=y
|
||||||
# end of Partition Table
|
# end of Partition Table
|
||||||
@@ -602,20 +602,32 @@ CONFIG_GATEWAY_CHANNEL_COUNT=2
|
|||||||
# Gateway Channel 1
|
# Gateway Channel 1
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
|
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
|
||||||
CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED=y
|
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_UART1 is not set
|
CONFIG_GATEWAY_CHANNEL1_PHY_UART1=y
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN=1
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN=2
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS=100
|
||||||
# end of Gateway Channel 1
|
# end of Gateway Channel 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 2
|
# Gateway Channel 2
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
||||||
CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED=y
|
# CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE is not set
|
# CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_UART2 is not set
|
CONFIG_GATEWAY_CHANNEL2_PHY_UART2=y
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN=6
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN=7
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS=100
|
||||||
# end of Gateway Channel 2
|
# end of Gateway Channel 2
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -662,6 +674,16 @@ CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
|||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
||||||
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
||||||
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_RX_BUFFER=256
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TX_BUFFER=256
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS=20
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS=20
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE=4096
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY=4
|
||||||
# end of Gateway Startup Services
|
# end of Gateway Startup Services
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -722,6 +744,7 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y
|
|||||||
#
|
#
|
||||||
# CONFIG_APPTRACE_DEST_JTAG is not set
|
# CONFIG_APPTRACE_DEST_JTAG is not set
|
||||||
CONFIG_APPTRACE_DEST_NONE=y
|
CONFIG_APPTRACE_DEST_NONE=y
|
||||||
|
# CONFIG_APPTRACE_DEST_UART0 is not set
|
||||||
# CONFIG_APPTRACE_DEST_UART1 is not set
|
# CONFIG_APPTRACE_DEST_UART1 is not set
|
||||||
# CONFIG_APPTRACE_DEST_UART2 is not set
|
# CONFIG_APPTRACE_DEST_UART2 is not set
|
||||||
# CONFIG_APPTRACE_DEST_USB_CDC is not set
|
# CONFIG_APPTRACE_DEST_USB_CDC is not set
|
||||||
@@ -748,6 +771,7 @@ CONFIG_BT_CONTROLLER_ENABLED=y
|
|||||||
# General
|
# General
|
||||||
#
|
#
|
||||||
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
||||||
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
||||||
@@ -1500,8 +1524,8 @@ CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4
|
|||||||
#
|
#
|
||||||
# Sleep Config
|
# Sleep Config
|
||||||
#
|
#
|
||||||
# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set
|
|
||||||
CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y
|
CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y
|
||||||
|
CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y
|
||||||
CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y
|
CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y
|
||||||
CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y
|
CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y
|
||||||
CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y
|
CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y
|
||||||
@@ -1640,7 +1664,40 @@ CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP=y
|
|||||||
#
|
#
|
||||||
# ESP PSRAM
|
# ESP PSRAM
|
||||||
#
|
#
|
||||||
# CONFIG_SPIRAM is not set
|
CONFIG_SPIRAM=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# SPI RAM config
|
||||||
|
#
|
||||||
|
CONFIG_SPIRAM_MODE_QUAD=y
|
||||||
|
# CONFIG_SPIRAM_MODE_OCT is not set
|
||||||
|
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
||||||
|
CONFIG_SPIRAM_CLK_IO=30
|
||||||
|
CONFIG_SPIRAM_CS_IO=26
|
||||||
|
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
||||||
|
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
||||||
|
# CONFIG_SPIRAM_RODATA is not set
|
||||||
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
|
# CONFIG_SPIRAM_SPEED_40M is not set
|
||||||
|
CONFIG_SPIRAM_SPEED=80
|
||||||
|
CONFIG_SPIRAM_BOOT_HW_INIT=y
|
||||||
|
CONFIG_SPIRAM_BOOT_INIT=y
|
||||||
|
CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y
|
||||||
|
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
|
||||||
|
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
||||||
|
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
||||||
|
CONFIG_SPIRAM_USE_MALLOC=y
|
||||||
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||||
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
||||||
|
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
||||||
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
|
# end of SPI RAM config
|
||||||
# end of ESP PSRAM
|
# end of ESP PSRAM
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1731,18 +1788,15 @@ CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
|
|||||||
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
||||||
CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
|
CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
|
||||||
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
|
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
|
||||||
CONFIG_ESP_CONSOLE_UART_DEFAULT=y
|
# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set
|
||||||
# CONFIG_ESP_CONSOLE_USB_CDC is not set
|
# CONFIG_ESP_CONSOLE_USB_CDC is not set
|
||||||
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set
|
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
||||||
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
|
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
|
||||||
# CONFIG_ESP_CONSOLE_NONE is not set
|
# CONFIG_ESP_CONSOLE_NONE is not set
|
||||||
# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set
|
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
|
||||||
CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y
|
|
||||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y
|
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y
|
||||||
CONFIG_ESP_CONSOLE_UART=y
|
CONFIG_ESP_CONSOLE_UART_NUM=-1
|
||||||
CONFIG_ESP_CONSOLE_UART_NUM=0
|
CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=4
|
||||||
CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0
|
|
||||||
CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
|
|
||||||
CONFIG_ESP_INT_WDT=y
|
CONFIG_ESP_INT_WDT=y
|
||||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
||||||
CONFIG_ESP_INT_WDT_CHECK_CPU1=y
|
CONFIG_ESP_INT_WDT_CHECK_CPU1=y
|
||||||
@@ -1895,6 +1949,7 @@ CONFIG_FATFS_CODEPAGE=437
|
|||||||
CONFIG_FATFS_FS_LOCK=0
|
CONFIG_FATFS_FS_LOCK=0
|
||||||
CONFIG_FATFS_TIMEOUT_MS=10000
|
CONFIG_FATFS_TIMEOUT_MS=10000
|
||||||
CONFIG_FATFS_PER_FILE_CACHE=y
|
CONFIG_FATFS_PER_FILE_CACHE=y
|
||||||
|
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
|
||||||
# CONFIG_FATFS_USE_FASTSEEK is not set
|
# CONFIG_FATFS_USE_FASTSEEK is not set
|
||||||
CONFIG_FATFS_USE_STRFUNC_NONE=y
|
CONFIG_FATFS_USE_STRFUNC_NONE=y
|
||||||
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
|
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
|
||||||
@@ -1972,6 +2027,7 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y
|
|||||||
#
|
#
|
||||||
# Extra
|
# Extra
|
||||||
#
|
#
|
||||||
|
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
|
||||||
# end of Extra
|
# end of Extra
|
||||||
|
|
||||||
CONFIG_FREERTOS_PORT=y
|
CONFIG_FREERTOS_PORT=y
|
||||||
@@ -2256,6 +2312,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y
|
|||||||
# mbedTLS
|
# mbedTLS
|
||||||
#
|
#
|
||||||
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
||||||
|
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
||||||
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
||||||
@@ -2412,12 +2469,15 @@ CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y
|
|||||||
CONFIG_LIBC_ASSERT_BUFFER_SIZE=200
|
CONFIG_LIBC_ASSERT_BUFFER_SIZE=200
|
||||||
# end of LibC
|
# end of LibC
|
||||||
|
|
||||||
|
CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# NVS
|
# NVS
|
||||||
#
|
#
|
||||||
# CONFIG_NVS_ENCRYPTION is not set
|
# CONFIG_NVS_ENCRYPTION is not set
|
||||||
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
||||||
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
||||||
|
# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set
|
||||||
# end of NVS
|
# end of NVS
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -2761,6 +2821,7 @@ CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
|||||||
# CONFIG_BLUEDROID_ENABLED is not set
|
# CONFIG_BLUEDROID_ENABLED is not set
|
||||||
CONFIG_NIMBLE_ENABLED=y
|
CONFIG_NIMBLE_ENABLED=y
|
||||||
CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
||||||
|
# CONFIG_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
||||||
# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_NIMBLE_PINNED_TO_CORE=0
|
||||||
CONFIG_NIMBLE_PINNED_TO_CORE_0=y
|
CONFIG_NIMBLE_PINNED_TO_CORE_0=y
|
||||||
@@ -2809,7 +2870,6 @@ CONFIG_POST_EVENTS_FROM_IRAM_ISR=y
|
|||||||
CONFIG_GDBSTUB_SUPPORT_TASKS=y
|
CONFIG_GDBSTUB_SUPPORT_TASKS=y
|
||||||
CONFIG_GDBSTUB_MAX_TASKS=32
|
CONFIG_GDBSTUB_MAX_TASKS=32
|
||||||
# CONFIG_OTA_ALLOW_HTTP is not set
|
# CONFIG_OTA_ALLOW_HTTP is not set
|
||||||
# CONFIG_ESP_SYSTEM_PD_FLASH is not set
|
|
||||||
CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000
|
CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000
|
||||||
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000
|
CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000
|
||||||
CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y
|
CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y
|
||||||
@@ -2845,7 +2905,9 @@ CONFIG_ESP32_PHY_MAX_TX_POWER=20
|
|||||||
# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set
|
# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set
|
||||||
CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y
|
CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y
|
||||||
CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y
|
CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y
|
||||||
# CONFIG_ESP32S3_SPIRAM_SUPPORT is not set
|
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
||||||
|
CONFIG_DEFAULT_PSRAM_CLK_IO=30
|
||||||
|
CONFIG_DEFAULT_PSRAM_CS_IO=26
|
||||||
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set
|
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set
|
||||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y
|
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y
|
||||||
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set
|
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set
|
||||||
@@ -2853,13 +2915,11 @@ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160
|
|||||||
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
|
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
|
||||||
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
||||||
CONFIG_MAIN_TASK_STACK_SIZE=3584
|
CONFIG_MAIN_TASK_STACK_SIZE=3584
|
||||||
CONFIG_CONSOLE_UART_DEFAULT=y
|
# CONFIG_CONSOLE_UART_DEFAULT is not set
|
||||||
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
||||||
# CONFIG_CONSOLE_UART_NONE is not set
|
# CONFIG_CONSOLE_UART_NONE is not set
|
||||||
# CONFIG_ESP_CONSOLE_UART_NONE is not set
|
# CONFIG_ESP_CONSOLE_UART_NONE is not set
|
||||||
CONFIG_CONSOLE_UART=y
|
CONFIG_CONSOLE_UART_NUM=-1
|
||||||
CONFIG_CONSOLE_UART_NUM=0
|
|
||||||
CONFIG_CONSOLE_UART_BAUDRATE=115200
|
|
||||||
CONFIG_INT_WDT=y
|
CONFIG_INT_WDT=y
|
||||||
CONFIG_INT_WDT_TIMEOUT_MS=300
|
CONFIG_INT_WDT_TIMEOUT_MS=300
|
||||||
CONFIG_INT_WDT_CHECK_CPU1=y
|
CONFIG_INT_WDT_CHECK_CPU1=y
|
||||||
@@ -2912,6 +2972,7 @@ CONFIG_TIMER_TASK_PRIORITY=1
|
|||||||
CONFIG_TIMER_TASK_STACK_DEPTH=2048
|
CONFIG_TIMER_TASK_STACK_DEPTH=2048
|
||||||
CONFIG_TIMER_QUEUE_LENGTH=10
|
CONFIG_TIMER_QUEUE_LENGTH=10
|
||||||
# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
|
# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set
|
||||||
|
CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y
|
||||||
# CONFIG_HAL_ASSERTION_SILIENT is not set
|
# CONFIG_HAL_ASSERTION_SILIENT is not set
|
||||||
# CONFIG_L2_TO_L3_COPY is not set
|
# CONFIG_L2_TO_L3_COPY is not set
|
||||||
CONFIG_ESP_GRATUITOUS_ARP=y
|
CONFIG_ESP_GRATUITOUS_ARP=y
|
||||||
|
|||||||
+148
-7
@@ -562,13 +562,13 @@ CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
|
|||||||
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
CONFIG_ESPTOOLPY_FLASHFREQ="80m"
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set
|
||||||
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
|
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
|
||||||
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set
|
||||||
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
CONFIG_ESPTOOLPY_BEFORE_RESET=y
|
||||||
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
|
||||||
@@ -587,8 +587,8 @@ CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
|||||||
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
|
||||||
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
|
# CONFIG_PARTITION_TABLE_TWO_OTA_LARGE is not set
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4M-single.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions-4M-single.csv"
|
||||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||||
CONFIG_PARTITION_TABLE_MD5=y
|
CONFIG_PARTITION_TABLE_MD5=y
|
||||||
# end of Partition Table
|
# end of Partition Table
|
||||||
@@ -596,7 +596,108 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||||||
#
|
#
|
||||||
# Gateway App
|
# Gateway App
|
||||||
#
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL_COUNT=2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 1
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
|
||||||
|
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
||||||
|
# CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_PHY_UART1=y
|
||||||
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN=1
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN=2
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS=100
|
||||||
|
# end of Gateway Channel 1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 2
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED is not set
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE is not set
|
||||||
|
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_PHY_UART2=y
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN=6
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN=7
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER=512
|
||||||
|
CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS=100
|
||||||
|
# end of Gateway Channel 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Cache
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
||||||
|
# CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR is not set
|
||||||
|
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=5000
|
||||||
|
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
||||||
|
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
||||||
|
# end of Gateway Cache
|
||||||
|
|
||||||
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
# 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_SMARTCONFIG_SUPPORTED=y
|
||||||
|
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
|
||||||
|
# CONFIG_GATEWAY_START_SMARTCONFIG_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC=60
|
||||||
|
CONFIG_GATEWAY_BRIDGE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_MODBUS_BRIDGE_SUPPORTED=y
|
||||||
|
# CONFIG_GATEWAY_START_MODBUS_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
||||||
|
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_RTU is not set
|
||||||
|
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_ASCII is not set
|
||||||
|
CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
||||||
|
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
||||||
|
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
||||||
|
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
|
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
||||||
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
||||||
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
||||||
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
||||||
|
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
||||||
|
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_BAUDRATE=9600
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_RX_BUFFER=256
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TX_BUFFER=256
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS=20
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS=20
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE=4096
|
||||||
|
CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY=4
|
||||||
|
# end of Gateway Startup Services
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Network Services
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_NETWORK_HTTP_ENABLED=y
|
||||||
|
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
|
# end of Gateway App
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -669,6 +770,7 @@ CONFIG_BT_CONTROLLER_ENABLED=y
|
|||||||
# General
|
# General
|
||||||
#
|
#
|
||||||
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
||||||
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
||||||
@@ -1421,8 +1523,8 @@ CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4
|
|||||||
#
|
#
|
||||||
# Sleep Config
|
# Sleep Config
|
||||||
#
|
#
|
||||||
# CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set
|
|
||||||
CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y
|
CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y
|
||||||
|
CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y
|
||||||
CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y
|
CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y
|
||||||
CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y
|
CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y
|
||||||
CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y
|
CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y
|
||||||
@@ -1561,7 +1663,40 @@ CONFIG_PM_RESTORE_CACHE_TAGMEM_AFTER_LIGHT_SLEEP=y
|
|||||||
#
|
#
|
||||||
# ESP PSRAM
|
# ESP PSRAM
|
||||||
#
|
#
|
||||||
# CONFIG_SPIRAM is not set
|
CONFIG_SPIRAM=y
|
||||||
|
|
||||||
|
#
|
||||||
|
# SPI RAM config
|
||||||
|
#
|
||||||
|
CONFIG_SPIRAM_MODE_QUAD=y
|
||||||
|
# CONFIG_SPIRAM_MODE_OCT is not set
|
||||||
|
CONFIG_SPIRAM_TYPE_AUTO=y
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
|
||||||
|
# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
|
||||||
|
CONFIG_SPIRAM_CLK_IO=30
|
||||||
|
CONFIG_SPIRAM_CS_IO=26
|
||||||
|
# CONFIG_SPIRAM_XIP_FROM_PSRAM is not set
|
||||||
|
# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set
|
||||||
|
# CONFIG_SPIRAM_RODATA is not set
|
||||||
|
# CONFIG_SPIRAM_SPEED_120M is not set
|
||||||
|
CONFIG_SPIRAM_SPEED_80M=y
|
||||||
|
# CONFIG_SPIRAM_SPEED_40M is not set
|
||||||
|
CONFIG_SPIRAM_SPEED=80
|
||||||
|
CONFIG_SPIRAM_BOOT_HW_INIT=y
|
||||||
|
CONFIG_SPIRAM_BOOT_INIT=y
|
||||||
|
CONFIG_SPIRAM_PRE_CONFIGURE_MEMORY_PROTECTION=y
|
||||||
|
CONFIG_SPIRAM_IGNORE_NOTFOUND=y
|
||||||
|
# CONFIG_SPIRAM_USE_MEMMAP is not set
|
||||||
|
# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
|
||||||
|
CONFIG_SPIRAM_USE_MALLOC=y
|
||||||
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||||
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
||||||
|
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
||||||
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
|
# end of SPI RAM config
|
||||||
# end of ESP PSRAM
|
# end of ESP PSRAM
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -1816,6 +1951,7 @@ CONFIG_FATFS_CODEPAGE=437
|
|||||||
CONFIG_FATFS_FS_LOCK=0
|
CONFIG_FATFS_FS_LOCK=0
|
||||||
CONFIG_FATFS_TIMEOUT_MS=10000
|
CONFIG_FATFS_TIMEOUT_MS=10000
|
||||||
CONFIG_FATFS_PER_FILE_CACHE=y
|
CONFIG_FATFS_PER_FILE_CACHE=y
|
||||||
|
CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
|
||||||
# CONFIG_FATFS_USE_FASTSEEK is not set
|
# CONFIG_FATFS_USE_FASTSEEK is not set
|
||||||
CONFIG_FATFS_USE_STRFUNC_NONE=y
|
CONFIG_FATFS_USE_STRFUNC_NONE=y
|
||||||
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
|
# CONFIG_FATFS_USE_STRFUNC_WITHOUT_CRLF_CONV is not set
|
||||||
@@ -1893,6 +2029,7 @@ CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y
|
|||||||
#
|
#
|
||||||
# Extra
|
# Extra
|
||||||
#
|
#
|
||||||
|
CONFIG_FREERTOS_TASK_CREATE_ALLOW_EXT_MEM=y
|
||||||
# end of Extra
|
# end of Extra
|
||||||
|
|
||||||
CONFIG_FREERTOS_PORT=y
|
CONFIG_FREERTOS_PORT=y
|
||||||
@@ -2177,6 +2314,7 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y
|
|||||||
# mbedTLS
|
# mbedTLS
|
||||||
#
|
#
|
||||||
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
||||||
|
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
||||||
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
||||||
@@ -2333,12 +2471,15 @@ CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y
|
|||||||
CONFIG_LIBC_ASSERT_BUFFER_SIZE=200
|
CONFIG_LIBC_ASSERT_BUFFER_SIZE=200
|
||||||
# end of LibC
|
# end of LibC
|
||||||
|
|
||||||
|
CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# NVS
|
# NVS
|
||||||
#
|
#
|
||||||
# CONFIG_NVS_ENCRYPTION is not set
|
# CONFIG_NVS_ENCRYPTION is not set
|
||||||
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
||||||
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
||||||
|
# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set
|
||||||
# end of NVS
|
# end of NVS
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
idf_component_register(
|
||||||
|
SRCS "src/gateway_485_control.cpp"
|
||||||
|
INCLUDE_DIRS "include"
|
||||||
|
REQUIRES esp_driver_uart freertos gateway_controller log
|
||||||
|
)
|
||||||
|
|
||||||
|
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
|
namespace gateway {
|
||||||
|
|
||||||
|
class GatewayController;
|
||||||
|
|
||||||
|
struct Gateway485ControlBridgeConfig {
|
||||||
|
bool enabled{false};
|
||||||
|
int tx_pin{-1};
|
||||||
|
int rx_pin{-1};
|
||||||
|
uint32_t baudrate{9600};
|
||||||
|
size_t rx_buffer_size{256};
|
||||||
|
size_t tx_buffer_size{256};
|
||||||
|
uint32_t read_timeout_ms{20};
|
||||||
|
uint32_t write_timeout_ms{20};
|
||||||
|
uint32_t task_stack_size{4096};
|
||||||
|
UBaseType_t task_priority{4};
|
||||||
|
};
|
||||||
|
|
||||||
|
class Gateway485ControlBridge {
|
||||||
|
public:
|
||||||
|
Gateway485ControlBridge(GatewayController& controller,
|
||||||
|
Gateway485ControlBridgeConfig config = {});
|
||||||
|
|
||||||
|
esp_err_t start();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void TaskEntry(void* arg);
|
||||||
|
void taskLoop();
|
||||||
|
void handleBytes(const uint8_t* data, size_t len);
|
||||||
|
void handleGatewayNotification(const std::vector<uint8_t>& frame);
|
||||||
|
|
||||||
|
GatewayController& controller_;
|
||||||
|
Gateway485ControlBridgeConfig config_;
|
||||||
|
TaskHandle_t task_handle_{nullptr};
|
||||||
|
bool started_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gateway
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#include "gateway_485_control.hpp"
|
||||||
|
|
||||||
|
#include "gateway_controller.hpp"
|
||||||
|
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace gateway {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr const char* kTag = "gateway_485";
|
||||||
|
constexpr uart_port_t kControlUart = UART_NUM_0;
|
||||||
|
constexpr size_t kCommandFrameMinLen = 7;
|
||||||
|
|
||||||
|
int EffectivePin(int pin) {
|
||||||
|
return pin >= 0 ? pin : UART_PIN_NO_CHANGE;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Gateway485ControlBridge::Gateway485ControlBridge(GatewayController& controller,
|
||||||
|
Gateway485ControlBridgeConfig config)
|
||||||
|
: controller_(controller), config_(config) {}
|
||||||
|
|
||||||
|
esp_err_t Gateway485ControlBridge::start() {
|
||||||
|
if (started_) {
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
if (!config_.enabled) {
|
||||||
|
ESP_LOGI(kTag, "UART0 control bridge disabled");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
if (uart_is_driver_installed(kControlUart)) {
|
||||||
|
ESP_LOGE(kTag, "UART0 driver already installed; move console or other users off UART0");
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uart_config_t uart_config{};
|
||||||
|
uart_config.baud_rate = static_cast<int>(config_.baudrate);
|
||||||
|
uart_config.data_bits = UART_DATA_8_BITS;
|
||||||
|
uart_config.parity = UART_PARITY_DISABLE;
|
||||||
|
uart_config.stop_bits = UART_STOP_BITS_1;
|
||||||
|
uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
|
||||||
|
uart_config.source_clk = UART_SCLK_DEFAULT;
|
||||||
|
|
||||||
|
esp_err_t err = uart_param_config(kControlUart, &uart_config);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(kTag, "failed to configure UART0: %s", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = uart_set_pin(kControlUart, EffectivePin(config_.tx_pin), EffectivePin(config_.rx_pin),
|
||||||
|
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(kTag, "failed to set UART0 pins: %s", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
err = uart_driver_install(kControlUart, static_cast<int>(config_.rx_buffer_size),
|
||||||
|
static_cast<int>(config_.tx_buffer_size), 0, nullptr, 0);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGE(kTag, "failed to install UART0 driver: %s", esp_err_to_name(err));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller_.addNotificationSink(
|
||||||
|
[this](const std::vector<uint8_t>& frame) { handleGatewayNotification(frame); });
|
||||||
|
|
||||||
|
const BaseType_t created = xTaskCreate(&Gateway485ControlBridge::TaskEntry,
|
||||||
|
"gateway_485_ctrl",
|
||||||
|
static_cast<uint32_t>(config_.task_stack_size), this,
|
||||||
|
config_.task_priority, &task_handle_);
|
||||||
|
if (created != pdPASS) {
|
||||||
|
uart_driver_delete(kControlUart);
|
||||||
|
task_handle_ = nullptr;
|
||||||
|
ESP_LOGE(kTag, "failed to create 485 control task");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
started_ = true;
|
||||||
|
ESP_LOGI(kTag, "485 control bridge started baud=%lu", static_cast<unsigned long>(config_.baudrate));
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gateway485ControlBridge::TaskEntry(void* arg) {
|
||||||
|
static_cast<Gateway485ControlBridge*>(arg)->taskLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gateway485ControlBridge::taskLoop() {
|
||||||
|
std::vector<uint8_t> read_buffer(std::max<size_t>(config_.rx_buffer_size, 64));
|
||||||
|
std::vector<uint8_t> pending;
|
||||||
|
pending.reserve(std::max<size_t>(config_.rx_buffer_size, 64));
|
||||||
|
const TickType_t timeout = pdMS_TO_TICKS(config_.read_timeout_ms);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const int read_len = uart_read_bytes(kControlUart, read_buffer.data(), read_buffer.size(), timeout);
|
||||||
|
if (read_len > 0) {
|
||||||
|
pending.insert(pending.end(), read_buffer.begin(), read_buffer.begin() + read_len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!pending.empty()) {
|
||||||
|
handleBytes(pending.data(), pending.size());
|
||||||
|
pending.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gateway485ControlBridge::handleBytes(const uint8_t* data, size_t len) {
|
||||||
|
if (data == nullptr || len < kCommandFrameMinLen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data[0] != 0x28 || data[1] != 0x01) {
|
||||||
|
ESP_LOGD(kTag, "ignored non-gateway UART0 burst len=%u", static_cast<unsigned>(len));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controller_.enqueueCommandFrame(std::vector<uint8_t>(data, data + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gateway485ControlBridge::handleGatewayNotification(const std::vector<uint8_t>& frame) {
|
||||||
|
if (!started_ || frame.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int written = uart_write_bytes(kControlUart, frame.data(), frame.size());
|
||||||
|
if (written < 0 || static_cast<size_t>(written) != frame.size()) {
|
||||||
|
ESP_LOGW(kTag, "failed to write UART0 notification len=%u", static_cast<unsigned>(frame.size()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uart_wait_tx_done(kControlUart, pdMS_TO_TICKS(config_.write_timeout_ms)) != ESP_OK) {
|
||||||
|
ESP_LOGW(kTag, "timed out flushing UART0 notification len=%u", static_cast<unsigned>(frame.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gateway
|
||||||
@@ -257,9 +257,13 @@ bool SnapshotHasDeviceType(const DaliDomainSnapshot& snapshot, int device_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> SnapshotBoolValue(const DaliDomainSnapshot& snapshot,
|
std::optional<bool> SnapshotBoolValue(const DaliDomainSnapshot& snapshot,
|
||||||
const std::string& key) {
|
std::string_view key) {
|
||||||
const auto found = snapshot.bools.find(key);
|
for (const auto& entry : snapshot.bools) {
|
||||||
return found == snapshot.bools.end() ? std::nullopt : std::optional<bool>(found->second);
|
if (std::string_view(entry.first) == key) {
|
||||||
|
return entry.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int> SnapshotIntValue(const DaliDomainSnapshot& snapshot,
|
std::optional<int> SnapshotIntValue(const DaliDomainSnapshot& snapshot,
|
||||||
@@ -1258,11 +1262,13 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::optional<DaliDomainSnapshot> diagnosticSnapshotLocked(int short_address,
|
std::optional<DaliDomainSnapshot> diagnosticSnapshotLocked(int short_address,
|
||||||
const std::string& kind) {
|
std::string_view kind) {
|
||||||
if (!ValidShortAddress(short_address) || kind.empty()) {
|
if (!ValidShortAddress(short_address) || kind.empty()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
const std::string key = kind + ":" + std::to_string(short_address);
|
std::string key(kind.data(), kind.size());
|
||||||
|
key += ":";
|
||||||
|
key += std::to_string(short_address);
|
||||||
const TickType_t now = xTaskGetTickCount();
|
const TickType_t now = xTaskGetTickCount();
|
||||||
const auto cached = diagnostic_snapshot_cache.find(key);
|
const auto cached = diagnostic_snapshot_cache.find(key);
|
||||||
if (cached != diagnostic_snapshot_cache.end() &&
|
if (cached != diagnostic_snapshot_cache.end() &&
|
||||||
@@ -1291,8 +1297,8 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<bool> readSnapshotBoolLocked(int short_address, const std::string& kind,
|
std::optional<bool> readSnapshotBoolLocked(int short_address, std::string_view kind,
|
||||||
const std::string& bool_key) {
|
std::string_view bool_key) {
|
||||||
const auto snapshot = diagnosticSnapshotLocked(short_address, kind);
|
const auto snapshot = diagnosticSnapshotLocked(short_address, kind);
|
||||||
if (!snapshot.has_value()) {
|
if (!snapshot.has_value()) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -1629,7 +1635,7 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldPublishGeneratedBacnetPointLocked(const GatewayModbusPointBinding& point) {
|
bool shouldPublishGeneratedBacnetPointLocked(const GatewayModbusPoint& point) {
|
||||||
if (!point.generated || point.space != GatewayModbusSpace::kDiscreteInput ||
|
if (!point.generated || point.space != GatewayModbusSpace::kDiscreteInput ||
|
||||||
point.access != GatewayModbusAccess::kReadOnly ||
|
point.access != GatewayModbusAccess::kReadOnly ||
|
||||||
!ValidShortAddress(point.short_address)) {
|
!ValidShortAddress(point.short_address)) {
|
||||||
@@ -1651,27 +1657,38 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
if (modbus == nullptr) {
|
if (modbus == nullptr) {
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
for (const auto& point : modbus->describePoints()) {
|
std::vector<GatewayModbusPoint> generated_points;
|
||||||
if (!shouldPublishGeneratedBacnetPointLocked(point)) {
|
generated_points.reserve(192);
|
||||||
|
for (const auto& inventory_entry : discovery_inventory) {
|
||||||
|
if (!ValidShortAddress(inventory_entry.first)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto* discovery = findDiscoveryEntryLocked(point.short_address);
|
generated_points.clear();
|
||||||
const auto object_instance = generatedBacnetBinaryInputInstance(point.address);
|
modbus->appendGeneratedPointsForShortAddress(
|
||||||
if (discovery == nullptr || !object_instance.has_value()) {
|
static_cast<uint8_t>(inventory_entry.first), &generated_points);
|
||||||
continue;
|
for (const auto& point : generated_points) {
|
||||||
|
if (!shouldPublishGeneratedBacnetPointLocked(point)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto* discovery = findDiscoveryEntryLocked(point.short_address);
|
||||||
|
const auto object_instance = generatedBacnetBinaryInputInstance(point.address);
|
||||||
|
if (discovery == nullptr || !object_instance.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto binding = modbus->describePoint(point);
|
||||||
|
const bool out_of_service = !discovery->online;
|
||||||
|
bindings.push_back(GatewayBacnetObjectBinding{channel.gateway_id,
|
||||||
|
binding.id,
|
||||||
|
binding.name,
|
||||||
|
BridgeObjectType::binaryInput,
|
||||||
|
object_instance.value(),
|
||||||
|
"presentValue",
|
||||||
|
out_of_service,
|
||||||
|
out_of_service
|
||||||
|
? kBacnetReliabilityCommunicationFailure
|
||||||
|
: kBacnetReliabilityNoFaultDetected,
|
||||||
|
true});
|
||||||
}
|
}
|
||||||
const bool out_of_service = !discovery->online;
|
|
||||||
bindings.push_back(GatewayBacnetObjectBinding{channel.gateway_id,
|
|
||||||
point.id,
|
|
||||||
point.name,
|
|
||||||
BridgeObjectType::binaryInput,
|
|
||||||
object_instance.value(),
|
|
||||||
"presentValue",
|
|
||||||
out_of_service,
|
|
||||||
out_of_service
|
|
||||||
? kBacnetReliabilityCommunicationFailure
|
|
||||||
: kBacnetReliabilityNoFaultDetected,
|
|
||||||
true});
|
|
||||||
}
|
}
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
@@ -2135,47 +2152,59 @@ struct GatewayBridgeService::ChannelRuntime {
|
|||||||
cJSON_AddItemToArray(bindings, item);
|
cJSON_AddItemToArray(bindings, item);
|
||||||
}
|
}
|
||||||
if (modbus != nullptr) {
|
if (modbus != nullptr) {
|
||||||
for (const auto& point : modbus->describePoints()) {
|
std::vector<GatewayModbusPoint> generated_points;
|
||||||
if (!shouldPublishGeneratedBacnetPointLocked(point)) {
|
generated_points.reserve(192);
|
||||||
|
for (const auto& inventory_entry : discovery_inventory) {
|
||||||
|
if (!ValidShortAddress(inventory_entry.first)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto object_instance = generatedBacnetBinaryInputInstance(point.address);
|
generated_points.clear();
|
||||||
const auto* discovery = findDiscoveryEntryLocked(point.short_address);
|
modbus->appendGeneratedPointsForShortAddress(
|
||||||
if (!object_instance.has_value() || discovery == nullptr) {
|
static_cast<uint8_t>(inventory_entry.first), &generated_points);
|
||||||
continue;
|
for (const auto& point : generated_points) {
|
||||||
|
if (!shouldPublishGeneratedBacnetPointLocked(point)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto object_instance = generatedBacnetBinaryInputInstance(point.address);
|
||||||
|
const auto* discovery = findDiscoveryEntryLocked(point.short_address);
|
||||||
|
if (!object_instance.has_value() || discovery == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cJSON* item = cJSON_CreateObject();
|
||||||
|
if (item == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto binding = modbus->describePoint(point);
|
||||||
|
cJSON_AddStringToObject(item, "model", binding.id.c_str());
|
||||||
|
cJSON_AddStringToObject(item, "name", binding.name.c_str());
|
||||||
|
cJSON_AddStringToObject(item, "objectType", "binaryInput");
|
||||||
|
cJSON_AddNumberToObject(item, "objectInstance", object_instance.value());
|
||||||
|
cJSON_AddStringToObject(item, "property", "presentValue");
|
||||||
|
cJSON_AddBoolToObject(item, "generated", true);
|
||||||
|
cJSON_AddStringToObject(item, "generatedKind",
|
||||||
|
GatewayModbusGeneratedKindToString(binding.generated_kind));
|
||||||
|
cJSON_AddNumberToObject(item, "shortAddress", binding.short_address);
|
||||||
|
if (!binding.diagnostic_snapshot.empty()) {
|
||||||
|
cJSON_AddStringToObject(item, "diagnosticSnapshot",
|
||||||
|
binding.diagnostic_snapshot.c_str());
|
||||||
|
}
|
||||||
|
if (!binding.diagnostic_bool.empty()) {
|
||||||
|
cJSON_AddStringToObject(item, "diagnosticBool", binding.diagnostic_bool.c_str());
|
||||||
|
}
|
||||||
|
if (binding.diagnostic_device_type >= 0) {
|
||||||
|
cJSON_AddNumberToObject(item, "diagnosticDeviceType",
|
||||||
|
binding.diagnostic_device_type);
|
||||||
|
}
|
||||||
|
const bool out_of_service = !discovery->online;
|
||||||
|
cJSON_AddBoolToObject(item, "outOfService", out_of_service);
|
||||||
|
cJSON_AddStringToObject(item, "reliability",
|
||||||
|
BacnetReliabilityToString(out_of_service
|
||||||
|
? kBacnetReliabilityCommunicationFailure
|
||||||
|
: kBacnetReliabilityNoFaultDetected));
|
||||||
|
cJSON_AddStringToObject(item, "inventoryState",
|
||||||
|
DiscoveryStateString(discovery->online));
|
||||||
|
cJSON_AddItemToArray(bindings, item);
|
||||||
}
|
}
|
||||||
cJSON* item = cJSON_CreateObject();
|
|
||||||
if (item == nullptr) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cJSON_AddStringToObject(item, "model", point.id.c_str());
|
|
||||||
cJSON_AddStringToObject(item, "name", point.name.c_str());
|
|
||||||
cJSON_AddStringToObject(item, "objectType", "binaryInput");
|
|
||||||
cJSON_AddNumberToObject(item, "objectInstance", object_instance.value());
|
|
||||||
cJSON_AddStringToObject(item, "property", "presentValue");
|
|
||||||
cJSON_AddBoolToObject(item, "generated", true);
|
|
||||||
cJSON_AddStringToObject(item, "generatedKind",
|
|
||||||
GatewayModbusGeneratedKindToString(point.generated_kind));
|
|
||||||
cJSON_AddNumberToObject(item, "shortAddress", point.short_address);
|
|
||||||
if (!point.diagnostic_snapshot.empty()) {
|
|
||||||
cJSON_AddStringToObject(item, "diagnosticSnapshot",
|
|
||||||
point.diagnostic_snapshot.c_str());
|
|
||||||
}
|
|
||||||
if (!point.diagnostic_bool.empty()) {
|
|
||||||
cJSON_AddStringToObject(item, "diagnosticBool", point.diagnostic_bool.c_str());
|
|
||||||
}
|
|
||||||
if (point.diagnostic_device_type >= 0) {
|
|
||||||
cJSON_AddNumberToObject(item, "diagnosticDeviceType",
|
|
||||||
point.diagnostic_device_type);
|
|
||||||
}
|
|
||||||
const bool out_of_service = !discovery->online;
|
|
||||||
cJSON_AddBoolToObject(item, "outOfService", out_of_service);
|
|
||||||
cJSON_AddStringToObject(item, "reliability",
|
|
||||||
BacnetReliabilityToString(out_of_service
|
|
||||||
? kBacnetReliabilityCommunicationFailure
|
|
||||||
: kBacnetReliabilityNoFaultDetected));
|
|
||||||
cJSON_AddStringToObject(item, "inventoryState", DiscoveryStateString(discovery->online));
|
|
||||||
cJSON_AddItemToArray(bindings, item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,12 +119,14 @@ struct GatewayModbusPoint {
|
|||||||
std::string name;
|
std::string name;
|
||||||
bool generated{false};
|
bool generated{false};
|
||||||
GatewayModbusGeneratedKind generated_kind{GatewayModbusGeneratedKind::kNone};
|
GatewayModbusGeneratedKind generated_kind{GatewayModbusGeneratedKind::kNone};
|
||||||
|
const char* generated_suffix{"point"};
|
||||||
|
const char* generated_name{"point"};
|
||||||
int short_address{-1};
|
int short_address{-1};
|
||||||
std::string model_id;
|
std::string model_id;
|
||||||
BridgeOperation operation{BridgeOperation::unknown};
|
BridgeOperation operation{BridgeOperation::unknown};
|
||||||
std::optional<int> bit_index;
|
std::optional<int> bit_index;
|
||||||
std::string diagnostic_snapshot;
|
const char* diagnostic_snapshot{""};
|
||||||
std::string diagnostic_bool;
|
const char* diagnostic_bool{""};
|
||||||
int diagnostic_device_type{-1};
|
int diagnostic_device_type{-1};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -165,8 +167,12 @@ class GatewayModbusBridge {
|
|||||||
void rebuildMap();
|
void rebuildMap();
|
||||||
std::optional<GatewayModbusPoint> findPoint(GatewayModbusSpace space,
|
std::optional<GatewayModbusPoint> findPoint(GatewayModbusSpace space,
|
||||||
uint16_t address) const;
|
uint16_t address) const;
|
||||||
|
GatewayModbusPointBinding describePoint(const GatewayModbusPoint& point) const;
|
||||||
|
void appendGeneratedPointsForShortAddress(uint8_t short_address,
|
||||||
|
std::vector<GatewayModbusPoint>* points) const;
|
||||||
std::vector<GatewayModbusPointBinding> describePoints() const;
|
std::vector<GatewayModbusPointBinding> describePoints() const;
|
||||||
std::vector<GatewayModbusPointBinding> describeHoldingRegisters() const;
|
std::vector<GatewayModbusPointBinding> describeHoldingRegisters() const;
|
||||||
|
const std::vector<GatewayModbusPoint>& points() const;
|
||||||
|
|
||||||
DaliBridgeResult readModelPoint(const GatewayModbusPoint& point) const;
|
DaliBridgeResult readModelPoint(const GatewayModbusPoint& point) const;
|
||||||
DaliBridgeResult writeRegisterPoint(const GatewayModbusPoint& point, uint16_t value) const;
|
DaliBridgeResult writeRegisterPoint(const GatewayModbusPoint& point, uint16_t value) const;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <map>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace gateway {
|
namespace gateway {
|
||||||
@@ -283,6 +282,16 @@ constexpr GeneratedDiagnosticBitSpec kGeneratedDiagnosticBitsTail[] = {
|
|||||||
{119, 1, "dt1", "controlGearFailure", "dt1_control_gear_failure", "DT1 control gear failure"},
|
{119, 1, "dt1", "controlGearFailure", "dt1_control_gear_failure", "DT1 control gear failure"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr size_t kGeneratedDiagnosticBitCount =
|
||||||
|
sizeof(kGeneratedDiagnosticBits) / sizeof(kGeneratedDiagnosticBits[0]) +
|
||||||
|
sizeof(kGeneratedDiagnosticBitsTail) / sizeof(kGeneratedDiagnosticBitsTail[0]);
|
||||||
|
constexpr size_t kGeneratedPointsPerShort = kGeneratedCoils.size() +
|
||||||
|
kGeneratedDiscreteInputs.size() +
|
||||||
|
kGeneratedHoldingRegisters.size() +
|
||||||
|
kGeneratedInputRegisters.size() +
|
||||||
|
kGeneratedDiagnosticBitCount;
|
||||||
|
constexpr size_t kGeneratedPointCount = kShortAddressCount * kGeneratedPointsPerShort;
|
||||||
|
|
||||||
uint16_t baseForSpace(GatewayModbusSpace space) {
|
uint16_t baseForSpace(GatewayModbusSpace space) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case GatewayModbusSpace::kCoil:
|
case GatewayModbusSpace::kCoil:
|
||||||
@@ -338,62 +347,165 @@ std::string generatedName(uint8_t short_address, const char* name) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addGeneratedPoint(std::map<PointKey, GatewayModbusPoint>* points, uint8_t short_address,
|
const char* literalOrEmpty(const char* value) {
|
||||||
const GeneratedPointSpec& spec) {
|
return value == nullptr ? "" : value;
|
||||||
if (points == nullptr) {
|
}
|
||||||
return;
|
|
||||||
|
PointKey keyForPoint(const GatewayModbusPoint& point) {
|
||||||
|
return PointKey{point.space, point.address};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pointLess(const GatewayModbusPoint& lhs, const GatewayModbusPoint& rhs) {
|
||||||
|
return keyForPoint(lhs) < keyForPoint(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pointKeyEqual(const GatewayModbusPoint& lhs, const GatewayModbusPoint& rhs) {
|
||||||
|
return lhs.space == rhs.space && lhs.address == rhs.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pointKeyEqual(const GatewayModbusPoint& point, const PointKey& key) {
|
||||||
|
return point.space == key.space && point.address == key.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GatewayModbusPoint>::const_iterator findStoredPoint(
|
||||||
|
const std::vector<GatewayModbusPoint>& points, PointKey key) {
|
||||||
|
const auto found = std::lower_bound(
|
||||||
|
points.begin(), points.end(), key,
|
||||||
|
[](const GatewayModbusPoint& point, const PointKey& value) {
|
||||||
|
return keyForPoint(point) < value;
|
||||||
|
});
|
||||||
|
if (found == points.end() || !pointKeyEqual(*found, key)) {
|
||||||
|
return points.end();
|
||||||
}
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
GatewayModbusPoint makeGeneratedPoint(uint8_t short_address,
|
||||||
|
const GeneratedPointSpec& spec) {
|
||||||
const uint16_t address = static_cast<uint16_t>(baseForSpace(spec.space) +
|
const uint16_t address = static_cast<uint16_t>(baseForSpace(spec.space) +
|
||||||
short_address * kShortStride + spec.offset);
|
short_address * kShortStride + spec.offset);
|
||||||
GatewayModbusPoint point;
|
GatewayModbusPoint point;
|
||||||
point.space = spec.space;
|
point.space = spec.space;
|
||||||
point.access = spec.access;
|
point.access = spec.access;
|
||||||
point.address = address;
|
point.address = address;
|
||||||
point.id = generatedId(short_address, spec.suffix);
|
|
||||||
point.name = generatedName(short_address, spec.name);
|
|
||||||
point.generated = true;
|
point.generated = true;
|
||||||
point.generated_kind = spec.kind;
|
point.generated_kind = spec.kind;
|
||||||
|
point.generated_suffix = spec.suffix == nullptr ? "point" : spec.suffix;
|
||||||
|
point.generated_name = spec.name == nullptr ? "point" : spec.name;
|
||||||
point.short_address = short_address;
|
point.short_address = short_address;
|
||||||
(*points)[PointKey{spec.space, address}] = std::move(point);
|
return point;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addGeneratedDiagnosticPoint(std::map<PointKey, GatewayModbusPoint>* points,
|
GatewayModbusPoint makeGeneratedDiagnosticPoint(uint8_t short_address,
|
||||||
uint8_t short_address,
|
const GeneratedDiagnosticBitSpec& spec) {
|
||||||
const GeneratedDiagnosticBitSpec& spec) {
|
|
||||||
if (points == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const uint16_t address = static_cast<uint16_t>(kDiagnosticDiscreteInputBase +
|
const uint16_t address = static_cast<uint16_t>(kDiagnosticDiscreteInputBase +
|
||||||
short_address * kDiagnosticStride + spec.offset);
|
short_address * kDiagnosticStride + spec.offset);
|
||||||
GatewayModbusPoint point;
|
GatewayModbusPoint point;
|
||||||
point.space = GatewayModbusSpace::kDiscreteInput;
|
point.space = GatewayModbusSpace::kDiscreteInput;
|
||||||
point.access = GatewayModbusAccess::kReadOnly;
|
point.access = GatewayModbusAccess::kReadOnly;
|
||||||
point.address = address;
|
point.address = address;
|
||||||
point.id = generatedId(short_address, spec.suffix);
|
|
||||||
point.name = generatedName(short_address, spec.name);
|
|
||||||
point.generated = true;
|
point.generated = true;
|
||||||
point.generated_kind = GatewayModbusGeneratedKind::kShortDiagnosticBit;
|
point.generated_kind = GatewayModbusGeneratedKind::kShortDiagnosticBit;
|
||||||
|
point.generated_suffix = spec.suffix == nullptr ? "point" : spec.suffix;
|
||||||
|
point.generated_name = spec.name == nullptr ? "point" : spec.name;
|
||||||
point.short_address = short_address;
|
point.short_address = short_address;
|
||||||
point.diagnostic_snapshot = spec.snapshot == nullptr ? "" : spec.snapshot;
|
point.diagnostic_snapshot = literalOrEmpty(spec.snapshot);
|
||||||
point.diagnostic_bool = spec.bool_key == nullptr ? "" : spec.bool_key;
|
point.diagnostic_bool = literalOrEmpty(spec.bool_key);
|
||||||
point.diagnostic_device_type = spec.device_type;
|
point.diagnostic_device_type = spec.device_type;
|
||||||
(*points)[PointKey{point.space, address}] = std::move(point);
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendIfNotOverridden(const std::vector<GatewayModbusPoint>& stored_points,
|
||||||
|
std::vector<GatewayModbusPoint>* points,
|
||||||
|
GatewayModbusPoint point) {
|
||||||
|
if (points == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (findStoredPoint(stored_points, keyForPoint(point)) != stored_points.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
points->push_back(std::move(point));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<GatewayModbusPoint> generatedPointForAddress(GatewayModbusSpace space,
|
||||||
|
uint16_t address) {
|
||||||
|
if (space == GatewayModbusSpace::kDiscreteInput &&
|
||||||
|
address >= kDiagnosticDiscreteInputBase) {
|
||||||
|
const uint16_t relative = static_cast<uint16_t>(address - kDiagnosticDiscreteInputBase);
|
||||||
|
const uint8_t short_address = static_cast<uint8_t>(relative / kDiagnosticStride);
|
||||||
|
const uint16_t offset = static_cast<uint16_t>(relative % kDiagnosticStride);
|
||||||
|
if (short_address >= kShortAddressCount) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedDiagnosticBits) {
|
||||||
|
if (spec.offset == offset) {
|
||||||
|
return makeGeneratedDiagnosticPoint(short_address, spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedDiagnosticBitsTail) {
|
||||||
|
if (spec.offset == offset) {
|
||||||
|
return makeGeneratedDiagnosticPoint(short_address, spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint16_t base = baseForSpace(space);
|
||||||
|
if (address < base) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
const uint16_t relative = static_cast<uint16_t>(address - base);
|
||||||
|
const uint8_t short_address = static_cast<uint8_t>(relative / kShortStride);
|
||||||
|
const uint16_t offset = static_cast<uint16_t>(relative % kShortStride);
|
||||||
|
if (short_address >= kShortAddressCount) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto find_regular_point = [short_address, offset](const auto& specs)
|
||||||
|
-> std::optional<GatewayModbusPoint> {
|
||||||
|
for (const auto& spec : specs) {
|
||||||
|
if (spec.offset == offset) {
|
||||||
|
return makeGeneratedPoint(short_address, spec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (space) {
|
||||||
|
case GatewayModbusSpace::kCoil:
|
||||||
|
return find_regular_point(kGeneratedCoils);
|
||||||
|
case GatewayModbusSpace::kDiscreteInput:
|
||||||
|
return find_regular_point(kGeneratedDiscreteInputs);
|
||||||
|
case GatewayModbusSpace::kHoldingRegister:
|
||||||
|
return find_regular_point(kGeneratedHoldingRegisters);
|
||||||
|
case GatewayModbusSpace::kInputRegister:
|
||||||
|
return find_regular_point(kGeneratedInputRegisters);
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayModbusPointBinding toBinding(const GatewayModbusPoint& point) {
|
GatewayModbusPointBinding toBinding(const GatewayModbusPoint& point) {
|
||||||
return GatewayModbusPointBinding{point.model_id,
|
GatewayModbusPointBinding binding;
|
||||||
point.space,
|
binding.model_id = point.model_id;
|
||||||
point.address,
|
binding.space = point.space;
|
||||||
point.id,
|
binding.address = point.address;
|
||||||
point.name,
|
if (point.generated) {
|
||||||
point.generated,
|
const auto short_address = static_cast<uint8_t>(point.short_address < 0 ? 0 : point.short_address);
|
||||||
point.generated_kind,
|
binding.id = generatedId(short_address, point.generated_suffix);
|
||||||
point.short_address,
|
binding.name = generatedName(short_address, point.generated_name);
|
||||||
point.access,
|
} else {
|
||||||
point.bit_index,
|
binding.id = point.id;
|
||||||
point.diagnostic_snapshot,
|
binding.name = point.name;
|
||||||
point.diagnostic_bool,
|
}
|
||||||
point.diagnostic_device_type};
|
binding.generated = point.generated;
|
||||||
|
binding.generated_kind = point.generated_kind;
|
||||||
|
binding.short_address = point.short_address;
|
||||||
|
binding.access = point.access;
|
||||||
|
binding.bit_index = point.bit_index;
|
||||||
|
binding.diagnostic_snapshot = literalOrEmpty(point.diagnostic_snapshot);
|
||||||
|
binding.diagnostic_bool = literalOrEmpty(point.diagnostic_bool);
|
||||||
|
binding.diagnostic_device_type = point.diagnostic_device_type;
|
||||||
|
return binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
int clampedInt(const DaliValue::Object& json, const std::string& key, int fallback,
|
int clampedInt(const DaliValue::Object& json, const std::string& key, int fallback,
|
||||||
@@ -657,29 +769,11 @@ void GatewayModbusBridge::setConfig(const GatewayModbusConfig& config) { config_
|
|||||||
const GatewayModbusConfig& GatewayModbusBridge::config() const { return config_; }
|
const GatewayModbusConfig& GatewayModbusBridge::config() const { return config_; }
|
||||||
|
|
||||||
void GatewayModbusBridge::rebuildMap() {
|
void GatewayModbusBridge::rebuildMap() {
|
||||||
std::map<PointKey, GatewayModbusPoint> next;
|
auto models = engine_.listModels();
|
||||||
for (uint8_t short_address = 0; short_address < kShortAddressCount; ++short_address) {
|
points_.clear();
|
||||||
for (const auto& spec : kGeneratedCoils) {
|
points_.reserve(models.size());
|
||||||
addGeneratedPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
for (const auto& spec : kGeneratedDiscreteInputs) {
|
|
||||||
addGeneratedPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
for (const auto& spec : kGeneratedHoldingRegisters) {
|
|
||||||
addGeneratedPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
for (const auto& spec : kGeneratedInputRegisters) {
|
|
||||||
addGeneratedPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
for (const auto& spec : kGeneratedDiagnosticBits) {
|
|
||||||
addGeneratedDiagnosticPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
for (const auto& spec : kGeneratedDiagnosticBitsTail) {
|
|
||||||
addGeneratedDiagnosticPoint(&next, short_address, spec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& model : engine_.listModels()) {
|
for (const auto& model : models) {
|
||||||
if (model.protocol != BridgeProtocolKind::modbus || !model.external.registerAddress.has_value()) {
|
if (model.protocol != BridgeProtocolKind::modbus || !model.external.registerAddress.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -701,46 +795,117 @@ void GatewayModbusBridge::rebuildMap() {
|
|||||||
if (model.dali.kind == BridgeDaliTargetKind::shortAddress && model.dali.shortAddress.has_value()) {
|
if (model.dali.kind == BridgeDaliTargetKind::shortAddress && model.dali.shortAddress.has_value()) {
|
||||||
point.short_address = model.dali.shortAddress.value();
|
point.short_address = model.dali.shortAddress.value();
|
||||||
}
|
}
|
||||||
next[PointKey{point.space, point.address}] = std::move(point);
|
points_.push_back(std::move(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
points_.clear();
|
std::stable_sort(points_.begin(), points_.end(), pointLess);
|
||||||
points_.reserve(next.size());
|
auto write = points_.begin();
|
||||||
for (auto& entry : next) {
|
for (auto read = points_.begin(); read != points_.end();) {
|
||||||
points_.push_back(std::move(entry.second));
|
auto next = read + 1;
|
||||||
|
while (next != points_.end() && pointKeyEqual(*read, *next)) {
|
||||||
|
++next;
|
||||||
|
}
|
||||||
|
if (write != next - 1) {
|
||||||
|
*write = std::move(*(next - 1));
|
||||||
|
}
|
||||||
|
++write;
|
||||||
|
read = next;
|
||||||
}
|
}
|
||||||
|
points_.erase(write, points_.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<GatewayModbusPoint> GatewayModbusBridge::findPoint(GatewayModbusSpace space,
|
std::optional<GatewayModbusPoint> GatewayModbusBridge::findPoint(GatewayModbusSpace space,
|
||||||
uint16_t address) const {
|
uint16_t address) const {
|
||||||
const auto found = std::find_if(points_.begin(), points_.end(), [space, address](const auto& point) {
|
const PointKey key{space, address};
|
||||||
return point.space == space && point.address == address;
|
const auto found = findStoredPoint(points_, key);
|
||||||
});
|
if (found != points_.end()) {
|
||||||
if (found == points_.end()) {
|
return *found;
|
||||||
return std::nullopt;
|
}
|
||||||
|
return generatedPointForAddress(space, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
GatewayModbusPointBinding GatewayModbusBridge::describePoint(
|
||||||
|
const GatewayModbusPoint& point) const {
|
||||||
|
return toBinding(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayModbusBridge::appendGeneratedPointsForShortAddress(
|
||||||
|
uint8_t short_address, std::vector<GatewayModbusPoint>* points) const {
|
||||||
|
if (points == nullptr || short_address >= kShortAddressCount) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedCoils) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedPoint(short_address, spec));
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedDiscreteInputs) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedPoint(short_address, spec));
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedHoldingRegisters) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedPoint(short_address, spec));
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedInputRegisters) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedPoint(short_address, spec));
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedDiagnosticBits) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedDiagnosticPoint(short_address, spec));
|
||||||
|
}
|
||||||
|
for (const auto& spec : kGeneratedDiagnosticBitsTail) {
|
||||||
|
appendIfNotOverridden(points_, points, makeGeneratedDiagnosticPoint(short_address, spec));
|
||||||
}
|
}
|
||||||
return *found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<GatewayModbusPointBinding> GatewayModbusBridge::describePoints() const {
|
std::vector<GatewayModbusPointBinding> GatewayModbusBridge::describePoints() const {
|
||||||
std::vector<GatewayModbusPointBinding> bindings;
|
std::vector<GatewayModbusPointBinding> bindings;
|
||||||
bindings.reserve(points_.size());
|
bindings.reserve(kGeneratedPointCount + points_.size());
|
||||||
|
std::vector<GatewayModbusPoint> generated_points;
|
||||||
|
generated_points.reserve(kGeneratedPointsPerShort);
|
||||||
|
for (uint8_t short_address = 0; short_address < kShortAddressCount; ++short_address) {
|
||||||
|
generated_points.clear();
|
||||||
|
appendGeneratedPointsForShortAddress(short_address, &generated_points);
|
||||||
|
for (const auto& point : generated_points) {
|
||||||
|
bindings.push_back(toBinding(point));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const auto& point : points_) {
|
for (const auto& point : points_) {
|
||||||
bindings.push_back(toBinding(point));
|
bindings.push_back(toBinding(point));
|
||||||
}
|
}
|
||||||
|
std::sort(bindings.begin(), bindings.end(), [](const auto& lhs, const auto& rhs) {
|
||||||
|
if (lhs.space != rhs.space) {
|
||||||
|
return static_cast<uint8_t>(lhs.space) < static_cast<uint8_t>(rhs.space);
|
||||||
|
}
|
||||||
|
return lhs.address < rhs.address;
|
||||||
|
});
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<GatewayModbusPointBinding> GatewayModbusBridge::describeHoldingRegisters() const {
|
std::vector<GatewayModbusPointBinding> GatewayModbusBridge::describeHoldingRegisters() const {
|
||||||
std::vector<GatewayModbusPointBinding> bindings;
|
std::vector<GatewayModbusPointBinding> bindings;
|
||||||
|
std::vector<GatewayModbusPoint> generated_points;
|
||||||
|
generated_points.reserve(kGeneratedPointsPerShort);
|
||||||
|
for (uint8_t short_address = 0; short_address < kShortAddressCount; ++short_address) {
|
||||||
|
generated_points.clear();
|
||||||
|
appendGeneratedPointsForShortAddress(short_address, &generated_points);
|
||||||
|
for (const auto& point : generated_points) {
|
||||||
|
if (point.space == GatewayModbusSpace::kHoldingRegister) {
|
||||||
|
bindings.push_back(toBinding(point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const auto& point : points_) {
|
for (const auto& point : points_) {
|
||||||
if (point.space == GatewayModbusSpace::kHoldingRegister) {
|
if (point.space == GatewayModbusSpace::kHoldingRegister) {
|
||||||
bindings.push_back(toBinding(point));
|
bindings.push_back(toBinding(point));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::sort(bindings.begin(), bindings.end(), [](const auto& lhs, const auto& rhs) {
|
||||||
|
return lhs.address < rhs.address;
|
||||||
|
});
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<GatewayModbusPoint>& GatewayModbusBridge::points() const {
|
||||||
|
return points_;
|
||||||
|
}
|
||||||
|
|
||||||
DaliBridgeResult GatewayModbusBridge::readModelPoint(const GatewayModbusPoint& point) const {
|
DaliBridgeResult GatewayModbusBridge::readModelPoint(const GatewayModbusPoint& point) const {
|
||||||
return executeModelPoint(point, std::nullopt);
|
return executeModelPoint(point, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user