From a1d977e09edf816e1f70aeb89238f6607f11ed7b Mon Sep 17 00:00:00 2001 From: John Date: Wed, 31 Aug 2022 20:18:27 +0200 Subject: [PATCH 1/4] add high speed note, correct feature bits --- docs/enhanced_proto.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/enhanced_proto.md b/docs/enhanced_proto.md index ee98bc16..19483cdd 100644 --- a/docs/enhanced_proto.md +++ b/docs/enhanced_proto.md @@ -1,6 +1,7 @@ ## Transfer speed -In order to compensate potential overhead of transfer encoding, the transfer speed is set to 9600 Baud with 8 bits, no parity, and 1 stop bit. +In order to compensate potential overhead of transfer encoding, the transfer speed is set to 9600 Baud or 115200 Baud +with 8 bits, no parity, and 1 stop bit. ## Protocol @@ -103,10 +104,8 @@ These are the predefined symbols as used above. * ERR_OVERRUN 0x01: buffer overrun error ### Feature bits (both directions) - * bit 7-1: tbd - * bit 2: full message sending (complete sequence instead of single bytes) - * bit 1: high speed transfer at 115200 Bd - When requested, the UART speed is changed to 115200 Bd immediately after sending the complete RESETTED reponse. + * bit 7-2: tbd + * // planned: bit 1: full message sending (complete sequence instead of single bytes) * bit 0: additional infos (version, PIC ID, etc.) ### Information IDs (both directions) From 31241ebec3a44444f4abb9c1e33face5d1b6c988 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 31 Aug 2022 20:21:59 +0200 Subject: [PATCH 2/4] add bootloader version and reset info --- docs/enhanced_proto.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/enhanced_proto.md b/docs/enhanced_proto.md index 19483cdd..3ad225fa 100644 --- a/docs/enhanced_proto.md +++ b/docs/enhanced_proto.md @@ -112,11 +112,13 @@ These are the predefined symbols as used above. The first level below is the `info_id` value and the second level describes the response data byte sequence. The first byte transferred in response is always the number of data bytes to be transferred (excluding the length itself). * 0x00: version - * `length`: =5 (2 before 20220220) + * `length`: =8 (2 before 20220220, 5 before 20220831) * `version`: version number * `features`: feature bits * `checksum_H` `checksum_L`: checksum (since 20220220) * `jumpers`: jumper settings + * `bootloader_version`: bootloader version (since 20220831) + * `bootloader_checksum_H` `bootloader_checksum_L`: bootloader checksum * 0x01: PIC ID * `length`: =9 * 9*`mui`: PIC MUI @@ -133,4 +135,7 @@ The first byte transferred in response is always the number of data bytes to be * `length`: =2 * `voltage_max`: maximum bus voltage in 10th volts * `voltage_min`: minimum bus voltage in 10th volts - + * 0x06: reset info (since 20220831) + * `length`: =2 + * `reset_cause`: reset cause (1=power-on, 2=brown-out, 3=watchdog, 4=clear, 5=reset, 6=stack, 7=memory) + * `restart_count`: restart count (within same power cycle) From b1893abe7d4c72cceec470205e62f2ab85b2149e Mon Sep 17 00:00:00 2001 From: John Date: Wed, 31 Aug 2022 20:24:01 +0200 Subject: [PATCH 3/4] reset the connection completely if adapter was reset --- src/lib/ebus/device.cpp | 14 +++++++++++++- src/lib/ebus/device.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lib/ebus/device.cpp b/src/lib/ebus/device.cpp index 5d712042..953fb551 100755 --- a/src/lib/ebus/device.cpp +++ b/src/lib/ebus/device.cpp @@ -80,7 +80,8 @@ Device::Device(const char* name, bool checkDevice, unsigned int latency, bool re bool enhancedProto) : m_name(name), m_checkDevice(checkDevice), m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency), m_readOnly(readOnly), - m_initialSend(initialSend), m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN), + m_initialSend(initialSend), m_enhancedProto(enhancedProto), m_fd(-1), m_resetRequested(false), + m_listener(nullptr), m_arbitrationMaster(SYN), m_arbitrationCheck(0), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0), m_extraFatures(0), m_infoId(0xff), m_infoLen(0), m_infoPos(0) { m_buffer = reinterpret_cast(malloc(m_bufSize)); @@ -158,6 +159,7 @@ result_t Device::afterOpen() { if (m_listener != nullptr) { m_listener->notifyStatus(false, "resetting"); } + m_resetRequested = true; } else if (m_initialSend && !write(ESC)) { return RESULT_ERR_SEND; } @@ -612,6 +614,16 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati m_arbitrationMaster = SYN; m_arbitrationCheck = 0; } + m_enhInfoTemperature = ""; + m_enhInfoSupplyVoltage = ""; + m_enhInfoBusVoltage = ""; + m_infoId = 0xff; + if (m_resetRequested) { + m_resetRequested = false; + } else { + close(); // on self-reset of device close and reopen it to have a clean startup + cancelRunningArbitration(arbitrationState); + } m_extraFatures = data; if (m_listener != nullptr) { m_listener->notifyStatus(false, (m_extraFatures&0x01) ? "reset, supports info" : "reset"); diff --git a/src/lib/ebus/device.h b/src/lib/ebus/device.h index e77312a3..1cf944aa 100755 --- a/src/lib/ebus/device.h +++ b/src/lib/ebus/device.h @@ -283,6 +283,8 @@ class Device { /** the opened file descriptor, or -1. */ int m_fd; + /** whether the reset of an enhanced device was already requested. */ + bool m_resetRequested; private: /** the @a DeviceListener, or nullptr. */ From 49a6014c43df32654c73d42b9bfcc0b9c4fc9ea2 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 31 Aug 2022 20:25:22 +0200 Subject: [PATCH 4/4] add bootloader version and reset info, debugging --- src/lib/ebus/device.cpp | 62 +++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/src/lib/ebus/device.cpp b/src/lib/ebus/device.cpp index 953fb551..993976a1 100755 --- a/src/lib/ebus/device.cpp +++ b/src/lib/ebus/device.cpp @@ -229,6 +229,10 @@ string Device::getEnhancedInfos() { return "cannot request config"; } } + res = requestEnhancedInfo(6); + if (res != RESULT_OK) { + return "cannot request reset info"; + } res = requestEnhancedInfo(3); if (res != RESULT_OK) { return "cannot request temperature"; @@ -448,7 +452,7 @@ bool Device::available() { symbol_t ch = m_buffer[(pos+m_bufPos)%m_bufSize]; if (!(ch&ENH_BYTE_FLAG)) { #ifdef DEBUG_RAW_TRAFFIC - fprintf(stdout, "raw avail direct\n"); + fprintf(stdout, "raw avail direct @%d+%d %2.2x\n", m_bufPos, pos, ch); fflush(stdout); #endif return true; @@ -461,7 +465,7 @@ bool Device::available() { ch = m_buffer[(pos+m_bufPos+1)%m_bufSize]; if (!(ch&ENH_BYTE_FLAG) || (ch&ENH_BYTE_MASK) != ENH_BYTE2) { #ifdef DEBUG_RAW_TRAFFIC - fprintf(stdout, "raw avail enhanced following bad\n"); + fprintf(stdout, "raw avail enhanced following bad @%d+%d %2.2x %2.2x\n", m_bufPos, pos, m_buffer[(pos+m_bufPos)%m_bufSize], ch); fflush(stdout); #endif if (m_listener != nullptr) { @@ -474,13 +478,13 @@ bool Device::available() { continue; } #ifdef DEBUG_RAW_TRAFFIC - fprintf(stdout, "raw avail enhanced\n"); + fprintf(stdout, "raw avail enhanced @%d+%d %2.2x %2.2x\n", m_bufPos, pos, m_buffer[(pos+m_bufPos)%m_bufSize], ch); fflush(stdout); #endif return true; } #ifdef DEBUG_RAW_TRAFFIC - fprintf(stdout, "raw avail enhanced bad\n"); + fprintf(stdout, "raw avail enhanced bad @%d+%d %2.2x\n", m_bufPos, pos, ch); fflush(stdout); #endif if (m_listener != nullptr) { @@ -510,11 +514,19 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati tail = (m_bufPos+m_bufLen) % m_bufSize; size_t head = m_bufLen-tail; memmove(m_buffer+head, m_buffer, tail); +#ifdef DEBUG_RAW_TRAFFIC + fprintf(stdout, "raw move tail %d @0 to @%d\n", tail, head); + fflush(stdout); +#endif } else { tail = 0; } // move head to first position memmove(m_buffer, m_buffer + m_bufPos, m_bufLen - tail); +#ifdef DEBUG_RAW_TRAFFIC + fprintf(stdout, "raw move head %d @%d to 0\n", m_bufLen - tail, m_bufPos); + fflush(stdout); +#endif } } m_bufPos = 0; @@ -526,7 +538,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati #ifdef DEBUG_RAW_TRAFFIC fprintf(stdout, "raw %ld+%ld <", m_bufLen, size); for (int pos=0; pos < size; pos++) { - fprintf(stdout, " %2.2x", m_buffer[m_bufLen+pos]); + fprintf(stdout, " %2.2x", m_buffer[(m_bufLen+pos)%m_bufSize]); } fprintf(stdout, "\n"); fflush(stdout); @@ -643,12 +655,19 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati switch ((m_infoLen << 8) | m_infoId) { case 0x0200: case 0x0500: // with firmware version and jumper info - stream << "firmware " << static_cast(m_infoBuf[0]) << "." << std::hex - << static_cast(m_infoBuf[1]); - if (m_infoLen>4) { - stream << " [" << std::hex << static_cast(m_infoBuf[2]) - << static_cast(m_infoBuf[3]) << "]"; - stream << ", jumpers 0x" << std::hex << static_cast(m_infoBuf[4]); + case 0x0800: // with firmware version, jumper info, and bootloader version + stream << "firmware " << static_cast(m_infoBuf[0]) << "." // version minor + << std::hex << static_cast(m_infoBuf[1]); // features mask + if (m_infoLen>=5) { + stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast(m_infoBuf[2]) + << std::setw(2) << static_cast(m_infoBuf[3]) << "]"; + stream << ", jumpers 0x" << std::setw(2) << static_cast(m_infoBuf[4]); + stream << std::setfill(' '); // reset + } + if (m_infoLen>=8) { + stream << ", bootloader " << std::dec << static_cast(m_infoBuf[5]); + stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast(m_infoBuf[6]) + << std::setw(2) << static_cast(m_infoBuf[7]) << "]"; } break; case 0x0901: @@ -658,7 +677,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati for (uint8_t pos = 0; pos < m_infoPos; pos++) { stream << " " << std::setw(2) << static_cast(m_infoBuf[pos]); } - if (m_infoId == 2 && m_infoBuf[2]!=0x3f) { + if (m_infoId == 2 && (m_infoBuf[2]&0x3f)!=0x3f) { // non-default arbitration delay val = (m_infoBuf[2]&0x3f)*10; // steps of 10us stream << ", arbitration delay " << std::dec << static_cast(val) << " us"; @@ -680,6 +699,25 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati << static_cast(m_infoBuf[0] / 10.0) << " V"; m_enhInfoBusVoltage = stream.str(); break; + case 0x0206: + stream << "reset cause "; + if (m_infoBuf[0]) { + stream << static_cast(m_infoBuf[0]) << "="; + switch (m_infoBuf[0]) { + case 1: stream << "power-on"; break; + case 2: stream << "brown-out"; break; + case 3: stream << "watchdog"; break; + case 4: stream << "clear"; break; + case 5: stream << "reset"; break; + case 6: stream << "stack"; break; + case 7: stream << "memory"; break; + default: stream << "other"; break; + } + stream << ", restart count " << static_cast(m_infoBuf[1]); + } else { + stream << "unknown"; + } + break; default: stream << "unknown 0x" << std::hex << std::setfill('0') << std::setw(2) << static_cast(m_infoId) << ", len " << std::dec << std::setw(0)