Berry Serial `config` to change parity on-the-fly for RS-485 (#22285)

This commit is contained in:
s-hadinger 2024-10-13 22:15:47 +02:00 committed by GitHub
parent 0c7e8c67f3
commit 314fcd0dbc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 55 additions and 0 deletions

View File

@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- HASPmota `cpicker` and `msgbox` (#22244) - HASPmota `cpicker` and `msgbox` (#22244)
- Support for DALI on ESP8266 - Support for DALI on ESP8266
- Command ``DaliWeb 1`` to enable light control for DALI broadcast address - 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 ### Breaking Changed

View File

@ -476,6 +476,42 @@ size_t TasmotaSerial::write(uint8_t b) {
return size; 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 #ifdef ESP8266
void IRAM_ATTR TasmotaSerial::rxRead(void) { void IRAM_ATTR TasmotaSerial::rxRead(void) {
if (!m_nwmode) { if (!m_nwmode) {

View File

@ -72,6 +72,7 @@ class TasmotaSerial : public Stream {
#ifdef ESP32 #ifdef ESP32
uint32_t getUart(void) const { return m_uart; } uint32_t getUart(void) const { return m_uart; }
HardwareSerial *getesp32hws(void) { return TSerial; } HardwareSerial *getesp32hws(void) { return TSerial; }
int32_t setConfig(uint32_t config);
#endif #endif
bool isValid(void) { return m_valid; } bool isValid(void) { return m_valid; }
bool overflow(void); bool overflow(void);

View File

@ -10,6 +10,7 @@
extern int b_serial_init(bvm *vm); extern int b_serial_init(bvm *vm);
extern int b_config_tx_en(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_deinit(bvm *vm);
extern int b_serial_write(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) read, func(b_serial_read)
available, func(b_serial_available) available, func(b_serial_available)
flush, func(b_serial_flush) flush, func(b_serial_flush)
config, func(b_serial_config)
} }
@const_object_info_end */ @const_object_info_end */

View File

@ -86,6 +86,21 @@ extern "C" {
be_return_nil(vm); 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)` // Berry: `deinit(void)`
int32_t b_serial_deinit(struct bvm *vm); int32_t b_serial_deinit(struct bvm *vm);
int32_t b_serial_deinit(struct bvm *vm) { int32_t b_serial_deinit(struct bvm *vm) {