New Comms change to prevent lockup during large table writes
This commit is contained in:
parent
76f6a7f1d5
commit
300c8699cc
|
@ -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
|
||||
|
|
|
@ -547,6 +547,8 @@ void command()
|
|||
break;
|
||||
|
||||
default:
|
||||
Serial.println(F("Err: Unknown cmd"));
|
||||
cmdPending = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<pageCount && !eepromWritesPending)
|
||||
while (page<pageCount && ( !eepromWritesPending || forceBurn ) )
|
||||
{
|
||||
writeConfig(page++);
|
||||
}
|
||||
}
|
||||
|
||||
void enableForceBurn() { forceBurn = true; }
|
||||
void disableForceBurn() { forceBurn = false; }
|
||||
|
||||
|
||||
// ================================= Internal write support ===============================
|
||||
|
||||
struct write_location {
|
||||
eeprom_address_t address;
|
||||
uint8_t counter;
|
||||
uint16_t counter;
|
||||
|
||||
/** Update byte to EEPROM by first comparing content and the need to write it.
|
||||
We only ever write to the EEPROM where the new value is different from the currently stored byte
|
||||
|
@ -79,13 +82,14 @@ struct write_location {
|
|||
|
||||
bool can_write() const
|
||||
{
|
||||
return counter<=EEPROM_MAX_WRITE_BLOCK;
|
||||
//return true;
|
||||
return (counter<=EEPROM_MAX_WRITE_BLOCK);
|
||||
}
|
||||
};
|
||||
|
||||
static inline write_location write_range(const byte *pStart, const byte *pEnd, write_location location)
|
||||
{
|
||||
while (location.can_write() && pStart!=pEnd)
|
||||
while ( (location.can_write() || forceBurn) && pStart!=pEnd)
|
||||
{
|
||||
location.update(*pStart);
|
||||
++pStart;
|
||||
|
@ -101,7 +105,7 @@ static inline write_location write(const table_row_iterator &row, write_location
|
|||
|
||||
static inline write_location write(table_value_iterator it, write_location location)
|
||||
{
|
||||
while (location.can_write() && !it.at_end())
|
||||
while ((location.can_write() || forceBurn) && !it.at_end())
|
||||
{
|
||||
location = write(*it, location);
|
||||
++it;
|
||||
|
@ -111,7 +115,7 @@ static inline write_location write(table_value_iterator it, write_location locat
|
|||
|
||||
static inline write_location write(table_axis_iterator it, write_location location)
|
||||
{
|
||||
while (location.can_write() && !it.at_end())
|
||||
while ((location.can_write() || forceBurn) && !it.at_end())
|
||||
{
|
||||
location.update((byte)*it);
|
||||
++location;
|
||||
|
|
|
@ -114,6 +114,8 @@ void loadConfig();
|
|||
void loadCalibration();
|
||||
void writeCalibration();
|
||||
void resetConfigPages();
|
||||
void enableForceBurn();
|
||||
void disableForceBurn();
|
||||
|
||||
//These are utility functions that prevent other files from having to use EEPROM.h directly
|
||||
byte readLastBaro();
|
||||
|
|
Loading…
Reference in New Issue