No logging inside interrupt.
Log from interrupt via Queue. Incomming message processing via Queue.
This commit is contained in:
parent
73792d79d2
commit
28a4a52dde
@ -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
|
||||
|
||||
@ -3,6 +3,9 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/uart/uart.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
#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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<uart::truma_IDFUARTComponent *>(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
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user