From 7db11014292278ce5d03f5b3724d520dbc25fbed Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Wed, 23 Aug 2017 17:18:59 +1000 Subject: [PATCH] Completely untested trailing spark for FC rotary ignitions May God have mercy on us all --- reference/speeduino.ini | 1 + speeduino/corrections.ino | 4 +-- speeduino/globals.h | 32 +++++++++++------------- speeduino/scheduledIO.h | 4 +++ speeduino/scheduledIO.ino | 3 ++- speeduino/speeduino.ino | 52 +++++++++++++++++++++++++++++++++++---- 6 files changed, 71 insertions(+), 25 deletions(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 785b24c1..275678ab 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -747,6 +747,7 @@ page = 11 requiresPowerCycle = boostMaxDuty requiresPowerCycle = useExtBaro requiresPowerCycle = baroPin + requiresPowerCycle = rotaryType defaultValue = pinLayout, 1 defaultValue = TrigPattern, 0 diff --git a/speeduino/corrections.ino b/speeduino/corrections.ino index e9bcf88c..2475c5c7 100644 --- a/speeduino/corrections.ino +++ b/speeduino/corrections.ino @@ -114,7 +114,7 @@ static inline byte correctionCranking() byte crankingValue = 100; //if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { crankingValue = 100 + configPage1.crankingPct; } if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) - { + { crankingValue = table2D_getValue(&crankingEnrichTable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); } return crankingValue; @@ -262,7 +262,7 @@ static inline byte correctionLaunch() static inline bool correctionDFCO() { bool DFCOValue = false; - if ( configPage2.dfcoEnabled == 1 ) + if ( configPage1.dfcoEnabled == 1 ) { if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) == 1 ) { DFCOValue = ( currentStatus.RPM > ( configPage2.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); } else { DFCOValue = ( currentStatus.RPM > (unsigned int)( (configPage2.dfcoRPM * 10) + configPage2.dfcoHyster) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); } diff --git a/speeduino/globals.h b/speeduino/globals.h index 7f66dea5..f268d577 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -29,6 +29,10 @@ #define MS_IN_MINUTE 60000 #define US_IN_MINUTE 60000000 +//Define the load algorithm +#define LOAD_SOURCE_MAP 0 +#define LOAD_SOURCE_TPS 1 + //Define bit positions within engine virable #define BIT_ENGINE_RUN 0 // Engine running #define BIT_ENGINE_CRANK 1 // Engine cranking @@ -85,6 +89,10 @@ #define IGN_MODE_SEQUENTIAL 3 #define IGN_MODE_ROTARY 4 +#define ROTARY_IGN_FC 0 +#define ROTARY_IGN_FD 1 +#define ROTARY_IGN_RX8 2 + #define SIZE_BYTE 8 #define SIZE_INT 16 @@ -132,6 +140,7 @@ struct table2D dwellVCorrectionTable; //6 bin dwell voltage correction (2D) struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D) struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D) struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature (2D) +struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing (2D) //These are for the direct port manipulation of the injectors and coils volatile byte *inj1_pin_port; @@ -579,23 +588,12 @@ See ini file for further info (Config Page 11 in the ini) struct config11 { byte crankingEnrichBins[4]; byte crankingEnrichValues[4]; - byte unused11_8; - byte unused11_9; - byte unused11_10; - byte unused11_11; - byte unused11_12; - byte unused11_13; - byte unused11_14; - byte unused11_15; - byte unused11_16; - byte unused11_17; - byte unused11_18; - byte unused11_19; - byte unused11_20; - byte unused10_21; - byte unused11_22; - byte unused11_23; - byte unused11_24; + + byte rotaryType : 2; + byte unused11_8c : 6; + + byte rotarySplitValues[8]; + byte rotarySplitBins[8]; byte unused11_25; byte unused11_26; byte unused11_27; diff --git a/speeduino/scheduledIO.h b/speeduino/scheduledIO.h index a6ba3049..90e75568 100644 --- a/speeduino/scheduledIO.h +++ b/speeduino/scheduledIO.h @@ -16,6 +16,10 @@ inline void endCoil4Charge(); inline void beginCoil5Charge(); inline void endCoil5Charge(); +//The following functions are used specifically for the trailing coil on rotary engines. They are separate as they also control the switching of the trailing select pin +inline void beginTrailingCoilCharge(); +inline void endTrailingCoilCharge(); + #define openInjector1() *inj1_pin_port |= (inj1_pin_mask); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ1) #define closeInjector1() *inj1_pin_port &= ~(inj1_pin_mask); BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_INJ1) #define openInjector2() *inj2_pin_port |= (inj2_pin_mask); BIT_SET(currentStatus.squirt, BIT_SQUIRT_INJ2) diff --git a/speeduino/scheduledIO.ino b/speeduino/scheduledIO.ino index 1539a7f4..b514d691 100644 --- a/speeduino/scheduledIO.ino +++ b/speeduino/scheduledIO.ino @@ -18,7 +18,8 @@ volatile bool tachoAlt = true; inline void beginCoil5Charge() { digitalWrite(pinCoil5, coilHIGH); TACH_PULSE_LOW(); } inline void endCoil5Charge() { digitalWrite(pinCoil5, coilLOW); TACH_PULSE_HIGH(); } - + inline void beginTrailingCoilCharge() { digitalWrite(pinCoil2, coilHIGH); } + inline void endTrailingCoilCharge() { digitalWrite(pinCoil2, coilLOW); *ign3_pin_port ^= (1 << ign3_pin_mask); } //Flip the select pin //As above but for ignition (Wasted COP mode) void beginCoil1and3Charge() { digitalWrite(pinCoil1, coilHIGH); digitalWrite(pinCoil3, coilHIGH); TACH_PULSE_LOW(); } diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index 188849cd..cc0ff652 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -199,6 +199,10 @@ void setup() IATRetardTable.xSize = 6; IATRetardTable.values = configPage2.iatRetValues; IATRetardTable.axisX = configPage2.iatRetBins; + rotarySplitTable.valueSize = SIZE_BYTE; + rotarySplitTable.xSize = 8; + rotarySplitTable.values = configPage11.rotarySplitValues; + rotarySplitTable.axisX = configPage11.rotarySplitBins; //Setup the calibration tables loadCalibration(); @@ -584,10 +588,20 @@ void setup() break; case IGN_MODE_ROTARY: - ign1StartFunction = beginCoil1Charge; - ign1EndFunction = endCoil1Charge; - ign2StartFunction = beginCoil1Charge; - ign2EndFunction = endCoil1Charge; + if(configPage11.rotaryType == ROTARY_IGN_FC) + { + ign1StartFunction = beginCoil1Charge; + ign1EndFunction = endCoil1Charge; + ign2StartFunction = beginCoil1Charge; + ign2EndFunction = endCoil1Charge; + + ign3StartFunction = beginTrailingCoilCharge; + ign3EndFunction = endTrailingCoilCharge; + ign4StartFunction = beginTrailingCoilCharge; + ign4EndFunction = endTrailingCoilCharge; + } + break; + default: @@ -892,7 +906,7 @@ void loop() //Calculate an injector pulsewidth from the VE currentStatus.corrections = correctionsFuel(); lastAdvance = currentStatus.advance; //Store the previous advance value - if (configPage1.algorithm == 0) //Check which fuelling algorithm is being used + if (configPage1.algorithm == LOAD_SOURCE_MAP) //Check which fuelling algorithm is being used { //Speed Density currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value @@ -1116,6 +1130,34 @@ void loop() ignition4StartAngle = ignition4EndAngle - dwellAngle; if(ignition4StartAngle > CRANK_ANGLE_MAX_IGN) {ignition4StartAngle -= CRANK_ANGLE_MAX_IGN;} } + else if(configPage2.sparkMode == IGN_MODE_ROTARY) + { + if(configPage11.rotaryType == ROTARY_IGN_FC) + { + byte splitDegrees = 0; + if (configPage1.algorithm == LOAD_SOURCE_MAP) { splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.MAP/2); } + else { splitDegrees = table2D_getValue(&rotarySplitTable, currentStatus.TPS/2); } + + //The trailing angles are set relative to the leading ones + ignition3EndAngle = ignition1EndAngle + splitDegrees; + ignition3StartAngle = ignition1EndAngle - dwellAngle; + ignition4EndAngle = ignition2EndAngle + splitDegrees; + ignition4StartAngle = ignition2EndAngle - dwellAngle; + + //This is a mess. Basically we need to figure out which one is going to fire next and set the select pin appropiately + int crankAngle = getCrankAngle(timePerDegree); + if(ignition3EndAngle < ignition4EndAngle) + { + if(ignition3EndAngle > crankAngle) { digitalWrite(pinCoil3, coilLOW); } + else { digitalWrite(pinCoil3, coilHIGH); } + } + else + { + if(ignition4EndAngle > crankAngle) { digitalWrite(pinCoil3, coilHIGH); } + else { digitalWrite(pinCoil3, coilLOW); } + } + } + } break; //5 cylinders case 5: