2152 lines
87 KiB
C++
2152 lines
87 KiB
C++
#include "globals.h"
|
|
#include "init.h"
|
|
#include "storage.h"
|
|
#include "updates.h"
|
|
#include "speeduino.h"
|
|
#include "timers.h"
|
|
#include "cancomms.h"
|
|
#include "utils.h"
|
|
#include "scheduledIO.h"
|
|
#include "scheduler.h"
|
|
#include "auxiliaries.h"
|
|
#include "sensors.h"
|
|
#include "decoders.h"
|
|
#include "corrections.h"
|
|
#include "idle.h"
|
|
#include "table.h"
|
|
#include BOARD_H //Note that this is not a real file, it is defined in globals.h.
|
|
|
|
void initialiseAll()
|
|
{
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
digitalWrite(LED_BUILTIN, LOW);
|
|
table3D_setSize(&fuelTable, 16);
|
|
table3D_setSize(&fuelTable2, 16);
|
|
table3D_setSize(&ignitionTable, 16);
|
|
table3D_setSize(&afrTable, 16);
|
|
table3D_setSize(&stagingTable, 8);
|
|
table3D_setSize(&boostTable, 8);
|
|
table3D_setSize(&vvtTable, 8);
|
|
table3D_setSize(&trim1Table, 6);
|
|
table3D_setSize(&trim2Table, 6);
|
|
table3D_setSize(&trim3Table, 6);
|
|
table3D_setSize(&trim4Table, 6);
|
|
|
|
loadConfig();
|
|
doUpdates(); //Check if any data items need updating (Occurs with firmware updates)
|
|
|
|
//Always start with a clean slate on the bootloader capabilities level
|
|
//This should be 0 until we hear otherwise from the 16u2
|
|
configPage4.bootloaderCaps = 0;
|
|
|
|
initBoard(); //This calls the current individual boards init function. See the board_xxx.ino files for these.
|
|
initialiseTimers();
|
|
|
|
Serial.begin(115200);
|
|
if (configPage9.enable_secondarySerial == 1) { CANSerial.begin(115200); }
|
|
|
|
#if defined(CORE_STM32) || defined(CORE_TEENSY)
|
|
configPage9.intcan_available = 1; // device has internal canbus
|
|
//Teensy onboard CAN not used currently
|
|
//enable local can interface
|
|
//setup can interface to 250k
|
|
//FlexCAN CANbus0(2500000, 0);
|
|
//static CAN_message_t txmsg,rxmsg;
|
|
//CANbus0.begin();
|
|
#endif
|
|
|
|
//Repoint the 2D table structs to the config pages that were just loaded
|
|
taeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
|
taeTable.xSize = 4;
|
|
taeTable.values = configPage4.taeValues;
|
|
taeTable.axisX = configPage4.taeBins;
|
|
maeTable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
|
maeTable.xSize = 4;
|
|
maeTable.values = configPage4.maeRates;
|
|
maeTable.axisX = configPage4.maeBins;
|
|
WUETable.valueSize = SIZE_BYTE; //Set this table to use byte values
|
|
WUETable.xSize = 10;
|
|
WUETable.values = configPage2.wueValues;
|
|
WUETable.axisX = configPage4.wueBins;
|
|
ASETable.valueSize = SIZE_BYTE;
|
|
ASETable.xSize = 4;
|
|
ASETable.values = configPage2.asePct;
|
|
ASETable.axisX = configPage2.aseBins;
|
|
ASECountTable.valueSize = SIZE_BYTE;
|
|
ASECountTable.xSize = 4;
|
|
ASECountTable.values = configPage2.aseCount;
|
|
ASECountTable.axisX = configPage2.aseBins;
|
|
PrimingPulseTable.valueSize = SIZE_BYTE;
|
|
PrimingPulseTable.xSize = 4;
|
|
PrimingPulseTable.values = configPage2.primePulse;
|
|
PrimingPulseTable.axisX = configPage2.primeBins;
|
|
crankingEnrichTable.valueSize = SIZE_BYTE;
|
|
crankingEnrichTable.valueSize = SIZE_BYTE;
|
|
crankingEnrichTable.xSize = 4;
|
|
crankingEnrichTable.values = configPage10.crankingEnrichValues;
|
|
crankingEnrichTable.axisX = configPage10.crankingEnrichBins;
|
|
|
|
dwellVCorrectionTable.valueSize = SIZE_BYTE;
|
|
dwellVCorrectionTable.xSize = 6;
|
|
dwellVCorrectionTable.values = configPage4.dwellCorrectionValues;
|
|
dwellVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
|
injectorVCorrectionTable.valueSize = SIZE_BYTE;
|
|
injectorVCorrectionTable.xSize = 6;
|
|
injectorVCorrectionTable.values = configPage6.injVoltageCorrectionValues;
|
|
injectorVCorrectionTable.axisX = configPage6.voltageCorrectionBins;
|
|
IATDensityCorrectionTable.valueSize = SIZE_BYTE;
|
|
IATDensityCorrectionTable.xSize = 9;
|
|
IATDensityCorrectionTable.values = configPage6.airDenRates;
|
|
IATDensityCorrectionTable.axisX = configPage6.airDenBins;
|
|
IATRetardTable.valueSize = SIZE_BYTE;
|
|
IATRetardTable.xSize = 6;
|
|
IATRetardTable.values = configPage4.iatRetValues;
|
|
IATRetardTable.axisX = configPage4.iatRetBins;
|
|
CLTAdvanceTable.valueSize = SIZE_BYTE;
|
|
CLTAdvanceTable.xSize = 6;
|
|
CLTAdvanceTable.values = (byte*)configPage4.cltAdvValues;
|
|
CLTAdvanceTable.axisX = configPage4.cltAdvBins;
|
|
rotarySplitTable.valueSize = SIZE_BYTE;
|
|
rotarySplitTable.xSize = 8;
|
|
rotarySplitTable.values = configPage10.rotarySplitValues;
|
|
rotarySplitTable.axisX = configPage10.rotarySplitBins;
|
|
|
|
flexFuelTable.valueSize = SIZE_BYTE;
|
|
flexFuelTable.xSize = 6;
|
|
flexFuelTable.values = configPage10.flexFuelAdj;
|
|
flexFuelTable.axisX = configPage10.flexFuelBins;
|
|
flexAdvTable.valueSize = SIZE_BYTE;
|
|
flexAdvTable.xSize = 6;
|
|
flexAdvTable.values = configPage10.flexAdvAdj;
|
|
flexAdvTable.axisX = configPage10.flexAdvBins;
|
|
flexBoostTable.valueSize = SIZE_INT;
|
|
flexBoostTable.xSize = 6;
|
|
flexBoostTable.values16 = configPage10.flexBoostAdj;
|
|
flexBoostTable.axisX = configPage10.flexBoostBins;
|
|
|
|
knockWindowStartTable.valueSize = SIZE_BYTE;
|
|
knockWindowStartTable.xSize = 6;
|
|
knockWindowStartTable.values = configPage10.knock_window_angle;
|
|
knockWindowStartTable.axisX = configPage10.knock_window_rpms;
|
|
knockWindowDurationTable.valueSize = SIZE_BYTE;
|
|
knockWindowDurationTable.xSize = 6;
|
|
knockWindowDurationTable.values = configPage10.knock_window_dur;
|
|
knockWindowDurationTable.axisX = configPage10.knock_window_rpms;
|
|
|
|
//Setup the calibration tables
|
|
loadCalibration();
|
|
|
|
//Set the pin mappings
|
|
if(configPage2.pinMapping == 255)
|
|
{
|
|
//First time running on this board
|
|
setPinMapping(3); //Force board to v0.4
|
|
configPage2.flexEnabled = false; //Have to disable flex. If this isn't done and the wrong flex pin is interrupt attached below, system can hang.
|
|
}
|
|
else { setPinMapping(configPage2.pinMapping); }
|
|
|
|
//Need to check early on whether the coil charging is inverted. If this is not set straight away it can cause an unwanted spark at bootup
|
|
if(configPage4.IgInv == 1) { coilHIGH = LOW; coilLOW = HIGH; }
|
|
else { coilHIGH = HIGH; coilLOW = LOW; }
|
|
endCoil1Charge();
|
|
endCoil2Charge();
|
|
endCoil3Charge();
|
|
endCoil4Charge();
|
|
endCoil5Charge();
|
|
#if (INJ_CHANNELS >= 6)
|
|
endCoil6Charge();
|
|
#endif
|
|
#if (INJ_CHANNELS >= 7)
|
|
endCoil7Charge();
|
|
#endif
|
|
#if (INJ_CHANNELS >= 8)
|
|
endCoil8Charge();
|
|
#endif
|
|
|
|
//Similar for injectors, make sure they're turned off
|
|
closeInjector1();
|
|
closeInjector2();
|
|
closeInjector3();
|
|
closeInjector4();
|
|
closeInjector5();
|
|
#if (IGN_CHANNELS >= 6)
|
|
closeInjector6();
|
|
#endif
|
|
#if (IGN_CHANNELS >= 7)
|
|
closeInjector7();
|
|
#endif
|
|
#if (IGN_CHANNELS >= 8)
|
|
closeInjector8();
|
|
#endif
|
|
|
|
//Set the tacho output default state
|
|
digitalWrite(pinTachOut, HIGH);
|
|
//Perform all initialisations
|
|
initialiseSchedulers();
|
|
//initialiseDisplay();
|
|
initialiseIdle();
|
|
initialiseFan();
|
|
initialiseAuxPWM();
|
|
initialiseCorrections();
|
|
initialiseADC();
|
|
|
|
//Lookup the current MAP reading for barometric pressure
|
|
instanteneousMAPReading();
|
|
//barometric reading can be taken from either an external sensor if enabled, or simply by using the initial MAP value
|
|
if ( configPage6.useExtBaro != 0 )
|
|
{
|
|
readBaro();
|
|
//EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro);
|
|
storeLastBaro(currentStatus.baro);
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* The highest sea-level pressure on Earth occurs in Siberia, where the Siberian High often attains a sea-level pressure above 105 kPa;
|
|
* with record highs close to 108.5 kPa.
|
|
* The lowest measurable sea-level pressure is found at the centers of tropical cyclones and tornadoes, with a record low of 87 kPa;
|
|
*/
|
|
if ((currentStatus.MAP >= BARO_MIN) && (currentStatus.MAP <= BARO_MAX)) //Check if engine isn't running
|
|
{
|
|
currentStatus.baro = currentStatus.MAP;
|
|
//EEPROM.update(EEPROM_LAST_BARO, currentStatus.baro);
|
|
storeLastBaro(currentStatus.baro);
|
|
}
|
|
else
|
|
{
|
|
//Attempt to use the last known good baro reading from EEPROM
|
|
if ((readLastBaro() >= BARO_MIN) && (readLastBaro() <= BARO_MAX)) //Make sure it's not invalid (Possible on first run etc)
|
|
{ currentStatus.baro = readLastBaro(); } //last baro correction
|
|
else { currentStatus.baro = 100; } //Final fall back position.
|
|
}
|
|
}
|
|
|
|
//Check whether the flex sensor is enabled and if so, attach an interupt for it
|
|
if(configPage2.flexEnabled > 0)
|
|
{
|
|
attachInterrupt(digitalPinToInterrupt(pinFlex), flexPulse, RISING);
|
|
currentStatus.ethanolPct = 0;
|
|
}
|
|
|
|
//Once the configs have been loaded, a number of one time calculations can be completed
|
|
req_fuel_uS = configPage2.reqFuel * 100; //Convert to uS and an int. This is the only variable to be used in calculations
|
|
inj_opentime_uS = configPage2.injOpen * 100; //Injector open time. Comes through as ms*10 (Eg 15.5ms = 155).
|
|
|
|
if(configPage10.stagingEnabled == true)
|
|
{
|
|
uint32_t totalInjector = configPage10.stagedInjSizePri + configPage10.stagedInjSizeSec;
|
|
/*
|
|
These values are a percentage of the req_fuel value that would be required for each injector channel to deliver that much fuel.
|
|
Eg:
|
|
Pri injectors are 250cc
|
|
Sec injectors are 500cc
|
|
Total injector capacity = 750cc
|
|
|
|
staged_req_fuel_mult_pri = 300% (The primary injectors would have to run 3x the overall PW in order to be the equivalent of the full 750cc capacity
|
|
staged_req_fuel_mult_sec = 150% (The secondary injectors would have to run 1.5x the overall PW in order to be the equivalent of the full 750cc capacity
|
|
*/
|
|
staged_req_fuel_mult_pri = (100 * totalInjector) / configPage10.stagedInjSizePri;
|
|
staged_req_fuel_mult_sec = (100 * totalInjector) / configPage10.stagedInjSizeSec;
|
|
}
|
|
|
|
//Begin the main crank trigger interrupt pin setup
|
|
//The interrupt numbering is a bit odd - See here for reference: arduino.cc/en/Reference/AttachInterrupt
|
|
//These assignments are based on the Arduino Mega AND VARY BETWEEN BOARDS. Please confirm the board you are using and update acordingly.
|
|
currentStatus.RPM = 0;
|
|
currentStatus.hasSync = false;
|
|
currentStatus.runSecs = 0;
|
|
currentStatus.secl = 0;
|
|
currentStatus.startRevolutions = 0;
|
|
currentStatus.syncLossCounter = 0;
|
|
currentStatus.flatShiftingHard = false;
|
|
currentStatus.launchingHard = false;
|
|
currentStatus.crankRPM = ((unsigned int)configPage4.crankRPM * 10); //Crank RPM limit (Saves us calculating this over and over again. It's updated once per second in timers.ino)
|
|
currentStatus.fuelPumpOn = false;
|
|
triggerFilterTime = 0; //Trigger filter time is the shortest possible time (in uS) that there can be between crank teeth (ie at max RPM). Any pulses that occur faster than this time will be disgarded as noise. This is simply a default value, the actual values are set in the setup() functinos of each decoder
|
|
dwellLimit_uS = (1000 * configPage4.dwellLimit);
|
|
currentStatus.nChannels = (INJ_CHANNELS << 4) + IGN_CHANNELS; //First 4 bits store the number of injection channels, 2nd 4 store the number of ignition channels
|
|
fpPrimeTime = 0;
|
|
|
|
noInterrupts();
|
|
initialiseTriggers();
|
|
|
|
//End crank triger interrupt attachment
|
|
if(configPage2.strokes == FOUR_STROKE)
|
|
{
|
|
//Default is 1 squirt per revolution, so we halve the given req-fuel figure (Which would be over 2 revolutions)
|
|
req_fuel_uS = req_fuel_uS / 2; //The req_fuel calculation above gives the total required fuel (At VE 100%) in the full cycle. If we're doing more than 1 squirt per cycle then we need to split the amount accordingly. (Note that in a non-sequential 4-stroke setup you cannot have less than 2 squirts as you cannot determine the stroke to make the single squirt on)
|
|
}
|
|
|
|
//Initial values for loop times
|
|
previousLoopTime = 0;
|
|
currentLoopTime = micros_safe();
|
|
|
|
mainLoopCount = 0;
|
|
|
|
currentStatus.nSquirts = configPage2.nCylinders / configPage2.divider; //The number of squirts being requested. This is manaully overriden below for sequential setups (Due to TS req_fuel calc limitations)
|
|
if(currentStatus.nSquirts == 0) { currentStatus.nSquirts = 1; } //Safety check. Should never happen as TS will give an error, but leave incase tune is manually altered etc.
|
|
if(configPage2.strokes == FOUR_STROKE) { CRANK_ANGLE_MAX_INJ = 720 / currentStatus.nSquirts; }
|
|
else { CRANK_ANGLE_MAX_INJ = 360 / currentStatus.nSquirts; }
|
|
|
|
//Calculate the number of degrees between cylinders
|
|
switch (configPage2.nCylinders) {
|
|
case 1:
|
|
channel1IgnDegrees = 0;
|
|
channel1InjDegrees = 0;
|
|
maxIgnOutputs = 1;
|
|
|
|
//Sequential ignition works identically on a 1 cylinder whether it's odd or even fire.
|
|
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) ) { CRANK_ANGLE_MAX_IGN = 720; }
|
|
|
|
if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) )
|
|
{
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
|
|
channel1InjEnabled = true;
|
|
|
|
//Check if injector staging is enabled
|
|
if(configPage10.stagingEnabled == true)
|
|
{
|
|
channel3InjEnabled = true;
|
|
channel3InjDegrees = channel1InjDegrees;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
channel1IgnDegrees = 0;
|
|
channel1InjDegrees = 0;
|
|
maxIgnOutputs = 2;
|
|
if (configPage2.engineType == EVEN_FIRE ) { channel2IgnDegrees = 180; }
|
|
else { channel2IgnDegrees = configPage2.oddfire2; }
|
|
|
|
//Sequential ignition works identically on a 2 cylinder whether it's odd or even fire (With the default being a 180 degree second cylinder).
|
|
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) ) { CRANK_ANGLE_MAX_IGN = 720; }
|
|
|
|
if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) )
|
|
{
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
//The below are true regardless of whether this is running sequential or not
|
|
if (configPage2.engineType == EVEN_FIRE ) { channel2InjDegrees = 180; }
|
|
else { channel2InjDegrees = configPage2.oddfire2; }
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
}
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
|
|
//Check if injector staging is enabled
|
|
if(configPage10.stagingEnabled == true)
|
|
{
|
|
channel3InjEnabled = true;
|
|
channel4InjEnabled = true;
|
|
|
|
channel3InjDegrees = channel1InjDegrees;
|
|
channel4InjDegrees = channel2InjDegrees;
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
channel1IgnDegrees = 0;
|
|
maxIgnOutputs = 3;
|
|
if (configPage2.engineType == EVEN_FIRE )
|
|
{
|
|
//Sequential and Single channel modes both run over 720 crank degrees, but only on 4 stroke engines.
|
|
if( ( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) || (configPage4.sparkMode == IGN_MODE_SINGLE) ) && (configPage2.strokes == FOUR_STROKE) )
|
|
{
|
|
channel2IgnDegrees = 240;
|
|
channel3IgnDegrees = 480;
|
|
|
|
CRANK_ANGLE_MAX_IGN = 720;
|
|
}
|
|
else
|
|
{
|
|
channel2IgnDegrees = 120;
|
|
channel3IgnDegrees = 240;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
channel2IgnDegrees = configPage2.oddfire2;
|
|
channel3IgnDegrees = configPage2.oddfire3;
|
|
}
|
|
|
|
//For alternatiing injection, the squirt occurs at different times for each channel
|
|
if( (configPage2.injLayout == INJ_SEMISEQUENTIAL) || (configPage2.injLayout == INJ_PAIRED) || (configPage2.strokes == TWO_STROKE) )
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 120;
|
|
channel3InjDegrees = 240;
|
|
|
|
//Adjust the injection angles based on the number of squirts
|
|
if (currentStatus.nSquirts > 2)
|
|
{
|
|
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
|
|
channel3InjDegrees = (channel3InjDegrees * 2) / currentStatus.nSquirts;
|
|
}
|
|
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
channel3InjDegrees = 0;
|
|
}
|
|
}
|
|
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 240;
|
|
channel3InjDegrees = 480;
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
channel3InjEnabled = true;
|
|
break;
|
|
case 4:
|
|
channel1IgnDegrees = 0;
|
|
channel1InjDegrees = 0;
|
|
maxIgnOutputs = 2; //Default value for 4 cylinder, may be changed below
|
|
if (configPage2.engineType == EVEN_FIRE )
|
|
{
|
|
channel2IgnDegrees = 180;
|
|
//Adjust the injection angles based on the number of squirts
|
|
if (currentStatus.nSquirts > 2)
|
|
{
|
|
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
|
|
}
|
|
|
|
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (configPage2.strokes == FOUR_STROKE) )
|
|
{
|
|
channel3IgnDegrees = 360;
|
|
channel4IgnDegrees = 540;
|
|
|
|
CRANK_ANGLE_MAX_IGN = 720;
|
|
maxIgnOutputs = 4;
|
|
}
|
|
else if(configPage4.sparkMode == IGN_MODE_ROTARY)
|
|
{
|
|
//Rotary uses the ign 3 and 4 schedules for the trailing spark. They are offset from the ign 1 and 2 channels respectively and so use the same degrees as them
|
|
channel3IgnDegrees = 0;
|
|
channel4IgnDegrees = 180;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
channel2IgnDegrees = configPage2.oddfire2;
|
|
channel3IgnDegrees = configPage2.oddfire3;
|
|
channel4IgnDegrees = configPage2.oddfire4;
|
|
maxIgnOutputs = 4;
|
|
}
|
|
|
|
//For alternatiing injection, the squirt occurs at different times for each channel
|
|
if( (configPage2.injLayout == INJ_SEMISEQUENTIAL) || (configPage2.injLayout == INJ_PAIRED) || (configPage2.strokes == TWO_STROKE) )
|
|
{
|
|
channel2InjDegrees = 180;
|
|
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
}
|
|
}
|
|
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
|
{
|
|
channel2InjDegrees = 180;
|
|
channel3InjDegrees = 360;
|
|
channel4InjDegrees = 540;
|
|
|
|
channel3InjEnabled = true;
|
|
channel4InjEnabled = true;
|
|
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
|
|
//Check if injector staging is enabled
|
|
if(configPage10.stagingEnabled == true)
|
|
{
|
|
channel3InjEnabled = true;
|
|
channel4InjEnabled = true;
|
|
|
|
channel3InjDegrees = channel1InjDegrees;
|
|
channel4InjDegrees = channel2InjDegrees;
|
|
}
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
break;
|
|
case 5:
|
|
channel1IgnDegrees = 0;
|
|
channel2IgnDegrees = 72;
|
|
channel3IgnDegrees = 144;
|
|
channel4IgnDegrees = 216;
|
|
channel5IgnDegrees = 288;
|
|
maxIgnOutputs = 4; //Only 4 actual outputs, so that's all that can be cut
|
|
|
|
if(configPage4.sparkMode == IGN_MODE_SEQUENTIAL)
|
|
{
|
|
channel2IgnDegrees = 144;
|
|
channel3IgnDegrees = 288;
|
|
channel4IgnDegrees = 432;
|
|
channel5IgnDegrees = 576;
|
|
|
|
CRANK_ANGLE_MAX_IGN = 720;
|
|
}
|
|
|
|
//For alternatiing injection, the squirt occurs at different times for each channel
|
|
if( (configPage2.injLayout == INJ_SEMISEQUENTIAL) || (configPage2.injLayout == INJ_PAIRED) || (configPage2.strokes == TWO_STROKE) )
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 72;
|
|
channel3InjDegrees = 144;
|
|
channel4InjDegrees = 216;
|
|
channel5InjDegrees = 288;
|
|
}
|
|
else if (configPage2.injLayout == INJ_SEQUENTIAL)
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 144;
|
|
channel3InjDegrees = 288;
|
|
channel4InjDegrees = 432;
|
|
channel5InjDegrees = 576;
|
|
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
}
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
channel3InjDegrees = 0;
|
|
channel4InjDegrees = 0;
|
|
channel5InjDegrees = 0;
|
|
}
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
channel3InjEnabled = false; //this is disabled as injector 5 function calls 3 & 5 together
|
|
channel4InjEnabled = true;
|
|
channel5InjEnabled = true;
|
|
break;
|
|
case 6:
|
|
channel1IgnDegrees = 0;
|
|
channel1InjDegrees = 0;
|
|
channel2IgnDegrees = 120;
|
|
channel2InjDegrees = 120;
|
|
channel3IgnDegrees = 240;
|
|
channel3InjDegrees = 240;
|
|
maxIgnOutputs = 3;
|
|
|
|
//Adjust the injection angles based on the number of squirts
|
|
if (currentStatus.nSquirts > 2)
|
|
{
|
|
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
|
|
channel3InjDegrees = (channel3InjDegrees * 2) / currentStatus.nSquirts;
|
|
}
|
|
|
|
#if INJ_CHANNELS >= 6
|
|
if (configPage2.injLayout == INJ_SEQUENTIAL)
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 120;
|
|
channel3InjDegrees = 240;
|
|
channel4InjDegrees = 360;
|
|
channel5InjDegrees = 480;
|
|
channel6InjDegrees = 600;
|
|
|
|
channel4InjEnabled = true;
|
|
channel5InjEnabled = true;
|
|
channel6InjEnabled = true;
|
|
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
#endif
|
|
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
channel3InjDegrees = 0;
|
|
}
|
|
|
|
configPage2.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
channel3InjEnabled = true;
|
|
break;
|
|
case 8:
|
|
channel1IgnDegrees = 0;
|
|
channel2IgnDegrees = channel2InjDegrees = 90;
|
|
channel3IgnDegrees = channel3InjDegrees = 180;
|
|
channel4IgnDegrees = channel4InjDegrees = 270;
|
|
|
|
//Adjust the injection angles based on the number of squirts
|
|
if (currentStatus.nSquirts > 2)
|
|
{
|
|
channel2InjDegrees = (channel2InjDegrees * 2) / currentStatus.nSquirts;
|
|
channel3InjDegrees = (channel3InjDegrees * 2) / currentStatus.nSquirts;
|
|
channel4InjDegrees = (channel4InjDegrees * 2) / currentStatus.nSquirts;
|
|
}
|
|
|
|
#if INJ_CHANNELS >= 8
|
|
if (configPage2.injLayout == INJ_SEQUENTIAL)
|
|
{
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 90;
|
|
channel3InjDegrees = 180;
|
|
channel4InjDegrees = 270;
|
|
channel5InjDegrees = 360;
|
|
channel6InjDegrees = 450;
|
|
channel7InjDegrees = 540;
|
|
channel8InjDegrees = 630;
|
|
|
|
channel5InjEnabled = true;
|
|
channel6InjEnabled = true;
|
|
channel7InjEnabled = true;
|
|
channel8InjEnabled = true;
|
|
|
|
CRANK_ANGLE_MAX_INJ = 720;
|
|
currentStatus.nSquirts = 1;
|
|
req_fuel_uS = req_fuel_uS * 2;
|
|
}
|
|
#endif
|
|
|
|
maxIgnOutputs = 4;
|
|
|
|
if (!configPage2.injTiming)
|
|
{
|
|
//For simultaneous, all squirts happen at the same time
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 0;
|
|
channel3InjDegrees = 0;
|
|
channel4InjDegrees = 0;
|
|
}
|
|
|
|
configPage2.injLayout = 0; //This is a failsafe. We can never run semi-sequential with more than 4 cylinders
|
|
|
|
channel1InjEnabled = true;
|
|
channel2InjEnabled = true;
|
|
channel3InjEnabled = true;
|
|
channel4InjEnabled = true;
|
|
break;
|
|
default: //Handle this better!!!
|
|
channel1InjDegrees = 0;
|
|
channel2InjDegrees = 180;
|
|
break;
|
|
}
|
|
|
|
if(CRANK_ANGLE_MAX_IGN == CRANK_ANGLE_MAX_INJ) { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_IGN; } //If both the injector max and ignition max angles are the same, make the overall system max this value
|
|
else if (CRANK_ANGLE_MAX_IGN > CRANK_ANGLE_MAX_INJ) { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_IGN; }
|
|
else { CRANK_ANGLE_MAX = CRANK_ANGLE_MAX_INJ; }
|
|
currentStatus.status3 = currentStatus.nSquirts << BIT_STATUS3_NSQUIRTS1; //Top 3 bits of the status3 variable are the number of squirts. This must be done after the above section due to nSquirts being forced to 1 for sequential
|
|
|
|
//Special case:
|
|
//3 or 5 squirts per cycle MUST be tracked over 720 degrees. This is because the angles for them (Eg 720/3=240) are not evenly divisible into 360
|
|
//This is ONLY the case on 4 stroke systems
|
|
if( (currentStatus.nSquirts == 3) || (currentStatus.nSquirts == 5) )
|
|
{
|
|
if(configPage2.strokes == FOUR_STROKE) { CRANK_ANGLE_MAX = 720; }
|
|
}
|
|
|
|
|
|
switch(configPage4.sparkMode)
|
|
{
|
|
case IGN_MODE_WASTED:
|
|
//Wasted Spark (Normal mode)
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil2Charge;
|
|
ign2EndFunction = endCoil2Charge;
|
|
ign3StartFunction = beginCoil3Charge;
|
|
ign3EndFunction = endCoil3Charge;
|
|
ign4StartFunction = beginCoil4Charge;
|
|
ign4EndFunction = endCoil4Charge;
|
|
ign5StartFunction = beginCoil5Charge;
|
|
ign5EndFunction = endCoil5Charge;
|
|
break;
|
|
|
|
case IGN_MODE_SINGLE:
|
|
//Single channel mode. All ignition pulses are on channel 1
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil1Charge;
|
|
ign2EndFunction = endCoil1Charge;
|
|
ign3StartFunction = beginCoil1Charge;
|
|
ign3EndFunction = endCoil1Charge;
|
|
ign4StartFunction = beginCoil1Charge;
|
|
ign4EndFunction = endCoil1Charge;
|
|
ign5StartFunction = beginCoil1Charge;
|
|
ign5EndFunction = endCoil1Charge;
|
|
break;
|
|
|
|
case IGN_MODE_WASTEDCOP:
|
|
//Wasted COP mode. Ignition channels 1&3 and 2&4 are paired together
|
|
//This is not a valid mode for >4 cylinders
|
|
if( configPage2.nCylinders <= 4 )
|
|
{
|
|
ign1StartFunction = beginCoil1and3Charge;
|
|
ign1EndFunction = endCoil1and3Charge;
|
|
ign2StartFunction = beginCoil2and4Charge;
|
|
ign2EndFunction = endCoil2and4Charge;
|
|
|
|
ign3StartFunction = nullCallback;
|
|
ign3EndFunction = nullCallback;
|
|
ign4StartFunction = nullCallback;
|
|
ign4EndFunction = nullCallback;
|
|
}
|
|
else
|
|
{
|
|
//If the person has inadvertantly selected this when running more than 4 cylinders, just use standard Wasted spark mode
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil2Charge;
|
|
ign2EndFunction = endCoil2Charge;
|
|
ign3StartFunction = beginCoil3Charge;
|
|
ign3EndFunction = endCoil3Charge;
|
|
ign4StartFunction = beginCoil4Charge;
|
|
ign4EndFunction = endCoil4Charge;
|
|
ign5StartFunction = beginCoil5Charge;
|
|
ign5EndFunction = endCoil5Charge;
|
|
}
|
|
break;
|
|
|
|
case IGN_MODE_SEQUENTIAL:
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil2Charge;
|
|
ign2EndFunction = endCoil2Charge;
|
|
ign3StartFunction = beginCoil3Charge;
|
|
ign3EndFunction = endCoil3Charge;
|
|
ign4StartFunction = beginCoil4Charge;
|
|
ign4EndFunction = endCoil4Charge;
|
|
ign5StartFunction = beginCoil5Charge;
|
|
ign5EndFunction = endCoil5Charge;
|
|
ign6StartFunction = beginCoil6Charge;
|
|
ign6EndFunction = endCoil6Charge;
|
|
ign7StartFunction = beginCoil7Charge;
|
|
ign7EndFunction = endCoil7Charge;
|
|
ign8StartFunction = beginCoil8Charge;
|
|
ign8EndFunction = endCoil8Charge;
|
|
break;
|
|
|
|
case IGN_MODE_ROTARY:
|
|
if(configPage10.rotaryType == ROTARY_IGN_FC)
|
|
{
|
|
//Ignition channel 1 is a wasted spark signal for leading signal on both rotors
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil1Charge;
|
|
ign2EndFunction = endCoil1Charge;
|
|
|
|
ign3StartFunction = beginTrailingCoilCharge;
|
|
ign3EndFunction = endTrailingCoilCharge1;
|
|
ign4StartFunction = beginTrailingCoilCharge;
|
|
ign4EndFunction = endTrailingCoilCharge2;
|
|
}
|
|
else if(configPage10.rotaryType == ROTARY_IGN_FD)
|
|
{
|
|
//Ignition channel 1 is a wasted spark signal for leading signal on both rotors
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil1Charge;
|
|
ign2EndFunction = endCoil1Charge;
|
|
|
|
//Trailing coils have their own channel each
|
|
//IGN2 = front rotor trailing spark
|
|
ign3StartFunction = beginCoil2Charge;
|
|
ign3EndFunction = endCoil2Charge;
|
|
//IGN3 = rear rotor trailing spark
|
|
ign4StartFunction = beginCoil3Charge;
|
|
ign4EndFunction = endCoil3Charge;
|
|
|
|
//IGN4 not used
|
|
}
|
|
else if(configPage10.rotaryType == ROTARY_IGN_RX8)
|
|
{
|
|
//RX8 outputs are simply 1 coil and 1 output per plug
|
|
|
|
//IGN1 is front rotor, leading spark
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
//IGN2 is rear rotor, leading spark
|
|
ign2StartFunction = beginCoil2Charge;
|
|
ign2EndFunction = endCoil2Charge;
|
|
//IGN3 = front rotor trailing spark
|
|
ign3StartFunction = beginCoil3Charge;
|
|
ign3EndFunction = endCoil3Charge;
|
|
//IGN4 = rear rotor trailing spark
|
|
ign4StartFunction = beginCoil4Charge;
|
|
ign4EndFunction = endCoil4Charge;
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
//Wasted spark (Shouldn't ever happen anyway)
|
|
ign1StartFunction = beginCoil1Charge;
|
|
ign1EndFunction = endCoil1Charge;
|
|
ign2StartFunction = beginCoil2Charge;
|
|
ign2EndFunction = endCoil2Charge;
|
|
ign3StartFunction = beginCoil3Charge;
|
|
ign3EndFunction = endCoil3Charge;
|
|
ign4StartFunction = beginCoil4Charge;
|
|
ign4EndFunction = endCoil4Charge;
|
|
ign5StartFunction = beginCoil5Charge;
|
|
ign5EndFunction = endCoil5Charge;
|
|
break;
|
|
}
|
|
|
|
//Begin priming the fuel pump. This is turned off in the low resolution, 1s interrupt in timers.ino
|
|
//First check that the priming time is not 0
|
|
if(configPage2.fpPrime > 0)
|
|
{
|
|
FUEL_PUMP_ON();
|
|
currentStatus.fuelPumpOn = true;
|
|
}
|
|
else { fpPrimed = true; } //If the user has set 0 for the pump priming, immediately mark the priming as being completed
|
|
|
|
interrupts();
|
|
//Perform the priming pulses. Set these to run at an arbitrary time in the future (100us). The prime pulse value is in ms*10, so need to multiple by 100 to get to uS
|
|
readCLT(false); // Need to read coolant temp to make priming pulsewidth work correctly. The false here disables use of the filter
|
|
unsigned long primingValue = table2D_getValue(&PrimingPulseTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
|
|
if(primingValue > 0)
|
|
{
|
|
setFuelSchedule1(100, (primingValue * 100 * 5)); //to acheive long enough priming pulses, the values in tuner studio are divided by 0.5 instead of 0.1, so multiplier of 5 is required.
|
|
setFuelSchedule2(100, (primingValue * 100 * 5));
|
|
setFuelSchedule3(100, (primingValue * 100 * 5));
|
|
setFuelSchedule4(100, (primingValue * 100 * 5));
|
|
}
|
|
|
|
|
|
initialisationComplete = true;
|
|
digitalWrite(LED_BUILTIN, HIGH);
|
|
}
|
|
|
|
void setPinMapping(byte boardID)
|
|
{
|
|
switch (boardID)
|
|
{
|
|
case 0:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the v0.1 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 11; //Output pin injector 3 is on
|
|
pinInjector4 = 10; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 6; //Pin for coil 1
|
|
pinCoil2 = 7; //Pin for coil 2
|
|
pinCoil3 = 12; //Pin for coil 3
|
|
pinCoil4 = 13; //Pin for coil 4
|
|
pinCoil5 = 14; //Pin for coil 5
|
|
pinTrigger = 2; //The CAS pin
|
|
pinTrigger2 = 3; //The CAS pin
|
|
pinTPS = A0; //TPS input pin
|
|
pinMAP = A1; //MAP sensor pin
|
|
pinIAT = A2; //IAT sensor pin
|
|
pinCLT = A3; //CLS sensor pin
|
|
pinO2 = A4; //O2 Sensor pin
|
|
pinIdle1 = 46; //Single wire idle control
|
|
pinIdle2 = 47; //2 wire idle control
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinFan = 47; //Pin for the fan output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinFlex = 19; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 43; //Reset control output
|
|
#endif
|
|
break;
|
|
case 1:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the v0.2 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 28; //Pin for coil 1
|
|
pinCoil2 = 24; //Pin for coil 2
|
|
pinCoil3 = 40; //Pin for coil 3
|
|
pinCoil4 = 36; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 20; //The CAS pin
|
|
pinTrigger2 = 21; //The Cam Sensor pin
|
|
pinTPS = A2; //TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinIdle1 = 30; //Single wire idle control
|
|
pinIdle2 = 31; //2 wire idle control
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinFan = 47; //Pin for the fan output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 43; //Reset control output
|
|
break;
|
|
#endif
|
|
case 2:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the v0.3 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 28; //Pin for coil 1
|
|
pinCoil2 = 24; //Pin for coil 2
|
|
pinCoil3 = 40; //Pin for coil 3
|
|
pinCoil4 = 36; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinIdle2 = 53; //2 wire idle control
|
|
pinBoost = 7; //Boost control
|
|
pinVVT_1 = 6; //Default VVT output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 26; //Enable pin for DRV8825
|
|
pinFan = A13; //Pin for the fan output
|
|
pinLaunch = 51; //Can be overwritten below
|
|
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 50; //Reset control output
|
|
|
|
#if defined(CORE_TEENSY35)
|
|
pinTrigger = 23;
|
|
pinStepperDir = 33;
|
|
pinStepperStep = 34;
|
|
pinCoil1 = 31;
|
|
pinTachOut = 28;
|
|
pinFan = 27;
|
|
pinCoil4 = 21;
|
|
pinCoil3 = 30;
|
|
pinO2 = A22;
|
|
#endif
|
|
#endif
|
|
break;
|
|
|
|
case 3:
|
|
//Pin mappings as per the v0.4 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinInjector6 = 50; //CAUTION: Uses the same as Coil 4 below.
|
|
pinCoil1 = 40; //Pin for coil 1
|
|
pinCoil2 = 38; //Pin for coil 2
|
|
pinCoil3 = 52; //Pin for coil 3
|
|
pinCoil4 = 50; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 49; //Tacho output pin (Goes to ULN2803)
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinIdle2 = 6; //2 wire idle control
|
|
pinBoost = 7; //Boost control
|
|
pinVVT_1 = 4; //Default VVT output
|
|
pinFuelPump = 45; //Fuel pump output (Goes to ULN2803)
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 24; //Enable pin for DRV8825
|
|
pinFan = 47; //Pin for the fan output (Goes to ULN2803)
|
|
pinLaunch = 51; //Can be overwritten below
|
|
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 43; //Reset control output
|
|
|
|
#if defined(CORE_TEENSY35)
|
|
pinInjector6 = 51;
|
|
|
|
pinTrigger = 23;
|
|
pinTrigger2 = 36;
|
|
pinStepperDir = 34;
|
|
pinStepperStep = 35;
|
|
pinCoil1 = 31;
|
|
pinCoil2 = 32;
|
|
pinTachOut = 28;
|
|
pinFan = 27;
|
|
pinCoil4 = 29;
|
|
pinCoil3 = 30;
|
|
pinO2 = A22;
|
|
#elif defined(STM32F4)
|
|
//Black F407VE wiki.stm32duino.com/index.php?title=STM32F407
|
|
//PC8~PC12 SDio
|
|
//PA13~PA15 & PB4 SWD(debug) pins
|
|
//PB0 EEPROM CS pin
|
|
//PA9 & PD10 Serial1
|
|
//PD5 & PD6 Serial2
|
|
pinInjector1 = PE7; //Output pin injector 1 is on
|
|
pinInjector2 = PE8; //Output pin injector 2 is on
|
|
pinInjector3 = PE9; //Output pin injector 3 is on
|
|
pinInjector4 = PE10; //Output pin injector 4 is on
|
|
pinInjector5 = PE11; //Output pin injector 5 is on
|
|
pinInjector6 = PE12; //Output pin injector 6 is on
|
|
pinCoil1 = PD0; //Pin for coil 1
|
|
pinCoil2 = PD1; //Pin for coil 2
|
|
pinCoil3 = PD2; //Pin for coil 3
|
|
pinCoil4 = PD3; //Pin for coil 4
|
|
pinCoil5 = PD4; //Pin for coil 5
|
|
pinTPS = A0; //TPS input pin
|
|
pinMAP = A1; //MAP sensor pin
|
|
pinIAT = A2; //IAT sensor pin
|
|
pinCLT = A3; //CLT sensor pin
|
|
pinO2 = A4; //O2 Sensor pin
|
|
pinBat = A5; //Battery reference voltage pin
|
|
pinBaro = A9;
|
|
pinIdle1 = PB8; //Single wire idle control
|
|
pinIdle2 = PB9; //2 wire idle control
|
|
pinBoost = PE0; //Boost control
|
|
pinVVT_1 = PE1; //Default VVT output
|
|
pinStepperDir = PD8; //Direction pin for DRV8825 driver
|
|
pinStepperStep = PB15; //Step pin for DRV8825 driver
|
|
pinStepperEnable = PD9; //Enable pin for DRV8825
|
|
pinDisplayReset = PE1; // OLED reset pin
|
|
pinFan = PE2; //Pin for the fan output
|
|
pinFuelPump = PC0; //Fuel pump output
|
|
pinTachOut = PC1; //Tacho output pin
|
|
//external interrupt enabled pins
|
|
//external interrupts could be enalbed in any pin, except same port numbers (PA4,PE4)
|
|
pinFlex = PE2; // Flex sensor (Must be external interrupt enabled)
|
|
pinTrigger = PE3; //The CAS pin
|
|
pinTrigger2 = PE4; //The Cam Sensor pin
|
|
#elif defined(CORE_STM32)
|
|
//blue pill wiki.stm32duino.com/index.php?title=Blue_Pill
|
|
//Maple mini wiki.stm32duino.com/index.php?title=Maple_Mini
|
|
//pins PA12, PA11 are used for USB or CAN couldn't be used for GPIO
|
|
pinInjector1 = PB7; //Output pin injector 1 is on
|
|
pinInjector2 = PB6; //Output pin injector 2 is on
|
|
pinInjector3 = PB5; //Output pin injector 3 is on
|
|
pinInjector4 = PB4; //Output pin injector 4 is on
|
|
pinCoil1 = PB3; //Pin for coil 1
|
|
pinCoil2 = PA15; //Pin for coil 2
|
|
pinCoil3 = PA14; //Pin for coil 3
|
|
pinCoil4 = PA9; //Pin for coil 4
|
|
pinCoil5 = PA8; //Pin for coil 5
|
|
pinTPS = A0; //TPS input pin
|
|
pinMAP = A1; //MAP sensor pin
|
|
pinIAT = A2; //IAT sensor pin
|
|
pinCLT = A3; //CLS sensor pin
|
|
pinO2 = A4; //O2 Sensor pin
|
|
pinBat = A5; //Battery reference voltage pin
|
|
pinBaro = pinMAP;
|
|
pinIdle1 = PB2; //Single wire idle control
|
|
pinIdle2 = PA2; //2 wire idle control
|
|
pinBoost = PA1; //Boost control
|
|
pinVVT_1 = PA0; //Default VVT output
|
|
pinStepperDir = PC15; //Direction pin for DRV8825 driver
|
|
pinStepperStep = PC14; //Step pin for DRV8825 driver
|
|
pinStepperEnable = PC13; //Enable pin for DRV8825
|
|
pinDisplayReset = PB2; // OLED reset pin
|
|
pinFan = PB1; //Pin for the fan output
|
|
pinFuelPump = PB11; //Fuel pump output
|
|
pinTachOut = PB10; //Tacho output pin
|
|
//external interrupt enabled pins
|
|
pinFlex = PB8; // Flex sensor (Must be external interrupt enabled)
|
|
pinTrigger = PA10; //The CAS pin
|
|
pinTrigger2 = PA13; //The Cam Sensor pin
|
|
#endif
|
|
break;
|
|
|
|
case 6:
|
|
//Pin mappings as per the 2001-05 MX5 PNP shield
|
|
pinInjector1 = 44; //Output pin injector 1 is on
|
|
pinInjector2 = 46; //Output pin injector 2 is on
|
|
pinInjector3 = 47; //Output pin injector 3 is on
|
|
pinInjector4 = 45; //Output pin injector 4 is on
|
|
pinInjector5 = 14; //Output pin injector 5 is on
|
|
pinCoil1 = 42; //Pin for coil 1
|
|
pinCoil2 = 43; //Pin for coil 2
|
|
pinCoil3 = 32; //Pin for coil 3
|
|
pinCoil4 = 33; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A5; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A3; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 23; //Tacho output pin (Goes to ULN2803)
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinBoost = 4;
|
|
pinVVT_1 = 11; //Default VVT output
|
|
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
|
|
pinFuelPump = 40; //Fuel pump output
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 24;
|
|
pinFan = 41; //Pin for the fan output
|
|
pinLaunch = 12; //Can be overwritten below
|
|
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 39; //Reset control output
|
|
|
|
//This is NOT correct. It has not yet been tested with this board
|
|
#if defined(CORE_TEENSY35)
|
|
pinTrigger = 23;
|
|
pinTrigger2 = 36;
|
|
pinStepperDir = 34;
|
|
pinStepperStep = 35;
|
|
pinCoil1 = 33; //Done
|
|
pinCoil2 = 24; //Done
|
|
pinCoil3 = 51; //Won't work (No mapping for pin 32)
|
|
pinCoil4 = 52; //Won't work (No mapping for pin 33)
|
|
pinFuelPump = 26; //Requires PVT4 adapter or above
|
|
pinFan = 50; //Won't work (No mapping for pin 35)
|
|
pinTachOut = 28; //Done
|
|
#endif
|
|
break;
|
|
|
|
case 8:
|
|
//Pin mappings as per the 1996-97 MX5 PNP shield
|
|
pinInjector1 = 11; //Output pin injector 1 is on
|
|
pinInjector2 = 10; //Output pin injector 2 is on
|
|
pinInjector3 = 9; //Output pin injector 3 is on
|
|
pinInjector4 = 8; //Output pin injector 4 is on
|
|
pinInjector5 = 14; //Output pin injector 5 is on
|
|
pinCoil1 = 39; //Pin for coil 1
|
|
pinCoil2 = 41; //Pin for coil 2
|
|
pinCoil3 = 32; //Pin for coil 3
|
|
pinCoil4 = 33; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A5; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A3; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = A9; //Tacho output pin (Goes to ULN2803)
|
|
pinIdle1 = 2; //Single wire idle control
|
|
pinBoost = 4;
|
|
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
|
|
pinFuelPump = 49; //Fuel pump output
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 24;
|
|
pinFan = 35; //Pin for the fan output
|
|
pinLaunch = 37; //Can be overwritten below
|
|
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 44; //Reset control output
|
|
|
|
//This is NOT correct. It has not yet been tested with this board
|
|
#if defined(CORE_TEENSY35)
|
|
pinTrigger = 23;
|
|
pinTrigger2 = 36;
|
|
pinStepperDir = 34;
|
|
pinStepperStep = 35;
|
|
pinCoil1 = 33; //Done
|
|
pinCoil2 = 24; //Done
|
|
pinCoil3 = 51; //Won't work (No mapping for pin 32)
|
|
pinCoil4 = 52; //Won't work (No mapping for pin 33)
|
|
pinFuelPump = 26; //Requires PVT4 adapter or above
|
|
pinFan = 50; //Won't work (No mapping for pin 35)
|
|
pinTachOut = 28; //Done
|
|
#endif
|
|
break;
|
|
|
|
case 9:
|
|
//Pin mappings as per the 89-95 MX5 PNP shield
|
|
pinInjector1 = 11; //Output pin injector 1 is on
|
|
pinInjector2 = 10; //Output pin injector 2 is on
|
|
pinInjector3 = 9; //Output pin injector 3 is on
|
|
pinInjector4 = 8; //Output pin injector 4 is on
|
|
pinInjector5 = 14; //Output pin injector 5 is on
|
|
pinCoil1 = 39; //Pin for coil 1
|
|
pinCoil2 = 41; //Pin for coil 2
|
|
pinCoil3 = 32; //Pin for coil 3
|
|
pinCoil4 = 33; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A5; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A3; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 49; //Tacho output pin (Goes to ULN2803)
|
|
pinIdle1 = 2; //Single wire idle control
|
|
pinBoost = 4;
|
|
pinIdle2 = 4; //2 wire idle control (Note this is shared with boost!!!)
|
|
pinFuelPump = 37; //Fuel pump output
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinFan = 35; //Pin for the fan output
|
|
pinLaunch = 12; //Can be overwritten below
|
|
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 44; //Reset control output
|
|
|
|
#if defined(CORE_TEENSY35)
|
|
pinTrigger = 23;
|
|
pinTrigger2 = 36;
|
|
pinStepperDir = 34;
|
|
pinStepperStep = 35;
|
|
pinCoil1 = 33; //Done
|
|
pinCoil2 = 24; //Done
|
|
pinCoil3 = 51; //Won't work (No mapping for pin 32)
|
|
pinCoil4 = 52; //Won't work (No mapping for pin 33)
|
|
pinFuelPump = 26; //Requires PVT4 adapter or above
|
|
pinFan = 50; //Won't work (No mapping for pin 35)
|
|
pinTachOut = 28; //Done
|
|
#endif
|
|
break;
|
|
|
|
case 10:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings for user turtanas PCB
|
|
pinInjector1 = 4; //Output pin injector 1 is on
|
|
pinInjector2 = 5; //Output pin injector 2 is on
|
|
pinInjector3 = 6; //Output pin injector 3 is on
|
|
pinInjector4 = 7; //Output pin injector 4 is on
|
|
pinInjector5 = 8; //Placeholder only - NOT USED
|
|
pinInjector6 = 9; //Placeholder only - NOT USED
|
|
pinInjector7 = 10; //Placeholder only - NOT USED
|
|
pinInjector8 = 11; //Placeholder only - NOT USED
|
|
pinCoil1 = 24; //Pin for coil 1
|
|
pinCoil2 = 28; //Pin for coil 2
|
|
pinCoil3 = 36; //Pin for coil 3
|
|
pinCoil4 = 40; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 18; //The CAS pin
|
|
pinTrigger2 = 19; //The Cam Sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinMAP2 = A8; //MAP2 sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A4; //O2 Sensor pin
|
|
pinBat = A7; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinSpareTemp1 = A6;
|
|
pinSpareTemp2 = A5;
|
|
pinTachOut = 41; //Tacho output pin transistori puuttuu 2n2222 tähän ja 1k 12v
|
|
pinFuelPump = 42; //Fuel pump output 2n2222
|
|
pinFan = 47; //Pin for the fan output
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinFlex = 2; // Flex sensor (Must be external interrupt enabled)
|
|
pinResetControl = 26; //Reset control output
|
|
|
|
#endif
|
|
break;
|
|
|
|
case 20:
|
|
#if defined(CORE_AVR) && !defined(SMALL_FLASH_MODE) //No support for bluepill here anyway
|
|
//Pin mappings as per the Plazomat In/Out shields Rev 0.1
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 28; //Pin for coil 1
|
|
pinCoil2 = 24; //Pin for coil 2
|
|
pinCoil3 = 40; //Pin for coil 3
|
|
pinCoil4 = 36; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinSpareOut1 = 4; //Spare LSD Output 1(PWM)
|
|
pinSpareOut2 = 5; //Spare LSD Output 2(PWM)
|
|
pinSpareOut3 = 6; //Spare LSD Output 3(PWM)
|
|
pinSpareOut4 = 7; //Spare LSD Output 4(PWM)
|
|
pinSpareOut5 = 50; //Spare LSD Output 5(digital)
|
|
pinSpareOut6 = 52; //Spare LSD Output 6(digital)
|
|
pinTrigger = 20; //The CAS pin
|
|
pinTrigger2 = 21; //The Cam Sensor pin
|
|
pinSpareTemp2 = A15; //spare Analog input 2
|
|
pinSpareTemp1 = A14; //spare Analog input 1
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinFan = 47; //Pin for the fan output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinResetControl = 26; //Reset control output
|
|
#endif
|
|
break;
|
|
|
|
case 30:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the dazv6 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 40; //Pin for coil 1
|
|
pinCoil2 = 38; //Pin for coil 2
|
|
pinCoil3 = 50; //Pin for coil 3
|
|
pinCoil4 = 52; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTrigger3 = 17; // cam sensor 2 pin
|
|
pinTPS = A2;//TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinO2_2 = A9; //O2 sensor pin (second sensor)
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinFuelPump = 45; //Fuel pump output
|
|
pinStepperDir = 20; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 21; //Step pin for DRV8825 driver
|
|
pinSpareHOut1 = 4; // high current output spare1
|
|
pinSpareHOut2 = 6; // high current output spare2
|
|
pinBoost = 7;
|
|
pinSpareLOut1 = 43; //low current output spare1
|
|
pinSpareLOut2 = 47;
|
|
pinSpareLOut3 = 49;
|
|
pinSpareLOut4 = 51;
|
|
pinSpareLOut5 = 53;
|
|
pinFan = 47; //Pin for the fan output
|
|
#endif
|
|
break;
|
|
|
|
case 40:
|
|
//Pin mappings as per the NO2C shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 11; //Output pin injector 3 is on - NOT USED
|
|
pinInjector4 = 12; //Output pin injector 4 is on - NOT USED
|
|
pinInjector5 = 13; //Placeholder only - NOT USED
|
|
pinCoil1 = 23; //Pin for coil 1
|
|
pinCoil2 = 22; //Pin for coil 2
|
|
pinCoil3 = 2; //Pin for coil 3 - ONLY WITH DB2
|
|
pinCoil4 = 3; //Pin for coil 4 - ONLY WITH DB2
|
|
pinCoil5 = 46; //Placeholder only - NOT USED
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinTPS = A3; //TPS input pin
|
|
pinMAP = A0; //MAP sensor pin
|
|
pinIAT = A5; //IAT sensor pin
|
|
pinCLT = A4; //CLT sensor pin
|
|
pinO2 = A2; //O2 sensor pin
|
|
pinBat = A1; //Battery reference voltage pin
|
|
pinBaro = A6; //Baro sensor pin - ONLY WITH DB
|
|
pinSpareTemp1 = A7; //spare Analog input 1 - ONLY WITH DB
|
|
pinDisplayReset = 48; // OLED reset pin - NOT USED
|
|
pinTachOut = 38; //Tacho output pin
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinIdle2 = 47; //2 wire idle control - NOT USED
|
|
pinBoost = 7; //Boost control
|
|
pinVVT_1 = 6; //Default VVT output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinStepperDir = 25; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 24; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 27; //Enable pin for DRV8825 driver
|
|
pinLaunch = 10; //Can be overwritten below
|
|
pinFlex = 20; // Flex sensor (Must be external interrupt enabled) - ONLY WITH DB
|
|
pinFan = 30; //Pin for the fan output - ONLY WITH DB
|
|
pinSpareLOut1 = 32; //low current output spare1 - ONLY WITH DB
|
|
pinSpareLOut2 = 34; //low current output spare2 - ONLY WITH DB
|
|
pinSpareLOut3 = 36; //low current output spare3 - ONLY WITH DB
|
|
pinResetControl = 26; //Reset control output
|
|
break;
|
|
|
|
case 41:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the UA4C shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 7; //Output pin injector 2 is on
|
|
pinInjector3 = 6; //Output pin injector 3 is on
|
|
pinInjector4 = 5; //Output pin injector 4 is on
|
|
pinInjector5 = 45; //Output pin injector 5 is on PLACEHOLDER value for now
|
|
pinCoil1 = 35; //Pin for coil 1
|
|
pinCoil2 = 36; //Pin for coil 2
|
|
pinCoil3 = 33; //Pin for coil 3
|
|
pinCoil4 = 34; //Pin for coil 4
|
|
pinCoil5 = 44; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinFlex = 20; // Flex sensor
|
|
pinTPS = A3; //TPS input pin
|
|
pinMAP = A0; //MAP sensor pin
|
|
pinBaro = A7; //Baro sensor pin
|
|
pinIAT = A5; //IAT sensor pin
|
|
pinCLT = A4; //CLS sensor pin
|
|
pinO2 = A1; //O2 Sensor pin
|
|
pinO2_2 = A9; //O2 sensor pin (second sensor)
|
|
pinBat = A2; //Battery reference voltage pin
|
|
pinSpareTemp1 = A8; //spare Analog input 1
|
|
pinLaunch = 37; //Can be overwritten below
|
|
pinDisplayReset = 48; // OLED reset pin PLACEHOLDER value for now
|
|
pinTachOut = 22; //Tacho output pin
|
|
pinIdle1 = 9; //Single wire idle control
|
|
pinIdle2 = 10; //2 wire idle control
|
|
pinFuelPump = 23; //Fuel pump output
|
|
pinVVT_1 = 11; //Default VVT output
|
|
pinStepperDir = 32; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 31; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 30; //Enable pin for DRV8825 driver
|
|
pinBoost = 12; //Boost control
|
|
pinSpareLOut1 = 26; //low current output spare1
|
|
pinSpareLOut2 = 27; //low current output spare2
|
|
pinSpareLOut3 = 28; //low current output spare3
|
|
pinSpareLOut4 = 29; //low current output spare4
|
|
pinFan = 24; //Pin for the fan output
|
|
pinResetControl = 46; //Reset control output PLACEHOLDER value for now
|
|
#endif
|
|
break;
|
|
|
|
case 45:
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings for the DIY-EFI CORE4 Module. This is an AVR only module
|
|
#if defined(CORE_AVR)
|
|
pinInjector1 = 10; //Output pin injector 1 is on
|
|
pinInjector2 = 11; //Output pin injector 2 is on
|
|
pinInjector3 = 12; //Output pin injector 3 is on
|
|
pinInjector4 = 9; //Output pin injector 4 is on
|
|
pinCoil1 = 39; //Pin for coil 1
|
|
pinCoil2 = 29; //Pin for coil 2
|
|
pinCoil3 = 28; //Pin for coil 3
|
|
pinCoil4 = 27; //Pin for coil 4
|
|
pinCoil5 = 26; //Placeholder for coil 5
|
|
pinTrigger = 19; //The CAS pin
|
|
pinTrigger2 = 18; //The Cam Sensor pin
|
|
pinFlex = 20; // Flex sensor
|
|
pinTPS = A3; //TPS input pin
|
|
pinMAP = A2; //MAP sensor pin
|
|
pinBaro = A15; //Baro sensor pin
|
|
pinIAT = A11; //IAT sensor pin
|
|
pinCLT = A4; //CLS sensor pin
|
|
pinO2 = A12; //O2 Sensor pin
|
|
pinO2_2 = A13; //O2 sensor pin (second sensor)
|
|
pinBat = A1; //Battery reference voltage pin
|
|
pinSpareTemp1 = A14; //spare Analog input 1
|
|
pinLaunch = 24; //Can be overwritten below
|
|
pinDisplayReset = 48; // OLED reset pin PLACEHOLDER value for now
|
|
pinTachOut = 38; //Tacho output pin
|
|
pinIdle1 = 42; //Single wire idle control
|
|
pinIdle2 = 43; //2 wire idle control
|
|
pinFuelPump = 41; //Fuel pump output
|
|
pinVVT_1 = 44; //Default VVT output
|
|
pinStepperDir = 32; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 31; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 30; //Enable pin for DRV8825 driver
|
|
pinBoost = 45; //Boost control
|
|
pinSpareLOut1 = 37; //low current output spare1
|
|
pinSpareLOut2 = 36; //low current output spare2
|
|
pinSpareLOut3 = 35; //low current output spare3
|
|
pinSpareLOut4 = 34; //low current output spare4
|
|
pinSpareLOut5 = 33; //low current output spare4
|
|
pinFan = 40; //Pin for the fan output
|
|
pinResetControl = 46; //Reset control output PLACEHOLDER value for now
|
|
#endif
|
|
#endif
|
|
break;
|
|
|
|
#if defined(CORE_TEENSY35)
|
|
case 50:
|
|
//Pin mappings as per the teensy rev A shield
|
|
pinInjector1 = 2; //Output pin injector 1 is on
|
|
pinInjector2 = 10; //Output pin injector 2 is on
|
|
pinInjector3 = 6; //Output pin injector 3 is on
|
|
pinInjector4 = 9; //Output pin injector 4 is on
|
|
//Placeholder only - NOT USED:
|
|
//pinInjector5 = 13;
|
|
pinCoil1 = 29; //Pin for coil 1
|
|
pinCoil2 = 30; //Pin for coil 2
|
|
pinCoil3 = 31; //Pin for coil 3 - ONLY WITH DB2
|
|
pinCoil4 = 32; //Pin for coil 4 - ONLY WITH DB2
|
|
//Placeholder only - NOT USED:
|
|
//pinCoil5 = 46;
|
|
pinTrigger = 23; //The CAS pin
|
|
pinTrigger2 = 36; //The Cam Sensor pin
|
|
pinTPS = 16; //TPS input pin
|
|
pinMAP = 17; //MAP sensor pin
|
|
pinIAT = 14; //IAT sensor pin
|
|
pinCLT = 15; //CLT sensor pin
|
|
pinO2 = A22; //O2 sensor pin
|
|
pinO2_2 = A21; //O2 sensor pin (second sensor)
|
|
pinBat = 18; //Battery reference voltage pin
|
|
pinTachOut = 20; //Tacho output pin
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinBoost = 11; //Boost control
|
|
pinFuelPump = 38; //Fuel pump output
|
|
pinStepperDir = 34; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 35; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 33; //Enable pin for DRV8825 driver
|
|
pinLaunch = 26; //Can be overwritten below
|
|
pinFan = 37; //Pin for the fan output - ONLY WITH DB
|
|
pinSpareHOut1 = 8; // high current output spare1
|
|
pinSpareHOut2 = 7; // high current output spare2
|
|
pinSpareLOut1 = 21; //low current output spare1
|
|
break;
|
|
|
|
case 51:
|
|
//Pin mappings as per the teensy revB board shield
|
|
pinInjector1 = 2; //Output pin injector 1 is on
|
|
pinInjector2 = 10; //Output pin injector 2 is on
|
|
pinInjector3 = 6; //Output pin injector 3 is on - NOT USED
|
|
pinInjector4 = 9; //Output pin injector 4 is on - NOT USED
|
|
pinCoil1 = 29; //Pin for coil 1
|
|
pinCoil2 = 30; //Pin for coil 2
|
|
pinCoil3 = 31; //Pin for coil 3 - ONLY WITH DB2
|
|
pinCoil4 = 32; //Pin for coil 4 - ONLY WITH DB2
|
|
pinTrigger = 23; //The CAS pin
|
|
pinTrigger2 = 36; //The Cam Sensor pin
|
|
pinTPS = 16; //TPS input pin
|
|
pinMAP = 17; //MAP sensor pin
|
|
pinIAT = 14; //IAT sensor pin
|
|
pinCLT = 15; //CLT sensor pin
|
|
pinO2 = A22; //O2 sensor pin
|
|
pinO2_2 = A21; //O2 sensor pin (second sensor)
|
|
pinBat = 18; //Battery reference voltage pin
|
|
pinTachOut = 20; //Tacho output pin
|
|
pinIdle1 = 5; //Single wire idle control
|
|
pinBoost = 11; //Boost control
|
|
pinFuelPump = 38; //Fuel pump output
|
|
pinStepperDir = 34; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 35; //Step pin for DRV8825 driver
|
|
pinStepperEnable = 33; //Enable pin for DRV8825 driver
|
|
pinLaunch = 26; //Can be overwritten below
|
|
pinFan = 37; //Pin for the fan output - ONLY WITH DB
|
|
pinSpareHOut1 = 8; // high current output spare1
|
|
pinSpareHOut2 = 7; // high current output spare2
|
|
pinSpareLOut1 = 21; //low current output spare1
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
#if defined(STM32F4)
|
|
//Black F407VE wiki.stm32duino.com/index.php?title=STM32F407
|
|
//PC8~PC12 SDio
|
|
//PA13~PA15 & PB4 SWD(debug) pins
|
|
//PB0 EEPROM CS pin
|
|
//PA9 & PD10 Serial1
|
|
//PD5 & PD6 Serial2
|
|
pinInjector1 = PE7; //Output pin injector 1 is on
|
|
pinInjector2 = PE8; //Output pin injector 2 is on
|
|
pinInjector3 = PE9; //Output pin injector 3 is on
|
|
pinInjector4 = PE10; //Output pin injector 4 is on
|
|
pinInjector5 = PE11; //Output pin injector 5 is on
|
|
pinInjector6 = PE12; //Output pin injector 6 is on
|
|
pinCoil1 = PD0; //Pin for coil 1
|
|
pinCoil2 = PD1; //Pin for coil 2
|
|
pinCoil3 = PD2; //Pin for coil 3
|
|
pinCoil4 = PD3; //Pin for coil 4
|
|
pinCoil5 = PD4; //Pin for coil 5
|
|
pinTPS = A0; //TPS input pin
|
|
pinMAP = A1; //MAP sensor pin
|
|
pinIAT = A2; //IAT sensor pin
|
|
pinCLT = A3; //CLT sensor pin
|
|
pinO2 = A4; //O2 Sensor pin
|
|
pinBat = A5; //Battery reference voltage pin
|
|
pinBaro = A9;
|
|
pinIdle1 = PB8; //Single wire idle control
|
|
pinIdle2 = PB9; //2 wire idle control
|
|
pinBoost = PE0; //Boost control
|
|
pinVVT_1 = PE1; //Default VVT output
|
|
pinStepperDir = PD8; //Direction pin for DRV8825 driver
|
|
pinStepperStep = PB15; //Step pin for DRV8825 driver
|
|
pinStepperEnable = PD9; //Enable pin for DRV8825
|
|
pinDisplayReset = PE1; // OLED reset pin
|
|
pinFan = PE2; //Pin for the fan output
|
|
pinFuelPump = PC0; //Fuel pump output
|
|
pinTachOut = PC1; //Tacho output pin
|
|
//external interrupt enabled pins
|
|
//external interrupts could be enalbed in any pin, except same port numbers (PA4,PE4)
|
|
pinFlex = PE2; // Flex sensor (Must be external interrupt enabled)
|
|
pinTrigger = PE3; //The CAS pin
|
|
pinTrigger2 = PE4; //The Cam Sensor pin
|
|
#else
|
|
#ifndef SMALL_FLASH_MODE //No support for bluepill here anyway
|
|
//Pin mappings as per the v0.2 shield
|
|
pinInjector1 = 8; //Output pin injector 1 is on
|
|
pinInjector2 = 9; //Output pin injector 2 is on
|
|
pinInjector3 = 10; //Output pin injector 3 is on
|
|
pinInjector4 = 11; //Output pin injector 4 is on
|
|
pinInjector5 = 12; //Output pin injector 5 is on
|
|
pinCoil1 = 28; //Pin for coil 1
|
|
pinCoil2 = 24; //Pin for coil 2
|
|
pinCoil3 = 40; //Pin for coil 3
|
|
pinCoil4 = 36; //Pin for coil 4
|
|
pinCoil5 = 34; //Pin for coil 5 PLACEHOLDER value for now
|
|
pinTrigger = 20; //The CAS pin
|
|
pinTrigger2 = 21; //The Cam Sensor pin
|
|
pinTPS = A2; //TPS input pin
|
|
pinMAP = A3; //MAP sensor pin
|
|
pinIAT = A0; //IAT sensor pin
|
|
pinCLT = A1; //CLS sensor pin
|
|
pinO2 = A8; //O2 Sensor pin
|
|
pinBat = A4; //Battery reference voltage pin
|
|
pinStepperDir = 16; //Direction pin for DRV8825 driver
|
|
pinStepperStep = 17; //Step pin for DRV8825 driver
|
|
pinDisplayReset = 48; // OLED reset pin
|
|
pinFan = 47; //Pin for the fan output
|
|
pinFuelPump = 4; //Fuel pump output
|
|
pinTachOut = 49; //Tacho output pin
|
|
pinFlex = 3; // Flex sensor (Must be external interrupt enabled)
|
|
pinBoost = 5;
|
|
pinIdle1 = 6;
|
|
pinResetControl = 43; //Reset control output
|
|
#endif
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
//Setup any devices that are using selectable pins
|
|
|
|
if ( (configPage6.launchPin != 0) && (configPage6.launchPin < BOARD_NR_GPIO_PINS) ) { pinLaunch = pinTranslate(configPage6.launchPin); }
|
|
if ( (configPage4.ignBypassPin != 0) && (configPage4.ignBypassPin < BOARD_NR_GPIO_PINS) ) { pinIgnBypass = pinTranslate(configPage4.ignBypassPin); }
|
|
if ( (configPage2.tachoPin != 0) && (configPage2.tachoPin < BOARD_NR_GPIO_PINS) ) { pinTachOut = pinTranslate(configPage2.tachoPin); }
|
|
if ( (configPage4.fuelPumpPin != 0) && (configPage4.fuelPumpPin < BOARD_NR_GPIO_PINS) ) { pinFuelPump = pinTranslate(configPage4.fuelPumpPin); }
|
|
if ( (configPage6.fanPin != 0) && (configPage6.fanPin < BOARD_NR_GPIO_PINS) ) { pinFan = pinTranslate(configPage6.fanPin); }
|
|
if ( (configPage6.boostPin != 0) && (configPage6.boostPin < BOARD_NR_GPIO_PINS) ) { pinBoost = pinTranslate(configPage6.boostPin); }
|
|
if ( (configPage6.vvtPin != 0) && (configPage6.vvtPin < BOARD_NR_GPIO_PINS) ) { pinVVT_1 = pinTranslate(configPage6.vvtPin); }
|
|
if ( (configPage6.useExtBaro != 0) && (configPage6.baroPin < BOARD_NR_GPIO_PINS) ) { pinBaro = configPage6.baroPin + A0; }
|
|
if ( (configPage6.useEMAP != 0) && (configPage10.EMAPPin < BOARD_NR_GPIO_PINS) ) { pinEMAP = configPage10.EMAPPin + A0; }
|
|
if ( (configPage10.fuel2InputPin != 0) && (configPage10.fuel2InputPin < BOARD_NR_GPIO_PINS) ) { pinFuel2Input = pinTranslate(configPage10.fuel2InputPin); }
|
|
|
|
//Currently there's no default pin for Idle Up
|
|
pinIdleUp = pinTranslate(configPage2.idleUpPin);
|
|
|
|
/* Reset control is a special case. If reset control is enabled, it needs its initial state set BEFORE its pinMode.
|
|
If that doesn't happen and reset control is in "Serial Command" mode, the Arduino will end up in a reset loop
|
|
because the control pin will go low as soon as the pinMode is set to OUTPUT. */
|
|
if ( (configPage4.resetControl != 0) && (configPage4.resetControlPin < BOARD_NR_GPIO_PINS) )
|
|
{
|
|
resetControl = configPage4.resetControl;
|
|
pinResetControl = pinTranslate(configPage4.resetControlPin);
|
|
setResetControlPinState();
|
|
pinMode(pinResetControl, OUTPUT);
|
|
}
|
|
|
|
//Finally, set the relevant pin modes for outputs
|
|
pinMode(pinCoil1, OUTPUT);
|
|
pinMode(pinCoil2, OUTPUT);
|
|
pinMode(pinCoil3, OUTPUT);
|
|
pinMode(pinCoil4, OUTPUT);
|
|
pinMode(pinCoil5, OUTPUT);
|
|
pinMode(pinInjector1, OUTPUT);
|
|
pinMode(pinInjector2, OUTPUT);
|
|
pinMode(pinInjector3, OUTPUT);
|
|
pinMode(pinInjector4, OUTPUT);
|
|
pinMode(pinInjector5, OUTPUT);
|
|
pinMode(pinTachOut, OUTPUT);
|
|
pinMode(pinIdle1, OUTPUT);
|
|
pinMode(pinIdle2, OUTPUT);
|
|
pinMode(pinFuelPump, OUTPUT);
|
|
pinMode(pinIgnBypass, OUTPUT);
|
|
pinMode(pinFan, OUTPUT);
|
|
pinMode(pinStepperDir, OUTPUT);
|
|
pinMode(pinStepperStep, OUTPUT);
|
|
pinMode(pinStepperEnable, OUTPUT);
|
|
pinMode(pinBoost, OUTPUT);
|
|
pinMode(pinVVT_1, OUTPUT);
|
|
|
|
//This is a legacy mode option to revert the MAP reading behaviour to match what was in place prior to the 201905 firmware
|
|
if(configPage2.legacyMAP > 0) { digitalWrite(pinMAP, HIGH); }
|
|
|
|
inj1_pin_port = portOutputRegister(digitalPinToPort(pinInjector1));
|
|
inj1_pin_mask = digitalPinToBitMask(pinInjector1);
|
|
inj2_pin_port = portOutputRegister(digitalPinToPort(pinInjector2));
|
|
inj2_pin_mask = digitalPinToBitMask(pinInjector2);
|
|
inj3_pin_port = portOutputRegister(digitalPinToPort(pinInjector3));
|
|
inj3_pin_mask = digitalPinToBitMask(pinInjector3);
|
|
inj4_pin_port = portOutputRegister(digitalPinToPort(pinInjector4));
|
|
inj4_pin_mask = digitalPinToBitMask(pinInjector4);
|
|
inj5_pin_port = portOutputRegister(digitalPinToPort(pinInjector5));
|
|
inj5_pin_mask = digitalPinToBitMask(pinInjector5);
|
|
inj6_pin_port = portOutputRegister(digitalPinToPort(pinInjector6));
|
|
inj6_pin_mask = digitalPinToBitMask(pinInjector6);
|
|
inj7_pin_port = portOutputRegister(digitalPinToPort(pinInjector7));
|
|
inj7_pin_mask = digitalPinToBitMask(pinInjector7);
|
|
inj8_pin_port = portOutputRegister(digitalPinToPort(pinInjector8));
|
|
inj8_pin_mask = digitalPinToBitMask(pinInjector8);
|
|
|
|
ign1_pin_port = portOutputRegister(digitalPinToPort(pinCoil1));
|
|
ign1_pin_mask = digitalPinToBitMask(pinCoil1);
|
|
ign2_pin_port = portOutputRegister(digitalPinToPort(pinCoil2));
|
|
ign2_pin_mask = digitalPinToBitMask(pinCoil2);
|
|
ign3_pin_port = portOutputRegister(digitalPinToPort(pinCoil3));
|
|
ign3_pin_mask = digitalPinToBitMask(pinCoil3);
|
|
ign4_pin_port = portOutputRegister(digitalPinToPort(pinCoil4));
|
|
ign4_pin_mask = digitalPinToBitMask(pinCoil4);
|
|
ign5_pin_port = portOutputRegister(digitalPinToPort(pinCoil5));
|
|
ign5_pin_mask = digitalPinToBitMask(pinCoil5);
|
|
ign6_pin_port = portOutputRegister(digitalPinToPort(pinCoil6));
|
|
ign6_pin_mask = digitalPinToBitMask(pinCoil6);
|
|
ign7_pin_port = portOutputRegister(digitalPinToPort(pinCoil7));
|
|
ign7_pin_mask = digitalPinToBitMask(pinCoil7);
|
|
ign8_pin_port = portOutputRegister(digitalPinToPort(pinCoil8));
|
|
ign8_pin_mask = digitalPinToBitMask(pinCoil8);
|
|
|
|
tach_pin_port = portOutputRegister(digitalPinToPort(pinTachOut));
|
|
tach_pin_mask = digitalPinToBitMask(pinTachOut);
|
|
pump_pin_port = portOutputRegister(digitalPinToPort(pinFuelPump));
|
|
pump_pin_mask = digitalPinToBitMask(pinFuelPump);
|
|
|
|
//And for inputs
|
|
#if defined(CORE_STM32)
|
|
#ifndef ARDUINO_ARCH_STM32 //libmaple core aka STM32DUINO
|
|
pinMode(pinMAP, INPUT_ANALOG);
|
|
pinMode(pinO2, INPUT_ANALOG);
|
|
pinMode(pinO2_2, INPUT_ANALOG);
|
|
pinMode(pinTPS, INPUT_ANALOG);
|
|
pinMode(pinIAT, INPUT_ANALOG);
|
|
pinMode(pinCLT, INPUT_ANALOG);
|
|
pinMode(pinBat, INPUT_ANALOG);
|
|
pinMode(pinBaro, INPUT_ANALOG);
|
|
#else
|
|
pinMode(pinMAP, INPUT);
|
|
pinMode(pinO2, INPUT);
|
|
pinMode(pinO2_2, INPUT);
|
|
pinMode(pinTPS, INPUT);
|
|
pinMode(pinIAT, INPUT);
|
|
pinMode(pinCLT, INPUT);
|
|
pinMode(pinBat, INPUT);
|
|
pinMode(pinBaro, INPUT);
|
|
#endif
|
|
#endif
|
|
pinMode(pinTrigger, INPUT);
|
|
pinMode(pinTrigger2, INPUT);
|
|
pinMode(pinTrigger3, INPUT);
|
|
|
|
//Each of the below are only set when their relevant function is enabled. This can help prevent pin conflicts that users aren't aware of with unused functions
|
|
if(configPage2.flexEnabled > 0)
|
|
{
|
|
pinMode(pinFlex, INPUT); //Standard GM / Continental flex sensor requires pullup, but this should be onboard. The internal pullup will not work (Requires ~3.3k)!
|
|
}
|
|
if(configPage6.launchEnabled > 0)
|
|
{
|
|
if (configPage6.lnchPullRes == true) { pinMode(pinLaunch, INPUT_PULLUP); }
|
|
else { pinMode(pinLaunch, INPUT); } //If Launch Pull Resistor is not set make input float.
|
|
}
|
|
if(configPage2.idleUpEnabled > 0)
|
|
{
|
|
if (configPage2.idleUpPolarity == 0) { pinMode(pinIdleUp, INPUT_PULLUP); } //Normal setting
|
|
else { pinMode(pinIdleUp, INPUT); } //inverted setting
|
|
}
|
|
if(configPage10.fuel2Mode == FUEL2_MODE_INPUT_SWITCH)
|
|
{
|
|
if (configPage10.fuel2InputPullup == true) { pinMode(pinFuel2Input, INPUT_PULLUP); } //With pullup
|
|
else { pinMode(pinFuel2Input, INPUT); } //Normal input
|
|
}
|
|
|
|
|
|
//These must come after the above pinMode statements
|
|
triggerPri_pin_port = portInputRegister(digitalPinToPort(pinTrigger));
|
|
triggerPri_pin_mask = digitalPinToBitMask(pinTrigger);
|
|
triggerSec_pin_port = portInputRegister(digitalPinToPort(pinTrigger2));
|
|
triggerSec_pin_mask = digitalPinToBitMask(pinTrigger2);
|
|
|
|
}
|
|
|
|
void initialiseTriggers()
|
|
{
|
|
byte triggerInterrupt = 0; // By default, use the first interrupt
|
|
byte triggerInterrupt2 = 1;
|
|
|
|
#if defined(CORE_AVR)
|
|
switch (pinTrigger) {
|
|
//Arduino Mega 2560 mapping
|
|
case 2:
|
|
triggerInterrupt = 0; break;
|
|
case 3:
|
|
triggerInterrupt = 1; break;
|
|
case 18:
|
|
triggerInterrupt = 5; break;
|
|
case 19:
|
|
triggerInterrupt = 4; break;
|
|
case 20:
|
|
triggerInterrupt = 3; break;
|
|
case 21:
|
|
triggerInterrupt = 2; break;
|
|
default:
|
|
triggerInterrupt = 0; break; //This should NEVER happen
|
|
}
|
|
#else
|
|
triggerInterrupt = pinTrigger;
|
|
#endif
|
|
|
|
#if defined(CORE_AVR)
|
|
switch (pinTrigger2) {
|
|
//Arduino Mega 2560 mapping
|
|
case 2:
|
|
triggerInterrupt2 = 0; break;
|
|
case 3:
|
|
triggerInterrupt2 = 1; break;
|
|
case 18:
|
|
triggerInterrupt2 = 5; break;
|
|
case 19:
|
|
triggerInterrupt2 = 4; break;
|
|
case 20:
|
|
triggerInterrupt2 = 3; break;
|
|
case 21:
|
|
triggerInterrupt2 = 2; break;
|
|
default:
|
|
triggerInterrupt2 = 0; break; //This should NEVER happen
|
|
}
|
|
#else
|
|
triggerInterrupt2 = pinTrigger2;
|
|
#endif
|
|
|
|
pinMode(pinTrigger, INPUT);
|
|
pinMode(pinTrigger2, INPUT);
|
|
pinMode(pinTrigger3, INPUT);
|
|
//digitalWrite(pinTrigger, HIGH);
|
|
detachInterrupt(triggerInterrupt);
|
|
detachInterrupt(triggerInterrupt2);
|
|
//The default values for edges
|
|
primaryTriggerEdge = 0; //This should ALWAYS be changed below
|
|
secondaryTriggerEdge = 0; //This is optional and may not be changed below, depending on the decoder in use
|
|
|
|
//Set the trigger function based on the decoder in the config
|
|
switch (configPage4.TrigPattern)
|
|
{
|
|
case 0:
|
|
//Missing tooth decoder
|
|
triggerSetup_missingTooth();
|
|
triggerHandler = triggerPri_missingTooth;
|
|
triggerSecondaryHandler = triggerSec_missingTooth;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_missingTooth;
|
|
getCrankAngle = getCrankAngle_missingTooth;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_missingTooth;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; }
|
|
else { secondaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
|
|
/*
|
|
if(configPage4.TrigEdge == 0) { attachInterrupt(triggerInterrupt, triggerHandler, RISING); }
|
|
else { attachInterrupt(triggerInterrupt, triggerHandler, FALLING); }
|
|
if(configPage4.TrigEdgeSec == 0) { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, RISING); }
|
|
else { attachInterrupt(triggerInterrupt2, triggerSec_missingTooth, FALLING); }
|
|
*/
|
|
break;
|
|
|
|
case 1:
|
|
// Basic distributor
|
|
triggerSetup_BasicDistributor();
|
|
triggerHandler = triggerPri_BasicDistributor;
|
|
getRPM = getRPM_BasicDistributor;
|
|
getCrankAngle = getCrankAngle_BasicDistributor;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_BasicDistributor;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
break;
|
|
|
|
case 2:
|
|
triggerSetup_DualWheel();
|
|
triggerHandler = triggerPri_DualWheel;
|
|
triggerSecondaryHandler = triggerSec_DualWheel;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_DualWheel;
|
|
getCrankAngle = getCrankAngle_DualWheel;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_DualWheel;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; }
|
|
else { secondaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 3:
|
|
triggerSetup_GM7X();
|
|
triggerHandler = triggerPri_GM7X;
|
|
getRPM = getRPM_GM7X;
|
|
getCrankAngle = getCrankAngle_GM7X;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_GM7X;
|
|
|
|
if(configPage4.TrigEdge == 0) { attachInterrupt(triggerInterrupt, triggerHandler, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { attachInterrupt(triggerInterrupt, triggerHandler, FALLING); }
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
break;
|
|
|
|
case 4:
|
|
triggerSetup_4G63();
|
|
triggerHandler = triggerPri_4G63;
|
|
triggerSecondaryHandler = triggerSec_4G63;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_4G63;
|
|
getCrankAngle = getCrankAngle_4G63;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_4G63;
|
|
|
|
primaryTriggerEdge = CHANGE;
|
|
secondaryTriggerEdge = FALLING;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 5:
|
|
triggerSetup_24X();
|
|
triggerHandler = triggerPri_24X;
|
|
triggerSecondaryHandler = triggerSec_24X;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_24X;
|
|
getCrankAngle = getCrankAngle_24X;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_24X;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = CHANGE; //Secondary is always on every change
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 6:
|
|
triggerSetup_Jeep2000();
|
|
triggerHandler = triggerPri_Jeep2000;
|
|
triggerSecondaryHandler = triggerSec_Jeep2000;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_Jeep2000;
|
|
getCrankAngle = getCrankAngle_Jeep2000;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Jeep2000;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = CHANGE;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 7:
|
|
triggerSetup_Audi135();
|
|
triggerHandler = triggerPri_Audi135;
|
|
triggerSecondaryHandler = triggerSec_Audi135;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_Audi135;
|
|
getCrankAngle = getCrankAngle_Audi135;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Audi135;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = RISING; //always rising for this trigger
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 8:
|
|
triggerSetup_HondaD17();
|
|
triggerHandler = triggerPri_HondaD17;
|
|
triggerSecondaryHandler = triggerSec_HondaD17;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_HondaD17;
|
|
getCrankAngle = getCrankAngle_HondaD17;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_HondaD17;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = CHANGE;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 9:
|
|
triggerSetup_Miata9905();
|
|
triggerHandler = triggerPri_Miata9905;
|
|
triggerSecondaryHandler = triggerSec_Miata9905;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_Miata9905;
|
|
getCrankAngle = getCrankAngle_Miata9905;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Miata9905;
|
|
|
|
//These may both need to change, not sure
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; }
|
|
else { secondaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 10:
|
|
triggerSetup_MazdaAU();
|
|
triggerHandler = triggerPri_MazdaAU;
|
|
triggerSecondaryHandler = triggerSec_MazdaAU;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_MazdaAU;
|
|
getCrankAngle = getCrankAngle_MazdaAU;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_MazdaAU;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = FALLING;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 11:
|
|
triggerSetup_non360();
|
|
triggerHandler = triggerPri_DualWheel; //Is identical to the dual wheel decoder, so that is used. Same goes for the secondary below
|
|
triggerSecondaryHandler = triggerSec_DualWheel; //Note the use of the Dual Wheel trigger function here. No point in having the same code in twice.
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_non360;
|
|
getCrankAngle = getCrankAngle_non360;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_non360;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = FALLING;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 12:
|
|
triggerSetup_Nissan360();
|
|
triggerHandler = triggerPri_Nissan360;
|
|
triggerSecondaryHandler = triggerSec_Nissan360;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_Nissan360;
|
|
getCrankAngle = getCrankAngle_Nissan360;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Nissan360;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = CHANGE;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 13:
|
|
triggerSetup_Subaru67();
|
|
triggerHandler = triggerPri_Subaru67;
|
|
triggerSecondaryHandler = triggerSec_Subaru67;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_Subaru67;
|
|
getCrankAngle = getCrankAngle_Subaru67;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Subaru67;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
secondaryTriggerEdge = FALLING;
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
case 14:
|
|
triggerSetup_Daihatsu();
|
|
triggerHandler = triggerPri_Daihatsu;
|
|
getRPM = getRPM_Daihatsu;
|
|
getCrankAngle = getCrankAngle_Daihatsu;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Daihatsu;
|
|
|
|
//No secondary input required for this pattern
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
break;
|
|
|
|
case 15:
|
|
triggerSetup_Harley();
|
|
triggerHandler = triggerPri_Harley;
|
|
//triggerSecondaryHandler = triggerSec_Harley;
|
|
getRPM = getRPM_Harley;
|
|
getCrankAngle = getCrankAngle_Harley;
|
|
triggerSetEndTeeth = triggerSetEndTeeth_Harley;
|
|
|
|
primaryTriggerEdge = RISING; //Always rising
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
break;
|
|
|
|
case 16:
|
|
//36-2-2-2
|
|
triggerSetup_ThirtySixMinus222();
|
|
triggerHandler = triggerPri_ThirtySixMinus222;
|
|
triggerSecondaryHandler = triggerSec_ThirtySixMinus222;
|
|
decoderHasSecondary = true;
|
|
getRPM = getRPM_missingTooth; //This uses the same function as the missing tooth decoder, so no need to duplicate code
|
|
getCrankAngle = getCrankAngle_missingTooth; //This uses the same function as the missing tooth decoder, so no need to duplicate code
|
|
triggerSetEndTeeth = triggerSetEndTeeth_ThirtySixMinus222;
|
|
|
|
if(configPage4.TrigEdge == 0) { primaryTriggerEdge = RISING; } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { primaryTriggerEdge = FALLING; }
|
|
if(configPage4.TrigEdgeSec == 0) { secondaryTriggerEdge = RISING; }
|
|
else { secondaryTriggerEdge = FALLING; }
|
|
|
|
attachInterrupt(triggerInterrupt, triggerHandler, primaryTriggerEdge);
|
|
attachInterrupt(triggerInterrupt2, triggerSecondaryHandler, secondaryTriggerEdge);
|
|
break;
|
|
|
|
default:
|
|
triggerHandler = triggerPri_missingTooth;
|
|
getRPM = getRPM_missingTooth;
|
|
getCrankAngle = getCrankAngle_missingTooth;
|
|
|
|
if(configPage4.TrigEdge == 0) { attachInterrupt(triggerInterrupt, triggerHandler, RISING); } // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
|
|
else { attachInterrupt(triggerInterrupt, triggerHandler, FALLING); }
|
|
break;
|
|
}
|
|
}
|