mirror of https://github.com/rusefi/wideband.git
Ts dev (#175)
* Remove pageValueWrite command support Move advanced pageChunkWrite is used * Straight logic in validateOffsetCount(), simplify, move to tunerstudio.cpp * Remove some more unused commands * More unused defines * Command defines cleanup * Test command * TS: fix signature * pageIdentifier is optional * pageActivate command is not used * TS: extract offset and size from incoming packet only for packets with such data * TS: cast to packet header * TS: use page in commands * TS: support scatteredOchGetCommand * TS: incapsulation * TS: scatter: optimization for CPU load * More CPU load optimization * Update libfirmware
This commit is contained in:
parent
4d8ee933e6
commit
e5a7952db0
|
@ -85,8 +85,8 @@ static void printErrorCounters() {
|
|||
// efiPrintf("TunerStudio size=%d / total=%d / errors=%d / H=%d / O=%d / P=%d / B=%d",
|
||||
// sizeof(engine->outputChannels), tsState.totalCounter, tsState.errorCounter, tsState.queryCommandCounter,
|
||||
// tsState.outputChannelsCommandCounter, tsState.readPageCommandsCounter, tsState.burnCommandCounter);
|
||||
// efiPrintf("TunerStudio W=%d / C=%d / P=%d", tsState.writeValueCommandCounter,
|
||||
// tsState.writeChunkCommandCounter, tsState.pageCommandCounter);
|
||||
// efiPrintf("TunerStudio W=%d / C=%d", tsState.writeValueCommandCounter,
|
||||
// tsState.writeChunkCommandCounter);
|
||||
}
|
||||
|
||||
/* TunerStudio repeats connection attempts at ~1Hz rate.
|
||||
|
@ -117,13 +117,17 @@ void TunerStudio::sendErrorCode(TsChannelBase* tsChannel, uint8_t code) {
|
|||
::sendErrorCode(tsChannel, code);
|
||||
}
|
||||
|
||||
void TunerStudio::handlePageSelectCommand(TsChannelBase *tsChannel, ts_response_format_e mode) {
|
||||
tsState.pageCommandCounter++;
|
||||
|
||||
sendOkResponse(tsChannel, mode);
|
||||
size_t getTunerStudioPageSize() {
|
||||
return GetConfigurationSize();
|
||||
}
|
||||
|
||||
bool validateOffsetCount(size_t offset, size_t count, TsChannelBase* tsChannel);
|
||||
// Validate whether the specified offset and count would cause an overrun in the tune.
|
||||
// Returns true if offset and count are in valid range
|
||||
bool validateOffsetCount(size_t offset, size_t count) {
|
||||
if (offset + count > getTunerStudioPageSize())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This command is needed to make the whole transfer a bit faster
|
||||
|
@ -135,7 +139,9 @@ void TunerStudio::handleWriteChunkCommand(TsChannelBase* tsChannel, ts_response_
|
|||
|
||||
tsState.writeChunkCommandCounter++;
|
||||
|
||||
if (validateOffsetCount(offset, count, tsChannel)) {
|
||||
if (!validateOffsetCount(offset, count)) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -149,7 +155,9 @@ void TunerStudio::handleCrc32Check(TsChannelBase *tsChannel, ts_response_format_
|
|||
tsState.crc32CheckCommandCounter++;
|
||||
|
||||
// Ensure we are reading from in bounds
|
||||
if (validateOffsetCount(offset, count, tsChannel)) {
|
||||
if (!validateOffsetCount(offset, count)) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -159,28 +167,12 @@ void TunerStudio::handleCrc32Check(TsChannelBase *tsChannel, ts_response_format_
|
|||
tsChannel->sendResponse(mode, (const uint8_t *) &crc, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 'Write' command receives a single value at a given offset
|
||||
* @note Writing values one by one is pretty slow
|
||||
*/
|
||||
void TunerStudio::handleWriteValueCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint8_t value) {
|
||||
(void)tsChannel;
|
||||
(void)mode;
|
||||
(void)value;
|
||||
|
||||
tsState.writeValueCommandCounter++;
|
||||
|
||||
tunerStudioDebug(tsChannel, "got W (Write)"); // we can get a lot of these
|
||||
|
||||
if (validateOffsetCount(offset, 1, tsChannel)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TunerStudio::handlePageReadCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count) {
|
||||
tsState.readPageCommandsCounter++;
|
||||
|
||||
if (validateOffsetCount(offset, count, tsChannel)) {
|
||||
if (!validateOffsetCount(offset, count)) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -211,11 +203,11 @@ static void handleBurnCommand(TsChannelBase* tsChannel, ts_response_format_e mod
|
|||
|
||||
static bool isKnownCommand(char command) {
|
||||
return command == TS_HELLO_COMMAND || command == TS_READ_COMMAND || command == TS_OUTPUT_COMMAND
|
||||
|| command == TS_PAGE_COMMAND || command == TS_BURN_COMMAND || command == TS_SINGLE_WRITE_COMMAND
|
||||
|| command == TS_BURN_COMMAND
|
||||
|| command == TS_CHUNK_WRITE_COMMAND
|
||||
|| command == TS_GET_SCATTERED_GET_COMMAND
|
||||
|| command == TS_CRC_CHECK_COMMAND
|
||||
|| command == TS_GET_FIRMWARE_VERSION
|
||||
|| command == TS_GET_CONFIG_ERROR;
|
||||
|| command == TS_GET_FIRMWARE_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,7 +224,8 @@ static void handleTestCommand(TsChannelBase* tsChannel) {
|
|||
* extension of the protocol to simplify troubleshooting
|
||||
*/
|
||||
tunerStudioDebug(tsChannel, "got T (Test)");
|
||||
tsChannel->write((const uint8_t*)VCS_VERSION, sizeof(VCS_VERSION));
|
||||
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), VCS_VERSION "\r\n");
|
||||
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
|
||||
|
||||
chsnprintf(testOutputBuffer, sizeof(testOutputBuffer), __DATE__ "\r\n");
|
||||
tsChannel->write((const uint8_t*)testOutputBuffer, strlen(testOutputBuffer));
|
||||
|
@ -463,22 +456,17 @@ static void handleGetVersion(TsChannelBase* tsChannel) {
|
|||
tsChannel->sendResponse(TS_CRC, (const uint8_t *) versionBuffer, strlen(versionBuffer) + 1);
|
||||
}
|
||||
|
||||
int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, char *data, int incomingPacketSize) {
|
||||
int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, char *data, size_t incomingPacketSize) {
|
||||
bool handled = true;
|
||||
(void)incomingPacketSize;
|
||||
|
||||
char command = data[0];
|
||||
data++;
|
||||
|
||||
const uint16_t* data16 = reinterpret_cast<uint16_t*>(data);
|
||||
|
||||
uint16_t offset = data16[0];
|
||||
uint16_t count = data16[1];
|
||||
|
||||
/* commands with no arguments */
|
||||
switch(command)
|
||||
{
|
||||
case TS_OUTPUT_COMMAND:
|
||||
tsState.outputChannelsCommandCounter++;
|
||||
cmdOutputChannels(tsChannel, offset, count);
|
||||
case TS_GET_SCATTERED_GET_COMMAND:
|
||||
handleScatteredReadCommand(tsChannel);
|
||||
break;
|
||||
case TS_HELLO_COMMAND:
|
||||
tunerStudioDebug(tsChannel, "got Query command");
|
||||
|
@ -487,29 +475,55 @@ int TunerStudio::handleCrcCommand(TsChannelBase* tsChannel, char *data, int inco
|
|||
case TS_GET_FIRMWARE_VERSION:
|
||||
handleGetVersion(tsChannel);
|
||||
break;
|
||||
case TS_PAGE_COMMAND:
|
||||
handlePageSelectCommand(tsChannel, TS_CRC);
|
||||
break;
|
||||
case TS_CHUNK_WRITE_COMMAND:
|
||||
handleWriteChunkCommand(tsChannel, TS_CRC, offset, count, data + sizeof(TunerStudioWriteChunkRequest));
|
||||
break;
|
||||
case TS_SINGLE_WRITE_COMMAND:
|
||||
handleWriteValueCommand(tsChannel, TS_CRC, offset, data[4]);
|
||||
break;
|
||||
case TS_CRC_CHECK_COMMAND:
|
||||
handleCrc32Check(tsChannel, TS_CRC, offset, count);
|
||||
break;
|
||||
case TS_BURN_COMMAND:
|
||||
handleBurnCommand(tsChannel, TS_CRC);
|
||||
break;
|
||||
case TS_READ_COMMAND:
|
||||
handlePageReadCommand(tsChannel, TS_CRC, offset, count);
|
||||
break;
|
||||
case TS_TEST_COMMAND:
|
||||
[[fallthrough]];
|
||||
case 'T':
|
||||
handleTestCommand(tsChannel);
|
||||
break;
|
||||
default:
|
||||
/* noone of simple commands */
|
||||
handled = false;
|
||||
}
|
||||
|
||||
if (handled)
|
||||
return true;
|
||||
|
||||
/* check if we can extract page, offset and count */
|
||||
if (incomingPacketSize < sizeof(TunerStudioDataPacketHeader)) {
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_UNDERRUN);
|
||||
tunerStudioError(tsChannel, "ERROR: underrun");
|
||||
return false;
|
||||
}
|
||||
|
||||
const TunerStudioDataPacketHeader* header = reinterpret_cast<TunerStudioDataPacketHeader*>(data);
|
||||
|
||||
switch(command)
|
||||
{
|
||||
case TS_OUTPUT_COMMAND:
|
||||
tsState.outputChannelsCommandCounter++;
|
||||
cmdOutputChannels(tsChannel, header->offset, header->count);
|
||||
break;
|
||||
case TS_CHUNK_WRITE_COMMAND:
|
||||
if (header->page == 0)
|
||||
handleWriteChunkCommand(tsChannel, TS_CRC, header->offset, header->count, data + sizeof(TunerStudioDataPacketHeader));
|
||||
else
|
||||
handleScatterListWriteCommand(tsChannel, header->offset, header->count, data + sizeof(TunerStudioDataPacketHeader));
|
||||
break;
|
||||
case TS_CRC_CHECK_COMMAND:
|
||||
if (header->page == 0)
|
||||
handleCrc32Check(tsChannel, TS_CRC, header->offset, header->count);
|
||||
else
|
||||
handleScatterListCrc32Check(tsChannel, header->offset, header->count);
|
||||
break;
|
||||
case TS_READ_COMMAND:
|
||||
if (header->page == 0)
|
||||
handlePageReadCommand(tsChannel, TS_CRC, header->offset, header->count);
|
||||
else
|
||||
handleScatterListReadCommand(tsChannel, header->offset, header->count);
|
||||
break;
|
||||
default:
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_UNRECOGNIZED_COMMAND);
|
||||
tunerStudioError(tsChannel, "ERROR: ignoring unexpected command");
|
||||
|
|
|
@ -16,8 +16,6 @@ typedef struct {
|
|||
int outputChannelsCommandCounter;
|
||||
int readPageCommandsCounter;
|
||||
int burnCommandCounter;
|
||||
int pageCommandCounter;
|
||||
int writeValueCommandCounter;
|
||||
int crc32CheckCommandCounter;
|
||||
int writeChunkCommandCounter;
|
||||
int errorCounter;
|
||||
|
@ -36,9 +34,11 @@ void requestBurn(void);
|
|||
void startTunerStudioConnectivity(void);
|
||||
|
||||
typedef struct {
|
||||
short int offset;
|
||||
short int count;
|
||||
} TunerStudioWriteChunkRequest;
|
||||
uint8_t cmd;
|
||||
uint16_t page;
|
||||
uint16_t offset;
|
||||
uint16_t count;
|
||||
} __attribute__((packed)) TunerStudioDataPacketHeader;
|
||||
|
||||
#define CONNECTIVITY_THREAD_STACK (512)
|
||||
#define CONNECTIVITY_THREAD_PRIO (NORMALPRIO + 1)
|
||||
|
|
|
@ -1,29 +1,18 @@
|
|||
#include "tunerstudio_impl.h"
|
||||
#include "tunerstudio.h"
|
||||
#include "tunerstudio_io.h"
|
||||
#include "byteswap.h"
|
||||
|
||||
/* configuration */
|
||||
#include "port.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <rusefi/crc.h>
|
||||
#include <rusefi/fragments.h>
|
||||
|
||||
void sendErrorCode(TsChannelBase *tsChannel, uint8_t code);
|
||||
|
||||
size_t getTunerStudioPageSize() {
|
||||
return GetConfigurationSize();
|
||||
}
|
||||
|
||||
// Validate whether the specified offset and count would cause an overrun in the tune.
|
||||
// Returns true if an overrun would occur.
|
||||
bool validateOffsetCount(size_t offset, size_t count, TsChannelBase* tsChannel) {
|
||||
if (offset + count > getTunerStudioPageSize()) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void sendOkResponse(TsChannelBase *tsChannel, ts_response_format_e mode);
|
||||
|
||||
FragmentList getFragments();
|
||||
|
||||
|
@ -48,3 +37,115 @@ void TunerStudio::cmdOutputChannels(TsChannelBase* tsChannel, uint16_t offset, u
|
|||
|
||||
tsChannel->crcAndWriteBuffer(TS_RESPONSE_OK, count);
|
||||
}
|
||||
|
||||
// Validate whether the specified offset and count would cause an overrun in the tune.
|
||||
// Returns true if offset and count are in valid range
|
||||
bool TunerStudio::validateScatterOffsetCount(size_t offset, size_t count) {
|
||||
if (offset + count > sizeof(highSpeedOffsets))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void TunerStudio::handleScatteredReadCommand(TsChannelBase* tsChannel) {
|
||||
#ifdef HIGH_SPEED_OPTIMIZED
|
||||
uint8_t *buffer = (uint8_t *)tsChannel->scratchBuffer;
|
||||
tsChannel->writeHeader(TS_RESPONSE_OK, highSpeedTotalSize);
|
||||
for (size_t i = 0; i < highSpeedChunks; i++) {
|
||||
chDbgAssert(NULL != highSpeedPtrs[i], "NULL pointer in scatter list");
|
||||
// copy to temp buffer to avoid changes before transmission, couse it can affect CRC
|
||||
memcpy(buffer, highSpeedPtrs[i], highSpeedSizes[i]);
|
||||
tsChannel->writeBody(buffer, highSpeedSizes[i]);
|
||||
}
|
||||
tsChannel->writeTail();
|
||||
#else
|
||||
size_t count = 0;
|
||||
uint8_t *buffer = (uint8_t *)tsChannel->scratchBuffer + 3; /* reserve 3 bytes for header */
|
||||
|
||||
for (size_t i = 0; i < HIGH_SPEED_COUNT; i++) {
|
||||
int packed = highSpeedOffsets[i];
|
||||
int type = packed >> 13;
|
||||
|
||||
if (type == 0)
|
||||
continue;
|
||||
int size = 1 << (type - 1);
|
||||
|
||||
int offset = packed & 0x1FFF;
|
||||
// write each data point and CRC incrementally
|
||||
copyRange(buffer + count, getFragments(), offset, size);
|
||||
count += size;
|
||||
}
|
||||
tsChannel->crcAndWriteBuffer(TS_RESPONSE_OK, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TunerStudio::handleScatterListWriteCommand(TsChannelBase* tsChannel, uint16_t offset, uint16_t count, void *content)
|
||||
{
|
||||
uint8_t * addr = (uint8_t *)highSpeedOffsets + offset;
|
||||
memcpy(addr, content, count);
|
||||
|
||||
#ifdef HIGH_SPEED_OPTIMIZED
|
||||
highSpeedChunks = 0;
|
||||
highSpeedTotalSize = 0;
|
||||
/* translate to CPU pointers */
|
||||
for (int i = 0; i < HIGH_SPEED_COUNT; i++) {
|
||||
int packed = highSpeedOffsets[i];
|
||||
int type = packed >> 13;
|
||||
|
||||
if (type == 0)
|
||||
continue;
|
||||
|
||||
int size = 1 << (type - 1);
|
||||
int offset = packed & 0x1FFF;
|
||||
highSpeedTotalSize += size;
|
||||
|
||||
uint8_t *ptr;
|
||||
|
||||
do {
|
||||
size_t availSize = getRangePtr(&ptr, getFragments(), offset, size);
|
||||
|
||||
/* note: no need to check ptr for NULL */
|
||||
if ((highSpeedChunks == 0) || /* first chunk */
|
||||
((highSpeedChunks > 0) &&
|
||||
(highSpeedPtrs[highSpeedChunks - 1] + highSpeedSizes[highSpeedChunks - 1] != ptr))) /* or not contiguous chunks */ {
|
||||
highSpeedPtrs[highSpeedChunks] = ptr;
|
||||
highSpeedSizes[highSpeedChunks] = size;
|
||||
highSpeedChunks++;
|
||||
} else {
|
||||
/* unite */
|
||||
highSpeedSizes[highSpeedChunks - 1] += size;
|
||||
}
|
||||
size -= availSize;
|
||||
offset += availSize;
|
||||
} while (size);
|
||||
}
|
||||
#endif
|
||||
|
||||
sendOkResponse(tsChannel, TS_CRC);
|
||||
}
|
||||
|
||||
void TunerStudio::handleScatterListReadCommand(TsChannelBase* tsChannel, uint16_t offset, uint16_t count)
|
||||
{
|
||||
if (!validateScatterOffsetCount(offset, count)) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t * addr = (uint8_t *)highSpeedOffsets + offset;
|
||||
tsChannel->sendResponse(TS_CRC, addr, count);
|
||||
}
|
||||
|
||||
void TunerStudio::handleScatterListCrc32Check(TsChannelBase *tsChannel, uint16_t offset, uint16_t count)
|
||||
{
|
||||
// Ensure we are reading from in bounds
|
||||
if (!validateScatterOffsetCount(offset, count)) {
|
||||
tunerStudioError(tsChannel, "ERROR: out of range");
|
||||
sendErrorCode(tsChannel, TS_RESPONSE_OUT_OF_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint8_t* start = (uint8_t *)highSpeedOffsets + offset;
|
||||
|
||||
uint32_t crc = SWAP_UINT32(crc32(start, count));
|
||||
tsChannel->sendResponse(TS_CRC, (const uint8_t *) &crc, 4);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#define HIGH_SPEED_COUNT 32
|
||||
|
||||
#define HIGH_SPEED_OPTIMIZED
|
||||
|
||||
struct TsChannelBase;
|
||||
|
||||
typedef enum {
|
||||
|
@ -23,7 +27,7 @@ protected:
|
|||
|
||||
class TunerStudio : public TunerStudioBase {
|
||||
public:
|
||||
int handleCrcCommand(TsChannelBase* tsChannel, char *data, int incomingPacketSize);
|
||||
int handleCrcCommand(TsChannelBase* tsChannel, char *data, size_t incomingPacketSize);
|
||||
bool handlePlainCommand(TsChannelBase* tsChannel, uint8_t command);
|
||||
|
||||
void cmdOutputChannels(TsChannelBase* tsChannel, uint16_t offset, uint16_t count) override;
|
||||
|
@ -35,7 +39,21 @@ public:
|
|||
void handleCrc32Check(TsChannelBase *tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count);
|
||||
void handleWriteValueCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint8_t value);
|
||||
void handlePageReadCommand(TsChannelBase* tsChannel, ts_response_format_e mode, uint16_t offset, uint16_t count);
|
||||
// Scatter mode support
|
||||
void handleScatteredReadCommand(TsChannelBase* tsChannel);
|
||||
void handleScatterListWriteCommand(TsChannelBase* tsChannel, uint16_t offset, uint16_t count, void *content);
|
||||
void handleScatterListReadCommand(TsChannelBase* tsChannel, uint16_t offset, uint16_t count);
|
||||
void handleScatterListCrc32Check(TsChannelBase *tsChannel, uint16_t offset, uint16_t count);
|
||||
|
||||
private:
|
||||
void sendErrorCode(TsChannelBase* tsChannel, uint8_t code);
|
||||
|
||||
bool validateScatterOffsetCount(size_t offset, size_t count);
|
||||
uint16_t highSpeedOffsets[HIGH_SPEED_COUNT];
|
||||
#ifdef HIGH_SPEED_OPTIMIZED
|
||||
uint8_t *highSpeedPtrs[HIGH_SPEED_COUNT];
|
||||
size_t highSpeedSizes[HIGH_SPEED_COUNT];
|
||||
size_t highSpeedChunks;
|
||||
size_t highSpeedTotalSize;
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -56,6 +56,56 @@ void TsChannelBase::crcAndWriteBuffer(uint8_t responseCode, size_t size) {
|
|||
flush();
|
||||
}
|
||||
|
||||
int TsChannelBase::writeHeader(uint8_t responseCode, size_t size)
|
||||
{
|
||||
uint8_t buffer[3];
|
||||
|
||||
// Index 0/1 = packet size (big endian)
|
||||
*(uint16_t*)buffer = SWAP_UINT16(size + 1);
|
||||
// Index 2 = response code
|
||||
buffer[2] = responseCode;
|
||||
|
||||
// start calculating CRC
|
||||
// CRC is computed on the responseCode and payload but not length
|
||||
crcAcc = crc32(&buffer[2], sizeof(buffer) - 2);
|
||||
// save packet size
|
||||
packetSize = size; /* + 3 bytes for head + 4 bytes of CRC */
|
||||
|
||||
// Write to the underlying stream
|
||||
write(buffer, sizeof(buffer), false);
|
||||
|
||||
return sizeof(buffer);
|
||||
}
|
||||
|
||||
int TsChannelBase::writeBody(uint8_t *buffer, size_t size)
|
||||
{
|
||||
chDbgAssert(size <= packetSize, "writeBody packet size is more than provided in header");
|
||||
// append CRC
|
||||
crcAcc = crc32inc(buffer, crcAcc, size);
|
||||
// adjust packet size
|
||||
packetSize -= size;
|
||||
|
||||
// Write to the underlying stream
|
||||
write(buffer, size, false);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int TsChannelBase::writeTail(void)
|
||||
{
|
||||
chDbgAssert(0 == packetSize, "writeTail unexpecded packet end");
|
||||
|
||||
uint8_t buffer[4];
|
||||
|
||||
// Place the CRC at the end
|
||||
*(uint32_t*)buffer = SWAP_UINT32(crcAcc);
|
||||
|
||||
// Write to the underlying stream
|
||||
write(buffer, sizeof(buffer), true);
|
||||
|
||||
return sizeof(buffer);
|
||||
}
|
||||
|
||||
void TsChannelBase::writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size) {
|
||||
uint8_t headerBuffer[3];
|
||||
uint8_t crcBuffer[4];
|
||||
|
|
|
@ -16,72 +16,19 @@
|
|||
/* TODO: find better place */
|
||||
#define BLOCKING_FACTOR 256
|
||||
|
||||
/* TODO: From autogenerated, rework! */
|
||||
#define TS_BURN_COMMAND 'B'
|
||||
#define TS_BURN_COMMAND_char B
|
||||
#define TS_CHUNK_WRITE_COMMAND 'C'
|
||||
#define TS_CHUNK_WRITE_COMMAND_char C
|
||||
#define ts_command_e_TS_BENCH_CATEGORY 22
|
||||
#define ts_command_e_TS_CLEAR_WARNINGS 17
|
||||
#define ts_command_e_TS_COMMAND_1 1
|
||||
#define ts_command_e_TS_COMMAND_11 11
|
||||
#define ts_command_e_TS_COMMAND_12 12
|
||||
#define ts_command_e_TS_COMMAND_13 13
|
||||
#define ts_command_e_TS_COMMAND_14 14
|
||||
#define ts_command_e_TS_COMMAND_15 15
|
||||
#define ts_command_e_TS_COMMAND_16 16
|
||||
#define ts_command_e_TS_COMMAND_4 4
|
||||
#define ts_command_e_TS_COMMAND_5 5
|
||||
#define ts_command_e_TS_COMMAND_9 9
|
||||
#define ts_command_e_TS_CRAZY 32
|
||||
#define ts_command_e_TS_DEBUG_MODE 0
|
||||
#define ts_command_e_TS_GRAB_PEDAL_UP 6
|
||||
#define ts_command_e_TS_GRAB_PEDAL_WOT 7
|
||||
#define ts_command_e_TS_GRAB_TPS_CLOSED 2
|
||||
#define ts_command_e_TS_GRAB_TPS_WOT 3
|
||||
#define ts_command_e_TS_IGNITION_CATEGORY 18
|
||||
#define ts_command_e_TS_INJECTOR_CATEGORY 19
|
||||
#define ts_command_e_TS_RESET_TLE8888 8
|
||||
#define ts_command_e_TS_UNUSED_23 23
|
||||
#define ts_command_e_TS_UNUSED_25 25
|
||||
#define ts_command_e_TS_UNUSED_26 26
|
||||
#define ts_command_e_TS_UNUSED_27 27
|
||||
#define ts_command_e_TS_UNUSED_28 28
|
||||
#define ts_command_e_TS_UNUSED_29 29
|
||||
#define ts_command_e_TS_UNUSED_30 30
|
||||
#define ts_command_e_TS_UNUSED_31 31
|
||||
#define ts_command_e_TS_UNUSED_CJ125_CALIB 24
|
||||
#define ts_command_e_TS_WIDEBAND 21
|
||||
#define ts_command_e_TS_WRITE_FLASH 10
|
||||
#define ts_command_e_TS_X14 20
|
||||
#define TS_COMMAND_F 'F'
|
||||
#define TS_COMMAND_F_char F
|
||||
#define TS_COMPOSITE_DISABLE 2
|
||||
#define TS_COMPOSITE_ENABLE 1
|
||||
#define TS_CRC_CHECK_COMMAND 'k'
|
||||
#define TS_CRC_CHECK_COMMAND_char k
|
||||
#define TS_FILE_VERSION 20210312
|
||||
#define TS_GET_CONFIG_ERROR 'e'
|
||||
#define TS_GET_CONFIG_ERROR_char e
|
||||
#define TS_GET_FIRMWARE_VERSION 'V'
|
||||
#define TS_GET_FIRMWARE_VERSION_char V
|
||||
#define TS_GET_LOGGER_GET_BUFFER 'L'
|
||||
#define TS_GET_LOGGER_GET_BUFFER_char L
|
||||
#define TS_GET_OUTPUTS_SIZE '4'
|
||||
#define TS_GET_OUTPUTS_SIZE_char 4
|
||||
#define TS_HELLO_COMMAND 'S'
|
||||
#define TS_HELLO_COMMAND_char S
|
||||
#define TS_ONLINE_PROTOCOL 'z'
|
||||
#define TS_ONLINE_PROTOCOL_char z
|
||||
#define TS_OUTPUT_COMMAND 'O'
|
||||
#define TS_OUTPUT_COMMAND_char O
|
||||
#define TS_PAGE_COMMAND 'P'
|
||||
#define TS_PAGE_COMMAND_char P
|
||||
#define TS_PROTOCOL "001"
|
||||
#define TS_QUERY_COMMAND 'Q'
|
||||
#define TS_QUERY_COMMAND_char Q
|
||||
#define TS_READ_COMMAND 'R'
|
||||
#define TS_READ_COMMAND_char R
|
||||
#define TS_TEST_COMMAND 't'
|
||||
#define TS_GET_SCATTERED_GET_COMMAND '9'
|
||||
|
||||
#define TS_RESPONSE_BURN_OK 4
|
||||
#define TS_RESPONSE_COMMAND_OK 7
|
||||
#define TS_RESPONSE_CRC_FAILURE 0x82
|
||||
|
@ -90,10 +37,6 @@
|
|||
#define TS_RESPONSE_OUT_OF_RANGE 0x84
|
||||
#define TS_RESPONSE_UNDERRUN 0x80
|
||||
#define TS_RESPONSE_UNRECOGNIZED_COMMAND 0x83
|
||||
#define TS_SINGLE_WRITE_COMMAND 'W'
|
||||
#define TS_SINGLE_WRITE_COMMAND_char W
|
||||
#define TS_TEST_COMMAND 't'
|
||||
#define TS_TEST_COMMAND_char t
|
||||
|
||||
class TsChannelBase {
|
||||
public:
|
||||
|
@ -127,8 +70,16 @@ public:
|
|||
void crcAndWriteBuffer(uint8_t responseCode, size_t size);
|
||||
void copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size);
|
||||
|
||||
int writeHeader(uint8_t responseCode, size_t size);
|
||||
int writeBody(uint8_t *buffer, size_t size);
|
||||
int writeTail(void);
|
||||
|
||||
private:
|
||||
void writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size);
|
||||
// CRC accumulator
|
||||
uint32_t crcAcc;
|
||||
// total size expected
|
||||
size_t packetSize;
|
||||
};
|
||||
|
||||
// This class represents a channel for a physical async serial poart
|
||||
|
|
|
@ -30,15 +30,14 @@ enable2ndByteCanID = false
|
|||
messageEnvelopeFormat = msEnvelope_1.0
|
||||
|
||||
endianness = little
|
||||
nPages = 1
|
||||
nPages = 2
|
||||
pageSize = 256, 64
|
||||
pageIdentifier = "\x00\x00", "\x00\x01"
|
||||
|
||||
pageIdentifier = "\x00\x00"
|
||||
pageReadCommand = "R%2o%2c"
|
||||
burnCommand = "B"
|
||||
pageActivate = "P"
|
||||
pageValueWrite = "W%2o%v"
|
||||
pageChunkWrite = "C%2o%2c%v"
|
||||
crc32CheckCommand = "k%2o%2c"
|
||||
pageReadCommand = "R%2i%2o%2c", "R%2i%2o%2c"
|
||||
burnCommand = "B%2i"
|
||||
pageChunkWrite = "C%2i%2o%2c%v", "C%2i%2o%2c%v"
|
||||
crc32CheckCommand = "k%2i%2o%2c", "k%2i%2o%2c"
|
||||
retrieveConfigError = "e"
|
||||
|
||||
; communication settings
|
||||
|
@ -57,13 +56,16 @@ enable2ndByteCanID = false
|
|||
|
||||
; CONFIG_DEFINITION_START
|
||||
|
||||
pageSize = 256
|
||||
page = 1
|
||||
|
||||
; name = class, type, offset, [shape], units, scale, translate, min, max, digits
|
||||
; First four bytes are used for internal tag. Should not be accessable from TS
|
||||
LsuSensorType = bits, U08, 135, [0:2], "LSU 4.9", "LSU 4.2", "LSU ADV"
|
||||
|
||||
page = 2 ; this is a RAM only page with no burnable flash
|
||||
; name = class, type, offset, [shape], units, scale, translate, min, max, digits
|
||||
highSpeedOffsets = array, U16, 0, [32], "", 1, 0, 0, 65535, 0, noMsqSave
|
||||
|
||||
[SettingContextHelp]
|
||||
|
||||
[Tuning]
|
||||
|
@ -71,10 +73,16 @@ LsuSensorType = bits, U08, 135, [0:2], "LSU 4.9", "LSU 4.2", "LSU ADV"
|
|||
[LoggerDefinition]
|
||||
|
||||
[OutputChannels]
|
||||
ochGetCommand = "O%2o%2c"
|
||||
; two zero bytes added after cmd byte to align with page read/write format
|
||||
ochGetCommand = "O\x00\x00%2o%2c"
|
||||
; see TS_OUTPUT_SIZE in console source code
|
||||
ochBlockSize = 256
|
||||
|
||||
; 11.2.3 Full Optimized – High Speed
|
||||
scatteredOchGetCommand = "9"
|
||||
scatteredOffsetArray = highSpeedOffsets
|
||||
scatteredGetEnabled = { 1 }
|
||||
|
||||
; Common
|
||||
VBatt = scalar, F32, 0, "V", 1, 0
|
||||
|
||||
|
|
|
@ -30,15 +30,14 @@ enable2ndByteCanID = false
|
|||
messageEnvelopeFormat = msEnvelope_1.0
|
||||
|
||||
endianness = little
|
||||
nPages = 1
|
||||
nPages = 2
|
||||
pageSize = 256, 64
|
||||
pageIdentifier = "\x00\x00", "\x00\x01"
|
||||
|
||||
pageIdentifier = "\x00\x00"
|
||||
pageReadCommand = "R%2o%2c"
|
||||
burnCommand = "B"
|
||||
pageActivate = "P"
|
||||
pageValueWrite = "W%2o%v"
|
||||
pageChunkWrite = "C%2o%2c%v"
|
||||
crc32CheckCommand = "k%2o%2c"
|
||||
pageReadCommand = "R%2i%2o%2c", "R%2i%2o%2c"
|
||||
burnCommand = "B%2i"
|
||||
pageChunkWrite = "C%2i%2o%2c%v", "C%2i%2o%2c%v"
|
||||
crc32CheckCommand = "k%2i%2o%2c", "k%2i%2o%2c"
|
||||
retrieveConfigError = "e"
|
||||
|
||||
; communication settings
|
||||
|
@ -57,7 +56,6 @@ enable2ndByteCanID = false
|
|||
|
||||
; CONFIG_DEFINITION_START
|
||||
|
||||
pageSize = 256
|
||||
page = 1
|
||||
|
||||
; name = class, type, offset, [shape], units, scale, translate, min, max, digits
|
||||
|
@ -71,6 +69,10 @@ Aux0InputSel = bits, U08, 133, [0:3], "AFR 0", "AFR 1", "Lambda 0", "L
|
|||
Aux1InputSel = bits, U08, 134, [0:3], "AFR 0", "AFR 1", "Lambda 0", "Lambda 1", "EGT 0", "EGT 1"
|
||||
LsuSensorType = bits, U08, 135, [0:2], "LSU 4.9", "LSU 4.2", "LSU ADV"
|
||||
|
||||
page = 2 ; this is a RAM only page with no burnable flash
|
||||
; name = class, type, offset, [shape], units, scale, translate, min, max, digits
|
||||
highSpeedOffsets = array, U16, 0, [32], "", 1, 0, 0, 65535, 0, noMsqSave
|
||||
|
||||
[SettingContextHelp]
|
||||
|
||||
[Tuning]
|
||||
|
@ -78,10 +80,16 @@ LsuSensorType = bits, U08, 135, [0:2], "LSU 4.9", "LSU 4.2", "LSU ADV"
|
|||
[LoggerDefinition]
|
||||
|
||||
[OutputChannels]
|
||||
ochGetCommand = "O%2o%2c"
|
||||
; two zero bytes added after cmd byte to align with page read/write format
|
||||
ochGetCommand = "O\x00\x00%2o%2c"
|
||||
; see TS_OUTPUT_SIZE in console source code
|
||||
ochBlockSize = 256
|
||||
|
||||
; 11.2.3 Full Optimized – High Speed
|
||||
scatteredOchGetCommand = "9"
|
||||
scatteredOffsetArray = highSpeedOffsets
|
||||
scatteredGetEnabled = { 1 }s
|
||||
|
||||
; Common
|
||||
VBatt = scalar, F32, 0, "V", 1, 0
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 16a8e0b636f0a8d5f88dfdd6a1a4639ad90da936
|
||||
Subproject commit 39b3a04dab617e7ff24577e99d0d7fac2ce44c9f
|
Loading…
Reference in New Issue