Fix for potential missed ignition signals at high rpm/high dwell

This commit is contained in:
Josh Stewart 2019-12-19 13:23:11 +11:00
parent da1d13875f
commit 3265f1b937
2 changed files with 178 additions and 54 deletions

View File

@ -427,6 +427,18 @@ void setIgnitionSchedule1(void (*startCallback)(), unsigned long timeout, unsign
interrupts();
IGN1_TIMER_ENABLE();
}
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule1.nextStartCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule1.nextEndCompare = ignitionSchedule1.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule1.hasNextSchedule = true;
}
}
}
static inline void refreshIgnitionSchedule1(unsigned long timeToEnd)
@ -464,6 +476,17 @@ void setIgnitionSchedule2(void (*startCallback)(), unsigned long timeout, unsign
interrupts();
IGN2_TIMER_ENABLE();
}
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule2.nextStartCompare = IGN2_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule2.nextEndCompare = ignitionSchedule2.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule2.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule3(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
@ -492,9 +515,12 @@ void setIgnitionSchedule3(void (*startCallback)(), unsigned long timeout, unsign
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule3.nextStartCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule3.nextEndCompare = ignitionSchedule3.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule3.hasNextSchedule = true;
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule3.nextStartCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule3.nextEndCompare = ignitionSchedule3.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule3.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
@ -524,9 +550,12 @@ void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsign
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule4.nextStartCompare = IGN4_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule4.nextEndCompare = ignitionSchedule4.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule4.hasNextSchedule = true;
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule4.nextStartCompare = IGN4_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule4.nextEndCompare = ignitionSchedule4.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule4.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
@ -552,6 +581,17 @@ void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsign
interrupts();
IGN5_TIMER_ENABLE();
}
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule5.nextStartCompare = IGN5_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule5.nextEndCompare = ignitionSchedule5.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule5.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule6(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
@ -580,9 +620,12 @@ void setIgnitionSchedule6(void (*startCallback)(), unsigned long timeout, unsign
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule6.nextStartCompare = IGN6_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule6.nextEndCompare = ignitionSchedule6.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule6.hasNextSchedule = true;
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule6.nextStartCompare = IGN6_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule6.nextEndCompare = ignitionSchedule6.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule6.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule7(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
@ -612,9 +655,12 @@ void setIgnitionSchedule7(void (*startCallback)(), unsigned long timeout, unsign
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule7.nextStartCompare = IGN7_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule7.nextEndCompare = ignitionSchedule7.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule7.hasNextSchedule = true;
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule7.nextStartCompare = IGN7_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule7.nextEndCompare = ignitionSchedule7.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule7.hasNextSchedule = true;
}
}
}
void setIgnitionSchedule8(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
@ -644,9 +690,12 @@ void setIgnitionSchedule8(void (*startCallback)(), unsigned long timeout, unsign
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule8.nextStartCompare = IGN8_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule8.nextEndCompare = ignitionSchedule8.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule8.hasNextSchedule = true;
if (timeout < MAX_TIMER_PERIOD)
{
ignitionSchedule8.nextStartCompare = IGN8_COUNTER + uS_TO_TIMER_COMPARE(timeout);
ignitionSchedule8.nextEndCompare = ignitionSchedule8.nextStartCompare + uS_TO_TIMER_COMPARE(duration);
ignitionSchedule8.hasNextSchedule = true;
}
}
}
@ -951,13 +1000,20 @@ static inline void ignitionSchedule1Interrupt() //Most ARM chips can simply call
else if (ignitionSchedule1.Status == RUNNING)
{
ignitionSchedule1.EndCallback();
// *ign1_pin_port &= ~(ign1_pin_mask);
ignitionSchedule1.Status = OFF; //Turn off the schedule
ignitionSchedule1.schedulesSet = 0;
ignitionSchedule1.hasNextSchedule = false;
ignitionSchedule1.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN1_TIMER_DISABLE();
//If there is a next schedule queued up, activate it
if(ignitionSchedule1.hasNextSchedule == true)
{
IGN1_COMPARE = ignitionSchedule1.nextStartCompare;
ignitionSchedule1.Status = PENDING;
ignitionSchedule1.schedulesSet = 1;
ignitionSchedule1.hasNextSchedule = false;
}
else{ IGN1_TIMER_DISABLE(); }
}
else if (ignitionSchedule1.Status == OFF)
{
@ -989,7 +1045,16 @@ static inline void ignitionSchedule2Interrupt() //Most ARM chips can simply call
ignitionSchedule2.schedulesSet = 0;
ignitionSchedule2.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN2_TIMER_DISABLE();
//If there is a next schedule queued up, activate it
if(ignitionSchedule2.hasNextSchedule == true)
{
IGN2_COMPARE = ignitionSchedule2.nextStartCompare;
ignitionSchedule2.Status = PENDING;
ignitionSchedule2.schedulesSet = 1;
ignitionSchedule2.hasNextSchedule = false;
}
else{ IGN2_TIMER_DISABLE(); }
}
else if (ignitionSchedule2.Status == OFF)
{
@ -1026,7 +1091,6 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
if(ignitionSchedule3.hasNextSchedule == true)
{
IGN3_COMPARE = ignitionSchedule3.nextStartCompare;
ignitionSchedule3.endCompare = ignitionSchedule3.nextEndCompare;
ignitionSchedule3.Status = PENDING;
ignitionSchedule3.schedulesSet = 1;
ignitionSchedule3.hasNextSchedule = false;
@ -1067,7 +1131,6 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
if(ignitionSchedule4.hasNextSchedule == true)
{
IGN4_COMPARE = ignitionSchedule4.nextStartCompare;
ignitionSchedule4.endCompare = ignitionSchedule4.nextEndCompare;
ignitionSchedule4.Status = PENDING;
ignitionSchedule4.schedulesSet = 1;
ignitionSchedule4.hasNextSchedule = false;
@ -1098,12 +1161,26 @@ static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call
}
else if (ignitionSchedule5.Status == RUNNING)
{
ignitionSchedule5.Status = OFF; //Turn off the schedule
ignitionSchedule5.EndCallback();
ignitionSchedule5.schedulesSet = 0;
ignitionSchedule5.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN5_TIMER_DISABLE();
ignitionSchedule5.Status = OFF; //Turn off the schedule
ignitionSchedule5.EndCallback();
ignitionSchedule5.schedulesSet = 0;
ignitionSchedule5.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
//If there is a next schedule queued up, activate it
if(ignitionSchedule5.hasNextSchedule == true)
{
IGN5_COMPARE = ignitionSchedule5.nextStartCompare;
ignitionSchedule5.Status = PENDING;
ignitionSchedule5.schedulesSet = 1;
ignitionSchedule5.hasNextSchedule = false;
}
else{ IGN5_TIMER_DISABLE(); }
}
else if (ignitionSchedule5.Status == OFF)
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN5_TIMER_DISABLE();
}
}
#endif
@ -1124,12 +1201,26 @@ static inline void ignitionSchedule6Interrupt() //Most ARM chips can simply call
}
else if (ignitionSchedule6.Status == RUNNING)
{
ignitionSchedule6.Status = OFF; //Turn off the schedule
ignitionSchedule6.EndCallback();
ignitionSchedule6.schedulesSet = 0;
ignitionSchedule6.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN6_TIMER_DISABLE();
ignitionSchedule6.Status = OFF; //Turn off the schedule
ignitionSchedule6.EndCallback();
ignitionSchedule6.schedulesSet = 0;
ignitionSchedule6.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
//If there is a next schedule queued up, activate it
if(ignitionSchedule6.hasNextSchedule == true)
{
IGN6_COMPARE = ignitionSchedule6.nextStartCompare;
ignitionSchedule6.Status = PENDING;
ignitionSchedule6.schedulesSet = 1;
ignitionSchedule6.hasNextSchedule = false;
}
else{ IGN6_TIMER_DISABLE(); }
}
else if (ignitionSchedule6.Status == OFF)
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN6_TIMER_DISABLE();
}
}
#endif
@ -1150,12 +1241,26 @@ static inline void ignitionSchedule7Interrupt() //Most ARM chips can simply call
}
else if (ignitionSchedule7.Status == RUNNING)
{
ignitionSchedule7.Status = OFF; //Turn off the schedule
ignitionSchedule7.EndCallback();
ignitionSchedule7.schedulesSet = 0;
ignitionSchedule7.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN7_TIMER_DISABLE();
ignitionSchedule7.Status = OFF; //Turn off the schedule
ignitionSchedule7.EndCallback();
ignitionSchedule7.schedulesSet = 0;
ignitionSchedule7.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
//If there is a next schedule queued up, activate it
if(ignitionSchedule7.hasNextSchedule == true)
{
IGN7_COMPARE = ignitionSchedule7.nextStartCompare;
ignitionSchedule7.Status = PENDING;
ignitionSchedule7.schedulesSet = 1;
ignitionSchedule7.hasNextSchedule = false;
}
else{ IGN7_TIMER_DISABLE(); }
}
else if (ignitionSchedule7.Status == OFF)
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN7_TIMER_DISABLE();
}
}
#endif
@ -1176,12 +1281,26 @@ static inline void ignitionSchedule8Interrupt() //Most ARM chips can simply call
}
else if (ignitionSchedule8.Status == RUNNING)
{
ignitionSchedule8.Status = OFF; //Turn off the schedule
ignitionSchedule8.EndCallback();
ignitionSchedule8.schedulesSet = 0;
ignitionSchedule8.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
IGN8_TIMER_DISABLE();
ignitionSchedule8.Status = OFF; //Turn off the schedule
ignitionSchedule8.EndCallback();
ignitionSchedule8.schedulesSet = 0;
ignitionSchedule8.endScheduleSetByDecoder = false;
ignitionCount += 1; //Increment the igintion counter
//If there is a next schedule queued up, activate it
if(ignitionSchedule8.hasNextSchedule == true)
{
IGN8_COMPARE = ignitionSchedule8.nextStartCompare;
ignitionSchedule8.Status = PENDING;
ignitionSchedule8.schedulesSet = 1;
ignitionSchedule8.hasNextSchedule = false;
}
else{ IGN8_TIMER_DISABLE(); }
}
else if (ignitionSchedule8.Status == OFF)
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN8_TIMER_DISABLE();
}
}
#endif

