From 311cae3fac636dcb1f69e0f4bdaaca9b9b699e26 Mon Sep 17 00:00:00 2001 From: Josh Stewart Date: Mon, 6 Mar 2023 16:49:30 +1100 Subject: [PATCH] Allow fuel staging up to 8 total fuel channels (All reasonable combinations) --- reference/speeduino.ini | 3 +- speeduino/globals.h | 2 +- speeduino/init.ino | 81 +++++++++++++- speeduino/speeduino.ino | 236 +++++++++++++++++++++++++++++++++++----- 4 files changed, 288 insertions(+), 34 deletions(-) diff --git a/reference/speeduino.ini b/reference/speeduino.ini index 2d2734c8..53a1051e 100644 --- a/reference/speeduino.ini +++ b/reference/speeduino.ini @@ -5273,7 +5273,8 @@ cmdVSSratio6 = "E\x99\x06" vvt2Error = bits, U08, 110, [2:2] fanStatus = bits, U08, 110, [3:3] burnPending = bits, U08, 110, [4:4] - UnusedBits4 = bits, U08, 110, [5:7] + stagingActive = bits, U08, 110, [5:5] + UnusedBits4 = bits, U08, 110, [6:7] vvt2Angle = scalar, S16, 111, "deg", 0.50, 0.000 vvt2Target = scalar, U08, 113, "deg", 0.50, 0.000 vvt2Duty = scalar, U08, 114, "%", 0.50, 0.000 diff --git a/speeduino/globals.h b/speeduino/globals.h index 3edf726c..424066c0 100644 --- a/speeduino/globals.h +++ b/speeduino/globals.h @@ -226,7 +226,7 @@ #define BIT_STATUS4_VVT2_ERROR 2 //VVT2 cam angle within limits or not #define BIT_STATUS4_FAN 3 //Fan Status #define BIT_STATUS4_BURNPENDING 4 -#define BIT_STATUS4_UNUSED6 5 +#define BIT_STATUS4_STAGING_ACTIVE 5 #define BIT_STATUS4_UNUSED7 6 #define BIT_STATUS4_UNUSED8 7 diff --git a/speeduino/init.ino b/speeduino/init.ino index 6770ed86..edc3bb09 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -478,7 +478,7 @@ void initialiseAll(void) //Check if injector staging is enabled if(configPage10.stagingEnabled == true) { - BIT_SET(channelInjEnabled, INJ3_CMD_BIT); + BIT_SET(channelInjEnabled, INJ2_CMD_BIT); channel3InjDegrees = channel1InjDegrees; } break; @@ -591,6 +591,24 @@ void initialiseAll(void) BIT_SET(channelInjEnabled, INJ1_CMD_BIT); BIT_SET(channelInjEnabled, INJ2_CMD_BIT); BIT_SET(channelInjEnabled, INJ3_CMD_BIT); + + //Check if injector staging is enabled + if(configPage10.stagingEnabled == true) + { + #if INJ_CHANNELS >= 6 + BIT_SET(channelInjEnabled, INJ4_CMD_BIT); + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + BIT_SET(channelInjEnabled, INJ6_CMD_BIT); + + channel4InjDegrees = channel1InjDegrees; + channel5InjDegrees = channel2InjDegrees; + channel6InjDegrees = channel3InjDegrees; + #else + //Staged output is on channel 4 + BIT_SET(channelInjEnabled, INJ4_CMD_BIT); + channel4InjDegrees = channel1InjDegrees; + #endif + } break; case 4: channel1IgnDegrees = 0; @@ -674,8 +692,31 @@ void initialiseAll(void) BIT_SET(channelInjEnabled, INJ3_CMD_BIT); BIT_SET(channelInjEnabled, INJ4_CMD_BIT); - channel3InjDegrees = channel1InjDegrees; - channel4InjDegrees = channel2InjDegrees; + if( (configPage2.injLayout == INJ_SEQUENTIAL) || (configPage2.injLayout == INJ_SEMISEQUENTIAL) ) + { + //Staging with 4 cylinders semi/sequential requires 8 total channels + #if INJ_CHANNELS >= 8 + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + BIT_SET(channelInjEnabled, INJ6_CMD_BIT); + BIT_SET(channelInjEnabled, INJ7_CMD_BIT); + BIT_SET(channelInjEnabled, INJ8_CMD_BIT); + + channel5InjDegrees = channel1InjDegrees; + channel6InjDegrees = channel2InjDegrees; + channel7InjDegrees = channel3InjDegrees; + channel8InjDegrees = channel4InjDegrees; + #else + //This is an invalid config as there are not enough outputs to support sequential + staging + //Put the staging output to the non-existant channel 5 + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + channel5InjDegrees = channel1InjDegrees; + #endif + } + else + { + channel3InjDegrees = channel1InjDegrees; + channel4InjDegrees = channel2InjDegrees; + } } BIT_SET(channelInjEnabled, INJ1_CMD_BIT); @@ -732,6 +773,9 @@ void initialiseAll(void) channel5InjDegrees = 576; BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + #if INJ_CHANNELS >= 6 + if(configPage10.stagingEnabled == true) { BIT_SET(channelInjEnabled, INJ6_CMD_BIT); } + #endif CRANK_ANGLE_MAX_INJ = 720; currentStatus.nSquirts = 1; @@ -743,6 +787,9 @@ void initialiseAll(void) BIT_SET(channelInjEnabled, INJ2_CMD_BIT); BIT_SET(channelInjEnabled, INJ3_CMD_BIT); BIT_SET(channelInjEnabled, INJ4_CMD_BIT); + #if INJ_CHANNELS >= 5 + if(configPage10.stagingEnabled == true) { BIT_SET(channelInjEnabled, INJ5_CMD_BIT); } + #endif break; case 6: channel1IgnDegrees = 0; @@ -783,7 +830,7 @@ void initialiseAll(void) } #if INJ_CHANNELS >= 6 - else if (configPage2.injLayout == INJ_SEQUENTIAL) + if (configPage2.injLayout == INJ_SEQUENTIAL) { channel1InjDegrees = 0; channel2InjDegrees = 120; @@ -800,6 +847,32 @@ void initialiseAll(void) currentStatus.nSquirts = 1; req_fuel_uS = req_fuel_uS * 2; } + else if(configPage10.stagingEnabled == true) //Check if injector staging is enabled + { + BIT_SET(channelInjEnabled, INJ3_CMD_BIT); + BIT_SET(channelInjEnabled, INJ4_CMD_BIT); + + if( (configPage2.injLayout == INJ_SEQUENTIAL) || (configPage2.injLayout == INJ_SEMISEQUENTIAL) ) + { + //Staging with 4 cylinders semi/sequential requires 8 total channels + #if INJ_CHANNELS >= 8 + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + BIT_SET(channelInjEnabled, INJ6_CMD_BIT); + BIT_SET(channelInjEnabled, INJ7_CMD_BIT); + BIT_SET(channelInjEnabled, INJ8_CMD_BIT); + + channel5InjDegrees = channel1InjDegrees; + channel6InjDegrees = channel2InjDegrees; + channel7InjDegrees = channel3InjDegrees; + channel8InjDegrees = channel4InjDegrees; + #else + //This is an invalid config as there are not enough outputs to support sequential + staging + //Put the staging output to the non-existant channel 5 + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + channel5InjDegrees = channel1InjDegrees; + #endif + } + } #endif BIT_SET(channelInjEnabled, INJ1_CMD_BIT); diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index be93a0b0..5db2d427 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -536,12 +536,18 @@ void loop(void) currentStatus.PW1 = ((100 - stagingSplit) * tempPW1) / 100; currentStatus.PW1 += inj_opentime_uS; + //PW2 is used temporarily to hold the secondary injector pulsewidth. It will be assigned to the correct channel below if(stagingSplit > 0) { - currentStatus.PW3 = (stagingSplit * tempPW3) / 100; - currentStatus.PW3 += inj_opentime_uS; + BIT_SET(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE); //Set the staging active flag + currentStatus.PW2 = (stagingSplit * tempPW3) / 100; + currentStatus.PW2 += inj_opentime_uS; + } + else + { + BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE); //Clear the staging active flag + currentStatus.PW2 = 0; } - else { currentStatus.PW3 = 0; } } else if(configPage10.stagingMode == STAGING_MODE_AUTO) { @@ -550,19 +556,145 @@ void loop(void) //If they exceed their limit, the extra duty is passed to the secondaries if(tempPW1 > pwLimit) { + BIT_SET(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE); //Set the staging active flag uint32_t extraPW = tempPW1 - pwLimit + inj_opentime_uS; //The open time must be added here AND below because tempPW1 does not include an open time. The addition of it here takes into account the fact that pwLlimit does not contain an allowance for an open time. currentStatus.PW1 = pwLimit; - currentStatus.PW3 = ((extraPW * staged_req_fuel_mult_sec) / staged_req_fuel_mult_pri); //Convert the 'left over' fuel amount from primary injector scaling to secondary - currentStatus.PW3 += inj_opentime_uS; + currentStatus.PW2 = ((extraPW * staged_req_fuel_mult_sec) / staged_req_fuel_mult_pri); //Convert the 'left over' fuel amount from primary injector scaling to secondary + currentStatus.PW2 += inj_opentime_uS; } - else { currentStatus.PW3 = 0; } //If tempPW1 < pwLImit it means that the entire fuel load can be handled by the primaries. Simply set the secondaries to 0 + else + { + //If tempPW1 < pwLImit it means that the entire fuel load can be handled by the primaries and staging is inactive. + //Secondary PW is simply set to 0 + BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE); //Clear the staging active flag + currentStatus.PW2 = 0; + } } - //Set the 2nd channel of each stage with the same pulseWidth - currentStatus.PW2 = currentStatus.PW1; - currentStatus.PW4 = currentStatus.PW3; + //Allocate the primary and secondary pulse widths based on the fuel configuration + switch (configPage2.nCylinders) + { + case 1: + //Nothing required for 1 cylinder, channels are correct already + break; + case 2: + //Prmaary pulsewidth on channels 1 and 2, secondary on channels 3 and 4 + currentStatus.PW3 = currentStatus.PW2; + currentStatus.PW4 = currentStatus.PW2; + currentStatus.PW2 = currentStatus.PW1; + break; + case 3: + //6 channels required for 'normal' 3 cylinder staging support + #if INJ_CHANNELS >= 6 + //Primary pulsewidth on channels 1, 2 and 3, secondary on channels 4, 5 and 6 + currentStatus.PW4 = currentStatus.PW2; + currentStatus.PW5 = currentStatus.PW2; + currentStatus.PW6 = currentStatus.PW2; + #else + //If there are not enough channels, then primary pulsewidth is on channels 1, 2 and 3, secondary on channel 4 + currentStatus.PW4 = currentStatus.PW2; + #endif + currentStatus.PW2 = currentStatus.PW1; + currentStatus.PW3 = currentStatus.PW1; + break; + case 4: + if( (configPage2.injLayout == INJ_SEQUENTIAL) || (configPage2.injLayout == INJ_SEMISEQUENTIAL) ) + { + //Staging with 4 cylinders semi/sequential requires 8 total channels + #if INJ_CHANNELS >= 8 + currentStatus.PW5 = currentStatus.PW2; + currentStatus.PW6 = currentStatus.PW2; + currentStatus.PW7 = currentStatus.PW2; + currentStatus.PW8 = currentStatus.PW2; + + currentStatus.PW2 = currentStatus.PW1; + currentStatus.PW3 = currentStatus.PW1; + currentStatus.PW4 = currentStatus.PW1; + #else + //This is an invalid config as there are not enough outputs to support sequential + staging + //Put the staging output to the non-existant channel 5 + BIT_SET(channelInjEnabled, INJ5_CMD_BIT); + channel5InjDegrees = channel1InjDegrees; + #endif + } + else + { + currentStatus.PW3 = currentStatus.PW2; + currentStatus.PW4 = currentStatus.PW2; + currentStatus.PW2 = currentStatus.PW1; + } + break; + + case 5: + //No easily supportable 5 cylinder staging option unless there are at least 5 channels + #if INJ_CHANNELS >= 5 + if (configPage2.injLayout != INJ_SEQUENTIAL) + { + currentStatus.PW5 = currentStatus.PW2; + } + #if INJ_CHANNELS >= 6 + currentStatus.PW6 = currentStatus.PW2; + #endif + #endif + + currentStatus.PW2 = currentStatus.PW1; + currentStatus.PW3 = currentStatus.PW1; + currentStatus.PW4 = currentStatus.PW1; + break; + + case 6: + #if INJ_CHANNELS >= 6 + //8 cylinder staging only if not sequential + if (configPage2.injLayout != INJ_SEQUENTIAL) + { + currentStatus.PW4 = currentStatus.PW2; + currentStatus.PW5 = currentStatus.PW2; + currentStatus.PW6 = currentStatus.PW2; + } + #if INJ_CHANNELS >= 8 + else + { + //If there are 8 channels, then the 6 cylinder sequential option is available by using channels 7 + 8 for staging + currentStatus.PW7 = currentStatus.PW2; + currentStatus.PW8 = currentStatus.PW2; + + currentStatus.PW4 = currentStatus.PW1; + currentStatus.PW5 = currentStatus.PW1; + currentStatus.PW6 = currentStatus.PW1; + } + #endif + #endif + currentStatus.PW2 = currentStatus.PW1; + currentStatus.PW3 = currentStatus.PW1; + break; + + case 8: + #if INJ_CHANNELS >= 8 + //8 cylinder staging only if not sequential + if (configPage2.injLayout != INJ_SEQUENTIAL) + { + currentStatus.PW5 = currentStatus.PW2; + currentStatus.PW6 = currentStatus.PW2; + currentStatus.PW7 = currentStatus.PW2; + currentStatus.PW8 = currentStatus.PW2; + } + #endif + currentStatus.PW2 = currentStatus.PW1; + currentStatus.PW3 = currentStatus.PW1; + currentStatus.PW4 = currentStatus.PW1; + break; + + default: + //Assume 4 cylinder non-seq for default + currentStatus.PW3 = currentStatus.PW2; + currentStatus.PW4 = currentStatus.PW2; + currentStatus.PW2 = currentStatus.PW1; + break; + } } - else + else { BIT_CLEAR(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE); } //Clear the staging active flag + + if( BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == false) { //If staging is off, all the pulse widths are set the same (Sequential and other adjustments may be made below) currentStatus.PW2 = currentStatus.PW1; @@ -587,11 +719,11 @@ void loop(void) //Single cylinder case 1: //The only thing that needs to be done for single cylinder is to check for staging. - if( (configPage10.stagingEnabled == true) && (currentStatus.PW3 > 0) ) + if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) { PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging //injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree); - injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); } break; //2 cylinders @@ -600,15 +732,15 @@ void loop(void) injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage6.fuelTrimEnabled > 0) ) - { - currentStatus.PW1 = applyFuelTrimToPW(&trim1Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW1); - currentStatus.PW2 = applyFuelTrimToPW(&trim2Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW2); - } - else if( (configPage10.stagingEnabled == true) && (currentStatus.PW3 > 0) ) + { + currentStatus.PW1 = applyFuelTrimToPW(&trim1Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW1); + currentStatus.PW2 = applyFuelTrimToPW(&trim2Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW2); + } + else if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) { PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging - //injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree); - injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees); + injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged currently) if(injector4StartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { injector4StartAngle -= CRANK_ANGLE_MAX_INJ; } @@ -621,12 +753,12 @@ void loop(void) injector2StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); - if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (configPage6.fuelTrimEnabled > 0) ) - { - currentStatus.PW1 = applyFuelTrimToPW(&trim1Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW1); - currentStatus.PW2 = applyFuelTrimToPW(&trim2Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW2); - currentStatus.PW3 = applyFuelTrimToPW(&trim3Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW3); - } + if ( (configPage2.injLayout == INJ_SEQUENTIAL) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) + { + currentStatus.PW1 = applyFuelTrimToPW(&trim1Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW1); + currentStatus.PW2 = applyFuelTrimToPW(&trim2Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW2); + currentStatus.PW3 = applyFuelTrimToPW(&trim3Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW3); + } break; //4 cylinders case 4: @@ -639,6 +771,16 @@ void loop(void) injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees); + #if INJ_CHANNELS >= 8 + if( (configPage10.stagingEnabled == true) && (configPage6.fuelTrimEnabled > 0) ) + { + PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging + injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees); + injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); + injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees); + } + #endif if(configPage6.fuelTrimEnabled > 0) { @@ -648,13 +790,13 @@ void loop(void) currentStatus.PW4 = applyFuelTrimToPW(&trim4Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW4); } } - else if( (configPage10.stagingEnabled == true) && (currentStatus.PW3 > 0) ) + else if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) { PWdivTimerPerDegree = div(currentStatus.PW3, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging //injector3StartAngle = calculateInjector3StartAngle(PWdivTimerPerDegree); injector3StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); - injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged currently) + injector4StartAngle = injector3StartAngle + (CRANK_ANGLE_MAX_INJ / 2); //Phase this either 180 or 360 degrees out from inj3 (In reality this will always be 180 as you can't have sequential and staged with only 4 channels) if(injector4StartAngle > (uint16_t)CRANK_ANGLE_MAX_INJ) { injector4StartAngle -= CRANK_ANGLE_MAX_INJ; } } else @@ -670,6 +812,16 @@ void loop(void) #if INJ_CHANNELS >= 5 injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees); #endif + + //Staging is possible by using the 6th channel if available + #if INJ_CHANNELS >= 6 + if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) + { + PWdivTimerPerDegree = div(currentStatus.PW6, timePerDegree).quot; + injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel6InjDegrees); + } + #endif + break; //6 cylinders case 6: @@ -682,7 +834,7 @@ void loop(void) #if INJ_CHANNELS >= 6 if((configPage2.injLayout == INJ_SEQUENTIAL) && currentStatus.hasSync) { - if( CRANK_ANGLE_MAX_INJ != 720 ) { changeHalfToFullSync(); } + if( CRANK_ANGLE_MAX_INJ != 720 ) { changeHalfToFullSync(); } injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees); injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel5InjDegrees); @@ -697,10 +849,29 @@ void loop(void) currentStatus.PW5 = applyFuelTrimToPW(&trim5Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW5); currentStatus.PW6 = applyFuelTrimToPW(&trim6Table, currentStatus.fuelLoad, currentStatus.RPM, currentStatus.PW6); } + + //Staging is possible with sequential on 8 channel boards by using outputs 7 + 8 for the staged injectors + #if INJ_CHANNELS >= 8 + if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) + { + PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for staging PW as it will be dramatically different to PW1 when staging + injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees); + injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); + injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + } + #endif } else { if( BIT_CHECK(currentStatus.status3, BIT_STATUS3_HALFSYNC) && (CRANK_ANGLE_MAX_INJ != 360) ) { changeFullToHalfSync(); } + + if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) + { + PWdivTimerPerDegree = div(currentStatus.PW4, timePerDegree).quot; //Need to redo this for staging PW as it will be dramatically different to PW1 when staging + injector4StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees); + injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); + injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + } } #endif break; @@ -741,6 +912,15 @@ void loop(void) else { if( BIT_CHECK(currentStatus.status3, BIT_STATUS3_HALFSYNC) && (CRANK_ANGLE_MAX_INJ != 360) ) { changeFullToHalfSync(); } + + if( (configPage10.stagingEnabled == true) && (BIT_CHECK(currentStatus.status4, BIT_STATUS4_STAGING_ACTIVE) == true) ) + { + PWdivTimerPerDegree = div(currentStatus.PW5, timePerDegree).quot; //Need to redo this for PW3 as it will be dramatically different to PW1 when staging + injector5StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel1InjDegrees); + injector6StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel2InjDegrees); + injector7StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel3InjDegrees); + injector8StartAngle = calculateInjectorStartAngle(PWdivTimerPerDegree, channel4InjDegrees); + } } #endif