From 838e571d10d1b258d54bf80d29ec2419204c79fd Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 1 Oct 2019 22:58:08 +0200 Subject: [PATCH 1/2] Fix TasmotaSerial: move serial send to IRAM for high speed baud rates --- .../README.md | 0 .../examples/swsertest/swsertest.ino | 0 .../keywords.txt | 0 .../library.json | 2 +- .../library.properties | 2 +- .../src/TasmotaSerial.cpp | 62 ++++++++++++++----- .../src/TasmotaSerial.h | 2 + sonoff/_changelog.ino | 1 + 8 files changed, 50 insertions(+), 19 deletions(-) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/README.md (100%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/examples/swsertest/swsertest.ino (100%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/keywords.txt (100%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/library.json (94%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/library.properties (94%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/src/TasmotaSerial.cpp (88%) rename lib/{TasmotaSerial-2.4.0 => TasmotaSerial-2.4.1}/src/TasmotaSerial.h (97%) diff --git a/lib/TasmotaSerial-2.4.0/README.md b/lib/TasmotaSerial-2.4.1/README.md similarity index 100% rename from lib/TasmotaSerial-2.4.0/README.md rename to lib/TasmotaSerial-2.4.1/README.md diff --git a/lib/TasmotaSerial-2.4.0/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-2.4.1/examples/swsertest/swsertest.ino similarity index 100% rename from lib/TasmotaSerial-2.4.0/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-2.4.1/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-2.4.0/keywords.txt b/lib/TasmotaSerial-2.4.1/keywords.txt similarity index 100% rename from lib/TasmotaSerial-2.4.0/keywords.txt rename to lib/TasmotaSerial-2.4.1/keywords.txt diff --git a/lib/TasmotaSerial-2.4.0/library.json b/lib/TasmotaSerial-2.4.1/library.json similarity index 94% rename from lib/TasmotaSerial-2.4.0/library.json rename to lib/TasmotaSerial-2.4.1/library.json index cdce0deba..554d9ea9e 100644 --- a/lib/TasmotaSerial-2.4.0/library.json +++ b/lib/TasmotaSerial-2.4.1/library.json @@ -1,6 +1,6 @@ { "name": "TasmotaSerial", - "version": "2.4.0", + "version": "2.4.1", "keywords": [ "serial", "io", "TasmotaSerial" ], diff --git a/lib/TasmotaSerial-2.4.0/library.properties b/lib/TasmotaSerial-2.4.1/library.properties similarity index 94% rename from lib/TasmotaSerial-2.4.0/library.properties rename to lib/TasmotaSerial-2.4.1/library.properties index f1486dfab..b326d7404 100644 --- a/lib/TasmotaSerial-2.4.0/library.properties +++ b/lib/TasmotaSerial-2.4.1/library.properties @@ -1,5 +1,5 @@ name=TasmotaSerial -version=2.4.0 +version=2.4.1 author=Theo Arends maintainer=Theo Arends sentence=Implementation of software serial with hardware serial fallback for ESP8266. diff --git a/lib/TasmotaSerial-2.4.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp similarity index 88% rename from lib/TasmotaSerial-2.4.0/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp index 5ffcaf390..0a1386375 100644 --- a/lib/TasmotaSerial-2.4.0/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp @@ -213,6 +213,7 @@ int TasmotaSerial::available() #ifdef TM_SERIAL_USE_IRAM #define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)) if (!m_high_speed) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts +#define TM_SERIAL_WAIT_SND_FAST { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } #else @@ -221,31 +222,58 @@ int TasmotaSerial::available() #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } #endif +#ifdef TM_SERIAL_USE_IRAM +void ICACHE_RAM_ATTR TasmotaSerial::_fast_write(uint8_t b) { +#else +void TasmotaSerial::_fast_write(uint8_t b) { +#endif + uint32_t wait = m_bit_time; + uint32_t start = ESP.getCycleCount(); + // Start bit; + digitalWrite(m_tx_pin, LOW); + TM_SERIAL_WAIT_SND_FAST; + for (uint32_t i = 0; i < 8; i++) { + digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); + TM_SERIAL_WAIT_SND_FAST; + b >>= 1; + } + // Stop bit(s) + digitalWrite(m_tx_pin, HIGH); + for (uint32_t i = 0; i < m_stop_bits; i++) { + TM_SERIAL_WAIT_SND_FAST; + } +} + size_t TasmotaSerial::write(uint8_t b) { if (m_hardserial) { return Serial.write(b); } else { if (-1 == m_tx_pin) return 0; - if (m_high_speed) cli(); // Disable interrupts in order to get a clean transmit - uint32_t wait = m_bit_time; - //digitalWrite(m_tx_pin, HIGH); // already in HIGH mode - uint32_t start = ESP.getCycleCount(); - // Start bit; - digitalWrite(m_tx_pin, LOW); - TM_SERIAL_WAIT_SND; - for (uint32_t i = 0; i < 8; i++) { - digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); - TM_SERIAL_WAIT_SND; - b >>= 1; - } - // Stop bit(s) - digitalWrite(m_tx_pin, HIGH); - // re-enable interrupts during stop bits, it's not an issue if they are longer than expected - if (m_high_speed) sei(); - for (uint32_t i = 0; i < m_stop_bits; i++) { + if (m_high_speed) { + cli(); // Disable interrupts in order to get a clean transmit + _fast_write(b); + sei(); + } else { + uint32_t wait = m_bit_time; + //digitalWrite(m_tx_pin, HIGH); // already in HIGH mode + uint32_t start = ESP.getCycleCount(); + // Start bit; + digitalWrite(m_tx_pin, LOW); TM_SERIAL_WAIT_SND; + for (uint32_t i = 0; i < 8; i++) { + digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); + TM_SERIAL_WAIT_SND; + b >>= 1; + } + // Stop bit(s) + digitalWrite(m_tx_pin, HIGH); + // re-enable interrupts during stop bits, it's not an issue if they are longer than expected + for (uint32_t i = 0; i < m_stop_bits; i++) { + TM_SERIAL_WAIT_SND; + } } + return 1; } } diff --git a/lib/TasmotaSerial-2.4.0/src/TasmotaSerial.h b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h similarity index 97% rename from lib/TasmotaSerial-2.4.0/src/TasmotaSerial.h rename to lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h index 41f3cd0d7..81545f522 100644 --- a/lib/TasmotaSerial-2.4.0/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.h @@ -81,6 +81,8 @@ class TasmotaSerial : public Stream { bool m_high_speed = false; bool m_very_high_speed = false; // above 100000 bauds uint8_t *m_buffer; + + void _fast_write(uint8_t b); // IRAM minimized version }; #endif // TasmotaSerial_h diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 7739e9a0b..be07e8788 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -7,6 +7,7 @@ * Add initial support for shutters by Stefan Bode (#288) * Add command to MCP230xx: sensor29 pin,0/1/2 for OFF/ON/TOGGLE * Add initial support for PCF8574 I2C I/O Expander (currently output only) by Stefan Bode + * Fix TasmotaSerial: move serial send to IRAM for high speed baud rates * * 6.6.0.13 20190922 * Add command EnergyReset4 x,x to initialize total usage for two tarrifs From 3e7e882ee5a9ad774daae77b18e54d2f59898a5d Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 2 Oct 2019 17:20:03 +0200 Subject: [PATCH 2/2] Update TasmotaSerial.cpp --- lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp index 0a1386375..ebce5a496 100644 --- a/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-2.4.1/src/TasmotaSerial.cpp @@ -218,6 +218,7 @@ int TasmotaSerial::available() #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } #else #define TM_SERIAL_WAIT_SND { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } +#define TM_SERIAL_WAIT_SND_FAST { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV { while (ESP.getCycleCount() < (wait + start)); wait += m_bit_time; } #define TM_SERIAL_WAIT_RCV_LOOP { while (ESP.getCycleCount() < (wait + start)); } #endif