View File

@ -1017,17 +1017,15 @@ void loop()
if (crankAngle > CRANK_ANGLE_MAX_IGN ) { crankAngle -= 360; }
#if IGN_CHANNELS >= 1
if ( (ignition1StartAngle <= crankAngle) && (ignitionSchedule1.Status == RUNNING) ) { ignition1StartAngle += CRANK_ANGLE_MAX_IGN; }
if ( (ignition1StartAngle > crankAngle) && (curRollingCut != 1) )
{
if(ignitionSchedule1.Status != RUNNING)
{
setIgnitionSchedule1(ign1StartFunction,
//((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
angleToTime((ignition1StartAngle - crankAngle), CRANKMATH_METHOD_INTERVAL_REV),
currentStatus.dwell + fixedCrankingOverride, //((unsigned long)((unsigned long)currentStatus.dwell* currentStatus.RPM) / newRPM) + fixedCrankingOverride,
ign1EndFunction
);
}
setIgnitionSchedule1(ign1StartFunction,
//((unsigned long)(ignition1StartAngle - crankAngle) * (unsigned long)timePerDegree),
angleToTime((ignition1StartAngle - crankAngle), CRANKMATH_METHOD_INTERVAL_REV),
currentStatus.dwell + fixedCrankingOverride, //((unsigned long)((unsigned long)currentStatus.dwell* currentStatus.RPM) / newRPM) + fixedCrankingOverride,
ign1EndFunction
);
}
#endif
@ -1061,6 +1059,7 @@ void loop()
//if (tempStartAngle > tempCrankAngle)
{
unsigned long ignition2StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule2.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition2StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition2StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition2StartTime = 0; }
@ -1084,6 +1083,7 @@ void loop()
//if (tempStartAngle > tempCrankAngle)
{
long ignition3StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule3.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition3StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition3StartTime = 0; }
@ -1108,6 +1108,7 @@ void loop()
{
long ignition4StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule4.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition4StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition4StartTime = 0; }
@ -1132,6 +1133,7 @@ void loop()
{
long ignition5StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule5.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition5StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
//else if (tempStartAngle < tempCrankAngle) { ignition4StartTime = ((long)(360 - tempCrankAngle + tempStartAngle) * (long)timePerDegree); }
else { ignition5StartTime = 0; }
@ -1153,6 +1155,7 @@ void loop()
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
{
unsigned long ignition6StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule6.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition6StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
else { ignition6StartTime = 0; }
@ -1174,6 +1177,7 @@ void loop()
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
{
unsigned long ignition7StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule7.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition7StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
else { ignition7StartTime = 0; }
@ -1195,6 +1199,7 @@ void loop()
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
{
unsigned long ignition8StartTime = 0;
if ( (tempStartAngle <= tempCrankAngle) && (ignitionSchedule8.Status == RUNNING) ) { tempStartAngle += CRANK_ANGLE_MAX_IGN; }
if(tempStartAngle > tempCrankAngle) { ignition8StartTime = angleToTime((tempStartAngle - tempCrankAngle), CRANKMATH_METHOD_INTERVAL_REV); }
else { ignition8StartTime = 0; }