Performance optimisation on the missing tooth decoder

This commit is contained in:
Josh Stewart 2019-11-12 15:28:43 +11:00
parent 554f58eb28
commit 3dd92b15fe
1 changed files with 85 additions and 71 deletions

View File

@ -278,91 +278,105 @@ void triggerPri_missingTooth()
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
//if(toothCurrentCount > checkSyncToothCount || currentStatus.hasSync == false)
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) )
{
//Begin the missing tooth detection
//If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after the gap
if(configPage4.triggerMissingTeeth == 1) { targetGap = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) >> 1; } //Multiply by 1.5 (Checks for a gap 1.5x greater than the last one) (Uses bitshift to multiply by 3 then divide by 2. Much faster than multiplying by 1.5)
else { targetGap = ((toothLastToothTime - toothLastMinusOneToothTime)) * configPage4.triggerMissingTeeth; } //Multiply by 2 (Checks for a gap 2x greater than the last one)
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) )
{
bool isMissingTooth = false;
if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; }
/*
Performance Optimisation:
Only need to try and detect the missing tooth if:
1. WE don't have sync yet
2. We have sync and are in the 2nd half of the wheel (Missing tooth will/should never occur in the first have)
3. RPM is under 2000. This is to ensure that we don't interfer with strange timing when cranking or idling. Optimisation not really required at these speeds anyway
*/
if( (currentStatus.hasSync == false) || (currentStatus.RPM < 2000) || (toothCurrentCount >= (triggerActualTeeth >> 1)) )
{
//Begin the missing tooth detection
//If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after the gap
if(configPage4.triggerMissingTeeth == 1) { targetGap = (3 * (toothLastToothTime - toothLastMinusOneToothTime)) >> 1; } //Multiply by 1.5 (Checks for a gap 1.5x greater than the last one) (Uses bitshift to multiply by 3 then divide by 2. Much faster than multiplying by 1.5)
else { targetGap = ((toothLastToothTime - toothLastMinusOneToothTime)) * configPage4.triggerMissingTeeth; } //Multiply by 2 (Checks for a gap 2x greater than the last one)
if ( (curGap > targetGap) || (toothCurrentCount > triggerActualTeeth) )
{
//Missing tooth detected
if( (toothCurrentCount < triggerActualTeeth) && (currentStatus.hasSync == true) )
{
//This occurs when we're at tooth #1, but haven't seen all the other teeth. This indicates a signal issue so we flag lost sync so this will attempt to resync on the next revolution.
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
}
//This is to handle a special case on startup where sync can be obtained and the system immediately thinks the revs have jumped:
//else if (currentStatus.hasSync == false && toothCurrentCount < checkSyncToothCount ) { triggerFilterTime = 0; }
else
{
if(currentStatus.hasSync == true)
{
currentStatus.startRevolutions++; //Counter
if ( configPage4.TrigSpeed == CAM_SPEED ) { currentStatus.startRevolutions++; } //Add an extra revolution count if we're running at cam speed
if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; }
if ( (curGap > targetGap) || (toothCurrentCount > triggerActualTeeth) )
{
//Missing tooth detected
isMissingTooth = true;
if( (toothCurrentCount < triggerActualTeeth) && (currentStatus.hasSync == true) )
{
//This occurs when we're at tooth #1, but haven't seen all the other teeth. This indicates a signal issue so we flag lost sync so this will attempt to resync on the next revolution.
currentStatus.hasSync = false;
currentStatus.syncLossCounter++;
}
else { currentStatus.startRevolutions = 0; }
toothCurrentCount = 1;
revolutionOne = !revolutionOne; //Flip sequential revolution tracker
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
//if Sequential fuel or ignition is in use, further checks are needed before determining sync
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) || (configPage2.injLayout == INJ_SEQUENTIAL) )
//This is to handle a special case on startup where sync can be obtained and the system immediately thinks the revs have jumped:
//else if (currentStatus.hasSync == false && toothCurrentCount < checkSyncToothCount ) { triggerFilterTime = 0; }
else
{
//If either fuel or ignition is sequential, only declare sync if the cam tooth has been seen OR if the missing wheel is on the cam
if( (secondaryToothCount > 0) || (configPage4.TrigSpeed == CAM_SPEED) )
{
currentStatus.hasSync = true;
if(configPage4.trigPatternSec == SEC_TRIGGER_SINGLE) { secondaryToothCount = 0; } //Reset the secondary tooth counter to prevent it overflowing
}
if(currentStatus.hasSync == true)
{
currentStatus.startRevolutions++; //Counter
if ( configPage4.TrigSpeed == CAM_SPEED ) { currentStatus.startRevolutions++; } //Add an extra revolution count if we're running at cam speed
}
else { currentStatus.startRevolutions = 0; }
toothCurrentCount = 1;
revolutionOne = !revolutionOne; //Flip sequential revolution tracker
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
//if Sequential fuel or ignition is in use, further checks are needed before determining sync
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) || (configPage2.injLayout == INJ_SEQUENTIAL) )
{
//If either fuel or ignition is sequential, only declare sync if the cam tooth has been seen OR if the missing wheel is on the cam
if( (secondaryToothCount > 0) || (configPage4.TrigSpeed == CAM_SPEED) )
{
currentStatus.hasSync = true;
if(configPage4.trigPatternSec == SEC_TRIGGER_SINGLE) { secondaryToothCount = 0; } //Reset the secondary tooth counter to prevent it overflowing
}
}
else { currentStatus.hasSync = true; } //If nothing is using sequential, we have sync
triggerFilterTime = 0; //This is used to prevent a condition where serious intermitent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
}
else { currentStatus.hasSync = true; } //If nothing is using sequential, we have sync
triggerFilterTime = 0; //This is used to prevent a condition where serious intermitent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
}
}
else
{
//Filter can only be recalc'd for the regular teeth, not the missing one.
setFilter(curGap);
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = true;
}
}
else
{
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
}
}
}
if(isMissingTooth == false)
{
//Regular (non-missing) tooth
setFilter(curGap);
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
triggerToothAngleIsCorrect = true;
}
}
else
{
//We fall here on initial startup when enough teeth have not yet been seen
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
}
//NEW IGNITION MODE
if( (configPage2.perToothIgn == true) && (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
{
//ignition1EndTooth = 11;
//ignition1EndAngle = 0;
//NEW IGNITION MODE
if( (configPage2.perToothIgn == true) && (!BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
{
//ignition1EndTooth = 11;
//ignition1EndAngle = 0;
int16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage4.triggerAngle;
//if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) ) { IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( fastDegreesToUS( ignitionLimits( (ignition1EndAngle - crankAngle) ) ) ); }
//if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) ) { IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( 9048 ); }
//else { if (toothCurrentCount == ignition1EndTooth) { ignitionSchedule1.endCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE( 9048 ); } }
//if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) ) { IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( fastDegreesToUS( ignitionLimits( (ignition1EndAngle - crankAngle) ) ) ); }
//if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) ) { IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( 9048 ); }
//else { if (toothCurrentCount == ignition1EndTooth) { ignitionSchedule1.endCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE( 9048 ); } }
if( (configPage4.sparkMode == IGN_MODE_SEQUENTIAL) && (revolutionOne == true) && (configPage4.TrigSpeed == CRANK_SPEED) )
{
crankAngle += 360;
checkPerToothTiming(crankAngle, (configPage4.triggerTeeth + toothCurrentCount));
}
else{ checkPerToothTiming(crankAngle, toothCurrentCount); }
}
}
}
}