mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-22 18:26:30 +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]
|
||||
### Added
|
||||
- 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
|
||||
|
||||
|
@ -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 ``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 ``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 NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
|
||||
- Support for two phase power calibration using commands ``PowerSet2``, ``VoltageSet2`` and ``CurrentSet2``
|
||||
|
@ -134,12 +134,70 @@ bool TasmotaSerial::freeUart(void) {
|
||||
}
|
||||
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
|
||||
|
||||
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) {
|
||||
if (!m_valid) { return false; }
|
||||
|
||||
if (m_hardserial) {
|
||||
if (serial_buffer_size < 256) {
|
||||
serial_buffer_size = 256;
|
||||
}
|
||||
#ifdef ESP8266
|
||||
Serial.flush();
|
||||
Serial.begin(speed, (SerialConfig)config);
|
||||
@ -157,10 +215,10 @@ bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
||||
TSerial = new HardwareSerial(m_uart);
|
||||
#else
|
||||
if (0 == m_uart) {
|
||||
Serial.flush();
|
||||
Serial.end();
|
||||
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||
TSerial = &Serial;
|
||||
Serial.flush();
|
||||
Serial.end();
|
||||
delay(10); // Allow time to cleanup queues - if not used hangs ESP32
|
||||
TSerial = &Serial;
|
||||
} else {
|
||||
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
|
||||
}
|
||||
}
|
||||
TSerial->begin(speed, 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 (speed <= 9600) {
|
||||
// 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);
|
||||
}
|
||||
m_speed = speed;
|
||||
m_config = config;
|
||||
Esp32Begin();
|
||||
// Serial.printf("TSR: Using UART%d\n", m_uart);
|
||||
#endif // ESP32
|
||||
} 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);
|
||||
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);
|
||||
void end(bool turnOffDebug = true);
|
||||
bool hardwareSerial(void);
|
||||
@ -65,6 +68,7 @@ class TasmotaSerial : public Stream {
|
||||
bool isValidGPIOpin(int pin);
|
||||
#ifdef ESP32
|
||||
bool freeUart(void);
|
||||
void Esp32Begin(void);
|
||||
#endif
|
||||
size_t txWrite(uint8_t byte);
|
||||
|
||||
@ -80,18 +84,20 @@ class TasmotaSerial : public Stream {
|
||||
uint32_t m_bit_follow_metric = 0;
|
||||
uint32_t m_in_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_nwmode;
|
||||
bool m_hardserial;
|
||||
bool m_hardswap;
|
||||
bool m_high_speed = false;
|
||||
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
|
||||
|
||||
#ifdef ESP32
|
||||
uint32_t m_speed;
|
||||
uint32_t m_config;
|
||||
HardwareSerial *TSerial;
|
||||
int m_uart = 0;
|
||||
#endif
|
||||
|
@ -575,6 +575,7 @@
|
||||
// Commands xdrv_08_serial_bridge.ino
|
||||
#define D_CMND_SSERIALSEND "SSerialSend"
|
||||
#define D_CMND_SBAUDRATE "SBaudrate"
|
||||
#define D_CMND_SSERIALBUFFER "SSerialBuffer"
|
||||
#define D_CMND_SSERIALCONFIG "SSerialConfig"
|
||||
#define D_JSON_SSERIALRECEIVED "SSerialReceived"
|
||||
|
||||
|
@ -27,20 +27,22 @@
|
||||
|
||||
#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
|
||||
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 = {
|
||||
&CmndSSerialSend, &CmndSBaudrate, &CmndSSerialConfig };
|
||||
&CmndSSerialSend, &CmndSBaudrate, &CmndSSerialBuffer, &CmndSSerialConfig };
|
||||
|
||||
#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;
|
||||
|
||||
unsigned long serial_bridge_polling_window = 0;
|
||||
@ -263,6 +265,28 @@ void CmndSBaudrate(void) {
|
||||
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) {
|
||||
// See TasmotaSerialConfig for possible options
|
||||
// SSerialConfig 0..23 where 3 equals 8N1
|
||||
|
Loading…
x
Reference in New Issue
Block a user