Merge remote-tracking branch 'origin/master' into feature/knx

This commit is contained in:
John
2022-08-31 20:34:09 +02:00
3 changed files with 76 additions and 20 deletions
+11 -7
View File
@@ -1,6 +1,7 @@
## Transfer speed ## 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 ## Protocol
@@ -103,21 +104,21 @@ These are the predefined symbols as used above.
* ERR_OVERRUN 0x01: buffer overrun error * ERR_OVERRUN 0x01: buffer overrun error
### Feature bits (both directions) ### Feature bits (both directions)
* bit 7-1: tbd * bit 7-2: tbd
* bit 2: full message sending (complete sequence instead of single bytes) * // planned: bit 1: 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 0: additional infos (version, PIC ID, etc.) * bit 0: additional infos (version, PIC ID, etc.)
### Information IDs (both directions) ### Information IDs (both directions)
The first level below is the `info_id` value and the second level describes the response data byte sequence. 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). The first byte transferred in response is always the number of data bytes to be transferred (excluding the length itself).
* 0x00: version * 0x00: version
* `length`: =5 (2 before 20220220) * `length`: =8 (2 before 20220220, 5 before 20220831)
* `version`: version number * `version`: version number
* `features`: feature bits * `features`: feature bits
* `checksum_H` `checksum_L`: checksum (since 20220220) * `checksum_H` `checksum_L`: checksum (since 20220220)
* `jumpers`: jumper settings * `jumpers`: jumper settings
* `bootloader_version`: bootloader version (since 20220831)
* `bootloader_checksum_H` `bootloader_checksum_L`: bootloader checksum
* 0x01: PIC ID * 0x01: PIC ID
* `length`: =9 * `length`: =9
* 9*`mui`: PIC MUI * 9*`mui`: PIC MUI
@@ -134,4 +135,7 @@ The first byte transferred in response is always the number of data bytes to be
* `length`: =2 * `length`: =2
* `voltage_max`: maximum bus voltage in 10th volts * `voltage_max`: maximum bus voltage in 10th volts
* `voltage_min`: minimum 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)
+63 -13
View File
@@ -80,7 +80,8 @@ Device::Device(const char* name, bool checkDevice, unsigned int latency, bool re
bool enhancedProto) bool enhancedProto)
: m_name(name), m_checkDevice(checkDevice), : m_name(name), m_checkDevice(checkDevice),
m_latency(HOST_LATENCY_MS+(enhancedProto?ENHANCED_LATENCY_MS:0)+latency), m_readOnly(readOnly), 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_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_extraFatures(0), m_infoId(0xff), m_infoLen(0), m_infoPos(0) {
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize)); m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
@@ -158,6 +159,7 @@ result_t Device::afterOpen() {
if (m_listener != nullptr) { if (m_listener != nullptr) {
m_listener->notifyStatus(false, "resetting"); m_listener->notifyStatus(false, "resetting");
} }
m_resetRequested = true;
} else if (m_initialSend && !write(ESC)) { } else if (m_initialSend && !write(ESC)) {
return RESULT_ERR_SEND; return RESULT_ERR_SEND;
} }
@@ -227,6 +229,10 @@ string Device::getEnhancedInfos() {
return "cannot request config"; return "cannot request config";
} }
} }
res = requestEnhancedInfo(6);
if (res != RESULT_OK) {
return "cannot request reset info";
}
res = requestEnhancedInfo(3); res = requestEnhancedInfo(3);
if (res != RESULT_OK) { if (res != RESULT_OK) {
return "cannot request temperature"; return "cannot request temperature";
@@ -446,7 +452,7 @@ bool Device::available() {
symbol_t ch = m_buffer[(pos+m_bufPos)%m_bufSize]; symbol_t ch = m_buffer[(pos+m_bufPos)%m_bufSize];
if (!(ch&ENH_BYTE_FLAG)) { if (!(ch&ENH_BYTE_FLAG)) {
#ifdef DEBUG_RAW_TRAFFIC #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); fflush(stdout);
#endif #endif
return true; return true;
@@ -459,7 +465,7 @@ bool Device::available() {
ch = m_buffer[(pos+m_bufPos+1)%m_bufSize]; ch = m_buffer[(pos+m_bufPos+1)%m_bufSize];
if (!(ch&ENH_BYTE_FLAG) || (ch&ENH_BYTE_MASK) != ENH_BYTE2) { if (!(ch&ENH_BYTE_FLAG) || (ch&ENH_BYTE_MASK) != ENH_BYTE2) {
#ifdef DEBUG_RAW_TRAFFIC #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); fflush(stdout);
#endif #endif
if (m_listener != nullptr) { if (m_listener != nullptr) {
@@ -472,13 +478,13 @@ bool Device::available() {
continue; continue;
} }
#ifdef DEBUG_RAW_TRAFFIC #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); fflush(stdout);
#endif #endif
return true; return true;
} }
#ifdef DEBUG_RAW_TRAFFIC #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); fflush(stdout);
#endif #endif
if (m_listener != nullptr) { if (m_listener != nullptr) {
@@ -508,11 +514,19 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
tail = (m_bufPos+m_bufLen) % m_bufSize; tail = (m_bufPos+m_bufLen) % m_bufSize;
size_t head = m_bufLen-tail; size_t head = m_bufLen-tail;
memmove(m_buffer+head, m_buffer, 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 { } else {
tail = 0; tail = 0;
} }
// move head to first position // move head to first position
memmove(m_buffer, m_buffer + m_bufPos, m_bufLen - tail); 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; m_bufPos = 0;
@@ -524,7 +538,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
#ifdef DEBUG_RAW_TRAFFIC #ifdef DEBUG_RAW_TRAFFIC
fprintf(stdout, "raw %ld+%ld <", m_bufLen, size); fprintf(stdout, "raw %ld+%ld <", m_bufLen, size);
for (int pos=0; pos < size; pos++) { 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"); fprintf(stdout, "\n");
fflush(stdout); fflush(stdout);
@@ -612,6 +626,16 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
m_arbitrationMaster = SYN; m_arbitrationMaster = SYN;
m_arbitrationCheck = 0; 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; m_extraFatures = data;
if (m_listener != nullptr) { if (m_listener != nullptr) {
m_listener->notifyStatus(false, (m_extraFatures&0x01) ? "reset, supports info" : "reset"); m_listener->notifyStatus(false, (m_extraFatures&0x01) ? "reset, supports info" : "reset");
@@ -631,12 +655,19 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
switch ((m_infoLen << 8) | m_infoId) { switch ((m_infoLen << 8) | m_infoId) {
case 0x0200: case 0x0200:
case 0x0500: // with firmware version and jumper info case 0x0500: // with firmware version and jumper info
stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." << std::hex case 0x0800: // with firmware version, jumper info, and bootloader version
<< static_cast<unsigned>(m_infoBuf[1]); stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." // version minor
if (m_infoLen>4) { << std::hex << static_cast<unsigned>(m_infoBuf[1]); // features mask
stream << " [" << std::hex << static_cast<unsigned>(m_infoBuf[2]) if (m_infoLen>=5) {
<< static_cast<unsigned>(m_infoBuf[3]) << "]"; stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[2])
stream << ", jumpers 0x" << std::hex << static_cast<unsigned>(m_infoBuf[4]); << std::setw(2) << static_cast<unsigned>(m_infoBuf[3]) << "]";
stream << ", jumpers 0x" << std::setw(2) << static_cast<unsigned>(m_infoBuf[4]);
stream << std::setfill(' '); // reset
}
if (m_infoLen>=8) {
stream << ", bootloader " << std::dec << static_cast<unsigned>(m_infoBuf[5]);
stream << " [" << std::setfill('0') << std::setw(2) << std::hex << static_cast<unsigned>(m_infoBuf[6])
<< std::setw(2) << static_cast<unsigned>(m_infoBuf[7]) << "]";
} }
break; break;
case 0x0901: case 0x0901:
@@ -646,7 +677,7 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
for (uint8_t pos = 0; pos < m_infoPos; pos++) { for (uint8_t pos = 0; pos < m_infoPos; pos++) {
stream << " " << std::setw(2) << static_cast<unsigned>(m_infoBuf[pos]); stream << " " << std::setw(2) << static_cast<unsigned>(m_infoBuf[pos]);
} }
if (m_infoId == 2 && m_infoBuf[2]!=0x3f) { if (m_infoId == 2 && (m_infoBuf[2]&0x3f)!=0x3f) {
// non-default arbitration delay // non-default arbitration delay
val = (m_infoBuf[2]&0x3f)*10; // steps of 10us val = (m_infoBuf[2]&0x3f)*10; // steps of 10us
stream << ", arbitration delay " << std::dec << static_cast<unsigned>(val) << " us"; stream << ", arbitration delay " << std::dec << static_cast<unsigned>(val) << " us";
@@ -668,6 +699,25 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
<< static_cast<float>(m_infoBuf[0] / 10.0) << " V"; << static_cast<float>(m_infoBuf[0] / 10.0) << " V";
m_enhInfoBusVoltage = stream.str(); m_enhInfoBusVoltage = stream.str();
break; break;
case 0x0206:
stream << "reset cause ";
if (m_infoBuf[0]) {
stream << static_cast<unsigned>(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<unsigned>(m_infoBuf[1]);
} else {
stream << "unknown";
}
break;
default: default:
stream << "unknown 0x" << std::hex << std::setfill('0') << std::setw(2) stream << "unknown 0x" << std::hex << std::setfill('0') << std::setw(2)
<< static_cast<unsigned>(m_infoId) << ", len " << std::dec << std::setw(0) << static_cast<unsigned>(m_infoId) << ", len " << std::dec << std::setw(0)
+2
View File
@@ -283,6 +283,8 @@ class Device {
/** the opened file descriptor, or -1. */ /** the opened file descriptor, or -1. */
int m_fd; int m_fd;
/** whether the reset of an enhanced device was already requested. */
bool m_resetRequested;
private: private:
/** the @a DeviceListener, or nullptr. */ /** the @a DeviceListener, or nullptr. */