prepare upcoming adapter3 firmware enhancements
This commit is contained in:
+49
-73
@@ -23,7 +23,9 @@ first second
|
|||||||
#### from ebusd to interface
|
#### from ebusd to interface
|
||||||
* initialization request
|
* initialization request
|
||||||
`<INIT> <features>`
|
`<INIT> <features>`
|
||||||
Requests an initialization of the interface and requests special features in the data byte (tbd).
|
Requests an initialization of the interface and optionally requests special features.
|
||||||
|
The data byte `d` indicates interest in certain features (like full message sending instead of arbitration only).
|
||||||
|
The feature bits are defined below in the symbols section.
|
||||||
* send data request
|
* send data request
|
||||||
`<SEND> <data>`
|
`<SEND> <data>`
|
||||||
Requests the specified data byte in `d` to be sent to the eBUS.
|
Requests the specified data byte in `d` to be sent to the eBUS.
|
||||||
@@ -32,12 +34,19 @@ first second
|
|||||||
`<START> <master>`
|
`<START> <master>`
|
||||||
Requests the start of the arbitration process after the next received `<SYN>` symbol with the specified master address in `d`.
|
Requests the start of the arbitration process after the next received `<SYN>` symbol with the specified master address in `d`.
|
||||||
If the master address is `<SYN>`, the current arbitration is supposed to be cancelled.
|
If the master address is `<SYN>`, the current arbitration is supposed to be cancelled.
|
||||||
|
* information request
|
||||||
|
`<INFO> <info_id>`
|
||||||
|
Requests the transfer of additional info identified by `info_id`.
|
||||||
|
The possible `info_id` values are defined below in the symbols section.
|
||||||
|
Sending a new info request while the response for the previous one is still in progress immediately terminates the
|
||||||
|
transfer of the previous response.
|
||||||
|
|
||||||
#### from interface to ebusd
|
#### from interface to ebusd
|
||||||
* initialization response
|
* initialization response
|
||||||
`<RESETTED> <features>`
|
`<RESETTED> <features>`
|
||||||
Indicates a reboot or an initial ebusd connection on the interface and is expected to be returned after an `<INIT`> request.
|
Indicates a reboot or an initial ebusd connection on the interface and is expected to be returned after an `<INIT`> request.
|
||||||
The data byte `d` indicates availability of certain features (like full message sending instead of arbitration only, tbd).
|
The data byte `d` indicates availability of certain features (like full message sending instead of arbitration only).
|
||||||
|
The feature bits are defined below in the symbols section.
|
||||||
* receive data notification
|
* receive data notification
|
||||||
`<RECEIVED> <data>`
|
`<RECEIVED> <data>`
|
||||||
Indicates that the specified data byte in `d` was received from the eBUS.
|
Indicates that the specified data byte in `d` was received from the eBUS.
|
||||||
@@ -51,6 +60,12 @@ first second
|
|||||||
`<FAILED> <master>`
|
`<FAILED> <master>`
|
||||||
Indicates that the last arbitration request failed (arbitration was lost or sending failed).
|
Indicates that the last arbitration request failed (arbitration was lost or sending failed).
|
||||||
The data byte in `d` contains the master address that has won the arbitration.
|
The data byte in `d` contains the master address that has won the arbitration.
|
||||||
|
* information response
|
||||||
|
`<INFO> <data>`
|
||||||
|
Transfers one data byte in response to the INFO request. The first byte transferred in response is the number of
|
||||||
|
data bytes to be transferred (excluding the length itself). The format of the data sequence depends on the `info_id`
|
||||||
|
value from the request.
|
||||||
|
The possible `info_id` values are defined below in the symbols section.
|
||||||
* eBUS communication error
|
* eBUS communication error
|
||||||
`<ERROR_EBUS> <error>`
|
`<ERROR_EBUS> <error>`
|
||||||
Indicates an error in the eBUS UART.
|
Indicates an error in the eBUS UART.
|
||||||
@@ -72,86 +87,47 @@ These are the predefined symbols as used above.
|
|||||||
* INIT 0x0
|
* INIT 0x0
|
||||||
* SEND 0x1
|
* SEND 0x1
|
||||||
* START 0x2
|
* START 0x2
|
||||||
|
* INFO 0x3
|
||||||
|
|
||||||
### Command response symbols (from interface to ebusd)
|
### Command response symbols (from interface to ebusd)
|
||||||
* RESETTED 0x0
|
* RESETTED 0x0
|
||||||
* RECEIVED 0x1
|
* RECEIVED 0x1
|
||||||
* STARTED 0x2
|
* STARTED 0x2
|
||||||
|
* INFO 0x3
|
||||||
* FAILED 0xa
|
* FAILED 0xa
|
||||||
|
|
||||||
### Error codes (from interface to ebusd)
|
### Error codes (from interface to ebusd)
|
||||||
* ERR_FRAMING 0x00: framing error
|
* ERR_FRAMING 0x00: framing error
|
||||||
* ERR_OVERRUN 0x00: buffer overrun error
|
* 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 0: additional infos (version, PIC ID, etc.)
|
||||||
|
|
||||||
## Examples
|
### Information IDs (both directions)
|
||||||
|
The first level below is the `info_id` value and the second level describes the response data byte sequence.
|
||||||
### Passive receive
|
The first byte transferred in response is always the number of data bytes to be transferred (excluding the length itself).
|
||||||
The master-slave data sequence (without SYN, ACK, and CRC) `1008951200 / 0164` when ebusd is only listening to traffic on the bus would usually be transferred as follows (with all extra symbols seen on the bus):
|
* 0x00: version
|
||||||
|
* `length`: =2
|
||||||
|order|eBUS proto|eBUS byte|sender|enhanced proto|enhanced bytes|
|
* `version`: version number
|
||||||
|----:|-----|-----|-----|-----|-----|
|
* `features`: feature bits
|
||||||
|1|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
* 0x01: PIC ID
|
||||||
|2|`QQ`|0x10|interface|`<0x10>`|0x10|
|
* `length`: =9
|
||||||
|3|`ZZ`|0x08|interface|`<0x08>`|0x08|
|
* 9*`mui`: PIC MUI
|
||||||
|4|`PB`|0x95|interface|`<RECEIVED> <0x95>`|0xC6 0x95|
|
* 0x02: PIC config
|
||||||
|5|`SB`|0x12|interface|`<0x12>`|0x12|
|
* `length`: =8
|
||||||
|6|`NN`|0x00|interface|`<0x00>`|0x00|
|
* 8*`config_H` `config_L`: PIC config
|
||||||
|7|`CRC`|0xB1|interface|`<RECEIVED> <0xB1>`|0xC6 0xB1|
|
* 0x03: PIC temperature
|
||||||
|8|`ACK`|0x00|interface|`<0x00>`|0x00|
|
* `length`: =1
|
||||||
|9|`NN`|0x01|interface|`<0x01>`|0x01|
|
* `temp`: temperature in degrees Celsius
|
||||||
|10|`DD`|0x64|interface|`<0x64>`|0x64|
|
* 0x04: PIC supply voltage
|
||||||
|11|`CRC`|0xFF|interface|`<RECEIVED> <0xFF>`|0xC7 0xBF|
|
* `length`: =2
|
||||||
|12|`ACK`|0x00|interface|`<0x00>`|0x00|
|
* `millivolt_H` `millivolt_L`: voltage value in mV
|
||||||
|13|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
* 0x05: bus voltage
|
||||||
|
* `length`: =2
|
||||||
### Active successful send
|
* `voltage_max`: maximum bus voltage in 10th volts
|
||||||
The same data sequence `1008951200 / 0164` when initiated by ebusd as master (with address 0x10) would usually be transferred as follows (with all extra symbols seen on the bus):
|
* `voltage_min`: minimum bus voltage in 10th volts
|
||||||
|
|
||||||
|order|eBUS proto|eBUS byte|sender|enhanced proto|enhanced bytes|
|
|
||||||
|----:|-----|-----|-----|-----|-----|
|
|
||||||
|1| | |ebusd|`<START> <0x10>`|0xC8 0x90|
|
|
||||||
|2|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
|
||||||
|3|`QQ`|0x10|interface|`<STARTED> <0x10>`|0xC8 0x90|
|
|
||||||
|4|`ZZ`|0x08|ebusd|`<0x08>`|0x08|
|
|
||||||
|5|`ZZ`|0x08|interface|`<0x08>`|0x08|
|
|
||||||
|6|`PB`|0x95|ebusd|`<SEND> <0x95>`|0xC6 0x95|
|
|
||||||
|7|`PB`|0x95|interface|`<RECEIVED> <0x95>`|0xC6 0x95|
|
|
||||||
|8|`SB`|0x12|ebusd|`<0x12>`|0x12|
|
|
||||||
|9|`SB`|0x12|interface|`<0x12>`|0x12|
|
|
||||||
|10|`NN`|0x00|ebusd|`<0x00>`|0x00|
|
|
||||||
|11|`NN`|0x00|interface|`<0x00>`|0x00|
|
|
||||||
|12|`CRC`|0xB1|ebusd|`<SEND> <0xB1>`|0xC6 0xB1|
|
|
||||||
|13|`CRC`|0xB1|interface|`<RECEIVED> <0xB1>`|0xC6 0xB1|
|
|
||||||
|14|`ACK`|0x00|interface|`<0x00>`|0x00|
|
|
||||||
|15|`NN`|0x01|interface|`<0x01>`|0x01|
|
|
||||||
|16|`DD`|0x64|interface|`<0x64>`|0x64|
|
|
||||||
|17|`CRC`|0xFF|interface|`<RECEIVED> <0xFF>`|0xC7 0xBF|
|
|
||||||
|18|`ACK`|0x00|ebusd|`<0x00>`|0x00|
|
|
||||||
|19|`ACK`|0x00|interface|`<0x00>`|0x00|
|
|
||||||
|20|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
|
||||||
|
|
||||||
|
|
||||||
### Active successful send as SYN generator
|
|
||||||
The same data sequence `1008951200 / 0164` when initiated by ebusd as master (with address 0x10) and acting as SYN generator would usually be transferred as follows (with all extra symbols seen on the bus):
|
|
||||||
|
|
||||||
|order|eBUS proto|eBUS byte|sender|enhanced proto|enhanced bytes|
|
|
||||||
|----:|-----|-----|-----|-----|-----|
|
|
||||||
|1| | |ebusd|`<START> <0x10>`|0xC8 0x90|
|
|
||||||
|2|`SYN`|0xAA|ebusd|`<SEND> <0xAA>`|0xC6 0xAA|
|
|
||||||
|3|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
|
||||||
|4|`QQ`|0x10|interface|`<STARTED> <0x10>`|0xC8 0x90|
|
|
||||||
|...|see above| | | | |
|
|
||||||
The rest of the communcation is the same as before (from 4.)
|
|
||||||
|
|
||||||
|
|
||||||
### Active failed traffic
|
|
||||||
A failed arbitration when initiated by ebusd as master (with address 0x10) would usually be transferred as follows (with all extra symbols seen on the bus):
|
|
||||||
|
|
||||||
|order|eBUS proto|eBUS byte|sender|enhanced proto|enhanced byte|
|
|
||||||
|----:|-----|-----|-----|-----|-----|
|
|
||||||
|1| | |ebusd|`<START> <0x10>`|0xC8 0x90|
|
|
||||||
|2|`SYN`|0xAA|interface|`<RECEIVED> <0xAA>`|0xC6 0xAA|
|
|
||||||
|3| |0x10|ebusd|`<FAILED> <0x10>`|0xE0 0x90|
|
|
||||||
|4|`QQ`|0x03|interface|`<0x03>`|0x03|
|
|
||||||
|
|
||||||
|
|||||||
@@ -1911,6 +1911,10 @@ result_t MainLoop::executeInfo(const vector<string>& args, const string& user, o
|
|||||||
if (!m_updateCheck.empty()) {
|
if (!m_updateCheck.empty()) {
|
||||||
*ostream << "update check: " << m_updateCheck << "\n";
|
*ostream << "update check: " << m_updateCheck << "\n";
|
||||||
}
|
}
|
||||||
|
string info = m_device->getEnhancedInfos();
|
||||||
|
if (!info.empty()) {
|
||||||
|
*ostream << "device: " << info << "\n";
|
||||||
|
}
|
||||||
if (!user.empty()) {
|
if (!user.empty()) {
|
||||||
*ostream << "user: " << user << "\n";
|
*ostream << "user: " << user << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
+97
-4
@@ -60,6 +60,8 @@ namespace ebusd {
|
|||||||
#define ENH_RES_RECEIVED ((uint8_t)0x1)
|
#define ENH_RES_RECEIVED ((uint8_t)0x1)
|
||||||
#define ENH_REQ_START ((uint8_t)0x2)
|
#define ENH_REQ_START ((uint8_t)0x2)
|
||||||
#define ENH_RES_STARTED ((uint8_t)0x2)
|
#define ENH_RES_STARTED ((uint8_t)0x2)
|
||||||
|
#define ENH_REQ_INFO ((uint8_t)0x3)
|
||||||
|
#define ENH_RES_INFO ((uint8_t)0x3)
|
||||||
#define ENH_RES_FAILED ((uint8_t)0xa)
|
#define ENH_RES_FAILED ((uint8_t)0xa)
|
||||||
#define ENH_RES_ERROR_EBUS ((uint8_t)0xb)
|
#define ENH_RES_ERROR_EBUS ((uint8_t)0xb)
|
||||||
#define ENH_RES_ERROR_HOST ((uint8_t)0xc)
|
#define ENH_RES_ERROR_HOST ((uint8_t)0xc)
|
||||||
@@ -79,7 +81,8 @@ Device::Device(const char* name, bool checkDevice, unsigned int latency, bool re
|
|||||||
: m_name(name), m_checkDevice(checkDevice),
|
: m_name(name), m_checkDevice(checkDevice),
|
||||||
m_latency(HOST_LATENCY_MS+latency), m_readOnly(readOnly), m_initialSend(initialSend),
|
m_latency(HOST_LATENCY_MS+latency), m_readOnly(readOnly), m_initialSend(initialSend),
|
||||||
m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN),
|
m_enhancedProto(enhancedProto), m_fd(-1), m_listener(nullptr), m_arbitrationMaster(SYN),
|
||||||
m_arbitrationCheck(false), m_bufSize(((MAX_LEN+1+3)/4)*4), m_bufLen(0), m_bufPos(0) {
|
m_arbitrationCheck(false), 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<symbol_t*>(malloc(m_bufSize));
|
m_buffer = reinterpret_cast<symbol_t*>(malloc(m_bufSize));
|
||||||
if (!m_buffer) {
|
if (!m_buffer) {
|
||||||
m_bufSize = 0;
|
m_bufSize = 0;
|
||||||
@@ -141,8 +144,9 @@ result_t Device::open() {
|
|||||||
|
|
||||||
result_t Device::afterOpen() {
|
result_t Device::afterOpen() {
|
||||||
m_bufLen = 0;
|
m_bufLen = 0;
|
||||||
|
m_extraFatures = 0;
|
||||||
if (m_enhancedProto) {
|
if (m_enhancedProto) {
|
||||||
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INIT, 0); // TODO define additional feature flags
|
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INIT, 0x01); // extra feature: info
|
||||||
#ifdef DEBUG_RAW_TRAFFIC
|
#ifdef DEBUG_RAW_TRAFFIC
|
||||||
fprintf(stdout, "raw enhanced > %2.2x %2.2x\n", buf[0], buf[1]);
|
fprintf(stdout, "raw enhanced > %2.2x %2.2x\n", buf[0], buf[1]);
|
||||||
#endif
|
#endif
|
||||||
@@ -176,6 +180,47 @@ bool Device::isValid() {
|
|||||||
return m_fd != -1;
|
return m_fd != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result_t Device::requestEnhancedInfo(symbol_t infoId) {
|
||||||
|
if (!m_enhancedProto || m_extraFatures == 0 || infoId == 0xff) {
|
||||||
|
return RESULT_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
if (m_infoId != 0xff) {
|
||||||
|
usleep(40000);
|
||||||
|
if (m_infoId != 0xff) {
|
||||||
|
return RESULT_ERR_DUPLICATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbol_t buf[2] = makeEnhancedSequence(ENH_REQ_INFO, infoId);
|
||||||
|
#ifdef DEBUG_RAW_TRAFFIC
|
||||||
|
fprintf(stdout, "raw enhanced > %2.2x %2.2x\n", buf[0], buf[1]);
|
||||||
|
#endif
|
||||||
|
m_infoPos = 0;
|
||||||
|
m_infoId = infoId;
|
||||||
|
if (::write(m_fd, buf, 2) != 2) {
|
||||||
|
return RESULT_ERR_DEVICE;
|
||||||
|
}
|
||||||
|
return RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Device::getEnhancedInfos() {
|
||||||
|
if (!m_enhancedProto || m_extraFatures == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
result_t res = requestEnhancedInfo(0);
|
||||||
|
if (res != RESULT_OK) {
|
||||||
|
return "cannot request info";
|
||||||
|
}
|
||||||
|
res = requestEnhancedInfo(1);
|
||||||
|
res = requestEnhancedInfo(2);
|
||||||
|
res = requestEnhancedInfo(3);
|
||||||
|
res = requestEnhancedInfo(4);
|
||||||
|
res = requestEnhancedInfo(5);
|
||||||
|
if (m_infoPos == 0) {
|
||||||
|
return "did not get info";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
result_t Device::send(symbol_t value) {
|
result_t Device::send(symbol_t value) {
|
||||||
if (!isValid()) {
|
if (!isValid()) {
|
||||||
return RESULT_ERR_DEVICE;
|
return RESULT_ERR_DEVICE;
|
||||||
@@ -528,9 +573,57 @@ bool Device::read(symbol_t* value, bool isAvailable, ArbitrationState* arbitrati
|
|||||||
m_arbitrationMaster = SYN;
|
m_arbitrationMaster = SYN;
|
||||||
m_arbitrationCheck = false;
|
m_arbitrationCheck = false;
|
||||||
}
|
}
|
||||||
// TODO define additional feature flags
|
m_extraFatures = data;
|
||||||
if (m_listener != nullptr) {
|
if (m_listener != nullptr) {
|
||||||
m_listener->notifyStatus(false, "reset");
|
m_listener->notifyStatus(false, (m_extraFatures&0x01) ? "reset, supports info" : "reset");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ENH_RES_INFO:
|
||||||
|
if (m_infoLen == 0) {
|
||||||
|
if (data<=16) { // max length
|
||||||
|
m_infoLen = data;
|
||||||
|
m_infoPos = 0;
|
||||||
|
}
|
||||||
|
} else if (m_infoPos < m_infoLen) {
|
||||||
|
m_infoBuf[m_infoPos++] = data;
|
||||||
|
if (m_infoPos >= m_infoLen) {
|
||||||
|
unsigned int val;
|
||||||
|
ostringstream stream;
|
||||||
|
stream << "extra info: ";
|
||||||
|
switch ((m_infoLen<<8) | m_infoId) {
|
||||||
|
case 0x0200:
|
||||||
|
stream << "firmware " << static_cast<unsigned>(m_infoBuf[0]) << "." << std::hex << static_cast<unsigned>(m_infoBuf[1]) << ".";
|
||||||
|
break;
|
||||||
|
case 0x0901:
|
||||||
|
case 0x0802:
|
||||||
|
stream << (m_infoId == 1 ? "ID" : "config");
|
||||||
|
stream << std::hex << std::setfill('0');
|
||||||
|
for (uint8_t pos = 0; pos<m_infoPos; pos++) {
|
||||||
|
stream << " " << std::setw(2) << static_cast<unsigned>(m_infoBuf[pos]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x0203:
|
||||||
|
val = (static_cast<unsigned>(m_infoBuf[0])<<8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||||
|
stream << "temperature " << static_cast<unsigned>(val) << " °C";
|
||||||
|
break;
|
||||||
|
case 0x0204:
|
||||||
|
val = (static_cast<unsigned>(m_infoBuf[0])<<8) | static_cast<unsigned>(m_infoBuf[1]);
|
||||||
|
stream << "supply voltage " << static_cast<unsigned>(val) << " mV";
|
||||||
|
break;
|
||||||
|
case 0x0205:
|
||||||
|
stream << "bus voltage " << std::fixed << std::setprecision(1)
|
||||||
|
<< static_cast<float>(m_infoBuf[1] / 10.0) << " V - "
|
||||||
|
<< static_cast<float>(m_infoBuf[0] / 10.0) << " V";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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_infoPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_listener->notifyStatus(false, stream.str().c_str());
|
||||||
|
m_infoLen = 0;
|
||||||
|
m_infoId = 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENH_RES_ERROR_EBUS:
|
case ENH_RES_ERROR_EBUS:
|
||||||
|
|||||||
@@ -206,6 +206,9 @@ class Device {
|
|||||||
*/
|
*/
|
||||||
void setListener(DeviceListener* listener) { m_listener = listener; }
|
void setListener(DeviceListener* listener) { m_listener = listener; }
|
||||||
|
|
||||||
|
result_t requestEnhancedInfo(symbol_t infoId);
|
||||||
|
|
||||||
|
string getEnhancedInfos();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@@ -288,6 +291,21 @@ class Device {
|
|||||||
|
|
||||||
/** the read buffer read position. */
|
/** the read buffer read position. */
|
||||||
size_t m_bufPos;
|
size_t m_bufPos;
|
||||||
|
|
||||||
|
/** the extra features supported by the device. */
|
||||||
|
symbol_t m_extraFatures;
|
||||||
|
|
||||||
|
/** the ID of the last requested info. */
|
||||||
|
symbol_t m_infoId;
|
||||||
|
|
||||||
|
/** the info buffer expected length. */
|
||||||
|
size_t m_infoLen;
|
||||||
|
|
||||||
|
/** the info buffer write position. */
|
||||||
|
size_t m_infoPos;
|
||||||
|
|
||||||
|
/** the info buffer. */
|
||||||
|
symbol_t m_infoBuf[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user