diff --git a/reference/speeduino.ini b/reference/speeduino.ini index fef3c05f..fbc501e3 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -90,7 +90,7 @@ #define fullStatus_def_6= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" #define fullStatus_def_7= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" ;Rules start at index 240 - #define fullStatus_def_8= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "running seconds x10", "Rule 1", "Rule 2", "Rule 3", "Rule 4", "Rule 5", "Rule 6", "Rule 7", "Rule 8", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" + #define fullStatus_def_8= "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "running seconds x10", "Rule 1", "Rule 2", "Rule 3", "Rule 4", "Rule 5", "Rule 6", "Rule 7", "Rule 8", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID" #define fullStatus_def = $fullStatus_def_1, $fullStatus_def_2, $fullStatus_def_3, $fullStatus_def_4, $fullStatus_def_5, $fullStatus_def_6, $fullStatus_def_7, $fullStatus_def_8 boostTableLabels = bits, U08, [0:1], "Duty Cycle %", "kPa" @@ -215,14 +215,14 @@ pageChunkWrite = "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v", "M%2i%2o%2c%v" crc32CheckCommand = "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i", "d%2i" - blockingFactor = 256 + blockingFactor = 251 ; Serial buffer is 257 bytes and there are 6 bytes of overhead (2 for the size and 4 for the CRC). Total paload is therefore 257-6=251. ;tableBlockingFactor = 2048 - tableBlockingFactor = 256 + tableBlockingFactor = 244 ; Serial buffer is 257 bytes. There are 7 bytes overhead for the M command + 2 bytes for the size + 4 bytes for the CRC. 257 - 7 - 2 - 4 = 244 bytes. delayAfterPortOpen=1000 ;validateArrayBounds = true blockReadTimeout = 2000 tsWriteBlocks = on - interWriteDelay = 1 ;Ignored when tsWriteBlocks is on + interWriteDelay = 10 ;Ignored when tsWriteBlocks is on pageActivationDelay = 10 restrictSquirtRelationship = false ;This requires TS 3.1 or above #if NEW_COMMS @@ -1251,7 +1251,7 @@ page = 13 outputPin6 = bits, U08, 8, [0:7], $comp_IO_Pins outputPin7 = bits, U08, 9, [0:7], $comp_IO_Pins outputDelay = array, U08, 10, [ 8], "S", 0.1, 0.0, 0.0, 25.5, 1 - firstDataIn = array, U08, 18, [ 8], "", 1.0, 0.0, 0.0, 65535.0, 0 + firstDataIn = array, U08, 18, [ 8], "", 1.0, 0.0, 0.0, 255.0, 0 firstDataIn0= bits, U08, 18, [0:7], $fullStatus_def firstDataIn1= bits, U08, 19, [0:7], $fullStatus_def firstDataIn2= bits, U08, 20, [0:7], $fullStatus_def @@ -1260,7 +1260,7 @@ page = 13 firstDataIn5= bits, U08, 23, [0:7], $fullStatus_def firstDataIn6= bits, U08, 24, [0:7], $fullStatus_def firstDataIn7= bits, U08, 25, [0:7], $fullStatus_def - secondDataIn = array, U08, 26, [ 8], "", 1.0, 0.0, 0.0, 65535.0, 0 + secondDataIn = array, U08, 26, [ 8], "", 1.0, 0.0, 0.0, 255.0, 0 secondDataIn0= bits, U08, 26, [0:7], $fullStatus_def secondDataIn1= bits, U08, 27, [0:7], $fullStatus_def secondDataIn2= bits, U08, 28, [0:7], $fullStatus_def diff --git a/speeduino/comms.cpp b/speeduino/comms.cpp index 57ecbacd..8ff1a2ae 100644 --- a/speeduino/comms.cpp +++ b/speeduino/comms.cpp @@ -547,6 +547,8 @@ void command() break; default: + Serial.println(F("Err: Unknown cmd")); + cmdPending = false; break; } } diff --git a/speeduino/newComms.cpp b/speeduino/newComms.cpp index 130ee20b..524031b8 100644 --- a/speeduino/newComms.cpp +++ b/speeduino/newComms.cpp @@ -234,6 +234,14 @@ void processSerialCommand() break; case 'b': // New EEPROM burn command to only burn a single page at a time + + if(isEepromWritePending()) + { + //There is already a write pending, so we can't do anything + sendSerialReturnCode(SERIAL_RC_BUSY_ERR); + break; + } + writeConfig(serialPayload[2]); //Read the table number and perform burn. Note that byte 1 in the array is unused sendSerialReturnCode(SERIAL_RC_BURN_OK); break; @@ -245,6 +253,25 @@ void processSerialCommand() break; } + case 'd': // Send a CRC32 hash of a given page + { + uint32_t CRC32_val = calculatePageCRC32( serialPayload[2] ); + uint8_t payloadCRC32[5]; + + //First byte is the flag + payloadCRC32[0] = SERIAL_RC_OK; + + //Split the 4 bytes of the CRC32 value into individual bytes and send + payloadCRC32[1] = ((CRC32_val >> 24) & 255); + payloadCRC32[2] = ((CRC32_val >> 16) & 255); + payloadCRC32[3] = ((CRC32_val >> 8) & 255); + payloadCRC32[4] = (CRC32_val & 255); + + sendSerialPayload( &payloadCRC32, 5); + + break; + } + case 'E': // receive command button commands { uint16_t cmdCombined = word(serialPayload[1], serialPayload[2]); @@ -309,6 +336,13 @@ void processSerialCommand() sendSerialReturnCode(SERIAL_RC_OK); break; + case 'I': // send CAN ID + { + byte serialVersion[] = {SERIAL_RC_OK, 0}; + sendSerialPayload(&serialVersion, 2); + break; + } + case 'J': //Start the composite logger currentStatus.compositeLogEnabled = true; currentStatus.toothLogEnabled = false; //Safety first (Should never be required) @@ -337,25 +371,54 @@ void processSerialCommand() sendSerialReturnCode(SERIAL_RC_OK); break; - case 'd': // Send a CRC32 hash of a given page + case 'M': { - uint32_t CRC32_val = calculatePageCRC32( serialPayload[2] ); - uint8_t payloadCRC32[5]; - - //First byte is the flag - payloadCRC32[0] = SERIAL_RC_OK; + //New write command + //7 bytes required: + //2 - Page identifier + //2 - offset + //2 - Length + //1 - 1st New value + byte offset1, offset2, length1, length2; - //Split the 4 bytes of the CRC32 value into individual bytes and send - payloadCRC32[1] = ((CRC32_val >> 24) & 255); - payloadCRC32[2] = ((CRC32_val >> 16) & 255); - payloadCRC32[3] = ((CRC32_val >> 8) & 255); - payloadCRC32[4] = (CRC32_val & 255); - - sendSerialPayload( &payloadCRC32, 5); + uint8_t currentPage = serialPayload[2]; //Page ID is 2 bytes, but as the first byte is always 0 it can be ignored + offset1 = serialPayload[3]; + offset2 = serialPayload[4]; + uint16_t valueOffset = word(offset2, offset1); + length1 = serialPayload[5]; + length2 = serialPayload[6]; + uint16_t chunkSize = word(length2, length1); + if( (valueOffset + chunkSize) > getPageSize(currentPage)) + { + //This should never happen, but just incase + sendSerialReturnCode(SERIAL_RC_RANGE_ERR); + break; + } + + if(isEepromWritePending()) + { + enableForceBurn(); + writeConfig(currentPage); + disableForceBurn(); + } + + //page_iterator_t entity = map_page_offset_to_entity(currentPage, valueOffset); + for(uint16_t i = 0; i < chunkSize; i++) + { + setPageValue(currentPage, (valueOffset + i), serialPayload[7 + i]); + } + + { + //enableForceBurn(); + writeConfig(currentPage); + //disableForceBurn(); + } + + sendSerialReturnCode(SERIAL_RC_OK); + break; - } - + } /* * New method for sending page values (MS command equivalent is 'r') @@ -661,33 +724,6 @@ void processSerialCommand() } break; - - case 'M': - { - //New write command - //7 bytes required: - //2 - Page identifier - //2 - offset - //2 - Length - //1 - 1st New value - byte offset1, offset2, length1, length2; - - uint8_t currentPage = serialPayload[2]; - offset1 = serialPayload[3]; - offset2 = serialPayload[4]; - uint16_t valueOffset = word(offset2, offset1); - length1 = serialPayload[5]; - length2 = serialPayload[6]; - uint16_t chunkSize = word(length2, length1); - - for(uint16_t i = 0; i < chunkSize; i++) - { - setPageValue(currentPage, (valueOffset + i), serialPayload[7 + i]); - } - sendSerialReturnCode(SERIAL_RC_OK); - break; - } - case 'w': { #ifdef RTC_ENABLED @@ -808,6 +844,8 @@ void processSerialCommand() } default: + //Unknown command + sendSerialReturnCode(SERIAL_RC_UKWN_ERR); break; } } diff --git a/speeduino/storage.cpp b/speeduino/storage.cpp index ef96950a..2431afdf 100644 --- a/speeduino/storage.cpp +++ b/speeduino/storage.cpp @@ -32,6 +32,7 @@ A full copy of the license may be found in the projects root directory #define EEPROM_LAST_BARO (EEPROM_CALIBRATION_O2_BINS-1) static bool eepromWritesPending = false; +static bool forceBurn = false; bool isEepromWritePending() { @@ -45,18 +46,20 @@ void writeAllConfig() uint8_t pageCount = getPageCount(); uint8_t page = 1U; writeConfig(page++); - while (page