Refactored DALI using TasmotaDali library v1.0.0 adding frame receive buffer

This commit is contained in:
Theo Arends 2025-11-28 14:21:17 +01:00
parent be6de4c6bc
commit 59164211a0
4 changed files with 30 additions and 26 deletions

View File

@ -7,11 +7,13 @@ All notable changes to this project will be documented in this file.
### Added
- Support for ESP32-P4 rev.3 (#24146)
- Support for Analog Gauges (#24153)
- Support for MakeSkyBlue Solar Charger Energy Monitor (#24151)
### Breaking Changed
### Changed
- ESP32 Platform from 2025.11.30 to 2025.11.31, Framework (Arduino Core) from v3.1.5 to v3.1.6 and IDF from v5.3.4.251110 to v5.3.4.251110 (#24146)
- Refactored DALI using TasmotaDali library v1.0.0 adding frame receive buffer
### Fixed
- ESP32-P4 Hosted MCU updated to v2.6.6 solving WiFi boot issues (#24146)

View File

@ -116,6 +116,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
### Added
- Support for ESP32-P4 rev.3 [#24146](https://github.com/arendst/Tasmota/issues/24118)
- Support for Analog Gauges [#24153](https://github.com/arendst/Tasmota/issues/24153)
- Support for MakeSkyBlue Solar Charger Energy Monitor [#24151](https://github.com/arendst/Tasmota/issues/24151)
- Commands `DaliSend` and `DaliQuery` allow extended commands with prefix for DeviceType defaulting to DT6
- ESP8266 GPIOViewer memory map if enabled with `#define GV_USE_ESPINFO`
- HostedMCU file update using command `HostedLoad <version>|<filename>`
@ -137,6 +138,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- JPEGDEC library from v1.8.3 to v1.8.4 [#24120](https://github.com/arendst/Tasmota/issues/24120)
- GPIOViewer from v1.6.3 to v1.7.0
- Refactored library UDisplay [#24007](https://github.com/arendst/Tasmota/issues/24007)
- Refactored DALI using TasmotaDali library v1.0.0 adding frame receive buffer
- Increased filesystem file name size from 48 to 50 characters
### Fixed

View File

@ -226,10 +226,11 @@ void TasmotaDali::ReceiveData(void) {
1 2 3 4 5 6 7
*/
uint32_t wait = ESP.getCycleCount() + (m_bit_time / 2);
DaliFrame frame;
frame.data = 0; // Received dali data
frame.meta = 0; // Bit count 0..32 bit
int bit_state = 0;
bool dali_read;
uint32_t bit_count = 0;
uint32_t received_dali_data = 0;
uint32_t bit_number = 0;
while (bit_number < 72) {
while (ESP.getCycleCount() < wait);
@ -239,15 +240,17 @@ void TasmotaDali::ReceiveData(void) {
bit_state += (dali_read) ? 1 : -1;
if (0 == bit_state) { // Manchester encoding total 2 bits is always 0
if (bit_number > 2) { // Skip start bit
received_dali_data <<= 1;
received_dali_data |= dali_read;
frame.data <<= 1;
frame.data |= dali_read;
}
}
else if (2 == bit_state) { // Invalid manchester data (might be stop bit)
// bn 19 -> 8, 35 -> 16, 51 -> 24, 67 -> 32
bit_count = (bit_number - 3) / 2; // 0..32 bit
bit_state = 0;
bit_number = 69; // Continue receiving stop bits
// bn 19 -> 8, 35 -> 16, 51 -> 24, 67 -> 32
if (bit_number > 4) {
frame.meta = (bit_number - 3) / 2; // 1..32 bit
}
bit_state = 0;
bit_number = 69; // Continue receiving stop bits
}
else if (abs(bit_state) > 1) { // Invalid manchester data (too many 0 or 1)
break;
@ -257,7 +260,7 @@ void TasmotaDali::ReceiveData(void) {
break;
}
else if (dali_read != 1) { // Invalid level of stop bit
bit_state = 1;
bit_state = 1; // Could be collision
break;
}
}
@ -265,12 +268,10 @@ void TasmotaDali::ReceiveData(void) {
}
m_last_activity = millis(); // Start Forward Frame delay time (>22Te)
if ((0 == bit_state) && // Valid Manchester encoding including start and stop bits
(bit_count >= 8) && // Minimum 8-bits (backward frame)
(bit_count <= 32)) { // Maximum 32-bits (forward and event frame)
DaliFrame frame;
frame.meta = bit_count; // 8..32 bit
frame.data = received_dali_data;
if (frame.meta > 0) { // Any valid bit received
if (bit_state != 0) { // Invalid Manchester encoding including start and stop bits
frame.meta | TM_DALI_COLLISION; // Possible collision or invalid reply of repeated frame
}
uint32_t prev = (0 == m_in_pos) ? m_buffer_size -1 : m_in_pos -1;
if ((m_buffer[prev].data != frame.data) ||
(m_buffer[prev].meta != frame.meta)) { // Skip duplicates

View File

@ -384,11 +384,9 @@ void DaliSendData(uint32_t adr, uint32_t cmd) {
}
}
#ifdef DALI_DEBUG
AddLog(Dali->log_level, PSTR("DLI: Tx 0x%08X %2d DT%d%s"),
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Tx 0x%08X %2d DT%d%s"),
frame.data, frame.meta & TM_DALI_BIT_COUNT_MASK,
Dali->device_type, (frame.meta & TM_DALI_SEND_TWICE)?" twice":"");
#endif // DALI_DEBUG
Dali->dali->write(frame); // Takes 14.7 ms
@ -412,17 +410,16 @@ int DaliSendWaitResponse(uint32_t adr, uint32_t cmd, uint32_t timeout) {
frame.meta = 0;
if (Dali->dali->available()) {
frame = Dali->dali->read();
if (frame.meta > 127) {
if ((frame.meta & TM_DALI_COLLISION) ||
(frame.meta != 8)) {
result = -2; // Collision
}
else if (8 == frame.meta) { // Backward frame
result = (frame.data &0xFF);
else {
result = (frame.data &0xFF); // Backward frame
}
}
#ifdef DALI_DEBUG
AddLog(Dali->log_level, PSTR("DLI: Rx 0x%08X %2d response"), result, frame.meta);
#endif // DALI_DEBUG
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Rx 0x%08X %2d response"), result, frame.meta);
return result;
}
@ -718,8 +715,10 @@ void DaliLoop(void) {
DaliFrame frame = Dali->dali->read();
AddLog((1 == Dali->probe) ? LOG_LEVEL_DEBUG : LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Rx 0x%08X %2d queue %d%s"),
frame.data, frame.meta, queue, (8 == frame.meta)?" backward":"");
uint32_t bit_count = frame.meta & TM_DALI_BIT_COUNT_MASK;
bool collision = frame.meta & TM_DALI_COLLISION;
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("DLI: Rx 0x%08X %2d queue %d%s%s"),
frame.data, bit_count, queue, (8 == bit_count)?" backward":"", (collision)?" collision":"");
if ((frame.meta != 16) || // Skip backward frames
(1 == Dali->probe)) { // Probe only