Merge branch 'dev'

This commit is contained in:
proddy
2025-12-31 21:26:15 +01:00
parent eaa277fef0
commit 28135c225b
385 changed files with 40221 additions and 38187 deletions

View File

@@ -1,6 +1,6 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2024 emsesp.org - proddy, MichaelDvP
* Copyright 2020-2025 emsesp.org - proddy, MichaelDvP
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,9 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* ESP32 UART port by @ArwedL and improved by @MichaelDvP. See https://github.com/emsesp/EMS-ESP/issues/380
*/
// ESP32 UART port by @ArwedL and improved by @MichaelDvP. See https://github.com/emsesp/EMS-ESP/issues/380
#ifndef EMSESP_STANDALONE
@@ -33,13 +31,12 @@
namespace emsesp {
uint8_t EMSuart::last_tx_src_ = 0;
static TaskHandle_t xHandle;
static QueueHandle_t uart_queue;
uint8_t tx_mode_ = 0xFF;
uint8_t tx_mode_ = EMS_TXMODE_INIT;
uint32_t inverse_mask = 0;
/*
* receive task, wait for break and call incoming_telegram
*/
// receive task, wait for break and call incoming_telegram
void EMSuart::uart_event_task(void * pvParameters) {
uart_event_t event;
uint8_t telegram[EMS_MAXBUFFERSIZE];
@@ -55,8 +52,7 @@ void EMSuart::uart_event_task(void * pvParameters) {
uart_read_bytes(EMSUART_NUM, telegram, length, portMAX_DELAY);
EMSESP::incoming_telegram(telegram, (uint8_t)(length - 1));
} else { // flush buffer up to break
uint8_t buf[length];
uart_read_bytes(EMSUART_NUM, buf, length, portMAX_DELAY);
uart_flush_input(EMSUART_NUM);
}
length = 0;
} else if (event.type == UART_BUFFER_FULL) {
@@ -68,19 +64,20 @@ void EMSuart::uart_event_task(void * pvParameters) {
vTaskDelete(NULL);
}
/*
* init UART driver
*/
// initialize UART driver
void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t tx_gpio) {
if (tx_mode_ == 0xFF) {
uart_config_t uart_config = {
.baud_rate = EMSUART_BAUD,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0, // not used - https://docs.espressif.com/projects/esp-idf/en/v3.3.6/api-reference/peripherals/uart.html
.source_clk = UART_SCLK_APB,
if (tx_mode_ == EMS_TXMODE_INIT) {
uart_config_t uart_config = {.baud_rate = EMSUART_BAUD,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 0,
.source_clk = UART_SCLK_APB
#if ESP_ARDUINO_VERSION_MAJOR >= 3
,
.flags = {0, 0}
#endif
};
#if defined(EMSUART_RX_INVERT)
inverse_mask |= UART_SIGNAL_RXD_INV;
@@ -91,30 +88,33 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
uart_param_config(EMSUART_NUM, &uart_config);
uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_set_line_inverse(EMSUART_NUM, inverse_mask);
uart_driver_install(EMSUART_NUM, 129, 0, (EMS_MAXBUFFERSIZE + 1) * 2, &uart_queue, 0); // buffer must be > fifo
uart_driver_install(EMSUART_NUM, UART_FIFO_LEN + 1, 0, (EMS_MAXBUFFERSIZE + 1) * 2, &uart_queue, 0); // buffer must be > fifo
uart_set_rx_full_threshold(EMSUART_NUM, 1);
uart_set_rx_timeout(EMSUART_NUM, 0); // disable
// note esp32s3 crashes with 2k stacksize, stack overflow here sometimes wipes settingsfiles.
xTaskCreate(uart_event_task, "uart_event_task", 2560, NULL, configMAX_PRIORITIES - 1, NULL);
#if defined(CONFIG_FREERTOS_UNICORE) || (EMSESP_UART_RUNNING_CORE < 0)
xTaskCreate(uart_event_task, "uart_event_task", EMSESP_UART_STACKSIZE, NULL, EMSESP_UART_PRIORITY, &xHandle);
#else
xTaskCreatePinnedToCore(uart_event_task, "uart_event_task", EMSESP_UART_STACKSIZE, NULL, EMSESP_UART_PRIORITY, &xHandle, EMSESP_UART_RUNNING_CORE);
#endif
} else {
uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
vTaskResume(xHandle);
}
tx_mode_ = tx_mode;
uart_enable_intr_mask(EMSUART_NUM, UART_BRK_DET_INT_ENA | UART_RXFIFO_FULL_INT_ENA);
}
/*
* Stop, disable interrupt
*/
// Stop, disable interrupt
void EMSuart::stop() {
if (tx_mode_ != 0xFF) { // only call after driver initialisation
if (tx_mode_ != EMS_TXMODE_INIT) { // only call after driver initialisation
uart_disable_intr_mask(EMSUART_NUM, UART_BRK_DET_INT_ENA | UART_RXFIFO_FULL_INT_ENA);
// TODO should we xTaskSuspend() the event task here?
vTaskSuspend(xHandle);
}
};
/*
* generate <BRK> by inverting tx
*/
// generate <BRK> by inverting tx
void IRAM_ATTR EMSuart::uart_gen_break(uint32_t length_us) {
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mux);
@@ -124,35 +124,34 @@ void IRAM_ATTR EMSuart::uart_gen_break(uint32_t length_us) {
portEXIT_CRITICAL(&mux);
}
/*
* Sends a 1-byte poll, ending with a <BRK>
*/
// Sends a 1-byte poll, ending with a <BRK>
void EMSuart::send_poll(const uint8_t data) {
transmit(&data, 1);
}
/*
* Send data to Tx line, ending with a <BRK>
* buf contains the CRC and len is #bytes including the CRC
* returns code, 1=success
*/
uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
// Send data to Tx line, ending with a <BRK>
// buf contains the CRC and len is #bytes including the CRC
// returns code, 1=success
uint8_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
if (len == 0 || len >= EMS_MAXBUFFERSIZE) {
return EMS_TX_STATUS_ERR;
}
if (tx_mode_ == 0) {
// TXMODE is OFF
if (tx_mode_ == EMS_TXMODE_OFF) {
return EMS_TX_STATUS_OK;
}
last_tx_src_ = len < 4 ? 0 : buf[0];
last_tx_src_ = len < 4 ? 0 : buf[0]; // update last tx source
if (tx_mode_ == EMS_TXMODE_HW) { // hardware controlled mode
// TXMODE is hardware controlled mode
if (tx_mode_ == EMS_TXMODE_HW) {
uart_write_bytes_with_break(EMSUART_NUM, buf, len, 10);
return EMS_TX_STATUS_OK;
}
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ with long delay
// TXMODE is EMS+ with long delay
if (tx_mode_ == EMS_TXMODE_EMSPLUS) {
for (uint8_t i = 0; i < len; i++) {
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
delayMicroseconds(EMSUART_TX_WAIT_PLUS);
@@ -161,7 +160,8 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
return EMS_TX_STATUS_OK;
}
if (tx_mode_ == EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay
// TXMODE is HT3 with 7 bittimes delay
if (tx_mode_ == EMS_TXMODE_HT3) {
for (uint8_t i = 0; i < len; i++) {
uart_write_bytes(EMSUART_NUM, &buf[i], 1);
delayMicroseconds(EMSUART_TX_WAIT_HT3);
@@ -170,7 +170,7 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
return EMS_TX_STATUS_OK;
}
// mode 1: wait for echo after each byte
// TXMODE default: wait for echo after each byte
for (uint8_t i = 0; i < len; i++) {
size_t rx0, rx1;
uart_get_buffered_data_len(EMSUART_NUM, &rx0);

View File

@@ -1,6 +1,6 @@
/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2024 emsesp.org - proddy, MichaelDvP
* Copyright 2020-2025 emsesp.org - proddy, MichaelDvP
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,11 +24,24 @@
#ifndef EMSESP_EMSUART_H
#define EMSESP_EMSUART_H
#ifndef EMSESP_UART_RUNNING_CORE
#define EMSESP_UART_RUNNING_CORE -1
#endif
#ifndef EMSESP_UART_STACKSIZE
#define EMSESP_UART_STACKSIZE 2560
#endif
#ifndef EMSESP_UART_PRIORITY
#define EMSESP_UART_PRIORITY configMAX_PRIORITIES - 1
#endif
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
#define EMSUART_NUM UART_NUM_1 // on C3 and S2 there is no UART2, use UART1 for all
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
#define EMS_TXMODE_INIT 0xFF
#define EMS_TXMODE_OFF 0
#define EMS_TXMODE_DEFAULT 1
#define EMS_TXMODE_EMSPLUS 2
#define EMS_TXMODE_HT3 3
@@ -61,11 +74,11 @@ class EMSuart {
EMSuart() = default;
~EMSuart() = default;
static void start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t tx_gpio);
static void send_poll(const uint8_t data);
static void stop();
static uint16_t transmit(const uint8_t * buf, const uint8_t len);
static uint8_t last_tx_src() {
static void start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t tx_gpio);
static void send_poll(const uint8_t data);
static void stop();
static uint8_t transmit(const uint8_t * buf, const uint8_t len);
static uint8_t last_tx_src() {
return last_tx_src_;
}