From bb880346696e2734d2afa0c26e129b7c93752c84 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 4 Dec 2022 10:50:58 +0100 Subject: [PATCH] Fix LD2410 Hardware Watchdogs --- .../TasmotaSerial-3.6.0/src/TasmotaSerial.cpp | 29 +++++++++++++------ .../TasmotaSerial-3.6.0/src/TasmotaSerial.h | 1 + .../tasmota_xsns_sensor/xsns_102_ld2410.ino | 9 ++++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp index 97c30b750..7e960b05c 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp @@ -283,6 +283,10 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) { return m_valid; } +void TasmotaSerial::setReadChunkMode(bool mode) { + m_very_high_speed = mode; +} + bool TasmotaSerial::hardwareSerial(void) { #ifdef ESP8266 return m_hardserial; @@ -345,7 +349,9 @@ int TasmotaSerial::read(void) { return TSerial->read(); #endif // ESP32 } else { - if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; + if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { + return -1; + } uint32_t ch = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; return ch; @@ -361,7 +367,9 @@ size_t TasmotaSerial::read(char* buffer, size_t size) { return TSerial->read(buffer, size); #endif // ESP32 } else { - if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { return 0; } + if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) { + return 0; + } size_t count = 0; for( ; size && (m_in_pos != m_out_pos) ; --size, ++count) { *buffer++ = m_buffer[m_out_pos]; @@ -461,14 +469,17 @@ size_t TasmotaSerial::write(uint8_t b) { } void IRAM_ATTR TasmotaSerial::rxRead(void) { - uint32_t m_out_pos_fixed = m_out_pos; if (!m_nwmode) { - int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; - uint32_t bit_mask = 0x01 << (m_data_bits -1); + uint32_t start = ESP.getCycleCount(); // Advance the starting point for the samples but compensate for the // initial delay which occurs before the interrupt is delivered uint32_t wait = m_bit_start_time; - uint32_t start = ESP.getCycleCount(); + // Decide to read as much data as buffer can hold or a single byte + // The first option may keep interrupt busy too long resulting in Hardware Watchdog + // The second option may receive ocasional invalid data + // User control by function setReadChunkMode() + int32_t loop_read = m_very_high_speed ? serial_buffer_size : 1; + uint32_t bit_mask = 0x01 << (m_data_bits -1); while (loop_read-- > 0) { // try to receive all consecutive bytes in a row uint32_t rec = 0; for (uint32_t i = 0; i < m_data_bits; i++) { @@ -478,7 +489,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } // Store the received value in the buffer unless we have an overflow uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = rec; m_in_pos = next; } else { @@ -547,7 +558,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { } //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } @@ -561,7 +572,7 @@ void IRAM_ATTR TasmotaSerial::rxRead(void) { // bit zero was 0, //stobyte(0,ssp->ss_byte>>1); uint32_t next = (m_in_pos + 1) % serial_buffer_size; - if (next != m_out_pos_fixed) { + if (next != m_out_pos) { m_buffer[m_in_pos] = ss_byte >> 1; m_in_pos = next; } diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h index 97fc1406c..cf93f3443 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h @@ -55,6 +55,7 @@ class TasmotaSerial : public Stream { size_t read(uint8_t* buffer, size_t size) { return read(reinterpret_cast(buffer), size); } + void setReadChunkMode(bool mode); int available(void) override; void flush(void) override; diff --git a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino index ad4457492..7a8c008e4 100644 --- a/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_102_ld2410.ino @@ -199,13 +199,13 @@ void Ld2410Input(void) { config_header = (Ld2410Match(LD2410_config_header, 0)); // FDFCFBFA if (target_header || config_header) { uint32_t len = LD2410.buffer[4] +10; // Total packet size - if (len > LD2410_BUFFER_SIZE) { + if (len > LD2410_BUFFER_SIZE) { LD2410.byte_counter = 0; // Invalid data break; // Exit loop to satisfy yields } if (LD2410.byte_counter < len) { continue; } // Need complete packet -// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); if (target_header) { // F4F3F2F1 @@ -217,10 +217,11 @@ void Ld2410Input(void) { } else if (config_header) { // FDFCFBFA - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); +// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Rcvd %*_H"), len, LD2410.buffer); if (Ld2410Match(LD2410_config_footer, len -4)) { // 04030201 Ld1410HandleConfigData(); + LD2410Serial->setReadChunkMode(0); // Disable chunk mode fixing Hardware Watchdogs } } } @@ -254,6 +255,7 @@ void Ld2410SendCommand(uint32_t command, uint8_t *val, uint32_t val_len) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("LD2: Send %*_H"), len, buffer); + LD2410Serial->setReadChunkMode(1); // Enable chunk mode introducing possible Hardware Watchdogs LD2410Serial->flush(); LD2410Serial->write(buffer, len); } @@ -401,6 +403,7 @@ void Ld2410Detect(void) { LD2410.buffer = (uint8_t*)malloc(LD2410_BUFFER_SIZE); // Default 64 if (!LD2410.buffer) { return; } LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2); +// LD2410Serial = new TasmotaSerial(Pin(GPIO_LD2410_RX), Pin(GPIO_LD2410_TX), 2, 1); if (LD2410Serial->begin(256000)) { if (LD2410Serial->hardwareSerial()) { ClaimSerial(); }