diff --git a/CHANGELOG.md b/CHANGELOG.md index 864eda1c9..47eefda92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - HASPmota `cpicker` and `msgbox` (#22244) - Support for DALI on ESP8266 - Command ``DaliWeb 1`` to enable light control for DALI broadcast address +- Berry Serial `config` to change parity on-the-fly for RS-485 ### Breaking Changed diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp index ef8f87596..119b6d149 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.cpp @@ -476,6 +476,42 @@ size_t TasmotaSerial::write(uint8_t b) { return size; } +#ifdef ESP32 +// Add ability to change parity on the fly, for RS-485 +// See https://github.com/arendst/Tasmota/discussions/22272 +int32_t TasmotaSerial::setConfig(uint32_t config) { + + uint32_t data_bits_before = (m_config & 0xc) >> 2; + uint32_t parity_before = m_config & 0x3; + uint32_t stop_bits_before = (m_config & 0x30) >> 4; + + uint32_t data_bits = (config & 0xc) >> 2; + uint32_t parity = config & 0x3; + uint32_t stop_bits = (config & 0x30) >> 4; + + esp_err_t err; + + if (data_bits_before != data_bits) { + if (err = uart_set_word_length(m_uart, (uart_word_length_t) data_bits)) { + return (int32_t) err; + } + } + if (parity_before != parity) { + if (err = uart_set_parity(m_uart, (uart_parity_t) parity)) { + return (int32_t) err; + } + } + if (stop_bits_before != stop_bits) { + if (err = uart_set_stop_bits(m_uart, (uart_stop_bits_t) stop_bits)) { + return (int32_t) err; + } + } + + m_config = config; + return 0; // no error +} +#endif + #ifdef ESP8266 void IRAM_ATTR TasmotaSerial::rxRead(void) { if (!m_nwmode) { diff --git a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h index b380bec69..a5928d215 100644 --- a/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h +++ b/lib/default/TasmotaSerial-3.6.0/src/TasmotaSerial.h @@ -72,6 +72,7 @@ class TasmotaSerial : public Stream { #ifdef ESP32 uint32_t getUart(void) const { return m_uart; } HardwareSerial *getesp32hws(void) { return TSerial; } + int32_t setConfig(uint32_t config); #endif bool isValid(void) { return m_valid; } bool overflow(void); diff --git a/lib/libesp32/berry_tasmota/src/be_serial_lib.c b/lib/libesp32/berry_tasmota/src/be_serial_lib.c index 6592f270d..8de620c6b 100644 --- a/lib/libesp32/berry_tasmota/src/be_serial_lib.c +++ b/lib/libesp32/berry_tasmota/src/be_serial_lib.c @@ -10,6 +10,7 @@ extern int b_serial_init(bvm *vm); extern int b_config_tx_en(bvm *vm); +extern int b_serial_config(bvm *vm); extern int b_serial_deinit(bvm *vm); extern int b_serial_write(bvm *vm); @@ -92,5 +93,6 @@ class be_class_serial (scope: global, name: serial) { read, func(b_serial_read) available, func(b_serial_available) flush, func(b_serial_flush) + config, func(b_serial_config) } @const_object_info_end */ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_serial.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_serial.ino index 810daccf6..e0efe5ae0 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_serial.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_serial.ino @@ -86,6 +86,21 @@ extern "C" { be_return_nil(vm); } + // Berry: `config(config:int) -> nil or exception` + int32_t b_serial_config(struct bvm *vm); + int32_t b_serial_config(struct bvm *vm) { + be_getmember(vm, 1, ".p"); + TasmotaSerial * ser = (TasmotaSerial *) be_tocomptr(vm, -1); + if (ser) { + uint32_t config = be_toint(vm, 2); + int32_t err = ser->setConfig(config); + if (err) { + be_raisef(vm, "internal_error", "Unable to set serial config err %d", err); + } + } + be_return_nil(vm); + } + // Berry: `deinit(void)` int32_t b_serial_deinit(struct bvm *vm); int32_t b_serial_deinit(struct bvm *vm) {