diff --git a/README.md b/README.md index 95ffe85..d521a3d 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,6 @@ The following [ESP Home actions](https://esphome.io/guides/automations.html#acti ## TODO - [ ] This file -- [ ] ESP32 IDF support - [ ] RP2040 support - [ ] Testing of Combi 4E / Combi 6E and Alde devices (I only have access to an Combi 4) - [ ] More Testing diff --git a/components/truma_inetbox/LinBusListener.cpp b/components/truma_inetbox/LinBusListener.cpp index 0c526bb..dbc0aac 100644 --- a/components/truma_inetbox/LinBusListener.cpp +++ b/components/truma_inetbox/LinBusListener.cpp @@ -21,11 +21,11 @@ void LinBusListener::dump_config() { void LinBusListener::setup() { ESP_LOGCONFIG(TAG, "Setting up LIN BUS..."); - this->time_per_baud_ = (1000.0f * 1000.0f / this->parent_->get_baud_rate()); - this->time_per_lin_break_ = this->time_per_baud_ * this->lin_break_length * 1.1; - this->time_per_pid_ = this->time_per_baud_ * this->frame_length_ * 1.1; - this->time_per_first_byte_ = this->time_per_baud_ * this->frame_length_ * 3.0; - this->time_per_byte_ = this->time_per_baud_ * this->frame_length_ * 1.1; + // this->time_per_baud_ = (1000.0f * 1000.0f / this->parent_->get_baud_rate()); + // this->time_per_lin_break_ = this->time_per_baud_ * this->lin_break_length * 1.1; + // this->time_per_pid_ = this->time_per_baud_ * this->frame_length_ * 1.1; + // this->time_per_first_byte_ = this->time_per_baud_ * this->frame_length_ * 3.0; + // this->time_per_byte_ = this->time_per_baud_ * this->frame_length_ * 1.1; // call device specific function this->setup_framework(); @@ -55,6 +55,12 @@ void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) { data_CRC = data_checksum(data, len, this->current_PID_with_parity_); } + // I am answering too quick ~50-60us after stop bit. Normal communication has a ~100us pause (second stop bits). + // The heater is answering after ~500-600us. + // If there is any issue I might have to add a delay here. + // Check when last byte was read from buffer and wait at least one baud time. + // It is working when I answer quicker. + if (!this->observer_mode_) { this->write_array(data, len); this->write(data_CRC); @@ -63,6 +69,30 @@ void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) { ESP_LOGV(TAG, "RESPONSE %02x %s %02x", this->current_PID_, format_hex_pretty(data, len).c_str(), data_CRC); } +void LinBusListener::onReceive_() { + // Check if Lin Bus is faulty. + if (this->fault_pin_ != nullptr) { + if (!this->fault_pin_->digital_read()) { + if (!this->fault_on_lin_bus_reported_) { + this->fault_on_lin_bus_reported_ = true; + ESP_LOGE(TAG, "Fault on LIN BUS detected."); + } + // Ignore any data present in buffer + this->clear_uart_buffer_(); + } else if (this->fault_on_lin_bus_reported_) { + this->fault_on_lin_bus_reported_ = false; + ESP_LOGI(TAG, "Fault on LIN BUS fixed."); + } + } + + if (!this->fault_on_lin_bus_reported_) { + while (this->available()) { + // this->last_data_recieved_ = micros(); + this->read_lin_frame_(); + } + } +} + void LinBusListener::read_lin_frame_() { u_int8_t buf; switch (this->current_state_) { @@ -128,6 +158,8 @@ void LinBusListener::read_lin_frame_() { this->current_state_ = READ_STATE_ACT; } break; + default: + break; } if (this->current_state_ == READ_STATE_ACT && this->current_data_count_ > 1) { diff --git a/components/truma_inetbox/LinBusListener.h b/components/truma_inetbox/LinBusListener.h index a8e3918..c48ac67 100644 --- a/components/truma_inetbox/LinBusListener.h +++ b/components/truma_inetbox/LinBusListener.h @@ -4,6 +4,11 @@ #include "esphome/core/component.h" #include "esphome/components/uart/uart.h" +#ifdef USE_ESP32_FRAMEWORK_ESP_IDF +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#endif // USE_ESP32_FRAMEWORK_ESP_IDF + namespace esphome { namespace truma_inetbox { @@ -34,19 +39,19 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice { virtual void lin_message_recieved_(const u_int8_t pid, const u_int8_t *message, u_int8_t length) = 0; private: - // Microseconds per UART Baud - u_int32_t time_per_baud_; - // 9.. 15 - u_int8_t lin_break_length = 13; - // Microseconds per LIN Break - u_int32_t time_per_lin_break_; - u_int8_t frame_length_ = (8 /* bits */ + 1 /* Start bit */ + 2 /* Stop bits */); - // Microseconds per UART Byte (UART Frame) - u_int32_t time_per_pid_; - // Microseconds per UART Byte (UART Frame) - u_int32_t time_per_first_byte_; - // Microseconds per UART Byte (UART Frame) - u_int32_t time_per_byte_; + // // Microseconds per UART Baud + // u_int32_t time_per_baud_; + // // 9.. 15 + // u_int8_t lin_break_length = 13; + // // Microseconds per LIN Break + // u_int32_t time_per_lin_break_; + // u_int8_t frame_length_ = (8 /* bits */ + 1 /* Start bit */ + 2 /* Stop bits */); + // // Microseconds per UART Byte (UART Frame) + // u_int32_t time_per_pid_; + // // Microseconds per UART Byte (UART Frame) + // u_int32_t time_per_first_byte_; + // // Microseconds per UART Byte (UART Frame) + // u_int32_t time_per_byte_; bool fault_on_lin_bus_reported_ = false; bool can_write_lin_answer_ = false; @@ -66,11 +71,17 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice { // up to 8 byte data frame + CRC u_int8_t current_data_[9] = {}; // // Time when the last LIN data was available. - // int64_t last_data_recieved_; + // uint32_t last_data_recieved_; + void onReceive_(); void read_lin_frame_(); void clear_uart_buffer_(); void setup_framework(); + +#ifdef USE_ESP32_FRAMEWORK_ESP_IDF + TaskHandle_t _eventTask; + static void _uartEventTask(void *args); +#endif // USE_ESP32_FRAMEWORK_ESP_IDF }; } // namespace truma_inetbox diff --git a/components/truma_inetbox/LinBusListener_esp32_arduino.cpp b/components/truma_inetbox/LinBusListener_esp32_arduino.cpp index 7f2fcf3..5d11496 100644 --- a/components/truma_inetbox/LinBusListener_esp32_arduino.cpp +++ b/components/truma_inetbox/LinBusListener_esp32_arduino.cpp @@ -16,7 +16,7 @@ void LinBusListener::setup_framework() { auto uartComp = static_cast(this->parent_); auto uart_num = uartComp->get_hw_serial_number(); - auto hwSerial = uartComp->get_hw_serial(); + auto hw_serial = uartComp->get_hw_serial(); // Extract from `uartSetFastReading` - Can't call it because I don't have access to `uart_t` object. @@ -34,32 +34,10 @@ void LinBusListener::setup_framework() { uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT uart_intr_config(uart_num, &uart_intr); - hwSerial->onReceive( - [this]() { - // Check if Lin Bus is faulty. - if (this->fault_pin_ != nullptr) { - if (!this->fault_pin_->digital_read()) { - if (!this->fault_on_lin_bus_reported_) { - this->fault_on_lin_bus_reported_ = true; - ESP_LOGE(TAG, "Fault on LIN BUS detected."); - } - // Ignore any data present in buffer - this->clear_uart_buffer_(); - } else if (this->fault_on_lin_bus_reported_) { - this->fault_on_lin_bus_reported_ = false; - ESP_LOGI(TAG, "Fault on LIN BUS fixed."); - } - } - - if (!this->fault_on_lin_bus_reported_) { - while (this->available()) { - // this->last_data_recieved_ = esp_timer_get_time(); - this->read_lin_frame_(); - } - } - }, - false); - hwSerial->onReceiveError([this](hardwareSerial_error_t val) { + hw_serial->onReceive([this]() { this->onReceive_(); }, false); + hw_serial->onReceiveError([this](hardwareSerial_error_t val) { + // Ignore any data present in buffer + this->clear_uart_buffer_(); if (val == UART_BREAK_ERROR) { // If the break is valid the `onReceive` is called first and the break is handeld. Therfore the expectation is // that the state should be in waiting for `SYNC`. @@ -67,14 +45,6 @@ void LinBusListener::setup_framework() { this->current_state_ = READ_STATE_BREAK; } return; - } else if (val == UART_BUFFER_FULL_ERROR) { - ESP_LOGW(TAG, "UART_BUFFER_FULL_ERROR"); - } else if (val == UART_FIFO_OVF_ERROR) { - ESP_LOGW(TAG, "UART_FIFO_OVF_ERROR"); - } else if (val == UART_FRAME_ERROR) { - ESP_LOGW(TAG, "UART_FRAME_ERROR"); - } else if (val == UART_PARITY_ERROR) { - ESP_LOGW(TAG, "UART_PARITY_ERROR"); } }); } diff --git a/components/truma_inetbox/LinBusListener_esp_idf.cpp b/components/truma_inetbox/LinBusListener_esp_idf.cpp index 8b842d0..191d51c 100644 --- a/components/truma_inetbox/LinBusListener_esp_idf.cpp +++ b/components/truma_inetbox/LinBusListener_esp_idf.cpp @@ -1,6 +1,7 @@ #ifdef USE_ESP32_FRAMEWORK_ESP_IDF #include "LinBusListener.h" #include "esphome/core/log.h" +#include "soc/uart_reg.h" #include "esphome/components/uart/truma_uart_component_esp_idf.h" #include "esphome/components/uart/uart_component_esp_idf.h" @@ -11,20 +12,59 @@ static const char *const TAG = "truma_inetbox.LinBusListener"; void LinBusListener::setup_framework() { // uartSetFastReading - auto uartComp = ((*uart::truma_IDFUARTComponent) this->parent_); + auto uartComp = static_cast(this->parent_); + + auto uart_num = uartComp->get_hw_serial_number(); // Tweak the fifo settings so data is available as soon as the first byte is recieved. // If not it will wait either until fifo is filled or a certain time has passed. uart_intr_config_t uart_intr; - uart_intr.intr_enable_mask = 0; // UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M | UART_FRM_ERR_INT_ENA_M | - // UART_RXFIFO_OVF_INT_ENA_M | UART_BRK_DET_INT_ENA_M | UART_PARITY_ERR_INT_ENA_M; + uart_intr.intr_enable_mask = + UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M; // only these IRQs - no BREAK, PARITY or OVERFLOW uart_intr.rxfifo_full_thresh = 1; // UART_FULL_THRESH_DEFAULT, //120 default!! aghh! need receive 120 chars before we see them uart_intr.rx_timeout_thresh = - 1; // UART_TOUT_THRESH_DEFAULT, //10 works well for my short messages I need send/receive + 10; // UART_TOUT_THRESH_DEFAULT, //10 works well for my short messages I need send/receive uart_intr.txfifo_empty_intr_thresh = 10; // UART_EMPTY_THRESH_DEFAULT - uart_intr_config(uartComp->get_hw_serial_number(), &uart_intr); + uart_intr_config(uart_num, &uart_intr); + + // Creating UART event Task + xTaskCreatePinnedToCore(LinBusListener::_uartEventTask, + "uart_event_task", // name + ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE, // stack size (in words) + this, // input params + 24, // priority + &_eventTask, // handle + ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE // core + ); + if (_eventTask == NULL) { + ESP_LOGE(TAG, " -- UART%d Event Task not Created!", uart_num); + } } + +void LinBusListener::_uartEventTask(void *args) { + LinBusListener *instance = (LinBusListener *) args; + auto uartComp = static_cast(instance->parent_); + auto uart_num = uartComp->get_hw_serial_number(); + auto uartEventQueue = uartComp->get_uart_event_queue(); + uart_event_t event; + for (;;) { + // Waiting for UART event. + if (xQueueReceive(*uartEventQueue, (void *) &event, (portTickType) portMAX_DELAY)) { + if (event.type == UART_DATA && instance->available() > 0) { + instance->onReceive_(); + } else if (event.type == UART_BREAK) { + // If the break is valid the `onReceive` is called first and the break is handeld. Therfore the expectation is + // that the state should be in waiting for `SYNC`. + if (instance->current_state_ != READ_STATE_SYNC) { + instance->current_state_ = READ_STATE_BREAK; + } + } + } + } + vTaskDelete(NULL); +} + } // namespace truma_inetbox } // namespace esphome diff --git a/components/truma_inetbox/TrumaiNetBoxApp.cpp b/components/truma_inetbox/TrumaiNetBoxApp.cpp index 626e691..032ad0a 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.cpp +++ b/components/truma_inetbox/TrumaiNetBoxApp.cpp @@ -66,7 +66,7 @@ const std::array TrumaiNetBoxApp::lin_identifier() { } void TrumaiNetBoxApp::lin_reset_device() { - this->device_registered_ = esp_timer_get_time(); + this->device_registered_ = micros(); this->init_recieved_ = 0; this->status_heater_valid_ = false; @@ -90,9 +90,8 @@ void TrumaiNetBoxApp::lin_reset_device() { } void TrumaiNetBoxApp::register_listener(const std::function &func) { - auto listener = StatusFrameListener{ - .on_heater_change = func, - }; + StatusFrameListener listener = {}; + listener.on_heater_change = func; this->listeners_heater_.push_back(std::move(listener)); if (this->status_heater_valid_) { @@ -100,9 +99,8 @@ void TrumaiNetBoxApp::register_listener(const std::function &func) { - auto listener = StatusFrameListener{ - .on_timer_change = func, - }; + StatusFrameListener listener = {}; + listener.on_timer_change = func; this->listeners_heater_.push_back(std::move(listener)); if (this->status_timer_valid_) { @@ -110,9 +108,8 @@ void TrumaiNetBoxApp::register_listener(const std::function &func) { - auto listener = StatusFrameListener{ - .on_clock_change = func, - }; + StatusFrameListener listener = {}; + listener.on_clock_change = func; this->listeners_heater_.push_back(std::move(listener)); if (this->status_clock_valid_) { @@ -120,9 +117,8 @@ void TrumaiNetBoxApp::register_listener(const std::function &func) { - auto listener = StatusFrameListener{ - .on_config_change = func, - }; + StatusFrameListener listener = {}; + listener.on_config_change = func; this->listeners_heater_.push_back(std::move(listener)); if (this->status_config_valid_) { @@ -190,7 +186,7 @@ bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) { } bool TrumaiNetBoxApp::lin_read_field_by_identifier_(u_int8_t identifier, std::array *response) { - this->device_registered_ = esp_timer_get_time(); + this->device_registered_ = micros(); if (identifier == 0x00 /* LIN Product Identification */) { auto lin_identifier = this->lin_identifier(); (*response)[0] = lin_identifier[0]; @@ -389,7 +385,7 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.27.02.01.01.00.40.03.22.02.00.01.00.00 - H2.00.01 0340.22 auto device = statusFrame->inner.device; - this->init_recieved_ = esp_timer_get_time(); + this->init_recieved_ = micros(); ESP_LOGV(TAG, "StatusFrameDevice %d/%d - %d.%02d.%02d %04x.%02x", device.device_id + 1, device.device_count, device.software_revision[0], device.software_revision[1], device.software_revision[2], @@ -405,28 +401,28 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message bool TrumaiNetBoxApp::has_update_to_submit_() { if (this->init_requested_ == 0) { - this->init_requested_ = esp_timer_get_time(); + this->init_requested_ = micros(); ESP_LOGV(TAG, "Requesting initial data."); return true; } else if (this->init_recieved_ == 0) { - auto init_wait_time = esp_timer_get_time() - this->init_requested_; + auto init_wait_time = micros() - this->init_requested_; // it has been 5 seconds and i am still awaiting the init data. if (init_wait_time > 1000 * 1000 * 5) { ESP_LOGV(TAG, "Requesting initial data again."); - this->init_requested_ = esp_timer_get_time(); + this->init_requested_ = micros(); return true; } } else if (this->update_status_heater_unsubmitted_ || this->update_status_timer_unsubmitted_ || this->update_status_clock_unsubmitted_) { if (this->update_time_ == 0) { ESP_LOGV(TAG, "Notify CP Plus I got updates."); - this->update_time_ = esp_timer_get_time(); + this->update_time_ = micros(); return true; } - auto update_wait_time = esp_timer_get_time() - this->update_time_; + auto update_wait_time = micros() - this->update_time_; if (update_wait_time > 1000 * 1000 * 5) { ESP_LOGV(TAG, "Notify CP Plus again I still got updates."); - this->update_time_ = esp_timer_get_time(); + this->update_time_ = micros(); return true; } } diff --git a/components/truma_inetbox/TrumaiNetBoxApp.h b/components/truma_inetbox/TrumaiNetBoxApp.h index 030d53b..9544c62 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.h +++ b/components/truma_inetbox/TrumaiNetBoxApp.h @@ -326,10 +326,10 @@ union StatusFrame { // NOLINT(altera-struct-pack-align) } __attribute__((packed)); struct StatusFrameListener { - std::function on_heater_change; - std::function on_timer_change; - std::function on_clock_change; - std::function on_config_change; + std::function on_heater_change = nullptr; + std::function on_timer_change = nullptr; + std::function on_clock_change = nullptr; + std::function on_config_change = nullptr; }; class TrumaiNetBoxApp : public LinBusProtocol { @@ -395,9 +395,9 @@ class TrumaiNetBoxApp : public LinBusProtocol { time::RealTimeClock *time_; // Truma CP Plus needs init (reset). This device is not registered. - int64_t device_registered_ = 0; - int64_t init_requested_ = 0; - int64_t init_recieved_ = 0; + uint32_t device_registered_ = 0; + uint32_t init_requested_ = 0; + uint32_t init_recieved_ = 0; u_int8_t message_counter = 1; std::vector listeners_heater_; @@ -424,7 +424,7 @@ class TrumaiNetBoxApp : public LinBusProtocol { StatusFrameConfig status_config_; // last time CP plus was informed I got an update msg. - int64_t update_time_ = 0; + uint32_t update_time_ = 0; // Prepared means `update_status_heater_` was copied from `status_heater_`. bool update_status_heater_prepared_ = false; // Prepared means an update is already awating fetch from CP plus. diff --git a/components/truma_inetbox/__init__.py b/components/truma_inetbox/__init__.py index 515940e..26f9ff5 100644 --- a/components/truma_inetbox/__init__.py +++ b/components/truma_inetbox/__init__.py @@ -6,7 +6,6 @@ from esphome.const import ( CONF_ID, CONF_CS_PIN, CONF_TEMPERATURE, - CONF_ON_MESSAGE, CONF_TRIGGER_ID, CONF_STOP, CONF_TIME_ID, @@ -62,7 +61,6 @@ CONFIG_SCHEMA = cv.All( # Reading and communication is done in a seperate thread/core. .extend(cv.polling_component_schema("500ms")) .extend(uart.UART_DEVICE_SCHEMA), - cv.only_with_arduino, cv.only_on(["esp32"]), ) FINAL_VALIDATE_SCHEMA = cv.All( diff --git a/components/truma_inetbox/binary_sensor/TrumaCpPlusBinarySensor.cpp b/components/truma_inetbox/binary_sensor/TrumaCpPlusBinarySensor.cpp index 096a872..83ba0d9 100644 --- a/components/truma_inetbox/binary_sensor/TrumaCpPlusBinarySensor.cpp +++ b/components/truma_inetbox/binary_sensor/TrumaCpPlusBinarySensor.cpp @@ -13,7 +13,7 @@ void TrumaCpPlusBinarySensor::update() { return; } auto timeout = this->parent_->get_last_cp_plus_request() + 30 * 1000 * 1000 /* 30 seconds*/; - this->publish_state(esp_timer_get_time() < timeout); + this->publish_state(micros() < timeout); } void TrumaCpPlusBinarySensor::dump_config() { ESP_LOGCONFIG("", "Truma CP Plus Binary Sensor"); } diff --git a/components/truma_inetbox/binary_sensor/TrumaHeaterBinarySensor.cpp b/components/truma_inetbox/binary_sensor/TrumaHeaterBinarySensor.cpp index 30f56ea..fa758cd 100644 --- a/components/truma_inetbox/binary_sensor/TrumaHeaterBinarySensor.cpp +++ b/components/truma_inetbox/binary_sensor/TrumaHeaterBinarySensor.cpp @@ -30,6 +30,8 @@ void TrumaHeaterBinarySensor::setup() { case TRUMA_BINARY_SENSOR_TYPE::HEATER_ELECTRICITY: this->publish_state(status_heater->energy_mix_a == EnergyMix::ENERGY_MIX_ELECTRICITY); break; + default: + break; } }); } diff --git a/components/truma_inetbox/binary_sensor/TrumaTimerBinarySensor.cpp b/components/truma_inetbox/binary_sensor/TrumaTimerBinarySensor.cpp index 749261a..1a3a8ef 100644 --- a/components/truma_inetbox/binary_sensor/TrumaTimerBinarySensor.cpp +++ b/components/truma_inetbox/binary_sensor/TrumaTimerBinarySensor.cpp @@ -19,6 +19,8 @@ void TrumaTimerBinarySensor::setup() { case TRUMA_BINARY_SENSOR_TYPE::TIMER_WATER: this->publish_state(status_timer->timer_target_temp_water != TargetTemp::TARGET_TEMP_OFF); break; + default: + break; } }); } diff --git a/components/truma_inetbox/helpers.cpp b/components/truma_inetbox/helpers.cpp index 5c0d58e..9273bf0 100644 --- a/components/truma_inetbox/helpers.cpp +++ b/components/truma_inetbox/helpers.cpp @@ -89,7 +89,7 @@ const std::string operating_status_to_str(OperatingStatus val) { } else if (val == OperatingStatus::OPERATING_STATUS_ON_9) { return "ON (9)"; } else { - return str_snprintf("ON %x", (uint8_t) val); + return esphome::str_snprintf("ON %u", 6, (uint8_t) val); } } diff --git a/components/uart/truma_uart_component_esp32_arduino.h b/components/uart/truma_uart_component_esp32_arduino.h index 7c795fb..64fe636 100644 --- a/components/uart/truma_uart_component_esp32_arduino.h +++ b/components/uart/truma_uart_component_esp32_arduino.h @@ -9,7 +9,6 @@ namespace uart { class truma_ESP32ArduinoUARTComponent : public ESP32ArduinoUARTComponent { public: - bool is_hw_serial() { return true; } HardwareSerial *get_hw_serial() { return this->hw_serial_; } uint8_t get_hw_serial_number() { return this->number_; } }; diff --git a/components/uart/truma_uart_component_esp_idf.h b/components/uart/truma_uart_component_esp_idf.h index 2dc0177..0fc4333 100644 --- a/components/uart/truma_uart_component_esp_idf.h +++ b/components/uart/truma_uart_component_esp_idf.h @@ -9,8 +9,9 @@ namespace uart { class truma_IDFUARTComponent : public IDFUARTComponent { public: - bool is_hw_serial() { return true; } uint8_t get_hw_serial_number() { return this->uart_num_; } + // `QueueHandle_t uart_event_queue_;` is also added to base class. + QueueHandle_t *get_uart_event_queue() { return &this->uart_event_queue_; } }; } // namespace uart diff --git a/components/uart/uart_component_esp_idf.cpp b/components/uart/uart_component_esp_idf.cpp index 80255cc..d1316e0 100644 --- a/components/uart/uart_component_esp_idf.cpp +++ b/components/uart/uart_component_esp_idf.cpp @@ -79,7 +79,11 @@ void IDFUARTComponent::setup() { return; } - err = uart_driver_install(this->uart_num_, this->rx_buffer_size_, 0, 0, nullptr, 0); + err = uart_driver_install(this->uart_num_, this->rx_buffer_size_, + 0, // UART TX ring buffer size. + // If set to zero, driver will not use TX buffer, TX function will block task until all + // data have been sent out. + 20, &(this->uart_event_queue_), 0); if (err != ESP_OK) { ESP_LOGW(TAG, "uart_driver_install failed: %s", esp_err_to_name(err)); this->mark_failed(); diff --git a/components/uart/uart_component_esp_idf.h b/components/uart/uart_component_esp_idf.h index 27fb80d..1ccbeae 100644 --- a/components/uart/uart_component_esp_idf.h +++ b/components/uart/uart_component_esp_idf.h @@ -26,6 +26,7 @@ class IDFUARTComponent : public UARTComponent, public Component { protected: void check_logger_conflict() override; uart_port_t uart_num_; + QueueHandle_t uart_event_queue_; uart_config_t get_config_(); SemaphoreHandle_t lock_;