Split the sendPage functions between binary and ascii

This commit is contained in:
Josh Stewart 2019-04-20 17:14:37 +10:00
parent dc7b789a4e
commit 64f300206b
2 changed files with 411 additions and 368 deletions

View File

@ -54,7 +54,8 @@ void sendValues(uint16_t, uint16_t,byte, byte);
void sendValuesLegacy();
void receiveValue(uint16_t, byte);
void saveConfig();
void sendPage(bool);
void sendPage();
void sendPageASCII();
void receiveCalibration(byte);
void sendToothLog(bool);
void testComm();

View File

@ -160,7 +160,7 @@ void command()
break;
case 'L': // List the contents of current page in human readable form
sendPage(true);
sendPageASCII();
break;
case 'm': //Send the current free memory
@ -296,7 +296,7 @@ void command()
break;
case 'V': // send VE table and constants in binary
sendPage(false);
sendPage();
break;
case 'W': // receive new VE obr constant at 'W'+<offset>+<newbyte>
@ -914,13 +914,146 @@ void receiveValue(uint16_t valueOffset, byte newValue)
//if(Serial.available() > 16) { command(); }
}
/*
sendPage() packs the data within the current page (As set with the 'P' command)
into a buffer and sends it.
Note that some translation of the data is required to lay it out in the way Megasqurit / TunerStudio expect it
useChar - If true, all values are send as chars, this is for the serial command line interface. TunerStudio expects data as raw values, so this must be set false in that case
/**
* @brief Packs the data within the current page (As set with the 'P' command) into a buffer and sends it.
*
* Note that some translation of the data is required to lay it out in the way Megasqurit / TunerStudio expect it
* Data is sent in binary format, as defined by in each page in the ini
*/
void sendPage(bool useChar)
void sendPage()
{
void* pnt_configPage = &configPage2; //Default value is for safety only. Will be changed below if needed.
struct table3D currentTable = fuelTable; //Default value is for safety only. Will be changed below if needed.
bool sendComplete = false; //Used to track whether all send operations are complete
switch (currentPage)
{
case veMapPage:
currentTable = fuelTable;
break;
case veSetPage:
pnt_configPage = &configPage2; //Create a pointer to Page 1 in memory
break;
case ignMapPage:
currentTable = ignitionTable;
break;
case ignSetPage:
pnt_configPage = &configPage4; //Create a pointer to Page 2 in memory
break;
case afrMapPage:
currentTable = afrTable;
break;
case afrSetPage:
pnt_configPage = &configPage6; //Create a pointer to Page 3 in memory
break;
case boostvvtPage:
{
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
byte response[80]; //Bit hacky, but send 1 map at a time (Each map is 8x8, so 64 + 8 + 8)
//Boost table
for (int x = 0; x < 64; x++) { response[x] = boostTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(boostTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(boostTable.axisY[7 - (y - 72)]); }
Serial.write((byte *)&response, 80);
//VVT table
for (int x = 0; x < 64; x++) { response[x] = vvtTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(vvtTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(vvtTable.axisY[7 - (y - 72)]); }
Serial.write((byte *)&response, 80);
//Staging table
for (int x = 0; x < 64; x++) { response[x] = stagingTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(stagingTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(stagingTable.axisY[7 - (y - 72)] / TABLE_LOAD_MULTIPLIER); }
Serial.write((byte *)&response, 80);
sendComplete = true;
break;
}
case seqFuelPage:
{
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
byte response[192]; //Bit hacky, but the size is: (6x6 + 6 + 6) * 4 = 192
//trim1 table
for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x] = byte(trim1Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y] = byte(trim1Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim2 table
for (int x = 0; x < 36; x++) { response[x + 48] = trim2Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 48] = byte(trim2Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 48] = byte(trim2Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim3 table
for (int x = 0; x < 36; x++) { response[x + 96] = trim3Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 96] = byte(trim3Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 96] = byte(trim3Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim4 table
for (int x = 0; x < 36; x++) { response[x + 144] = trim4Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 144] = byte(trim4Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 144] = byte(trim4Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
Serial.write((byte *)&response, sizeof(response));
sendComplete = true;
break;
}
case canbusPage:
pnt_configPage = &configPage9; //Create a pointer to Page 10 in memory
break;
case warmupPage:
pnt_configPage = &configPage10; //Create a pointer to Page 11 in memory
break;
default:
#ifndef SMALL_FLASH_MODE
Serial.println(F("\nPage has not been implemented yet"));
#endif
//Just set default Values to avoid warnings
pnt_configPage = &configPage10;
currentTable = fuelTable;
sendComplete = true;
break;
}
if(!sendComplete)
{
if (isMap)
{
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
byte response[MAP_PAGE_SIZE];
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - (x / 16)][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
//loop();
for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
//loop();
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
//loop();
Serial.write((byte *)&response, sizeof(response));
} //is map
else
{
for (byte x = 0; x < npage_size[currentPage]; x++)
{
//response[x] = *((byte *)pnt_configPage + x);
Serial.write(*((byte *)pnt_configPage + x)); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x)
}
//Serial.write((byte *)&response, npage_size[currentPage]);
// }
} //isMap
} //sendComplete
}
/**
* @brief Similar to sendPage(), however data is sent in human readable format
*
* This is used for testing only (Not used by TunerStudio) in order to see current map and config data without the need for TunerStudio.
*/
void sendPageASCII()
{
void* pnt_configPage = &configPage2; //Default value is for safety only. Will be changed below if needed.
struct table3D currentTable = fuelTable; //Default value is for safety only. Will be changed below if needed.
@ -935,9 +1068,6 @@ void sendPage(bool useChar)
break;
case veSetPage:
// currentTitleIndex = 27;
if (useChar)
{
uint16_t* pnt16_configPage;
// To Display Values from Config Page 1
// When casting to the __FlashStringHelper type Serial.println uses the same subroutine as when using the F macro
@ -963,8 +1093,6 @@ void sendPage(bool useChar)
// Following loop displays remaining byte values of the page
for (pnt_configPage = (uint16_t *)&configPage2.mapMax + 1; pnt_configPage < (byte *)&configPage2 + npage_size[veSetPage]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
sendComplete = true;
}
else { pnt_configPage = &configPage2; } //Create a pointer to Page 1 in memory
break;
case ignMapPage:
@ -973,9 +1101,6 @@ void sendPage(bool useChar)
break;
case ignSetPage:
//currentTitleIndex = 56;
if (useChar)
{
//To Display Values from Config Page 2
Serial.println((const __FlashStringHelper *)&pageTitles[56]);
Serial.println(configPage4.triggerAngle);// configPsge2.triggerAngle is an int so just display it without complication
@ -1016,8 +1141,6 @@ void sendPage(bool useChar)
Serial.println(*((byte *)pnt_configPage));// Displaying remaining byte values of the page
}
sendComplete = true;
}
else { pnt_configPage = &configPage4; } //Create a pointer to Page 2 in memory
break;
case afrMapPage:
@ -1027,8 +1150,6 @@ void sendPage(bool useChar)
case afrSetPage:
//currentTitleIndex = 91;
if (useChar)
{
//To Display Values from Config Page 3
Serial.println((const __FlashStringHelper *)&pageTitles[91]);//special typecasting to enable suroutine that the F macro uses
for (pnt_configPage = &configPage6; pnt_configPage < &configPage6.voltageCorrectionBins[0]; pnt_configPage = (byte *)pnt_configPage + 1)
@ -1067,14 +1188,9 @@ void sendPage(bool useChar)
Serial.println(*((byte *)pnt_configPage));
}
sendComplete = true;
}
else { pnt_configPage = &configPage6; } //Create a pointer to Page 3 in memory
//Old configPage4 STARTED HERE!
//currentTitleIndex = 106;
//To Display Values from Config Page 4
if (useChar)
{
Serial.println((const __FlashStringHelper *)&pageTitles[106]);// F macro hack
for (byte y = 4; y; y--)// Display four equally sized arrays
{
@ -1114,43 +1230,14 @@ void sendPage(bool useChar)
// Following loop is for remaining byte value of page
for (pnt_configPage = (byte *)&configPage6.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage6 + npage_size[afrSetPage]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
sendComplete = true;
}
else { pnt_configPage = &configPage6; } //Create a pointer to Page 4 in memory
break;
case boostvvtPage:
if(useChar)
{
currentTable = boostTable;
currentTitleIndex = 121;
}
else
{
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
byte response[80]; //Bit hacky, but send 1 map at a time (Each map is 8x8, so 64 + 8 + 8)
//Boost table
for (int x = 0; x < 64; x++) { response[x] = boostTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(boostTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(boostTable.axisY[7 - (y - 72)]); }
Serial.write((byte *)&response, 80);
//VVT table
for (int x = 0; x < 64; x++) { response[x] = vvtTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(vvtTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(vvtTable.axisY[7 - (y - 72)]); }
Serial.write((byte *)&response, 80);
//Staging table
for (int x = 0; x < 64; x++) { response[x] = stagingTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(stagingTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(stagingTable.axisY[7 - (y - 72)] / TABLE_LOAD_MULTIPLIER); }
Serial.write((byte *)&response, 80);
sendComplete = true;
}
break;
case seqFuelPage:
if(useChar)
{
currentTable = trim1Table;
for (int y = 0; y < currentTable.ySize; y++)
{
@ -1182,55 +1269,25 @@ void sendPage(bool useChar)
Serial.println("");
}
sendComplete = true;
//Do.... Something?
}
else
{
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
byte response[192]; //Bit hacky, but the size is: (6x6 + 6 + 6) * 4 = 192
//trim1 table
for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x] = byte(trim1Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y] = byte(trim1Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim2 table
for (int x = 0; x < 36; x++) { response[x + 48] = trim2Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 48] = byte(trim2Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 48] = byte(trim2Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim3 table
for (int x = 0; x < 36; x++) { response[x + 96] = trim3Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 96] = byte(trim3Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 96] = byte(trim3Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim4 table
for (int x = 0; x < 36; x++) { response[x + 144] = trim4Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 144] = byte(trim4Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 144] = byte(trim4Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
Serial.write((byte *)&response, sizeof(response));
sendComplete = true;
}
break;
case canbusPage:
//currentTitleIndex = 141;
if (useChar)
{
//To Display Values from Config Page 10
Serial.println((const __FlashStringHelper *)&pageTitles[103]);//special typecasting to enable suroutine that the F macro uses
for (pnt_configPage = &configPage9; pnt_configPage < ((byte *)pnt_configPage + npage_size[canbusPage]); pnt_configPage = (byte *)pnt_configPage + 1)
for (pnt_configPage = &configPage9; pnt_configPage < ( (byte *)&configPage9 + npage_size[canbusPage]); pnt_configPage = (byte *)pnt_configPage + 1)
{
Serial.println(*((byte *)pnt_configPage));// Displaying byte values of config page 9 up to but not including the first array
}
sendComplete = true;
}
else { pnt_configPage = &configPage9; } //Create a pointer to Page 10 in memory
break;
case warmupPage:
if (useChar)
{
//NOT WRITTEN YET
#ifndef SMALL_FLASH_MODE
Serial.println(F("\nPage has not been implemented yet"));
#endif
sendComplete = true;
}
else { pnt_configPage = &configPage10; } //Create a pointer to Page 11 in memory
break;
default:
@ -1246,17 +1303,11 @@ void sendPage(bool useChar)
if(!sendComplete)
{
if (isMap)
{
if (useChar)
{
do //This is a do while loop that kicks in for the boostvvtPage
{
const char spaceChar = ' ';
/*while(pageTitles[currentTitleIndex])
{
Serial.print(pageTitles[currentTitleIndex]);
currentTitleIndex++;
}*/
Serial.println((const __FlashStringHelper *)&pageTitles[currentTitleIndex]);// F macro hack
Serial.println();
for (int y = 0; y < currentTable.ySize; y++)
@ -1311,21 +1362,6 @@ void sendPage(bool useChar)
}
else currentTitleIndex = 0;
}while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
} //use char
else
{
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
byte response[MAP_PAGE_SIZE];
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - (x / 16)][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
//loop();
for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
//loop();
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
//loop();
Serial.write((byte *)&response, sizeof(response));
}
} //is map
else
{
@ -1348,13 +1384,17 @@ void sendPage(bool useChar)
//response[x] = *((byte *)pnt_configPage + x);
Serial.write(*((byte *)pnt_configPage + x)); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x)
}
//Serial.write((byte *)&response, npage_size[currentPage]);
// }
} //isMap
} //sendComplete
}
/**
* @brief Retrieves a single value from a memory page, with data aligned as per the ini file
*
* @param page The page number to retrieve data from
* @param valueAddress The address in the page that should be returned. This is as per the page definition in the ini
* @return byte The requested value
*/
byte getPageValue(byte page, uint16_t valueAddress)
{
void* pnt_configPage = &configPage2; //Default value is for safety only. Will be changed below if needed.
@ -1491,8 +1531,10 @@ byte getPageValue(byte page, uint16_t valueAddress)
return returnValue;
}
/*
This function is used to store calibration data sent by Tuner Studio.
/**
* @brief Processes an incoming stream of calibration data from TunerStudio. Result is store in EEPROM and memory
*
* @param tableID Which calibration table to process. 0 = Coolant Sensor. 1 = IAT Sensor. 2 = O2 Sensor.
*/
void receiveCalibration(byte tableID)
{