diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index 4d2d5821..0e3606db 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -805,6 +805,8 @@ void loop() readIAT(); readO2(); readBat(); + if(eepromWritesPending == true) { writeAllConfig(); } //Check for any outstanding EEPROM writes. + #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3 //if Can interface is enabled then check for serial3 requests. if (configPage10.enable_canbus == 1) // megas only support can via secondary serial diff --git a/speeduino/storage.h b/speeduino/storage.h index 6d176a7e..0d109e97 100644 --- a/speeduino/storage.h +++ b/speeduino/storage.h @@ -1,11 +1,15 @@ #ifndef STORAGE_H #define STORAGE_H +void writeAllConfig(); void writeConfig(); void loadConfig(); void loadCalibration(); void writeCalibration(); +#define EEPROM_MAX_WRITE_BLOCK 50 //The maximum number of write operations that will be performed in one go. If we try to write to the EEPROM too fast (Each write takes ~3ms) then the rest of the system can hang) +bool eepromWritesPending = false; + /* Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes): |---------------------------------------------------| diff --git a/speeduino/storage.ino b/speeduino/storage.ino index fcb1ca43..dfe9dfd1 100644 --- a/speeduino/storage.ino +++ b/speeduino/storage.ino @@ -7,13 +7,30 @@ A full copy of the license may be found in the projects root directory #include "storage.h" #include "globals.h" #include "table.h" +#include "comms.h" #include +void writeAllConfig() +{ + writeConfig(1); + writeConfig(2); + writeConfig(3); + writeConfig(4); + writeConfig(5); + writeConfig(6); + writeConfig(7); + writeConfig(8); + writeConfig(9); + writeConfig(10); + writeConfig(11); +} + + /* Takes the current configuration (config pages and maps) and writes them to EEPROM as per the layout defined in storage.h */ -void writeConfig() +void writeConfig(byte tableNum) { /* We only ever write to the EEPROM where the new value is different from the currently stored byte @@ -21,268 +38,310 @@ void writeConfig() */ int offset; + int writeCounter = 0; //Create a pointer to the config page byte* pnt_configPage; + switch(tableNum) + { + case veMapPage: + /*--------------------------------------------------- + | Fuel table (See storage.h for data layout) - Page 1 + | 16x16 table itself + the 16 values along each of the axis + -----------------------------------------------------*/ + if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); } //Write the VE Tables RPM dimension size + if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); } //Write the VE Tables MAP/TPS dimension size + for(int x=EEPROM_CONFIG1_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_MAP; + if( EEPROM.read(x) != (fuelTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, fuelTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map + } - /*--------------------------------------------------- - | Fuel table (See storage.h for data layout) - Page 1 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); } //Write the VE Tables RPM dimension size - if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); } //Write the VE Tables MAP/TPS dimension size - for(int x=EEPROM_CONFIG1_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_XBINS; + if( EEPROM.read(x) != (byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) ) { EEPROM.write(x, byte(fuelTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG1_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG1_YBINS; + EEPROM.update(x, fuelTable.axisY[offset] / TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + break; + //That concludes the writing of the VE table - //RPM bins - for(int x=EEPROM_CONFIG1_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG2_START))); writeCounter++; } + } + break; - /*--------------------------------------------------- - | Config page 2 (See storage.h for data layout) - | 64 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 2 in memory - for(int x=EEPROM_CONFIG2_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_MAP; + if(EEPROM.read(x) != (ignitionTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, ignitionTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map with translation + } + //RPM bins + for(int x=EEPROM_CONFIG3_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_XBINS; + if(EEPROM.read(x) != byte(ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(ignitionTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG3_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG3_YBINS; + EEPROM.update(x, ignitionTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + //That concludes the writing of the IGN table + break; - /*--------------------------------------------------- - | Ignition table (See storage.h for data layout) - Page 1 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the Ignition table, basically the same thing as above - if(EEPROM.read(EEPROM_CONFIG3_XSIZE) != ignitionTable.xSize) { EEPROM.write(EEPROM_CONFIG3_XSIZE,ignitionTable.xSize); } //Write the ignition Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG3_YSIZE) != ignitionTable.ySize) { EEPROM.write(EEPROM_CONFIG3_YSIZE,ignitionTable.ySize); } //Write the ignition Table MAP/TPS dimension size + case ignSetPage: + /*--------------------------------------------------- + | Config page 2 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory + for(int x=EEPROM_CONFIG4_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG4_START))); writeCounter++; } + } + break; - for(int x=EEPROM_CONFIG3_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_MAP; + if(EEPROM.read(x) != (afrTable.values[15-(offset/16)][offset%16]) ) { EEPROM.write(x, afrTable.values[15-(offset/16)][offset%16]); writeCounter++; } //Write the 16x16 map + } + //RPM bins + for(int x=EEPROM_CONFIG5_XBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_XBINS; + if(EEPROM.read(x) != byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(afrTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + } + //TPS/MAP bins + for(int x=EEPROM_CONFIG5_YBINS; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG5_YBINS; + EEPROM.update(x, afrTable.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + } + //That concludes the writing of the AFR table + break; + case afrSetPage: + /*--------------------------------------------------- + | Config page 3 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage3; //Create a pointer to Page 3 in memory + for(int x=EEPROM_CONFIG6_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG6_START))); writeCounter++; } + } + break; - /*--------------------------------------------------- - | AFR table (See storage.h for data layout) - Page 5 - | 16x16 table itself + the 16 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the Ignition table, basically the same thing as above - if(EEPROM.read(EEPROM_CONFIG5_XSIZE) != afrTable.xSize) { EEPROM.write(EEPROM_CONFIG5_XSIZE,afrTable.xSize); } //Write the ignition Table RPM dimension size - if(EEPROM.read(EEPROM_CONFIG5_YSIZE) != afrTable.ySize) { EEPROM.write(EEPROM_CONFIG5_YSIZE,afrTable.ySize); } //Write the ignition Table MAP/TPS dimension size + case iacPage: + /*--------------------------------------------------- + | Config page 4 (See storage.h for data layout) + | 64 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 4 in memory + //The next 128 bytes can simply be pulled straight from the configTable + for(int x=EEPROM_CONFIG7_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG7_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG7_START))); writeCounter++; } + } + break; - for(int x=EEPROM_CONFIG5_MAP; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_MAP1; + if(EEPROM.read(x) != (boostTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(x, boostTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map + offset = y - EEPROM_CONFIG8_MAP2; + if(EEPROM.read(y) != (vvtTable.values[7-(offset/8)][offset%8]) ) { EEPROM.write(y, vvtTable.values[7-(offset/8)][offset%8]); writeCounter++; } //Write the 8x8 map + y++; + } + //RPM bins + y = EEPROM_CONFIG8_XBINS2; + for(int x=EEPROM_CONFIG8_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_XBINS1; + if(EEPROM.read(x) != byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(x, byte(boostTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + offset = y - EEPROM_CONFIG8_XBINS2; + if(EEPROM.read(y) != byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)) { EEPROM.write(y, byte(vvtTable.axisX[offset]/TABLE_RPM_MULTIPLIER)); writeCounter++; } //RPM bins are divided by 100 and converted to a byte + y++; + } + //TPS/MAP bins + y=EEPROM_CONFIG8_YBINS2; + for(int x=EEPROM_CONFIG8_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG8_YBINS1; + EEPROM.update(x, boostTable.axisY[offset]); //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100) + offset = y - EEPROM_CONFIG8_YBINS2; + EEPROM.update(y, vvtTable.axisY[offset]); //TABLE_LOAD_MULTIPLIER is NOT used for VVT as it is TPS based (0-100) + y++; + } + } + break; - /*--------------------------------------------------- - | Config page 4 (See storage.h for data layout) - | 64 byte long config table - -----------------------------------------------------*/ - pnt_configPage = (byte *)&configPage4; //Create a pointer to Page 4 in memory - //The next 128 bytes can simply be pulled straight from the configTable - for(int x=EEPROM_CONFIG7_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG9_MAP1; + EEPROM.update(x, (trim1Table.values[5-(offset/6)][offset%6]) ); //Write the 6x6 map + offset = y - EEPROM_CONFIG9_MAP2; + EEPROM.update(y, trim2Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map + offset = z - EEPROM_CONFIG9_MAP3; + EEPROM.update(z, trim3Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map + offset = i - EEPROM_CONFIG9_MAP4; + EEPROM.update(i, trim4Table.values[5-(offset/6)][offset%6]); //Write the 6x6 map + y++; + z++; + i++; + } + //RPM bins + y = EEPROM_CONFIG9_XBINS2; + z = EEPROM_CONFIG9_XBINS3; + i = EEPROM_CONFIG9_XBINS4; + for(int x=EEPROM_CONFIG9_XBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG9_XBINS1; + EEPROM.update(x, byte(trim1Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = y - EEPROM_CONFIG9_XBINS2; + EEPROM.update(y, byte(trim2Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = z - EEPROM_CONFIG9_XBINS3; + EEPROM.update(z, byte(trim3Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + offset = i - EEPROM_CONFIG9_XBINS4; + EEPROM.update(i, byte(trim4Table.axisX[offset]/TABLE_RPM_MULTIPLIER)); //RPM bins are divided by 100 and converted to a byte + y++; + z++; + i++; + } + //TPS/MAP bins + y=EEPROM_CONFIG9_YBINS2; + z=EEPROM_CONFIG9_YBINS3; + i=EEPROM_CONFIG9_YBINS4; + for(int x=EEPROM_CONFIG9_YBINS1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + offset = x - EEPROM_CONFIG9_YBINS1; + EEPROM.update(x, trim1Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = y - EEPROM_CONFIG9_YBINS2; + EEPROM.update(y, trim2Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = z - EEPROM_CONFIG9_YBINS3; + EEPROM.update(z, trim3Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + offset = i - EEPROM_CONFIG9_YBINS4; + EEPROM.update(i, trim4Table.axisY[offset]/TABLE_LOAD_MULTIPLIER); //Table load is divided by 2 (Allows for MAP up to 511) + y++; + z++; + i++; + } + } + break; - int y = EEPROM_CONFIG8_MAP2; //We do the 2 maps together in the same loop - for(int x=EEPROM_CONFIG8_MAP1; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG10_START))); } + } + break; - /*--------------------------------------------------- - | Fuel trim tables (See storage.h for data layout) - Page 9 - | 6x6 tables itself + the 6 values along each of the axis - -----------------------------------------------------*/ - //Begin writing the 2 tables, basically the same thing as above but we're doing these 2 together (2 tables per page instead of 1) - EEPROM.update(EEPROM_CONFIG9_XSIZE1,trim1Table.xSize); //Write the boost Table RPM dimension size - EEPROM.update(EEPROM_CONFIG9_YSIZE1,trim1Table.ySize); //Write the boost Table MAP/TPS dimension size - EEPROM.update(EEPROM_CONFIG9_XSIZE2,trim2Table.xSize); //Write the boost Table RPM dimension size - EEPROM.update(EEPROM_CONFIG9_YSIZE2,trim2Table.ySize); //Write the boost Table MAP/TPS dimension size - EEPROM.update(EEPROM_CONFIG9_XSIZE3,trim3Table.xSize); //Write the boost Table RPM dimension size - EEPROM.update(EEPROM_CONFIG9_YSIZE3,trim3Table.ySize); //Write the boost Table MAP/TPS dimension size - EEPROM.update(EEPROM_CONFIG9_XSIZE4,trim4Table.xSize); //Write the boost Table RPM dimension size - EEPROM.update(EEPROM_CONFIG9_YSIZE4,trim4Table.ySize); //Write the boost Table MAP/TPS dimension size + case warmupPage: + /*--------------------------------------------------- + | Config page 11 (See storage.h for data layout) + | 192 byte long config table + -----------------------------------------------------*/ + pnt_configPage = (byte *)&configPage11; //Create a pointer to Page 11 in memory + //As there are no 3d tables in this page, all 192 bytes can simply be read in + for(int x=EEPROM_CONFIG11_START; x EEPROM_MAX_WRITE_BLOCK) ) { eepromWritesPending = true; break; } //This is a safety check to make sure we don't attempt to write too much to the EEPROM at a time. + if(EEPROM.read(x) != *(pnt_configPage + byte(x - EEPROM_CONFIG11_START))) { EEPROM.write(x, *(pnt_configPage + byte(x - EEPROM_CONFIG11_START))); } + } + break; - y = EEPROM_CONFIG9_MAP2; //We do the 4 maps together in the same loop - int z = EEPROM_CONFIG9_MAP3; //We do the 4 maps together in the same loop - int i = EEPROM_CONFIG9_MAP4; //We do the 4 maps together in the same loop - for(int x=EEPROM_CONFIG9_MAP1; x