diff --git a/cancomms.h b/cancomms.h new file mode 100644 index 0000000..e254a0f --- /dev/null +++ b/cancomms.h @@ -0,0 +1,18 @@ +#ifndef CANCOMMS_H +#define CANCOMMS_H +//These are the page numbers that the Tuner Studio serial protocol uses to transverse the different map and config pages. +#define veMapPage 1 + + +uint8_t currentcanPage = 1;//Not the same as the speeduino config page numbers +uint8_t nCanretry = 0; //no of retrys +uint8_t cancmdfail = 0; //command fail yes/no +uint8_t canlisten = 0; +uint8_t Lbuffer[8]; //8 byte buffer to store incomng can data + + +void Cancommand();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable. +void sendCancommand(uint8_t cmdtype , uint16_t canadddress, uint8_t candata1, uint8_t candata2); +void testCanComm(); + +#endif // CANCOMMS_H diff --git a/cancomms.ino b/cancomms.ino new file mode 100644 index 0000000..767c6b6 --- /dev/null +++ b/cancomms.ino @@ -0,0 +1,147 @@ +/* +Speeduino - Simple engine management for the Arduino Mega 2560 platform +Copyright (C) Josh Stewart +A full copy of the license may be found in the projects root directory +can_comms was originally contributed by Darren Siepka +*/ + +/* +can_command is called when a command is received over serial3 from the Can interface +It parses the command and calls the relevant function +sendcancommand is called when a comman d is to be sent via serial3 to the Can interface +*/ + +//#include "cancomms.h" +//#include "globals.h" +//#include "storage.h" + +void Cancommand() +{ + switch (Serial3.read()) + { + case 'A': // sends all the bytes of realtime values + sendCanValues(); + break; + + case 'G': // this is the reply command sent by the Can interface + uint8_t Gdata; + while (Serial3.available() == 0) { } + cancmdfail = Serial3.read(); + if (cancmdfail == 0) + { + //command request failed and/or data/device was not available + } + while (Serial3.available() == 0) { } + Gdata= Serial3.read(); + break; + + case 'L': + uint8_t Llength; + while (Serial3.available() == 0) { } + canlisten = Serial3.read(); + if (canlisten == 0) + { + //command request failed and/or data/device was not available + break; + } + while (Serial3.available() == 0) { } + Llength= Serial3.read(); // next the number of bytes expected value + for (uint8_t Lcount = 0; Lcount > 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] = 0x00; //Barometer correction (%) + response[17] = currentStatus.corrections; //Total GammaE (%) + response[18] = currentStatus.VE; //Current VE 1 (%) + response[19] = currentStatus.afrTarget; + response[20] = (byte)(currentStatus.PW / 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%) + //Need to split the int loopsPerSecond value into 2 bytes + response[24] = lowByte(currentStatus.loopsPerSecond); + response[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); + + response[28] = currentStatus.batCorrection; //Battery voltage correction (%) + response[29] = currentStatus.spark; //Spark related bitfield + response[30] = currentStatus.O2_2; //O2 + + //rpmDOT must be sent as a signed integer + response[31] = lowByte(currentStatus.rpmDOT); + response[32] = highByte(currentStatus.rpmDOT); + + response[33] = currentStatus.flex; //Flex sensor value (or 0 if not used) + + Serial3.write(response, (size_t)packetSize); + + return; +} + +// this routine sends a request(either "0" for a "G" or "1" for a "L" to the Can interface +void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint8_t candata2) +{ + switch (cmdtype) + { + case 0: + Serial3.print("G"); + Serial3.write(canaddress); //tscanid of speeduino device + Serial3.write(candata1); // table id + Serial3.write(candata2); //table memory offset + break; + + case 1: //send request to listen for a can message + Serial3.print("L"); + Serial3.write(canaddress); //11 bit canaddress of device to listen for + break; + } +} + diff --git a/globals.h b/globals.h index 45999a9..c9953af 100644 --- a/globals.h +++ b/globals.h @@ -211,6 +211,7 @@ struct config1 { byte algorithm : 1; //"Speed Density", "Alpha-N" byte baroCorr : 1; byte injLayout : 2; + byte canenable : 1; //is can interface enabled byte primePulse; byte dutyLim; diff --git a/speeduino.ino b/speeduino.ino index 4259e13..8bf512c 100644 --- a/speeduino.ino +++ b/speeduino.ino @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "table.h" #include "scheduler.h" #include "comms.h" +#include "cancomms.h" #include "math.h" #include "corrections.h" #include "timers.h" @@ -160,6 +161,7 @@ void setup() table3D_setSize(&vvtTable, 8); loadConfig(); + if (configPage1.canenable ==1){Serial3.begin(115200);} //Repoint the 2D table structs to the config pages that were just loaded taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values @@ -720,6 +722,17 @@ void loop() command(); } } + //if Can interface is enabled then check for serial3 requests. + if (configPage1.canenable == 1) + { + if ( ((mainLoopCount & 31) == 1) or (Serial3.available() > SERIAL_BUFFER_THRESHOLD) ) + { + if (Serial3.available() > 0) + { + Cancommand(); + } + } + } // if (configPage1.displayType && (mainLoopCount & 255) == 1) { updateDisplay();} //Displays currently disabled