4ce3513dd2
- 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>
113 lines
3.7 KiB
C++
113 lines
3.7 KiB
C++
#include "gateway_usb_setup.hpp"
|
|
|
|
#include "gateway_controller.hpp"
|
|
|
|
#include "driver/usb_serial_jtag.h"
|
|
#include "esp_log.h"
|
|
|
|
#include <algorithm>
|
|
|
|
namespace gateway {
|
|
|
|
namespace {
|
|
constexpr const char* kTag = "gateway_usb";
|
|
constexpr size_t kCommandFrameMinLen = 7;
|
|
}
|
|
|
|
GatewayUsbSetupBridge::GatewayUsbSetupBridge(GatewayController& controller,
|
|
DaliDomainService& dali_domain,
|
|
GatewayUsbSetupBridgeConfig config)
|
|
: controller_(controller), dali_domain_(dali_domain), config_(config) {}
|
|
|
|
esp_err_t GatewayUsbSetupBridge::start() {
|
|
if (started_) {
|
|
return ESP_OK;
|
|
}
|
|
if (!config_.enabled) {
|
|
ESP_LOGI(kTag, "USB Serial/JTAG setup bridge disabled; USB remains available for debug");
|
|
return ESP_OK;
|
|
}
|
|
|
|
if (!usb_serial_jtag_is_driver_installed()) {
|
|
usb_serial_jtag_driver_config_t driver_config = {};
|
|
driver_config.rx_buffer_size = static_cast<int>(config_.rx_buffer_size);
|
|
driver_config.tx_buffer_size = static_cast<int>(config_.tx_buffer_size);
|
|
esp_err_t err = usb_serial_jtag_driver_install(&driver_config);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(kTag, "failed to install USB Serial/JTAG driver: %s", esp_err_to_name(err));
|
|
return err;
|
|
}
|
|
}
|
|
|
|
dali_domain_.addRawFrameSink([this](const DaliRawFrame& frame) { handleRawFrame(frame); });
|
|
|
|
const BaseType_t ok = xTaskCreate(&GatewayUsbSetupBridge::TaskEntry, "gateway_usb_setup",
|
|
static_cast<uint32_t>(config_.task_stack_size), this,
|
|
config_.task_priority, &task_handle_);
|
|
if (ok != pdPASS) {
|
|
ESP_LOGE(kTag, "failed to create USB setup task");
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
|
|
started_ = true;
|
|
ESP_LOGI(kTag, "USB Serial/JTAG setup bridge started channel=%u", config_.channel_index);
|
|
return ESP_OK;
|
|
}
|
|
|
|
void GatewayUsbSetupBridge::TaskEntry(void* arg) {
|
|
auto* self = static_cast<GatewayUsbSetupBridge*>(arg);
|
|
self->taskLoop();
|
|
}
|
|
|
|
void GatewayUsbSetupBridge::taskLoop() {
|
|
std::vector<uint8_t> buffer(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 = usb_serial_jtag_read_bytes(buffer.data(), buffer.size(), timeout);
|
|
if (read_len > 0) {
|
|
handleBytes(buffer.data(), static_cast<size_t>(read_len));
|
|
}
|
|
}
|
|
}
|
|
|
|
void GatewayUsbSetupBridge::handleBytes(const uint8_t* data, size_t len) {
|
|
if (data == nullptr || len == 0) {
|
|
return;
|
|
}
|
|
|
|
if (len >= kCommandFrameMinLen) {
|
|
controller_.enqueueCommandFrame(std::vector<uint8_t>(data, data + len));
|
|
return;
|
|
}
|
|
|
|
const uint8_t gateway_id = setupGatewayId();
|
|
if (!dali_domain_.writeBridgeFrame(gateway_id, data, len)) {
|
|
ESP_LOGW(kTag, "failed to write USB raw setup frame channel=%u len=%u", config_.channel_index,
|
|
static_cast<unsigned>(len));
|
|
}
|
|
}
|
|
|
|
void GatewayUsbSetupBridge::handleRawFrame(const DaliRawFrame& frame) {
|
|
if (!config_.enabled || frame.channel_index != config_.channel_index || frame.data.empty()) {
|
|
return;
|
|
}
|
|
|
|
const int written = usb_serial_jtag_write_bytes(frame.data.data(), frame.data.size(),
|
|
pdMS_TO_TICKS(config_.write_timeout_ms));
|
|
if (written < 0 || static_cast<size_t>(written) != frame.data.size()) {
|
|
ESP_LOGW(kTag, "failed to forward USB raw setup frame channel=%u len=%u", frame.channel_index,
|
|
static_cast<unsigned>(frame.data.size()));
|
|
}
|
|
}
|
|
|
|
uint8_t GatewayUsbSetupBridge::setupGatewayId() const {
|
|
for (const auto& channel : dali_domain_.channelInfo()) {
|
|
if (channel.channel_index == config_.channel_index) {
|
|
return channel.gateway_id;
|
|
}
|
|
}
|
|
return config_.channel_index;
|
|
}
|
|
|
|
} // namespace gateway
|