diff --git a/components/truma_inetbox/LinBusListener.cpp b/components/truma_inetbox/LinBusListener.cpp index f4202dd..04fb06a 100644 --- a/components/truma_inetbox/LinBusListener.cpp +++ b/components/truma_inetbox/LinBusListener.cpp @@ -26,6 +26,7 @@ static const char *const TAG = "truma_inetbox.LinBusListener"; #define LIN_SYNC 0x55 #define DIAGNOSTIC_FRAME_MASTER 0x3c #define DIAGNOSTIC_FRAME_SLAVE 0x3d +#define QUEUE_WAIT_DONT_BLOCK (TickType_t) 0 void LinBusListener::dump_config() { ESP_LOGCONFIG(TAG, "LinBusListener:"); @@ -53,6 +54,8 @@ void LinBusListener::setup() { this->fault_pin_->setup(); } + assert(this->log_queue_ != 0); + // call device specific function this->setup_framework(); @@ -60,18 +63,24 @@ void LinBusListener::setup() { // Enable LIN driver if not in oberserver mode. this->cs_pin_->digital_write(!this->observer_mode_); } + + // Register interval to submit log messages + this->set_interval("logmsg", 50, [this]() { this->process_log_queue_(QUEUE_WAIT_DONT_BLOCK); }); } void LinBusListener::update() { this->check_for_lin_fault_(); } -void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) { +void LinBusListener::write_lin_answer_(const u_int8_t *data, u_int8_t len) { + QUEUE_LOG_MSG log_msg = QUEUE_LOG_MSG(); if (!this->can_write_lin_answer_) { - ESP_LOGE(TAG, "Cannot answer LIN because there is no open order from master."); + log_msg.type = QUEUE_LOG_MSG_TYPE::ERROR_LIN_ANSWER_CAN_WRITE_LIN_ANSWER; + xQueueSend(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); return; } this->can_write_lin_answer_ = false; if (len > 8) { - ESP_LOGE(TAG, "LIN answer cannot be longer than 8 bytes."); + log_msg.type = QUEUE_LOG_MSG_TYPE::ERROR_LIN_ANSWER_TOO_LONG; + xQueueSend(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); return; } @@ -94,12 +103,18 @@ void LinBusListener::write_lin_answer_(const u_int8_t *data, size_t len) { this->current_PID_order_answered_ = true; this->write_array(data, len); this->write(data_CRC); - - ESP_LOGV(TAG, "RESPONSE %02X %s %02X", this->current_PID_, format_hex_pretty(data, len).c_str(), data_CRC); - } else { - ESP_LOGV(TAG, "RESPONSE %02X %s %02X - NOT SEND (OBSERVER MODE)", this->current_PID_, - format_hex_pretty(data, len).c_str(), data_CRC); } + +#ifdef ESPHOME_LOG_HAS_VERBOSE + log_msg.type = QUEUE_LOG_MSG_TYPE::VERBOSE_LIN_ANSWER_RESPONSE; + log_msg.current_PID = this->current_PID_; + for (u_int8_t i = 0; i < len; i++) { + log_msg.data[i] = data[i]; + } + log_msg.data[len] = data_CRC; + log_msg.len = len++; + xQueueSend(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); +#endif // ESPHOME_LOG_HAS_VERBOSE } bool LinBusListener::check_for_lin_fault_() { @@ -113,11 +128,15 @@ bool LinBusListener::check_for_lin_fault_() { this->fault_on_lin_bus_reported_ = 0x0F; } if (this->fault_on_lin_bus_reported_ % 3 == 0) { - ESP_LOGE(TAG, "Fault on LIN BUS detected."); + QUEUE_LOG_MSG log_msg = QUEUE_LOG_MSG(); + log_msg.type = QUEUE_LOG_MSG_TYPE::ERROR_CHECK_FOR_LIN_FAULT_DETECTED; + xQueueSend(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); } } else if (this->get_lin_bus_fault()) { this->fault_on_lin_bus_reported_ = 0; - ESP_LOGI(TAG, "Fault on LIN BUS fixed."); + QUEUE_LOG_MSG log_msg = QUEUE_LOG_MSG(); + log_msg.type = QUEUE_LOG_MSG_TYPE::INFO_CHECK_FOR_LIN_FAULT_FIXED; + xQueueSend(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); } else { this->fault_on_lin_bus_reported_ = 0; } @@ -144,19 +163,24 @@ void LinBusListener::onReceive_() { void LinBusListener::read_lin_frame_() { u_int8_t buf; + QUEUE_LOG_MSG log_msg = QUEUE_LOG_MSG(); switch (this->current_state_) { case READ_STATE_BREAK: // Check if there was an unanswered message before break. if (this->current_PID_with_parity_ != 0x00 && this->current_PID_ != 0x00 && this->current_data_valid) { - if (this->current_PID_order_answered_ && this->current_data_count_ < 8) { - // Expectation is that I can see an echo of my data from the lin driver chip. - ESP_LOGE(TAG, "PID %02X (%02X) order - unable to send response", this->current_PID_, - this->current_PID_with_parity_); - } else if (this->current_data_count_ == 0) { - ESP_LOGV(TAG, "PID %02X (%02X) order no answer", this->current_PID_, this->current_PID_with_parity_); - } else if (this->current_data_count_ < 8) { - ESP_LOGW(TAG, "PID %02X (%02X) %s partial data received", this->current_PID_, this->current_PID_with_parity_, - format_hex_pretty(this->current_data_, this->current_data_count_).c_str()); + if (this->current_data_count_ < 8) { + log_msg.current_PID = this->current_PID_; + if (this->current_PID_order_answered_) { + // Expectation is that I can see an echo of my data from the lin driver chip. + log_msg.type = QUEUE_LOG_MSG_TYPE::ERROR_READ_LIN_FRAME_UNABLE_TO_ANSWER; + } else { + log_msg.type = QUEUE_LOG_MSG_TYPE::ERROR_READ_LIN_FRAME_LOST_MSG; + for (u_int8_t i = 0; i < this->current_data_count_; i++) { + log_msg.data[i] = this->current_data_[i]; + } + log_msg.len = this->current_data_count_; + } + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); } } @@ -165,7 +189,11 @@ void LinBusListener::read_lin_frame_() { // First is Break expected if (!this->read_byte(&buf) || buf != LIN_BREAK) { - ESP_LOGVV(TAG, "0x%02X Expected BREAK not received.", buf); +#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE + log_msg.type = QUEUE_LOG_MSG_TYPE::VV_READ_LIN_FRAME_BREAK_EXPECTED; + log_msg.current_PID = buf; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); +#endif // ESPHOME_LOG_HAS_VERY_VERBOSE } else { // ESP_LOGVV(TAG, "%02X BREAK received.", buf); this->current_state_ = READ_STATE_SYNC; @@ -174,7 +202,11 @@ void LinBusListener::read_lin_frame_() { case READ_STATE_SYNC: // Second is Sync expected if (!this->read_byte(&buf) || buf != LIN_SYNC) { - ESP_LOGVV(TAG, "0x%02X Expected SYNC not found.", buf); +#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE + log_msg.type = QUEUE_LOG_MSG_TYPE::VV_READ_LIN_FRAME_SYNC_EXPECTED; + log_msg.current_PID = buf; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); +#endif // ESPHOME_LOG_HAS_VERY_VERBOSE this->current_state_ = buf == LIN_BREAK ? READ_STATE_SYNC : READ_STATE_BREAK; } else { // ESP_LOGVV(TAG, "%02X SYNC found.", buf); @@ -186,13 +218,16 @@ void LinBusListener::read_lin_frame_() { this->current_PID_ = this->current_PID_with_parity_ & 0x3F; if (this->lin_checksum_ == LIN_CHECKSUM::LIN_CHECKSUM_VERSION_2) { if (this->current_PID_with_parity_ != (this->current_PID_ | (addr_parity(this->current_PID_) << 6))) { - ESP_LOGW(TAG, "0x%02X LIN CRC error on SID.", this->current_PID_with_parity_); + log_msg.type = QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_SID_CRC; + log_msg.current_PID = this->current_PID_with_parity_; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); this->current_data_valid = false; } } if (this->current_data_valid) { this->can_write_lin_answer_ = true; + // Should I response to this PID order? Ask the handling class. this->answer_lin_order_(this->current_PID_); this->can_write_lin_answer_ = false; @@ -231,7 +266,8 @@ void LinBusListener::read_lin_frame_() { if (this->lin_checksum_ == LIN_CHECKSUM::LIN_CHECKSUM_VERSION_1 || (this->current_PID_ == DIAGNOSTIC_FRAME_MASTER || this->current_PID_ == DIAGNOSTIC_FRAME_SLAVE)) { if (data_CRC != data_checksum(this->current_data_, data_length, 0)) { - ESP_LOGW(TAG, "LIN v1 CRC error"); + log_msg.type = QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_LINv1_CRC; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); this->current_data_valid = false; } if (this->current_PID_ == DIAGNOSTIC_FRAME_MASTER) { @@ -245,7 +281,8 @@ void LinBusListener::read_lin_frame_() { u_int8_t data_CRC_master = data_checksum(this->current_data_, data_length, this->current_PID_); u_int8_t data_CRC_slave = data_checksum(this->current_data_, data_length, this->current_PID_with_parity_); if (data_CRC != data_CRC_master && data_CRC != data_CRC_slave) { - ESP_LOGW(TAG, "LIN v2 CRC error"); + log_msg.type = QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_LINv2_CRC; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); this->current_data_valid = false; } message_source_know = true; @@ -254,23 +291,27 @@ void LinBusListener::read_lin_frame_() { } } - // Mark the PID of the TRUMA Combi heater as very verbose message. - if (this->current_PID_ == 0x20 || this->current_PID_ == 0x21 || this->current_PID_ == 0x22 || - ((this->current_PID_ == DIAGNOSTIC_FRAME_MASTER || this->current_PID_ == DIAGNOSTIC_FRAME_SLAVE) && - this->current_data_[0] == 0x01 /* ID of heater */)) { - ESP_LOGVV(TAG, "PID %02X (%02X) %s %s %s", this->current_PID_, this->current_PID_with_parity_, - format_hex_pretty(this->current_data_, this->current_data_count_).c_str(), - message_source_know ? (message_from_master ? " - MASTER" : " - SLAVE") : "", - this->current_data_valid ? "" : "INVALID"); - } else { - ESP_LOGV(TAG, "PID %02X (%02X) %s %s %S", this->current_PID_, this->current_PID_with_parity_, - format_hex_pretty(this->current_data_, this->current_data_count_).c_str(), - message_source_know ? (message_from_master ? " - MASTER" : " - SLAVE") : "", - this->current_data_valid ? "" : "INVALID"); +#ifdef ESPHOME_LOG_HAS_VERBOSE + log_msg.type = QUEUE_LOG_MSG_TYPE::VERBOSE_READ_LIN_FRAME_MSG; + log_msg.current_PID = this->current_PID_; + for (u_int8_t i = 0; i < this->current_data_count_; i++) { + log_msg.data[i] = this->current_data_[i]; } + log_msg.len = this->current_data_count_; + log_msg.current_data_valid = this->current_data_valid; + log_msg.message_source_know = message_source_know; + log_msg.message_from_master = message_from_master; + xQueueSendFromISR(this->log_queue_, (void *) &log_msg, QUEUE_WAIT_DONT_BLOCK); +#endif // ESPHOME_LOG_HAS_VERBOSE if (this->current_data_valid && message_from_master) { - this->lin_message_recieved_(this->current_PID_, this->current_data_, data_length); + QUEUE_LIN_MSG lin_msg; + lin_msg.current_PID = this->current_PID_; + lin_msg.len = this->current_data_count_ - 1; + for (u_int8_t i = 0; i < lin_msg.len; i++) { + lin_msg.data[i] = this->current_data_[i]; + } + xQueueSendFromISR(this->lin_msg_queue_, (void *) &lin_msg, QUEUE_WAIT_DONT_BLOCK); } this->current_state_ = READ_STATE_BREAK; } @@ -282,5 +323,98 @@ void LinBusListener::clear_uart_buffer_() { } } +void LinBusListener::process_lin_msg_queue_(TickType_t xTicksToWait) { + QUEUE_LIN_MSG lin_msg; + while (xQueueReceive(this->lin_msg_queue_, &lin_msg, xTicksToWait) == pdPASS) { + this->lin_message_recieved_(lin_msg.current_PID, lin_msg.data, lin_msg.len); + } +} + +void LinBusListener::process_log_queue_(TickType_t xTicksToWait) { + QUEUE_LOG_MSG log_msg; + while (xQueueReceive(this->log_queue_, &log_msg, xTicksToWait) == pdPASS) { + auto current_PID = log_msg.current_PID; + switch (log_msg.type) { + case QUEUE_LOG_MSG_TYPE::ERROR_LIN_ANSWER_CAN_WRITE_LIN_ANSWER: + ESP_LOGE(TAG, "Cannot answer LIN because there is no open order from master."); + break; + case QUEUE_LOG_MSG_TYPE::ERROR_LIN_ANSWER_TOO_LONG: + ESP_LOGE(TAG, "LIN answer cannot be longer than 8 bytes."); + break; +#ifdef ESPHOME_LOG_HAS_VERBOSE + case QUEUE_LOG_MSG_TYPE::VERBOSE_LIN_ANSWER_RESPONSE: + if (!this->observer_mode_) { + ESP_LOGV(TAG, "RESPONSE %02X %s", current_PID, format_hex_pretty(log_msg.data, log_msg.len).c_str()); + } else { + ESP_LOGV(TAG, "RESPONSE %02X %s - NOT SEND (OBSERVER MODE)", current_PID, + format_hex_pretty(log_msg.data, log_msg.len).c_str()); + } + break; +#endif // ESPHOME_LOG_HAS_VERBOSE + + case QUEUE_LOG_MSG_TYPE::ERROR_CHECK_FOR_LIN_FAULT_DETECTED: + ESP_LOGE(TAG, "Fault on LIN BUS detected."); + break; + case QUEUE_LOG_MSG_TYPE::INFO_CHECK_FOR_LIN_FAULT_FIXED: + ESP_LOGI(TAG, "Fault on LIN BUS fixed."); + break; + + case QUEUE_LOG_MSG_TYPE::ERROR_READ_LIN_FRAME_UNABLE_TO_ANSWER: + ESP_LOGE(TAG, "PID %02X order - unable to send response", current_PID); + break; + + case QUEUE_LOG_MSG_TYPE::ERROR_READ_LIN_FRAME_LOST_MSG: + if (log_msg.len == 0) { + ESP_LOGV(TAG, "PID %02X order no answer", current_PID); + } else if (log_msg.len < 8) { + ESP_LOGW(TAG, "PID %02X %s partial data received", current_PID, + format_hex_pretty(log_msg.data, log_msg.len).c_str()); + } + break; +#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE + case QUEUE_LOG_MSG_TYPE::VV_READ_LIN_FRAME_BREAK_EXPECTED: + ESP_LOGVV(TAG, "0x%02X Expected BREAK not received.", current_PID); + break; + case QUEUE_LOG_MSG_TYPE::VV_READ_LIN_FRAME_SYNC_EXPECTED: + ESP_LOGVV(TAG, "0x%02X Expected SYNC not found.", current_PID); + break; +#endif // ESPHOME_LOG_HAS_VERY_VERBOSE + case QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_SID_CRC: + ESP_LOGW(TAG, "0x%02X LIN CRC error on SID.", current_PID); + break; + case QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_LINv1_CRC: + ESP_LOGW(TAG, "LIN v1 CRC error"); + break; + case QUEUE_LOG_MSG_TYPE::WARN_READ_LIN_FRAME_LINv2_CRC: + ESP_LOGW(TAG, "LIN v2 CRC error"); + break; +#ifdef ESPHOME_LOG_HAS_VERBOSE + case QUEUE_LOG_MSG_TYPE::VERBOSE_READ_LIN_FRAME_MSG: + // Mark the PID of the TRUMA Combi heater as very verbose message. + if (current_PID == 0x20 || current_PID == 0x21 || current_PID == 0x22 || + ((current_PID == DIAGNOSTIC_FRAME_MASTER || current_PID == DIAGNOSTIC_FRAME_SLAVE) && + log_msg.data[0] == 0x01 /* ID of heater */)) { + ESP_LOGVV(TAG, "PID %02X %s %s %s", current_PID_, format_hex_pretty(log_msg.data, log_msg.len).c_str(), + log_msg.message_source_know ? (log_msg.message_from_master ? " - MASTER" : " - SLAVE") : "", + log_msg.current_data_valid ? "" : "INVALID"); + } else { + ESP_LOGV(TAG, "PID %02X %s %s %S", current_PID_, format_hex_pretty(log_msg.data, log_msg.len).c_str(), + log_msg.message_source_know ? (log_msg.message_from_master ? " - MASTER" : " - SLAVE") : "", + log_msg.current_data_valid ? "" : "INVALID"); + } + break; +#endif // ESPHOME_LOG_HAS_VERBOSE + default: + break; + } + } +} + +#undef LIN_BREAK +#undef LIN_SYNC +#undef DIAGNOSTIC_FRAME_MASTER +#undef DIAGNOSTIC_FRAME_SLAVE +#undef QUEUE_WAIT_DONT_BLOCK + } // namespace truma_inetbox } // namespace esphome diff --git a/components/truma_inetbox/LinBusListener.h b/components/truma_inetbox/LinBusListener.h index 2248fcf..ab05b82 100644 --- a/components/truma_inetbox/LinBusListener.h +++ b/components/truma_inetbox/LinBusListener.h @@ -3,6 +3,9 @@ #include "esphome/core/component.h" #include "esphome/components/uart/uart.h" +#include +#include + #ifdef USE_ESP32_FRAMEWORK_ESP_IDF #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -16,6 +19,50 @@ namespace truma_inetbox { enum class LIN_CHECKSUM { LIN_CHECKSUM_VERSION_1, LIN_CHECKSUM_VERSION_2 }; +struct QUEUE_LIN_MSG { + u_int8_t current_PID; + u_int8_t data[8]; + u_int8_t len; +}; + +enum class QUEUE_LOG_MSG_TYPE { + UNKNOWN, + ERROR_LIN_ANSWER_CAN_WRITE_LIN_ANSWER, + ERROR_LIN_ANSWER_TOO_LONG, +#ifdef ESPHOME_LOG_HAS_VERBOSE + VERBOSE_LIN_ANSWER_RESPONSE, +#endif // ESPHOME_LOG_HAS_VERBOSE + + ERROR_CHECK_FOR_LIN_FAULT_DETECTED, + INFO_CHECK_FOR_LIN_FAULT_FIXED, + + ERROR_READ_LIN_FRAME_UNABLE_TO_ANSWER, + ERROR_READ_LIN_FRAME_LOST_MSG, +#ifdef ESPHOME_LOG_HAS_VERY_VERBOSE + VV_READ_LIN_FRAME_BREAK_EXPECTED, + VV_READ_LIN_FRAME_SYNC_EXPECTED, +#endif // ESPHOME_LOG_HAS_VERY_VERBOSE + WARN_READ_LIN_FRAME_SID_CRC, + WARN_READ_LIN_FRAME_LINv1_CRC, + WARN_READ_LIN_FRAME_LINv2_CRC, +#ifdef ESPHOME_LOG_HAS_VERBOSE + VERBOSE_READ_LIN_FRAME_MSG, +#endif // ESPHOME_LOG_HAS_VERBOSE +}; + +// Log messages generated during interrupt are pushed to log queue. +struct QUEUE_LOG_MSG { + QUEUE_LOG_MSG_TYPE type; + u_int8_t current_PID; + u_int8_t data[9]; + u_int8_t len; +#ifdef ESPHOME_LOG_HAS_VERBOSE + bool current_data_valid; + bool message_source_know; + bool message_from_master; +#endif // ESPHOME_LOG_HAS_VERBOSE +}; + class LinBusListener : public PollingComponent, public uart::UARTDevice { public: float get_setup_priority() const override { return setup_priority::DATA; } @@ -41,7 +88,7 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice { GPIOPin *fault_pin_ = nullptr; bool observer_mode_ = false; - void write_lin_answer_(const u_int8_t *data, size_t len); + void write_lin_answer_(const u_int8_t *data, u_int8_t len); bool check_for_lin_fault_(); virtual bool answer_lin_order_(const u_int8_t pid) = 0; virtual void lin_message_recieved_(const u_int8_t pid, const u_int8_t *message, u_int8_t length) = 0; @@ -95,10 +142,30 @@ class LinBusListener : public PollingComponent, public uart::UARTDevice { void read_lin_frame_(); void clear_uart_buffer_(); void setup_framework(); + void process_lin_msg_queue_(TickType_t xTicksToWait); + void process_log_queue_(TickType_t xTicksToWait); + uint8_t lin_msg_static_queue_storage[6 * sizeof(QUEUE_LIN_MSG)]; + StaticQueue_t lin_msg_static_queue_; + QueueHandle_t lin_msg_queue_ = + xQueueCreateStatic(/* uxQueueLength */ 6, + /* uxItemSize */ sizeof(QUEUE_LIN_MSG), + /* pucQueueStorageBuffer */ lin_msg_static_queue_storage, &lin_msg_static_queue_); + + uint8_t log_static_queue_storage[6 * sizeof(QUEUE_LOG_MSG)]; + StaticQueue_t log_static_queue_; + QueueHandle_t log_queue_ = + xQueueCreateStatic(/* uxQueueLength */ 6, + /* uxItemSize */ sizeof(QUEUE_LOG_MSG), + /* pucQueueStorageBuffer */ log_static_queue_storage, &log_static_queue_); + +#ifdef USE_ESP32 + TaskHandle_t eventTaskHandle_; + static void eventTask_(void *args); +#endif // USE_ESP32 #ifdef USE_ESP32_FRAMEWORK_ESP_IDF - TaskHandle_t _eventTask; - static void _uartEventTask(void *args); + TaskHandle_t uartEventTaskHandle_; + static void uartEventTask_(void *args); #endif // USE_ESP32_FRAMEWORK_ESP_IDF #ifdef USE_RP2040 u_int8_t uart_number_ = 0; diff --git a/components/truma_inetbox/LinBusListener_esp32_arduino.cpp b/components/truma_inetbox/LinBusListener_esp32_arduino.cpp index 5d11496..9e38f58 100644 --- a/components/truma_inetbox/LinBusListener_esp32_arduino.cpp +++ b/components/truma_inetbox/LinBusListener_esp32_arduino.cpp @@ -47,6 +47,27 @@ void LinBusListener::setup_framework() { return; } }); + + // Creating LIN msg event Task + xTaskCreatePinnedToCore(LinBusListener::eventTask_, + "lin_event_task", // name + 4096, // stack size (in words) + this, // input params + 2, // priority + &this->eventTaskHandle_, // handle + 0 // core + ); + + if (this->eventTaskHandle_ == NULL) { + ESP_LOGE(TAG, " -- LIN message Task not created!"); + } +} + +void LinBusListener::eventTask_(void *args) { + LinBusListener *instance = (LinBusListener *) args; + for (;;) { + instance->process_lin_msg_queue_((portTickType) portMAX_DELAY); + } } } // namespace truma_inetbox diff --git a/components/truma_inetbox/LinBusListener_esp_idf.cpp b/components/truma_inetbox/LinBusListener_esp_idf.cpp index 191d51c..5a1b5ad 100644 --- a/components/truma_inetbox/LinBusListener_esp_idf.cpp +++ b/components/truma_inetbox/LinBusListener_esp_idf.cpp @@ -29,20 +29,34 @@ void LinBusListener::setup_framework() { uart_intr_config(uart_num, &uart_intr); // Creating UART event Task - xTaskCreatePinnedToCore(LinBusListener::_uartEventTask, + xTaskCreatePinnedToCore(LinBusListener::uartEventTask_, "uart_event_task", // name ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE, // stack size (in words) this, // input params 24, // priority - &_eventTask, // handle + &this->uartEventTaskHandle_, // handle ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE // core ); - if (_eventTask == NULL) { - ESP_LOGE(TAG, " -- UART%d Event Task not Created!", uart_num); + if (this->uartEventTaskHandle_ == NULL) { + ESP_LOGE(TAG, " -- UART%d Event Task not created!", uart_num); + } + + // Creating LIN msg event Task + xTaskCreatePinnedToCore(LinBusListener::eventTask_, + "lin_event_task", // name + ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE, // stack size (in words) + this, // input params + 2, // priority + &this->eventTaskHandle_, // handle + ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE // core + ); + + if (this->eventTaskHandle_ == NULL) { + ESP_LOGE(TAG, " -- LIN message Task not created!"); } } -void LinBusListener::_uartEventTask(void *args) { +void LinBusListener::uartEventTask_(void *args) { LinBusListener *instance = (LinBusListener *) args; auto uartComp = static_cast(instance->parent_); auto uart_num = uartComp->get_hw_serial_number(); @@ -65,6 +79,13 @@ void LinBusListener::_uartEventTask(void *args) { vTaskDelete(NULL); } +void LinBusListener::eventTask_(void *args) { + LinBusListener *instance = (LinBusListener *) args; + for (;;) { + instance->process_lin_msg_queue_((portTickType) portMAX_DELAY); + } +} + } // namespace truma_inetbox } // namespace esphome diff --git a/components/truma_inetbox/LinBusListener_rp2040.cpp b/components/truma_inetbox/LinBusListener_rp2040.cpp index b9d9955..51472b6 100644 --- a/components/truma_inetbox/LinBusListener_rp2040.cpp +++ b/components/truma_inetbox/LinBusListener_rp2040.cpp @@ -98,6 +98,14 @@ extern void loop1() { if (LIN_BUS_LISTENER_INSTANCE_2 != nullptr) { sleep2 = LIN_BUS_LISTENER_INSTANCE_2->onSerialEvent(); } + // TODO: Reconsider processing lin messages here. + // They contain blocking log messages. + if (LIN_BUS_LISTENER_INSTANCE_1 != nullptr) { + LIN_BUS_LISTENER_INSTANCE_1->process_lin_msg_queue_((portTickType) 0 /* No blocking*/); + } + if (LIN_BUS_LISTENER_INSTANCE_2 != nullptr) { + LIN_BUS_LISTENER_INSTANCE_2->process_lin_msg_queue_((portTickType) 0 /* No blocking*/); + } delay(sleep1 > sleep2 ? sleep2 : sleep1); } } diff --git a/components/truma_inetbox/LinBusProtocol.cpp b/components/truma_inetbox/LinBusProtocol.cpp index b35e44a..ec01b9f 100644 --- a/components/truma_inetbox/LinBusProtocol.cpp +++ b/components/truma_inetbox/LinBusProtocol.cpp @@ -25,7 +25,7 @@ bool LinBusProtocol::answer_lin_order_(const u_int8_t pid) { if (!this->updates_to_send_.empty()) { auto update_to_send_ = this->updates_to_send_.front(); this->updates_to_send_.pop(); - this->write_lin_answer_(update_to_send_.data(), update_to_send_.size()); + this->write_lin_answer_(update_to_send_.data(), (u_int8_t) update_to_send_.size()); return true; } } diff --git a/components/truma_inetbox/TrumaiNetBoxApp.cpp b/components/truma_inetbox/TrumaiNetBoxApp.cpp index 48f9df1..6f59192 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.cpp +++ b/components/truma_inetbox/TrumaiNetBoxApp.cpp @@ -182,7 +182,7 @@ bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) { if (this->updates_to_send_.empty() && !this->has_update_to_submit_()) { response[0] = 0xFE; } - this->write_lin_answer_(response.data(), sizeof(response)); + this->write_lin_answer_(response.data(), (u_int8_t) sizeof(response)); return true; } return LinBusProtocol::answer_lin_order_(pid); @@ -431,28 +431,31 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message } bool TrumaiNetBoxApp::has_update_to_submit_() { + // No logging in this message! + // It is called by interrupt. Logging is a blocking operation (especially when Wifi Logging). + // If logging is necessary use logging queue of LinBusListener class. if (this->init_requested_ == 0) { this->init_requested_ = micros(); - ESP_LOGD(TAG, "Requesting initial data."); + // ESP_LOGD(TAG, "Requesting initial data."); return true; } else if (this->init_recieved_ == 0) { 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_LOGD(TAG, "Requesting initial data again."); + // ESP_LOGD(TAG, "Requesting initial data again."); 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_LOGD(TAG, "Notify CP Plus I got updates."); + // ESP_LOGD(TAG, "Notify CP Plus I got updates."); this->update_time_ = micros(); return true; } auto update_wait_time = micros() - this->update_time_; if (update_wait_time > 1000 * 1000 * 5) { - ESP_LOGD(TAG, "Notify CP Plus again I still got updates."); + // ESP_LOGD(TAG, "Notify CP Plus again I still got updates."); this->update_time_ = micros(); return true; }