Move to TS optimised serial comms model + many minor serial improvements
This commit is contained in:
parent
71e963e196
commit
4380f8b0d5
|
@ -1847,7 +1847,8 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
|
||||
deadValue = { 0 } ; Convenient unchanging value.
|
||||
|
||||
ochGetCommand = "A"
|
||||
;ochGetCommand = "A"
|
||||
ochGetCommand = "r\$tsCanId\x07%2o%2c"
|
||||
ochBlockSize = 41
|
||||
|
||||
|
||||
|
@ -1935,9 +1936,9 @@ cmdtestspk450dc = "E\x03\x0C"
|
|||
throttle = { tps }, "%"
|
||||
|
||||
;cycleTime = { 60000.0 / rpm * (2.0-twoStroke) }
|
||||
cycleTime = { 60000.0 / rpm }
|
||||
cycleTime = { rpm ? ( 60000.0 / rpm ) : 0 }
|
||||
;nSquirts = { nCylinders/divider }
|
||||
dutyCycle = { 100.0*pulseWidth/cycleTime }
|
||||
dutyCycle = { rpm ? ( 100.0*pulseWidth/cycleTime ) : 0 }
|
||||
|
||||
boostCutOut = { boostCutFuel || boostCutSpark }
|
||||
lambda = { afr / stoich }
|
||||
|
|
|
@ -22,7 +22,7 @@ void canCommand()
|
|||
switch (Serial3.read())
|
||||
{
|
||||
case 'A': // sends the bytes of realtime values
|
||||
sendValues(packetSize,3); //send values to serial3
|
||||
sendValues(0, packetSize,3); //send values to serial3
|
||||
break;
|
||||
|
||||
case 'G': // this is the reply command sent by the Can interface
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
byte currentPage = 1;//Not the same as the speeduino config page numbers
|
||||
boolean isMap = true;
|
||||
unsigned long requestCount = 0; //The number of times the A command has been issued
|
||||
byte currentCommand;
|
||||
bool cmdPending = false;
|
||||
byte cmdGroup = 0;
|
||||
byte cmdValue = 0;
|
||||
int cmdCombined = 0; //the cmdgroup as high byte and cmdvalue as low byte
|
||||
|
@ -37,7 +39,7 @@ const char pageTitles[] PROGMEM //This is being stored in the avr flash instead
|
|||
};
|
||||
|
||||
void command();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable.
|
||||
void sendValues(int packetlength, byte portnum);
|
||||
void sendValues(uint16_t offset, uint16_t packetlength, byte portnum);
|
||||
void receiveValue(int offset, byte newValue);
|
||||
void saveConfig();
|
||||
void sendPage(bool useChar);
|
||||
|
|
|
@ -15,12 +15,16 @@ A detailed description of each call can be found at: http://www.msextra.com/doc/
|
|||
|
||||
void command()
|
||||
{
|
||||
switch (Serial.read())
|
||||
if (!cmdPending) { currentCommand = Serial.read(); }
|
||||
|
||||
switch (currentCommand)
|
||||
{
|
||||
|
||||
case 'A': // send x bytes of realtime values
|
||||
sendValues(packetSize, 0); //send values to serial0
|
||||
sendValues(0, packetSize, 0); //send values to serial0
|
||||
break;
|
||||
|
||||
|
||||
case 'B': // Burn current values to eeprom
|
||||
writeConfig();
|
||||
break;
|
||||
|
@ -30,13 +34,15 @@ void command()
|
|||
break;
|
||||
|
||||
case 'E': // receive command button commands
|
||||
while (Serial.available() == 0) { }
|
||||
cmdPending = true;
|
||||
|
||||
if(Serial.available() < 2) { return; }
|
||||
cmdGroup = Serial.read();
|
||||
while (Serial.available() == 0) { }
|
||||
cmdValue = Serial.read();
|
||||
cmdCombined = word(cmdGroup, cmdValue);
|
||||
if (currentStatus.RPM == 0) { commandButtons(); }
|
||||
|
||||
cmdPending = false;
|
||||
break;
|
||||
|
||||
case 'L': // List the contents of current page in human readable form
|
||||
|
@ -49,8 +55,9 @@ void command()
|
|||
|
||||
case 'P': // set the current page
|
||||
//A 2nd byte of data is required after the 'P' specifying the new page number.
|
||||
//This loop should never need to run as the byte should already be in the buffer, but is here just in case
|
||||
while (Serial.available() == 0) { }
|
||||
cmdPending = true;
|
||||
|
||||
if (Serial.available() == 0) { return; }
|
||||
currentPage = Serial.read();
|
||||
if (currentPage >= '0') {//This converts the ascii number char into binary
|
||||
currentPage -= '0';
|
||||
|
@ -61,10 +68,7 @@ void command()
|
|||
else {
|
||||
isMap = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R': // send 39 bytes of realtime values
|
||||
sendValues(39,0);
|
||||
cmdPending = false;
|
||||
break;
|
||||
|
||||
case 'F': // send serial protocol version
|
||||
|
@ -85,24 +89,25 @@ void command()
|
|||
break;
|
||||
|
||||
case 'W': // receive new VE obr constant at 'W'+<offset>+<newbyte>
|
||||
cmdPending = true;
|
||||
int valueOffset; //cannot use offset as a variable name, it is a reserved word for several teensy libraries
|
||||
while (Serial.available() == 0) { }
|
||||
|
||||
if (isMap)
|
||||
{
|
||||
if(Serial.available()< 3) { return; } // 1 additional byte is required on the MAP pages which are larger than 255 bytes
|
||||
byte offset1, offset2;
|
||||
offset1 = Serial.read();
|
||||
while (Serial.available() == 0) { }
|
||||
offset2 = Serial.read();
|
||||
valueOffset = word(offset2, offset1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Serial.available()< 2) { return; }
|
||||
valueOffset = Serial.read();
|
||||
}
|
||||
while (Serial.available() == 0) { }
|
||||
|
||||
receiveValue(valueOffset, Serial.read());
|
||||
cmdPending = false;
|
||||
break;
|
||||
|
||||
case 't': // receive new Calibration info. Command structure: "t", <tble_idx> <data array>. This is an MS2/Extra command, NOT part of MS1 spec
|
||||
|
@ -160,10 +165,33 @@ void command()
|
|||
sendToothLog(false); //Sends tooth log values as ints
|
||||
break;
|
||||
|
||||
case 'r': //Send 256 tooth log entries to a terminal emulator
|
||||
case 'z': //Send 256 tooth log entries to a terminal emulator
|
||||
sendToothLog(true); //Sends tooth log values as chars
|
||||
break;
|
||||
|
||||
case 'r': //New format for the optimised OutputChannels
|
||||
cmdPending = true;
|
||||
byte cmd;
|
||||
if (Serial.available() < 6) { return; }
|
||||
Serial.read(); //Read the $tsCanId
|
||||
cmd = Serial.read();
|
||||
|
||||
uint16_t offset, length;
|
||||
if(cmd == 0x07) //Send output channels command
|
||||
{
|
||||
byte tmp;
|
||||
tmp = Serial.read();
|
||||
offset = word(Serial.read(), tmp);
|
||||
tmp = Serial.read();
|
||||
length = word(Serial.read(), tmp);
|
||||
sendValues(offset, length, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//No other r/ commands should be called
|
||||
}
|
||||
cmdPending = false;
|
||||
break;
|
||||
|
||||
|
||||
case '?':
|
||||
|
@ -208,19 +236,21 @@ void command()
|
|||
/*
|
||||
This function returns the current values of a fixed group of variables
|
||||
*/
|
||||
void sendValues(int packetlength, byte portNum)
|
||||
//void sendValues(int packetlength, byte portNum)
|
||||
void sendValues(uint16_t offset, uint16_t packetLength, byte portNum)
|
||||
{
|
||||
byte response[packetlength];
|
||||
byte fullStatus[packetSize];
|
||||
byte response[packetLength];
|
||||
|
||||
if (portNum == 3)
|
||||
{
|
||||
//CAN serial
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
Serial3.write("A"); //confirm cmd type
|
||||
Serial3.write(packetlength); //confirm no of byte to be sent
|
||||
Serial3.write(packetLength); //confirm no of byte to be sent
|
||||
#elif defined(CORE_STM32)
|
||||
Serial2.write("A"); //confirm cmd type
|
||||
Serial2.write(packetlength); //confirm no of byte to be sent
|
||||
Serial2.write(packetLength); //confirm no of byte to be sent
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
@ -231,62 +261,67 @@ void sendValues(int packetlength, byte portNum)
|
|||
|
||||
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1 << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
|
||||
|
||||
response[0] = currentStatus.secl; //secl is simply a counter that increments each second. Used to track unexpected resets (Which will reset this count to 0)
|
||||
response[1] = currentStatus.squirt; //Squirt Bitfield
|
||||
response[2] = currentStatus.engine; //Engine Status Bitfield
|
||||
response[3] = (byte)(divu100(currentStatus.dwell)); //Dwell in ms * 10
|
||||
response[4] = (byte)(currentStatus.MAP >> 1); //map value is divided by 2
|
||||
response[5] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
||||
response[6] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
||||
response[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
||||
response[8] = currentStatus.battery10; //battery voltage
|
||||
response[9] = currentStatus.O2; //O2
|
||||
response[10] = currentStatus.egoCorrection; //Exhaust gas correction (%)
|
||||
response[11] = currentStatus.iatCorrection; //Air temperature Correction (%)
|
||||
response[12] = currentStatus.wueCorrection; //Warmup enrichment (%)
|
||||
response[13] = lowByte(currentStatus.RPM); //rpm HB
|
||||
response[14] = highByte(currentStatus.RPM); //rpm LB
|
||||
response[15] = currentStatus.TAEamount; //acceleration enrichment (%)
|
||||
response[16] = currentStatus.baro; //Barometer value
|
||||
response[17] = currentStatus.corrections; //Total GammaE (%)
|
||||
response[18] = currentStatus.VE; //Current VE 1 (%)
|
||||
response[19] = currentStatus.afrTarget;
|
||||
response[20] = (byte)(currentStatus.PW1 / 100); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
|
||||
response[21] = currentStatus.tpsDOT; //TPS DOT
|
||||
response[22] = currentStatus.advance;
|
||||
response[23] = currentStatus.TPS; // TPS (0% to 100%)
|
||||
fullStatus[0] = currentStatus.secl; //secl is simply a counter that increments each second. Used to track unexpected resets (Which will reset this count to 0)
|
||||
fullStatus[1] = currentStatus.squirt; //Squirt Bitfield
|
||||
fullStatus[2] = currentStatus.engine; //Engine Status Bitfield
|
||||
fullStatus[3] = (byte)(divu100(currentStatus.dwell)); //Dwell in ms * 10
|
||||
fullStatus[4] = (byte)(currentStatus.MAP >> 1); //map value is divided by 2
|
||||
fullStatus[5] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
|
||||
fullStatus[6] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
|
||||
fullStatus[7] = currentStatus.tpsADC; //TPS (Raw 0-255)
|
||||
fullStatus[8] = currentStatus.battery10; //battery voltage
|
||||
fullStatus[9] = currentStatus.O2; //O2
|
||||
fullStatus[10] = currentStatus.egoCorrection; //Exhaust gas correction (%)
|
||||
fullStatus[11] = currentStatus.iatCorrection; //Air temperature Correction (%)
|
||||
fullStatus[12] = currentStatus.wueCorrection; //Warmup enrichment (%)
|
||||
fullStatus[13] = lowByte(currentStatus.RPM); //rpm HB
|
||||
fullStatus[14] = highByte(currentStatus.RPM); //rpm LB
|
||||
fullStatus[15] = currentStatus.TAEamount; //acceleration enrichment (%)
|
||||
fullStatus[16] = currentStatus.baro; //Barometer value
|
||||
fullStatus[17] = currentStatus.corrections; //Total GammaE (%)
|
||||
fullStatus[18] = currentStatus.VE; //Current VE 1 (%)
|
||||
fullStatus[19] = currentStatus.afrTarget;
|
||||
fullStatus[20] = (byte)(currentStatus.PW1 / 100); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
|
||||
fullStatus[21] = currentStatus.tpsDOT; //TPS DOT
|
||||
fullStatus[22] = currentStatus.advance;
|
||||
fullStatus[23] = currentStatus.TPS; // TPS (0% to 100%)
|
||||
//Need to split the int loopsPerSecond value into 2 bytes
|
||||
response[24] = lowByte(currentStatus.loopsPerSecond);
|
||||
response[25] = highByte(currentStatus.loopsPerSecond);
|
||||
fullStatus[24] = lowByte(currentStatus.loopsPerSecond);
|
||||
fullStatus[25] = highByte(currentStatus.loopsPerSecond);
|
||||
|
||||
//The following can be used to show the amount of free memory
|
||||
currentStatus.freeRAM = freeRam();
|
||||
response[26] = lowByte(currentStatus.freeRAM); //(byte)((currentStatus.loopsPerSecond >> 8) & 0xFF);
|
||||
response[27] = highByte(currentStatus.freeRAM);
|
||||
fullStatus[26] = lowByte(currentStatus.freeRAM); //(byte)((currentStatus.loopsPerSecond >> 8) & 0xFF);
|
||||
fullStatus[27] = highByte(currentStatus.freeRAM);
|
||||
|
||||
response[28] = currentStatus.batCorrection; //Battery voltage correction (%)
|
||||
response[29] = currentStatus.spark; //Spark related bitfield
|
||||
response[30] = currentStatus.O2_2; //O2
|
||||
fullStatus[28] = currentStatus.batCorrection; //Battery voltage correction (%)
|
||||
fullStatus[29] = currentStatus.spark; //Spark related bitfield
|
||||
fullStatus[30] = currentStatus.O2_2; //O2
|
||||
|
||||
//rpmDOT must be sent as a signed integer
|
||||
response[31] = lowByte(currentStatus.rpmDOT);
|
||||
response[32] = highByte(currentStatus.rpmDOT);
|
||||
fullStatus[31] = lowByte(currentStatus.rpmDOT);
|
||||
fullStatus[32] = highByte(currentStatus.rpmDOT);
|
||||
|
||||
response[33] = currentStatus.ethanolPct; //Flex sensor value (or 0 if not used)
|
||||
response[34] = currentStatus.flexCorrection; //Flex fuel correction (% above or below 100)
|
||||
response[35] = currentStatus.flexIgnCorrection; //Ignition correction (Increased degrees of advance) for flex fuel
|
||||
response[36] = getNextError();
|
||||
response[37] = currentStatus.boostTarget;
|
||||
response[38] = currentStatus.boostDuty;
|
||||
response[39] = currentStatus.idleLoad;
|
||||
response[40] = currentStatus.testOutputs;
|
||||
fullStatus[33] = currentStatus.ethanolPct; //Flex sensor value (or 0 if not used)
|
||||
fullStatus[34] = currentStatus.flexCorrection; //Flex fuel correction (% above or below 100)
|
||||
fullStatus[35] = currentStatus.flexIgnCorrection; //Ignition correction (Increased degrees of advance) for flex fuel
|
||||
fullStatus[36] = getNextError();
|
||||
fullStatus[37] = currentStatus.boostTarget;
|
||||
fullStatus[38] = currentStatus.boostDuty;
|
||||
fullStatus[39] = currentStatus.idleLoad;
|
||||
fullStatus[40] = currentStatus.testOutputs;
|
||||
|
||||
for(byte x=0; x<packetLength; x++)
|
||||
{
|
||||
response[x] = fullStatus[offset+x];
|
||||
}
|
||||
|
||||
//cli();
|
||||
if (portNum == 0) { Serial.write(response, (size_t)packetlength); }
|
||||
if (portNum == 0) { Serial.write(response, (size_t)packetLength); }
|
||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
|
||||
else if (portNum == 3) { Serial3.write(response, (size_t)packetlength); }
|
||||
else if (portNum == 3) { Serial3.write(response, (size_t)packetLength); }
|
||||
#elif defined(CORE_STM32)
|
||||
else if (portNum == 3) { Serial2.write(response, (size_t)packetlength); }
|
||||
else if (portNum == 3) { Serial2.write(response, (size_t)packetLength); }
|
||||
#endif
|
||||
//sei();
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue