mirror of https://github.com/rusefi/speeduino.git
commit
dc4ebac47d
|
@ -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
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
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 the bytes of realtime values
|
||||||
|
sendValues(packetSize,3); //send values to serial3
|
||||||
|
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 <Llength ;Lcount++)
|
||||||
|
{
|
||||||
|
while (Serial3.available() == 0){}
|
||||||
|
// receive all x bytes into "Lbuffer"
|
||||||
|
Lbuffer[Lcount] = Serial3.read();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S': // send code version
|
||||||
|
for (unsigned int sig = 0; sig < sizeof(displaySignature) - 1; sig++){
|
||||||
|
Serial3.write(displaySignature[sig]);
|
||||||
|
}
|
||||||
|
//Serial3.print("speeduino 201609-dev");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Q': // send code version
|
||||||
|
for (unsigned int revn = 0; revn < sizeof( TSfirmwareVersion) - 1; revn++){
|
||||||
|
Serial3.write( TSfirmwareVersion[revn]);
|
||||||
|
}
|
||||||
|
//Serial3.print("speeduino 201609-dev");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
comms.h
2
comms.h
|
@ -28,7 +28,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 command();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable.
|
||||||
void sendValues();
|
void sendValues(int packetlength, byte portnum);
|
||||||
void receiveValue(int offset, byte newValue);
|
void receiveValue(int offset, byte newValue);
|
||||||
void saveConfig();
|
void saveConfig();
|
||||||
void sendPage(bool useChar);
|
void sendPage(bool useChar);
|
||||||
|
|
30
comms.ino
30
comms.ino
|
@ -17,8 +17,8 @@ void command()
|
||||||
{
|
{
|
||||||
switch (Serial.read())
|
switch (Serial.read())
|
||||||
{
|
{
|
||||||
case 'A': // send 22 bytes of realtime values
|
case 'A': // send x bytes of realtime values
|
||||||
sendValues(22);
|
sendValues(packetSize, 0); //send values to serial0
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'B': // Burn current values to eeprom
|
case 'B': // Burn current values to eeprom
|
||||||
|
@ -54,7 +54,7 @@ void command()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R': // send 39 bytes of realtime values
|
case 'R': // send 39 bytes of realtime values
|
||||||
sendValues(39);
|
sendValues(39,0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'F': // send serial protocol version
|
case 'F': // send serial protocol version
|
||||||
|
@ -198,13 +198,21 @@ void command()
|
||||||
/*
|
/*
|
||||||
This function returns the current values of a fixed group of variables
|
This function returns the current values of a fixed group of variables
|
||||||
*/
|
*/
|
||||||
void sendValues(int length)
|
void sendValues(int packetlength, byte portNum)
|
||||||
{
|
{
|
||||||
byte packetSize = 35;
|
byte response[packetlength];
|
||||||
byte response[packetSize];
|
|
||||||
|
if (portNum == 3)
|
||||||
if(requestCount == 0) { currentStatus.secl = 0; }
|
{
|
||||||
requestCount++;
|
//CAN serial
|
||||||
|
Serial3.write("A"); //confirm cmd type
|
||||||
|
Serial3.write(packetlength); //confirm no of byte to be sent
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(requestCount == 0) { currentStatus.secl = 0; }
|
||||||
|
requestCount++;
|
||||||
|
}
|
||||||
|
|
||||||
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1 << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
|
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1 << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
|
||||||
|
|
||||||
|
@ -253,8 +261,8 @@ void sendValues(int length)
|
||||||
response[34] = getNextError();
|
response[34] = getNextError();
|
||||||
|
|
||||||
//cli();
|
//cli();
|
||||||
Serial.write(response, (size_t)packetSize);
|
if (portNum == 0) { Serial.write(response, (size_t)packetlength); }
|
||||||
//Serial.flush();
|
else if (portNum == 3) { Serial3.write(response, (size_t)packetlength); }
|
||||||
//sei();
|
//sei();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
const byte signature = 20;
|
const byte signature = 20;
|
||||||
|
|
||||||
//const char signature[] = "speeduino";
|
//const char signature[] = "speeduino";
|
||||||
const char displaySignature[] = "Speeduino";
|
const char displaySignature[] = "speeduino 201609-dev";
|
||||||
const char TSfirmwareVersion[] = "2016.05";
|
const char TSfirmwareVersion[] = "Speeduino 2016.09";
|
||||||
|
|
||||||
const byte data_structure_version = 2; //This identifies the data structure when reading / writing.
|
const byte data_structure_version = 2; //This identifies the data structure when reading / writing.
|
||||||
const byte page_size = 64;
|
const byte page_size = 64;
|
||||||
const int map_page_size = 288;
|
const int map_page_size = 288;
|
||||||
|
const byte packetSize = 35;
|
||||||
|
|
||||||
//Handy bitsetting macros
|
//Handy bitsetting macros
|
||||||
#define BIT_SET(a,b) ((a) |= (1<<(b)))
|
#define BIT_SET(a,b) ((a) |= (1<<(b)))
|
||||||
|
@ -214,6 +215,7 @@ struct config1 {
|
||||||
byte algorithm : 1; //"Speed Density", "Alpha-N"
|
byte algorithm : 1; //"Speed Density", "Alpha-N"
|
||||||
byte baroCorr : 1;
|
byte baroCorr : 1;
|
||||||
byte injLayout : 2;
|
byte injLayout : 2;
|
||||||
|
byte canEnable : 1; //is can interface enabled
|
||||||
|
|
||||||
byte primePulse;
|
byte primePulse;
|
||||||
byte dutyLim;
|
byte dutyLim;
|
||||||
|
|
|
@ -576,4 +576,4 @@
|
||||||
<setting name="CELSIUS" value="CELSIUS"/>
|
<setting name="CELSIUS" value="CELSIUS"/>
|
||||||
</settings>
|
</settings>
|
||||||
<userComments Comment="These are user comments that can be related to a particular setting or dialog."/>
|
<userComments Comment="These are user comments that can be related to a particular setting or dialog."/>
|
||||||
</msq>
|
</msq>
|
|
@ -187,7 +187,8 @@ page = 2
|
||||||
algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N"
|
algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N"
|
||||||
baroCorr = bits, U08, 38, [3:3], "Off", "On"
|
baroCorr = bits, U08, 38, [3:3], "Off", "On"
|
||||||
injLayout = bits, U08, 38, [4:5], "Bank", "Semi-Sequential", "INVALID", "INVALID"
|
injLayout = bits, U08, 38, [4:5], "Bank", "Semi-Sequential", "INVALID", "INVALID"
|
||||||
|
canEnable = bits, U08, 38, [6:6], "Disable", "Enable"
|
||||||
|
|
||||||
primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1
|
primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1
|
||||||
dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0
|
dutyLim = scalar, U08, 40, "%", 1.0, 0.0, 0.0, 100.0, 0
|
||||||
unused41 = scalar, U08, 41, "RPM", 100.0, 0.0, 100, 25500, 0
|
unused41 = scalar, U08, 41, "RPM", 100.0, 0.0, 100, 25500, 0
|
||||||
|
@ -589,6 +590,8 @@ menuDialog = main
|
||||||
subMenu = vvtTbl, "VVT duty cycle", 8, { vvtEnabled }
|
subMenu = vvtTbl, "VVT duty cycle", 8, { vvtEnabled }
|
||||||
subMenu = std_separator
|
subMenu = std_separator
|
||||||
subMenu = tacho, "Tacho Output"
|
subMenu = tacho, "Tacho Output"
|
||||||
|
subMenu = std_separator
|
||||||
|
subMenu = canIO, "Canbus Interface"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -713,6 +716,9 @@ menuDialog = main
|
||||||
dialog = tacho, "Tacho"
|
dialog = tacho, "Tacho"
|
||||||
field = "Output pin", tachoPin
|
field = "Output pin", tachoPin
|
||||||
|
|
||||||
|
dialog = canIO, "CanBus interface"
|
||||||
|
field = "Enable/Disable", canEnable
|
||||||
|
|
||||||
dialog = accelEnrichments_center, ""
|
dialog = accelEnrichments_center, ""
|
||||||
field = "TPSdot Threshold", tpsThresh
|
field = "TPSdot Threshold", tpsThresh
|
||||||
field = "Accel Time", taeTime
|
field = "Accel Time", taeTime
|
||||||
|
|
|
@ -126,7 +126,7 @@ static inline unsigned int setQueue(volatile Schedule *queue[], Schedule *schedu
|
||||||
//Sort the queues. Both queues are kept in sync.
|
//Sort the queues. Both queues are kept in sync.
|
||||||
//This implementes a sorting networking based on the Bose-Nelson sorting network
|
//This implementes a sorting networking based on the Bose-Nelson sorting network
|
||||||
//See: http://pages.ripco.net/~jgamble/nw.html
|
//See: http://pages.ripco.net/~jgamble/nw.html
|
||||||
#define SWAP(x,y) if(tmpQueue[y] < tmpQueue[x]) { unsigned int tmp = tmpQueue[x]; tmpQueue[x] = tmpQueue[y]; tmpQueue[y] = tmp; Schedule *tmpS = queue[x]; queue[x] = queue[y]; queue[y] = tmpS; }
|
#define SWAP(x,y) if(tmpQueue[y] < tmpQueue[x]) { unsigned int tmp = tmpQueue[x]; tmpQueue[x] = tmpQueue[y]; tmpQueue[y] = tmp; volatile Schedule *tmpS = queue[x]; queue[x] = queue[y]; queue[y] = tmpS; }
|
||||||
//SWAP(0, 1); //Likely not needed
|
//SWAP(0, 1); //Likely not needed
|
||||||
//SWAP(2, 3); //Likely not needed
|
//SWAP(2, 3); //Likely not needed
|
||||||
SWAP(0, 2);
|
SWAP(0, 2);
|
||||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
|
#include "cancomms.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "corrections.h"
|
#include "corrections.h"
|
||||||
#include "timers.h"
|
#include "timers.h"
|
||||||
|
@ -148,7 +149,8 @@ volatile bool fpPrimed = false; //Tracks whether or not the fuel pump priming ha
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
if (configPage1.canEnable) { Serial3.begin(115200); }
|
||||||
|
|
||||||
//Setup the dummy fuel and ignition tables
|
//Setup the dummy fuel and ignition tables
|
||||||
//dummyFuelTable(&fuelTable);
|
//dummyFuelTable(&fuelTable);
|
||||||
|
@ -752,6 +754,17 @@ void loop()
|
||||||
command();
|
command();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//if Can interface is enabled then check for serial3 requests.
|
||||||
|
if (configPage1.canEnable)
|
||||||
|
{
|
||||||
|
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
|
// if (configPage1.displayType && (mainLoopCount & 255) == 1) { updateDisplay();} //Displays currently disabled
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue