From 82151d25a526e0afc571ad3dc0cfb49215edeb5f Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 29 Aug 2019 14:22:44 +0200 Subject: [PATCH] Optimize TasmotaSerial lib to lower iram usage Optimize TasmotaSerial lib to lower iram usage --- .../README.md | 0 .../examples/swsertest/swsertest.ino | 0 .../keywords.txt | 0 .../library.json | 0 .../library.properties | 0 .../src/TasmotaSerial.cpp | 177 +++++++++--------- .../src/TasmotaSerial.h | 24 +-- 7 files changed, 100 insertions(+), 101 deletions(-) rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/README.md (100%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/examples/swsertest/swsertest.ino (100%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/keywords.txt (100%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/library.json (100%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/library.properties (100%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/src/TasmotaSerial.cpp (69%) mode change 100755 => 100644 rename lib/{TasmotaSerial-2.3.2 => TasmotaSerial-2.3.3}/src/TasmotaSerial.h (85%) mode change 100755 => 100644 diff --git a/lib/TasmotaSerial-2.3.2/README.md b/lib/TasmotaSerial-2.3.3/README.md old mode 100755 new mode 100644 similarity index 100% rename from lib/TasmotaSerial-2.3.2/README.md rename to lib/TasmotaSerial-2.3.3/README.md diff --git a/lib/TasmotaSerial-2.3.2/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-2.3.3/examples/swsertest/swsertest.ino old mode 100755 new mode 100644 similarity index 100% rename from lib/TasmotaSerial-2.3.2/examples/swsertest/swsertest.ino rename to lib/TasmotaSerial-2.3.3/examples/swsertest/swsertest.ino diff --git a/lib/TasmotaSerial-2.3.2/keywords.txt b/lib/TasmotaSerial-2.3.3/keywords.txt old mode 100755 new mode 100644 similarity index 100% rename from lib/TasmotaSerial-2.3.2/keywords.txt rename to lib/TasmotaSerial-2.3.3/keywords.txt diff --git a/lib/TasmotaSerial-2.3.2/library.json b/lib/TasmotaSerial-2.3.3/library.json old mode 100755 new mode 100644 similarity index 100% rename from lib/TasmotaSerial-2.3.2/library.json rename to lib/TasmotaSerial-2.3.3/library.json diff --git a/lib/TasmotaSerial-2.3.2/library.properties b/lib/TasmotaSerial-2.3.3/library.properties old mode 100755 new mode 100644 similarity index 100% rename from lib/TasmotaSerial-2.3.2/library.properties rename to lib/TasmotaSerial-2.3.3/library.properties diff --git a/lib/TasmotaSerial-2.3.2/src/TasmotaSerial.cpp b/lib/TasmotaSerial-2.3.3/src/TasmotaSerial.cpp old mode 100755 new mode 100644 similarity index 69% rename from lib/TasmotaSerial-2.3.2/src/TasmotaSerial.cpp rename to lib/TasmotaSerial-2.3.3/src/TasmotaSerial.cpp index a6b42bf03..42b15937f --- a/lib/TasmotaSerial-2.3.2/src/TasmotaSerial.cpp +++ b/lib/TasmotaSerial-2.3.3/src/TasmotaSerial.cpp @@ -79,8 +79,8 @@ static void (*ISRList[16])() = { TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) { m_valid = false; - m_hardserial = 0; - m_hardswap = 0; + m_hardserial = false; + m_hardswap = false; m_stop_bits = 1; m_nwmode = nwmode; if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { @@ -90,11 +90,11 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_tx_pin = transmit_pin; m_in_pos = m_out_pos = 0; if (hardware_fallback && (((3 == m_rx_pin) && (1 == m_tx_pin)) || ((3 == m_rx_pin) && (-1 == m_tx_pin)) || ((-1 == m_rx_pin) && (1 == m_tx_pin)))) { - m_hardserial = 1; + m_hardserial = true; } else if ((2 == hardware_fallback) && (((13 == m_rx_pin) && (15 == m_tx_pin)) || ((13 == m_rx_pin) && (-1 == m_tx_pin)) || ((-1 == m_rx_pin) && (15 == m_tx_pin)))) { - m_hardserial = 1; - m_hardswap = 1; + m_hardserial = true; + m_hardswap = true; } else { if (m_rx_pin > -1) { @@ -104,8 +104,7 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal m_bit_time = ESP.getCpuFreqMHz() * 1000000 / TM_SERIAL_BAUDRATE; pinMode(m_rx_pin, INPUT); tms_obj_list[m_rx_pin] = this; - if (m_nwmode) attachInterrupt(m_rx_pin, ISRList[m_rx_pin], CHANGE); - else attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING); + attachInterrupt(m_rx_pin, ISRList[m_rx_pin], (m_nwmode) ? CHANGE : FALLING); } if (m_tx_pin > -1) { pinMode(m_tx_pin, OUTPUT); @@ -184,7 +183,7 @@ int TasmotaSerial::read() return Serial.read(); } else { if ((-1 == m_rx_pin) || (m_in_pos == m_out_pos)) return -1; - uint8_t ch = m_buffer[m_out_pos]; + uint32_t ch = m_buffer[m_out_pos]; m_out_pos = (m_out_pos +1) % serial_buffer_size; return ch; } @@ -214,19 +213,19 @@ size_t TasmotaSerial::write(uint8_t b) } else { if (-1 == m_tx_pin) return 0; if (m_high_speed) cli(); // Disable interrupts in order to get a clean transmit - unsigned long wait = m_bit_time; + uint32_t wait = m_bit_time; digitalWrite(m_tx_pin, HIGH); - unsigned long start = ESP.getCycleCount(); + uint32_t start = ESP.getCycleCount(); // Start bit; digitalWrite(m_tx_pin, LOW); TM_SERIAL_WAIT; - for (int i = 0; i < 8; i++) { + for (uint32_t i = 0; i < 8; i++) { digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); TM_SERIAL_WAIT; b >>= 1; } // Stop bit(s) - for (int i = 0; i < m_stop_bits; i++) { + for (uint32_t i = 0; i < m_stop_bits; i++) { digitalWrite(m_tx_pin, HIGH); TM_SERIAL_WAIT; } @@ -242,89 +241,89 @@ void ICACHE_RAM_ATTR TasmotaSerial::rxRead() void TasmotaSerial::rxRead() { #endif -if (!m_nwmode) { - // Advance the starting point for the samples but compensate for the - // initial delay which occurs before the interrupt is delivered - unsigned long wait = m_bit_time + m_bit_time/3 - 500; - unsigned long start = ESP.getCycleCount(); - uint8_t rec = 0; - for (int i = 0; i < 8; i++) { + if (!m_nwmode) { + // 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_time + m_bit_time/3 - 500; + uint32_t start = ESP.getCycleCount(); + uint8_t rec = 0; + for (uint32_t i = 0; i < 8; i++) { + TM_SERIAL_WAIT; + rec >>= 1; + if (digitalRead(m_rx_pin)) rec |= 0x80; + } + // Stop bit(s) TM_SERIAL_WAIT; - rec >>= 1; - if (digitalRead(m_rx_pin)) rec |= 0x80; - } - // Stop bit(s) - TM_SERIAL_WAIT; - if (2 == m_stop_bits) { - digitalRead(m_rx_pin); - TM_SERIAL_WAIT; - } - // Store the received value in the buffer unless we have an overflow - unsigned int next = (m_in_pos+1) % serial_buffer_size; - if (next != (int)m_out_pos) { - m_buffer[m_in_pos] = rec; - m_in_pos = next; - } - // Must clear this bit in the interrupt register, - // it gets set even when interrupts are disabled - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); -} else { - uint8_t diff; - uint8_t level; - - #define LASTBIT 9 - - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); - - level=digitalRead(m_rx_pin); - - if (!level && !ss_index) { - // start condition - ss_bstart=ESP.getCycleCount()-(m_bit_time/4); - ss_byte=0; - ss_index++; - //digitalWrite(1, LOW); + if (2 == m_stop_bits) { + digitalRead(m_rx_pin); + TM_SERIAL_WAIT; + } + // Store the received value in the buffer unless we have an overflow + uint32_t next = (m_in_pos+1) % serial_buffer_size; + if (next != (int)m_out_pos) { + m_buffer[m_in_pos] = rec; + m_in_pos = next; + } + // Must clear this bit in the interrupt register, + // it gets set even when interrupts are disabled + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); } else { - // now any bit changes go here - // calc bit number - diff=(ESP.getCycleCount()-ss_bstart)/m_bit_time; - //digitalWrite(1, level); + uint32_t diff; + uint32_t level; - if (!level && diff>LASTBIT) { - // start bit of next byte, store and restart - // leave irq at change - for (uint8_t i=ss_index;i<=LASTBIT;i++) { - ss_byte|=(1<ss_byte>>1); - unsigned int next = (m_in_pos+1) % serial_buffer_size; - if (next != (int)m_out_pos) { - m_buffer[m_in_pos] = ss_byte>>1; - m_in_pos = next; - } + #define LASTBIT 9 - ss_bstart=ESP.getCycleCount()-(m_bit_time/4); - ss_byte=0; - ss_index=1; - return; - } - if (diff>=LASTBIT) { - // bit zero was 0, - //stobyte(0,ssp->ss_byte>>1); - unsigned int next = (m_in_pos+1) % serial_buffer_size; - if (next != (int)m_out_pos) { - m_buffer[m_in_pos] = ss_byte>>1; - m_in_pos = next; - } - ss_byte=0; - ss_index=0; + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); + + level = digitalRead(m_rx_pin); + + if (!level && !ss_index) { + // start condition + ss_bstart = ESP.getCycleCount() - (m_bit_time / 4); + ss_byte = 0; + ss_index++; + //digitalWrite(1, LOW); } else { - // shift in - for (uint8_t i=ss_index;i LASTBIT) { + // start bit of next byte, store and restart + // leave irq at change + for (uint32_t i = ss_index; i <= LASTBIT; i++) { + ss_byte |= (1 << i); + } + //stobyte(0,ssp->ss_byte>>1); + uint32_t next = (m_in_pos + 1) % serial_buffer_size; + if (next != (uint32_t)m_out_pos) { + m_buffer[m_in_pos] = ss_byte >> 1; + m_in_pos = next; + } + + ss_bstart = ESP.getCycleCount() - (m_bit_time / 4); + ss_byte = 0; + ss_index = 1; + return; + } + if (diff >= LASTBIT) { + // bit zero was 0, + //stobyte(0,ssp->ss_byte>>1); + uint32_t next = (m_in_pos + 1) % serial_buffer_size; + if (next != (uint32_t)m_out_pos) { + m_buffer[m_in_pos] = ss_byte >> 1; + m_in_pos = next; + } + ss_byte = 0; + ss_index = 0; + } else { + // shift in + for (uint32_t i = ss_index; i < diff; i++) { + if (!level) ss_byte |= (1 << i); + } + ss_index = diff; } - ss_index=diff; } } } -} diff --git a/lib/TasmotaSerial-2.3.2/src/TasmotaSerial.h b/lib/TasmotaSerial-2.3.3/src/TasmotaSerial.h old mode 100755 new mode 100644 similarity index 85% rename from lib/TasmotaSerial-2.3.2/src/TasmotaSerial.h rename to lib/TasmotaSerial-2.3.3/src/TasmotaSerial.h index 57adb9e26..8c6340977 --- a/lib/TasmotaSerial-2.3.2/src/TasmotaSerial.h +++ b/lib/TasmotaSerial-2.3.3/src/TasmotaSerial.h @@ -20,7 +20,7 @@ #ifndef TasmotaSerial_h #define TasmotaSerial_h /*********************************************************************************************\ - * TasmotaSerial supports up to 115200 baud with fixed buffer size of 64 bytes using optional no iram + * TasmotaSerial supports up to 115200 baud with default buffer size of 64 bytes using optional no iram * * Based on EspSoftwareSerial v3.4.3 by Peter Lerup (https://github.com/plerup/espsoftwareserial) \*********************************************************************************************/ @@ -38,7 +38,7 @@ class TasmotaSerial : public Stream { public: - TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0,int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE); + TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE); virtual ~TasmotaSerial(); bool begin(long speed, int stop_bits = 1); @@ -60,22 +60,22 @@ class TasmotaSerial : public Stream { size_t txWrite(uint8_t byte); // Member variables + int m_rx_pin; + int m_tx_pin; + uint32_t m_stop_bits; + uint32_t ss_byte; + uint32_t ss_bstart; + uint32_t ss_index; + uint32_t m_bit_time; + uint32_t m_in_pos; + uint32_t m_out_pos; + uint32_t serial_buffer_size; bool m_valid; bool m_nwmode; bool m_hardserial; bool m_hardswap; bool m_high_speed; - int m_rx_pin; - int m_tx_pin; - int m_stop_bits; - int ss_byte; - unsigned long ss_bstart; - int ss_index; - unsigned long m_bit_time; - unsigned int m_in_pos; - unsigned int m_out_pos; uint8_t *m_buffer; - int serial_buffer_size; }; #endif // TasmotaSerial_h