mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Add command `SSerialBuffer 64..256
`
Add command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) (#17120)
This commit is contained in:
parent
3a20159dd5
commit
0674f9b0b6
@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
## [12.2.0.5]
|
## [12.2.0.5]
|
||||||
### Added
|
### Added
|
||||||
- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
|
- ESP32 DS18x20 parasitic power usage when defining W1_PARASITE_POWER (#17112)
|
||||||
|
- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) (#17120)
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
|
@ -112,6 +112,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
|
|||||||
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
- Command ``SetOption47 1..255`` to delay power on relay state in seconds reducing power surge. ``SO47 1`` delays until network connected. ``SO47 2`` delays until mqtt connected
|
||||||
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
|
- Command ``RgxClients`` for range extender clients list [#17048](https://github.com/arendst/Tasmota/issues/17048)
|
||||||
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
|
- Command ``RgxPort [tcp|udp], gateway_port, client_mac, client_port`` for range extender port forwardings [#17092](https://github.com/arendst/Tasmota/issues/17092)
|
||||||
|
- Command ``SSerialBuffer 64..256`` to change software serial bridge receive buffer size from default (64) to max local buffer size (256) [#17120](https://github.com/arendst/Tasmota/issues/17120)
|
||||||
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
|
- Command ``SwitchMode 16`` sending only MQTT message on inverted switch change [#17028](https://github.com/arendst/Tasmota/issues/17028)
|
||||||
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
|
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
|
||||||
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
||||||
|
@ -134,12 +134,70 @@ bool TasmotaSerial::freeUart(void) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TasmotaSerial::Esp32Begin(void) {
|
||||||
|
TSerial->begin(m_speed, m_config, m_rx_pin, m_tx_pin);
|
||||||
|
// For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
|
||||||
|
if (m_speed <= 9600) {
|
||||||
|
// At 9600, 10 chars are ~10ms
|
||||||
|
uart_set_rx_full_threshold(m_uart, 10);
|
||||||
|
} else if (m_speed < 115200) {
|
||||||
|
// At 19200, 120 chars are ~60ms
|
||||||
|
// At 76800, 120 chars are ~15ms
|
||||||
|
uart_set_rx_full_threshold(m_uart, 120);
|
||||||
|
} else {
|
||||||
|
// At 115200, 256 chars are ~20ms
|
||||||
|
// Zigbee requires to keep frames together, i.e. 256 bytes max
|
||||||
|
uart_set_rx_full_threshold(m_uart, 256);
|
||||||
|
}
|
||||||
|
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
|
||||||
|
if (m_speed < 115200) {
|
||||||
|
// At 76800 the timeout is ~1ms
|
||||||
|
uart_set_rx_timeout(m_uart, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
size_t TasmotaSerial::setRxBufferSize(size_t size) {
|
||||||
|
if (size != serial_buffer_size) {
|
||||||
|
if (m_hardserial) {
|
||||||
|
if (size > 256) { // Default hardware serial Rx buffer size
|
||||||
|
#ifdef ESP8266
|
||||||
|
serial_buffer_size = size;
|
||||||
|
Serial.setRxBufferSize(serial_buffer_size);
|
||||||
|
#endif // ESP8266
|
||||||
|
#ifdef ESP32
|
||||||
|
if (TSerial) {
|
||||||
|
// RX Buffer can't be resized when Serial is already running
|
||||||
|
serial_buffer_size = size;
|
||||||
|
TSerial->flush();
|
||||||
|
TSerial->end();
|
||||||
|
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||||
|
TSerial->setRxBufferSize(serial_buffer_size);
|
||||||
|
Esp32Begin();
|
||||||
|
}
|
||||||
|
#endif // ESP32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_buffer) {
|
||||||
|
uint8_t *m_buffer_temp = (uint8_t*)malloc(size); // Allocate new buffer
|
||||||
|
if (m_buffer_temp) { // If succesful de-allocate old buffer
|
||||||
|
free(m_buffer);
|
||||||
|
m_buffer = m_buffer_temp;
|
||||||
|
serial_buffer_size = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return serial_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
||||||
if (!m_valid) { return false; }
|
if (!m_valid) { return false; }
|
||||||
|
|
||||||
if (m_hardserial) {
|
if (m_hardserial) {
|
||||||
|
if (serial_buffer_size < 256) {
|
||||||
|
serial_buffer_size = 256;
|
||||||
|
}
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
Serial.begin(speed, (SerialConfig)config);
|
Serial.begin(speed, (SerialConfig)config);
|
||||||
@ -157,10 +215,10 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
|||||||
TSerial = new HardwareSerial(m_uart);
|
TSerial = new HardwareSerial(m_uart);
|
||||||
#else
|
#else
|
||||||
if (0 == m_uart) {
|
if (0 == m_uart) {
|
||||||
Serial.flush();
|
Serial.flush();
|
||||||
Serial.end();
|
Serial.end();
|
||||||
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||||
TSerial = &Serial;
|
TSerial = &Serial;
|
||||||
} else {
|
} else {
|
||||||
TSerial = new HardwareSerial(m_uart);
|
TSerial = new HardwareSerial(m_uart);
|
||||||
}
|
}
|
||||||
@ -173,25 +231,9 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
|||||||
return m_valid; // As we currently only support hardware serial on ESP32 it's safe to exit here
|
return m_valid; // As we currently only support hardware serial on ESP32 it's safe to exit here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
|
m_speed = speed;
|
||||||
// For low bit rate, below 9600, set the Full RX threshold at 10 bytes instead of the default 120
|
m_config = config;
|
||||||
if (speed <= 9600) {
|
Esp32Begin();
|
||||||
// At 9600, 10 chars are ~10ms
|
|
||||||
uart_set_rx_full_threshold(m_uart, 10);
|
|
||||||
} else if (speed < 115200) {
|
|
||||||
// At 19200, 120 chars are ~60ms
|
|
||||||
// At 76800, 120 chars are ~15ms
|
|
||||||
uart_set_rx_full_threshold(m_uart, 120);
|
|
||||||
} else {
|
|
||||||
// At 115200, 256 chars are ~20ms
|
|
||||||
// Zigbee requires to keep frames together, i.e. 256 bytes max
|
|
||||||
uart_set_rx_full_threshold(m_uart, 256);
|
|
||||||
}
|
|
||||||
// For bitrate below 115200, set the Rx time out to 6 chars instead of the default 10
|
|
||||||
if (speed < 115200) {
|
|
||||||
// At 76800 the timeout is ~1ms
|
|
||||||
uart_set_rx_timeout(m_uart, 6);
|
|
||||||
}
|
|
||||||
// Serial.printf("TSR: Using UART%d\n", m_uart);
|
// Serial.printf("TSR: Using UART%d\n", m_uart);
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,6 +40,9 @@ class TasmotaSerial : public Stream {
|
|||||||
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();
|
virtual ~TasmotaSerial();
|
||||||
|
|
||||||
|
size_t setRxBufferSize(size_t size);
|
||||||
|
size_t getRxBufferSize() { return serial_buffer_size; }
|
||||||
|
|
||||||
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
|
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
|
||||||
void end(bool turnOffDebug = true);
|
void end(bool turnOffDebug = true);
|
||||||
bool hardwareSerial(void);
|
bool hardwareSerial(void);
|
||||||
@ -65,6 +68,7 @@ class TasmotaSerial : public Stream {
|
|||||||
bool isValidGPIOpin(int pin);
|
bool isValidGPIOpin(int pin);
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
bool freeUart(void);
|
bool freeUart(void);
|
||||||
|
void Esp32Begin(void);
|
||||||
#endif
|
#endif
|
||||||
size_t txWrite(uint8_t byte);
|
size_t txWrite(uint8_t byte);
|
||||||
|
|
||||||
@ -80,18 +84,20 @@ class TasmotaSerial : public Stream {
|
|||||||
uint32_t m_bit_follow_metric = 0;
|
uint32_t m_bit_follow_metric = 0;
|
||||||
uint32_t m_in_pos;
|
uint32_t m_in_pos;
|
||||||
uint32_t m_out_pos;
|
uint32_t m_out_pos;
|
||||||
uint32_t serial_buffer_size;
|
uint32_t serial_buffer_size = TM_SERIAL_BUFFER_SIZE;
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
bool m_nwmode;
|
bool m_nwmode;
|
||||||
bool m_hardserial;
|
bool m_hardserial;
|
||||||
bool m_hardswap;
|
bool m_hardswap;
|
||||||
bool m_high_speed = false;
|
bool m_high_speed = false;
|
||||||
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 = nullptr;
|
||||||
|
|
||||||
void _fast_write(uint8_t b); // IRAM minimized version
|
void _fast_write(uint8_t b); // IRAM minimized version
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
uint32_t m_speed;
|
||||||
|
uint32_t m_config;
|
||||||
HardwareSerial *TSerial;
|
HardwareSerial *TSerial;
|
||||||
int m_uart = 0;
|
int m_uart = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -575,6 +575,7 @@
|
|||||||
// Commands xdrv_08_serial_bridge.ino
|
// Commands xdrv_08_serial_bridge.ino
|
||||||
#define D_CMND_SSERIALSEND "SSerialSend"
|
#define D_CMND_SSERIALSEND "SSerialSend"
|
||||||
#define D_CMND_SBAUDRATE "SBaudrate"
|
#define D_CMND_SBAUDRATE "SBaudrate"
|
||||||
|
#define D_CMND_SSERIALBUFFER "SSerialBuffer"
|
||||||
#define D_CMND_SSERIALCONFIG "SSerialConfig"
|
#define D_CMND_SSERIALCONFIG "SSerialConfig"
|
||||||
#define D_JSON_SSERIALRECEIVED "SSerialReceived"
|
#define D_JSON_SSERIALRECEIVED "SSerialReceived"
|
||||||
|
|
||||||
|
@ -27,20 +27,22 @@
|
|||||||
|
|
||||||
#define USE_SERIAL_BRIDGE_TEE
|
#define USE_SERIAL_BRIDGE_TEE
|
||||||
|
|
||||||
#ifdef ESP8266
|
|
||||||
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = MIN_INPUT_BUFFER_SIZE;
|
|
||||||
#else
|
|
||||||
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix
|
const char kSerialBridgeCommands[] PROGMEM = "|" // No prefix
|
||||||
D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALCONFIG;
|
D_CMND_SSERIALSEND "|" D_CMND_SBAUDRATE "|" D_CMND_SSERIALBUFFER "|" D_CMND_SSERIALCONFIG;
|
||||||
|
|
||||||
void (* const SerialBridgeCommand[])(void) PROGMEM = {
|
void (* const SerialBridgeCommand[])(void) PROGMEM = {
|
||||||
&CmndSSerialSend, &CmndSBaudrate, &CmndSSerialConfig };
|
&CmndSSerialSend, &CmndSBaudrate, &CmndSSerialBuffer, &CmndSSerialConfig };
|
||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = TM_SERIAL_BUFFER_SIZE; // 64 (TasmotaSerial.h)
|
||||||
|
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
|
||||||
|
#else
|
||||||
|
const uint16_t SERIAL_BRIDGE_BUFFER_MIN_SIZE = MIN_INPUT_BUFFER_SIZE; // 256
|
||||||
|
const uint16_t SERIAL_BRIDGE_BUFFER_SIZE = INPUT_BUFFER_SIZE; // 800
|
||||||
|
#endif
|
||||||
|
|
||||||
TasmotaSerial *SerialBridgeSerial = nullptr;
|
TasmotaSerial *SerialBridgeSerial = nullptr;
|
||||||
|
|
||||||
unsigned long serial_bridge_polling_window = 0;
|
unsigned long serial_bridge_polling_window = 0;
|
||||||
@ -263,6 +265,28 @@ void CmndSBaudrate(void) {
|
|||||||
ResponseCmndNumber(Settings->sbaudrate * 300);
|
ResponseCmndNumber(Settings->sbaudrate * 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CmndSSerialBuffer(void) {
|
||||||
|
// Allow non-pesistent serial receive buffer size change
|
||||||
|
if (SerialBridgeSerial->hardwareSerial()) {
|
||||||
|
// between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
|
||||||
|
CmndSerialBuffer();
|
||||||
|
} else {
|
||||||
|
// ESP8266 (software serial): between TM_SERIAL_BUFFER_SIZE and SERIAL_BRIDGE_BUFFER_SIZE characters
|
||||||
|
// ESP32 (hardware serial only): between MIN_INPUT_BUFFER_SIZE and MAX_INPUT_BUFFER_SIZE characters
|
||||||
|
if (XdrvMailbox.data_len > 0) {
|
||||||
|
size_t size = XdrvMailbox.payload;
|
||||||
|
if (XdrvMailbox.payload < SERIAL_BRIDGE_BUFFER_MIN_SIZE) {
|
||||||
|
size = SERIAL_BRIDGE_BUFFER_MIN_SIZE; // 64 / 256
|
||||||
|
}
|
||||||
|
else if (XdrvMailbox.payload > SERIAL_BRIDGE_BUFFER_SIZE) {
|
||||||
|
size = SERIAL_BRIDGE_BUFFER_SIZE; // 256 / 800
|
||||||
|
}
|
||||||
|
SerialBridgeSerial->setRxBufferSize(size);
|
||||||
|
}
|
||||||
|
ResponseCmndNumber(SerialBridgeSerial->getRxBufferSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CmndSSerialConfig(void) {
|
void CmndSSerialConfig(void) {
|
||||||
// See TasmotaSerialConfig for possible options
|
// See TasmotaSerialConfig for possible options
|
||||||
// SSerialConfig 0..23 where 3 equals 8N1
|
// SSerialConfig 0..23 where 3 equals 8N1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user