Make TasmotaSerial more generic

This commit is contained in:
Theo Arends 2020-04-20 14:54:08 +02:00
parent 18de0e2b2f
commit 6f207402ca
2 changed files with 37 additions and 56 deletions

View File

@ -1,5 +1,5 @@
/* /*
TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota TasmotaSerial.cpp - Implementation of software serial with hardware serial fallback for Tasmota
Copyright (C) 2020 Theo Arends Copyright (C) 2020 Theo Arends
@ -27,6 +27,8 @@ extern "C" {
#include <TasmotaSerial.h> #include <TasmotaSerial.h>
#ifdef ESP8266
// for STAGE and pre-2.6, we can have a single wrapper using attachInterruptArg() // for STAGE and pre-2.6, we can have a single wrapper using attachInterruptArg()
void ICACHE_RAM_ATTR callRxRead(void *self) { ((TasmotaSerial*)self)->rxRead(); }; void ICACHE_RAM_ATTR callRxRead(void *self) { ((TasmotaSerial*)self)->rxRead(); };
@ -79,9 +81,11 @@ static void (*ISRList[16])() = {
tms_isr_15 tms_isr_15
}; };
#ifdef ESP32 #else // ESP32
static uint8_t tasmota_serial_index = 3;
#endif static int tasmota_serial_index = 2; // Allow UART2 and UART1 only
#endif // ESP8266
TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size) TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback, int nwmode, int buffer_size)
{ {
@ -91,15 +95,13 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
m_stop_bits = 1; m_stop_bits = 1;
m_nwmode = nwmode; m_nwmode = nwmode;
serial_buffer_size = buffer_size; serial_buffer_size = buffer_size;
#ifdef ESP8266
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
return;
}
#endif
m_rx_pin = receive_pin; m_rx_pin = receive_pin;
m_tx_pin = transmit_pin; m_tx_pin = transmit_pin;
m_in_pos = m_out_pos = 0; m_in_pos = m_out_pos = 0;
#ifdef ESP8266 #ifdef ESP8266
if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) {
return;
}
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)))) { 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 = true; m_hardserial = true;
} }
@ -127,14 +129,16 @@ TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fal
digitalWrite(m_tx_pin, HIGH); digitalWrite(m_tx_pin, HIGH);
} }
} }
#else #else // ESP32
if (transmit_pin > 33) { return; } // GPIO34 - GPIO39 are Input only
m_hardserial = true; m_hardserial = true;
#endif #endif // ESP8266 - ESP32
m_valid = true; m_valid = true;
} }
TasmotaSerial::~TasmotaSerial() TasmotaSerial::~TasmotaSerial()
{ {
#ifdef ESP8266
if (!m_hardserial) { if (!m_hardserial) {
if (m_rx_pin > -1) { if (m_rx_pin > -1) {
detachInterrupt(m_rx_pin); detachInterrupt(m_rx_pin);
@ -144,6 +148,7 @@ TasmotaSerial::~TasmotaSerial()
} }
} }
} }
#endif // ESP8266
} }
bool TasmotaSerial::isValidGPIOpin(int pin) bool TasmotaSerial::isValidGPIOpin(int pin)
@ -165,26 +170,16 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
Serial.swap(); Serial.swap();
} }
#else // ESP32 #else // ESP32
tasmota_serial_index--; if (tasmota_serial_index > 0) { // We only support UART1 and UART2 and keep UART0 for debugging
if (2 == tasmota_serial_index) { m_uart = tasmota_serial_index;
m_uart = 2; tasmota_serial_index--;
Serial2.flush(); TSerial = new HardwareSerial(m_uart);
if (2 == m_stop_bits) { if (2 == m_stop_bits) {
Serial2.begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin); TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin);
} else { } else {
Serial2.begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin); TSerial->begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin);
} }
} } else {
else if (1 == tasmota_serial_index) {
m_uart = 1;
Serial1.flush();
if (2 == m_stop_bits) {
Serial1.begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin);
} else {
Serial1.begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin);
}
}
else {
m_valid = false; m_valid = false;
} }
// Serial.printf("TSR: Using UART%d\n", m_uart); // Serial.printf("TSR: Using UART%d\n", m_uart);
@ -216,11 +211,7 @@ void TasmotaSerial::flush() {
#ifdef ESP8266 #ifdef ESP8266
Serial.flush(); Serial.flush();
#else #else
if (2 == m_uart) { TSerial->flush();
Serial2.flush();
} else {
Serial1.flush();
}
#endif #endif
} else { } else {
m_in_pos = m_out_pos = 0; m_in_pos = m_out_pos = 0;
@ -232,11 +223,7 @@ int TasmotaSerial::peek() {
#ifdef ESP8266 #ifdef ESP8266
return Serial.peek(); return Serial.peek();
#else #else
if (2 == m_uart) { return TSerial->peek();
return Serial2.peek();
} else{
return Serial1.peek();
}
#endif #endif
} else { } 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;
@ -250,11 +237,7 @@ int TasmotaSerial::read()
#ifdef ESP8266 #ifdef ESP8266
return Serial.read(); return Serial.read();
#else #else
if (2 == m_uart) { return TSerial->read();
return Serial2.read();
} else {
return Serial1.read();
}
#endif #endif
} else { } 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;
@ -270,11 +253,7 @@ int TasmotaSerial::available()
#ifdef ESP8266 #ifdef ESP8266
return Serial.available(); return Serial.available();
#else #else
if (2 == m_uart) { return TSerial->available();
return Serial2.available();
} else {
return Serial1.available();
}
#endif #endif
} else { } else {
int avail = m_in_pos - m_out_pos; int avail = m_in_pos - m_out_pos;
@ -323,11 +302,7 @@ size_t TasmotaSerial::write(uint8_t b)
#ifdef ESP8266 #ifdef ESP8266
return Serial.write(b); return Serial.write(b);
#else #else
if (2 == m_uart) { return TSerial->write(b);
return Serial2.write(b);
} else {
return Serial1.write(b);
}
#endif #endif
} else { } else {
if (-1 == m_tx_pin) return 0; if (-1 == m_tx_pin) return 0;

View File

@ -1,5 +1,5 @@
/* /*
TasmotaSerial.h - Minimal implementation of software serial for Tasmota TasmotaSerial.h - Implementation of software serial with hardware serial fallback for Tasmota
Copyright (C) 2020 Theo Arends Copyright (C) 2020 Theo Arends
@ -36,6 +36,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <Stream.h> #include <Stream.h>
#ifdef ESP32
#include <HardwareSerial.h>
#endif
class TasmotaSerial : public Stream { class TasmotaSerial : public Stream {
public: 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);
@ -86,11 +90,13 @@ class TasmotaSerial : public Stream {
bool m_very_high_speed = false; // above 100000 bauds bool m_very_high_speed = false; // above 100000 bauds
uint8_t *m_buffer; uint8_t *m_buffer;
void _fast_write(uint8_t b); // IRAM minimized version
#ifdef ESP32 #ifdef ESP32
uint8_t m_uart = 0; HardwareSerial *TSerial;
int m_uart = 0;
#endif #endif
void _fast_write(uint8_t b); // IRAM minimized version
}; };
#endif // TasmotaSerial_h #endif // TasmotaSerial_h