diff --git a/firmware/console/binary/tunerstudio.cpp b/firmware/console/binary/tunerstudio.cpp index 007d9ec..7a11025 100644 --- a/firmware/console/binary/tunerstudio.cpp +++ b/firmware/console/binary/tunerstudio.cpp @@ -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(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(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"); diff --git a/firmware/console/binary/tunerstudio.h b/firmware/console/binary/tunerstudio.h index 112c8e1..d247f02 100644 --- a/firmware/console/binary/tunerstudio.h +++ b/firmware/console/binary/tunerstudio.h @@ -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) diff --git a/firmware/console/binary/tunerstudio_commands.cpp b/firmware/console/binary/tunerstudio_commands.cpp index 73af129..9a3a192 100644 --- a/firmware/console/binary/tunerstudio_commands.cpp +++ b/firmware/console/binary/tunerstudio_commands.cpp @@ -1,29 +1,18 @@ #include "tunerstudio_impl.h" #include "tunerstudio.h" #include "tunerstudio_io.h" +#include "byteswap.h" /* configuration */ #include "port.h" +#include + +#include #include 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); +} diff --git a/firmware/console/binary/tunerstudio_impl.h b/firmware/console/binary/tunerstudio_impl.h index 76ee0bf..94bfb82 100644 --- a/firmware/console/binary/tunerstudio_impl.h +++ b/firmware/console/binary/tunerstudio_impl.h @@ -7,6 +7,10 @@ #include #include +#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 }; diff --git a/firmware/console/binary/tunerstudio_io.cpp b/firmware/console/binary/tunerstudio_io.cpp index b9834f6..4287350 100644 --- a/firmware/console/binary/tunerstudio_io.cpp +++ b/firmware/console/binary/tunerstudio_io.cpp @@ -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]; diff --git a/firmware/console/binary/tunerstudio_io.h b/firmware/console/binary/tunerstudio_io.h index 85fdb84..23aea55 100644 --- a/firmware/console/binary/tunerstudio_io.h +++ b/firmware/console/binary/tunerstudio_io.h @@ -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 diff --git a/firmware/ini/rusefi_wb_f1.ini b/firmware/ini/rusefi_wb_f1.ini index 56bebbe..7a7fdfc 100644 --- a/firmware/ini/rusefi_wb_f1.ini +++ b/firmware/ini/rusefi_wb_f1.ini @@ -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 diff --git a/firmware/ini/rusefi_wb_f1_dual.ini b/firmware/ini/rusefi_wb_f1_dual.ini index 7aa1dc6..6d26d5a 100644 --- a/firmware/ini/rusefi_wb_f1_dual.ini +++ b/firmware/ini/rusefi_wb_f1_dual.ini @@ -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 diff --git a/firmware/libfirmware b/firmware/libfirmware index 16a8e0b..39b3a04 160000 --- a/firmware/libfirmware +++ b/firmware/libfirmware @@ -1 +1 @@ -Subproject commit 16a8e0b636f0a8d5f88dfdd6a1a4639ad90da936 +Subproject commit 39b3a04dab617e7ff24577e99d0d7fac2ce44c9f