initial commit

This commit is contained in:
Tony
2026-03-26 12:04:08 +08:00
commit 7e8ac7f566
31 changed files with 4304 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
#include "dali_comm.hpp"
#include <chrono>
#include <thread>
#ifdef ESP_PLATFORM
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#endif
DaliComm::DaliComm(SendCallback send_cb,
ReadCallback read_cb,
TransactCallback transact_cb,
DelayCallback delay_cb)
: send_(std::move(send_cb)),
read_(std::move(read_cb)),
transact_(std::move(transact_cb)),
delay_(std::move(delay_cb)) {}
void DaliComm::setSendCallback(SendCallback cb) { send_ = std::move(cb); }
void DaliComm::setReadCallback(ReadCallback cb) { read_ = std::move(cb); }
void DaliComm::setTransactCallback(TransactCallback cb) { transact_ = std::move(cb); }
void DaliComm::setDelayCallback(DelayCallback cb) { delay_ = std::move(cb); }
std::vector<uint8_t> DaliComm::checksum(const std::vector<uint8_t>& data) {
std::vector<uint8_t> out = data;
uint32_t sum = 0;
for (const auto b : out) {
sum += b;
}
out.push_back(static_cast<uint8_t>(sum & 0xFF));
return out;
}
bool DaliComm::write(const std::vector<uint8_t>& data) const { return writeFrame(data); }
std::vector<uint8_t> DaliComm::read(size_t len, uint32_t timeout_ms) const {
if (!read_) return {};
return read_(len, timeout_ms);
}
int DaliComm::checkGatewayType(int gateway) const {
if (!transact_) return 0;
const std::vector<uint8_t> usbProbe{0x01, 0x00, 0x00};
const std::vector<uint8_t> legacyProbe{0x28, 0x01, static_cast<uint8_t>(gateway), 0x11, 0x00, 0x00,
0xFF};
const std::vector<uint8_t> newProbe{0x28, 0x01, static_cast<uint8_t>(gateway), 0x11, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF};
const auto usbResp = transact_(usbProbe.data(), usbProbe.size());
if (!usbResp.empty() && usbResp[0] > 0) return 1;
const auto legacyResp = transact_(legacyProbe.data(), legacyProbe.size());
if (legacyResp.size() >= 2 && legacyResp[0] == gateway) return 2;
const auto newResp = transact_(newProbe.data(), newProbe.size());
if (newResp.size() >= 2 && newResp[0] == gateway) return 3;
return 0;
}
void DaliComm::flush() const {
if (!read_) return;
for (int i = 0; i < 10; i++) {
const auto data = read_(2, 100);
if (data.empty()) break;
}
}
bool DaliComm::resetBus() const {
const std::vector<uint8_t> frame{0x00, 0x00, 0x00};
if (!write(frame)) return false;
sleepMs(100);
if (!write(frame)) return false;
sleepMs(100);
return true;
}
bool DaliComm::sendRaw(uint8_t addr, uint8_t cmd) const { return sendCmd(addr, cmd); }
bool DaliComm::sendRawNew(uint8_t addr, uint8_t cmd, bool needVerify) const {
if (!needVerify) return sendCmd(addr, cmd);
return queryCmd(addr, cmd).has_value();
}
bool DaliComm::sendExtRaw(uint8_t addr, uint8_t cmd) const { return sendExtCmd(addr, cmd); }
bool DaliComm::sendExtRawNew(uint8_t addr, uint8_t cmd) const { return sendExtCmd(addr, cmd); }
std::optional<uint8_t> DaliComm::queryRaw(uint8_t addr, uint8_t cmd) const { return queryCmd(addr, cmd); }
std::optional<uint8_t> DaliComm::queryRawNew(uint8_t addr, uint8_t cmd) const {
return queryCmd(addr, cmd);
}
bool DaliComm::send(int dec_addr, uint8_t cmd) const { return sendCmd(toCmdAddr(dec_addr), cmd); }
std::optional<uint8_t> DaliComm::query(int dec_addr, uint8_t cmd) const {
return queryCmd(toCmdAddr(dec_addr), cmd);
}
bool DaliComm::getBusStatus() const { return checkGatewayType(0) > 0; }
uint8_t DaliComm::toCmdAddr(int dec_addr) { return static_cast<uint8_t>(dec_addr * 2 + 1); }
uint8_t DaliComm::toArcAddr(int dec_addr) { return static_cast<uint8_t>(dec_addr * 2); }
bool DaliComm::writeFrame(const std::vector<uint8_t>& frame) const {
if (!send_) return false;
return send_(frame.data(), frame.size());
}
void DaliComm::sleepMs(uint32_t ms) const {
if (delay_) {
delay_(ms);
return;
}
#ifdef ESP_PLATFORM
vTaskDelay(pdMS_TO_TICKS(ms));
#else
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
#endif
}
bool DaliComm::sendCmd(uint8_t addr, uint8_t cmd) const {
const std::vector<uint8_t> frame{0x10, addr, cmd};
return writeFrame(frame);
}
bool DaliComm::sendExtCmd(uint8_t addr, uint8_t cmd) const {
const std::vector<uint8_t> frame{0x11, addr, cmd};
const bool ret = writeFrame(frame);
sleepMs(100);
return ret;
}
std::optional<uint8_t> DaliComm::queryCmd(uint8_t addr, uint8_t cmd) const {
if (!transact_) return std::nullopt;
const std::vector<uint8_t> frame{0x12, addr, cmd};
const auto resp = transact_(frame.data(), frame.size());
if (resp.empty()) return std::nullopt;
// Gateway type 1 returns: 0xFF <data> on success; 0xFE no response; 0xFD invalid frame.
if (resp.size() == 1) {
if (resp[0] == 0xFE || resp[0] == 0xFD) return std::nullopt;
return resp[0];
}
if (resp[0] == 0xFF && resp.size() >= 2) {
return resp[1];
}
return resp.back();
}