|
|
|
@ -79,15 +79,11 @@ volatile unsigned long secondaryLastToothTime1 = 0; //The time (micros()) that t
|
|
|
|
|
uint16_t triggerActualTeeth;
|
|
|
|
|
volatile unsigned long triggerFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering)
|
|
|
|
|
volatile unsigned long triggerSecFilterTime; // The shortest time (in uS) that pulses will be accepted (Used for debounce filtering) for the secondary input
|
|
|
|
|
volatile bool validTrigger; //Is set true when the last trigger (Primary or secondary) was valid (ie passed filters)
|
|
|
|
|
|
|
|
|
|
volatile uint8_t decoderState = 0;
|
|
|
|
|
|
|
|
|
|
unsigned int triggerSecFilterTime_duration; // The shortest valid time (in uS) pulse DURATION
|
|
|
|
|
volatile uint16_t triggerToothAngle; //The number of crank degrees that elapse per tooth
|
|
|
|
|
volatile bool triggerToothAngleIsCorrect = false; //Whether or not the triggerToothAngle variable is currently accurate. Some patterns have times when the triggerToothAngle variable cannot be accurately set.
|
|
|
|
|
bool secondDerivEnabled = false; //The use of the 2nd derivative calculation is limited to certain decoders. This is set to either true or false in each decoders setup routine
|
|
|
|
|
bool decoderIsSequential; //Whether or not the decoder supports sequential operation
|
|
|
|
|
bool decoderIsLowRes = false; //Is set true, certain extra calculations are performed for better timing accuracy
|
|
|
|
|
bool decoderHasSecondary = false; //Whether or not the pattern uses a secondary input
|
|
|
|
|
bool decoderHasFixedCrankingTiming = false; //Whether or not the decoder supports fixed cranking timing
|
|
|
|
|
byte checkSyncToothCount; //How many teeth must've been seen on this revolution before we try to confirm sync (Useful for missing tooth type decoders)
|
|
|
|
|
unsigned long elapsedTime;
|
|
|
|
|
unsigned long lastCrankAngleCalc;
|
|
|
|
@ -164,7 +160,7 @@ static inline void addToothLogEntry(unsigned long toothTime, bool whichTooth)
|
|
|
|
|
*/
|
|
|
|
|
void loggerPrimaryISR(void)
|
|
|
|
|
{
|
|
|
|
|
validTrigger = false; //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_VALID_TRIGGER); //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters
|
|
|
|
|
bool validEdge = false; //This is set true below if the edge
|
|
|
|
|
/*
|
|
|
|
|
Need to still call the standard decoder trigger.
|
|
|
|
@ -178,12 +174,11 @@ void loggerPrimaryISR(void)
|
|
|
|
|
triggerHandler();
|
|
|
|
|
validEdge = true;
|
|
|
|
|
}
|
|
|
|
|
if( (currentStatus.toothLogEnabled == true) && (validTrigger == true) )
|
|
|
|
|
if( (currentStatus.toothLogEnabled == true) && (BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER)) )
|
|
|
|
|
{
|
|
|
|
|
//Tooth logger only logs when the edge was correct
|
|
|
|
|
if(validEdge == true) { addToothLogEntry(curGap, TOOTH_CRANK); }
|
|
|
|
|
}
|
|
|
|
|
//else if( (currentStatus.compositeLogEnabled == true) && (validTrigger == true) )
|
|
|
|
|
else if( (currentStatus.compositeLogEnabled == true) )
|
|
|
|
|
{
|
|
|
|
|
//Composite logger adds an entry regardless of which edge it was
|
|
|
|
@ -196,8 +191,8 @@ void loggerPrimaryISR(void)
|
|
|
|
|
*/
|
|
|
|
|
void loggerSecondaryISR(void)
|
|
|
|
|
{
|
|
|
|
|
validTrigger = false; //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters
|
|
|
|
|
validTrigger = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_VALID_TRIGGER); //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //This value will be set to the return value of the decoder function, indicating whether or not this pulse passed the filters
|
|
|
|
|
/* 3 checks here:
|
|
|
|
|
1) If the primary trigger is RISING, then check whether the primary is currently HIGH
|
|
|
|
|
2) If the primary trigger is FALLING, then check whether the primary is currently LOW
|
|
|
|
@ -209,7 +204,7 @@ void loggerSecondaryISR(void)
|
|
|
|
|
triggerSecondaryHandler();
|
|
|
|
|
}
|
|
|
|
|
//No tooth logger for the secondary input
|
|
|
|
|
if( (currentStatus.compositeLogEnabled == true) && (validTrigger == true) )
|
|
|
|
|
if( (currentStatus.compositeLogEnabled == true) && (BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER)) )
|
|
|
|
|
{
|
|
|
|
|
//Composite logger adds an entry regardless of which edge it was
|
|
|
|
|
addToothLogEntry(curGap2, TOOTH_CAM);
|
|
|
|
@ -354,8 +349,14 @@ static inline void checkPerToothTiming(int16_t crankAngle, uint16_t currentTooth
|
|
|
|
|
*/
|
|
|
|
|
void triggerSetup_missingTooth(void)
|
|
|
|
|
{
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
triggerToothAngle = 360 / configPage4.triggerTeeth; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
if(configPage4.TrigSpeed == CAM_SPEED) { triggerToothAngle = 720 / configPage4.triggerTeeth; } //Account for cam speed missing tooth
|
|
|
|
|
if(configPage4.TrigSpeed == CAM_SPEED)
|
|
|
|
|
{
|
|
|
|
|
//Account for cam speed missing tooth
|
|
|
|
|
triggerToothAngle = 720 / configPage4.triggerTeeth;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
}
|
|
|
|
|
triggerActualTeeth = configPage4.triggerTeeth - configPage4.triggerMissingTeeth; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
if (configPage4.trigPatternSec == SEC_TRIGGER_4_1)
|
|
|
|
@ -366,8 +367,7 @@ void triggerSetup_missingTooth(void)
|
|
|
|
|
{
|
|
|
|
|
triggerSecFilterTime = (1000000 / (MAX_RPM / 60));
|
|
|
|
|
}
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
|
|
|
|
|
toothLastMinusOneToothTime = 0;
|
|
|
|
|
toothCurrentCount = 0;
|
|
|
|
@ -384,7 +384,7 @@ void triggerPri_missingTooth(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS)
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
//if(toothCurrentCount > checkSyncToothCount || currentStatus.hasSync == false)
|
|
|
|
|
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) )
|
|
|
|
@ -456,7 +456,7 @@ void triggerPri_missingTooth(void)
|
|
|
|
|
triggerFilterTime = 0; //This is used to prevent a condition where serious intermittent 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
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //The tooth angle is double at this point
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -467,7 +467,7 @@ void triggerPri_missingTooth(void)
|
|
|
|
|
setFilter(curGap);
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -702,9 +702,9 @@ void triggerSetup_DualWheel(void)
|
|
|
|
|
toothCurrentCount = 255; //Default value
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = (1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true; //This is always true for this pattern
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //This is always true for this pattern
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -718,7 +718,7 @@ void triggerPri_DualWheel(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime )
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -922,11 +922,11 @@ void triggerSetup_BasicDistributor(void)
|
|
|
|
|
triggerFilterTime = 60000000L / MAX_RPM / configPage2.nCylinders; // Minimum time required between teeth
|
|
|
|
|
triggerFilterTime = triggerFilterTime / 2; //Safety margin
|
|
|
|
|
triggerFilterTime = 0;
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
toothCurrentCount = 0; //Default value
|
|
|
|
|
decoderHasFixedCrankingTiming = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_HAS_FIXED_CRANKING);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
if(configPage2.nCylinders <= 4) { MAX_STALL_TIME = (1851UL * triggerToothAngle); }//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
|
|
|
|
|
else { MAX_STALL_TIME = (3200UL * triggerToothAngle); } //Minimum 50rpm. (3200uS is the time per degree at 50rpm).
|
|
|
|
|
|
|
|
|
@ -965,7 +965,7 @@ void triggerPri_BasicDistributor(void)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
if ( configPage4.ignCranklock && BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
|
|
|
|
|
{
|
|
|
|
@ -1064,8 +1064,8 @@ void triggerSetEndTeeth_BasicDistributor(void)
|
|
|
|
|
void triggerSetup_GM7X(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 360 / 6; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1075,7 +1075,7 @@ void triggerPri_GM7X(void)
|
|
|
|
|
curTime = micros();
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
if( (toothLastToothTime > 0) && (toothLastMinusOneToothTime > 0) )
|
|
|
|
|
{
|
|
|
|
@ -1085,7 +1085,7 @@ void triggerPri_GM7X(void)
|
|
|
|
|
toothOneMinusOneTime = toothOneTime;
|
|
|
|
|
toothOneTime = curTime;
|
|
|
|
|
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1094,12 +1094,12 @@ void triggerPri_GM7X(void)
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount = 3;
|
|
|
|
|
currentStatus.hasSync = true;
|
|
|
|
|
triggerToothAngleIsCorrect = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //The tooth angle is double at this point
|
|
|
|
|
currentStatus.startRevolutions++; //Counter
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1202,13 +1202,12 @@ void triggerSetup_4G63(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 180; //The number of degrees that passes from tooth to tooth (primary)
|
|
|
|
|
toothCurrentCount = 99; //Fake tooth count represents no sync
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
decoderHasFixedCrankingTiming = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_HAS_FIXED_CRANKING);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
MAX_STALL_TIME = 366667UL; //Minimum 50rpm based on the 110 degree tooth spacing
|
|
|
|
|
if(initialisationComplete == false) { toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initial check to prevent the fuel pump just staying on all the time
|
|
|
|
|
//decoderIsLowRes = true;
|
|
|
|
|
|
|
|
|
|
//Note that these angles are for every rising and falling edge
|
|
|
|
|
if(configPage2.nCylinders == 6)
|
|
|
|
@ -1258,7 +1257,7 @@ void triggerPri_4G63(void)
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
if ( (curGap >= triggerFilterTime) || (currentStatus.startRevolutions == 0) )
|
|
|
|
|
{
|
|
|
|
|
validTrigger = true; //Flag that this pulse was accepted as a valid trigger
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
triggerFilterTime = curGap >> 2; //This only applies during non-sync conditions. If there is sync then triggerFilterTime gets changed again below with a better value.
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
@ -1458,7 +1457,7 @@ void triggerSec_4G63(void)
|
|
|
|
|
if ( (curGap2 >= triggerSecFilterTime) )//|| (currentStatus.startRevolutions == 0) )
|
|
|
|
|
{
|
|
|
|
|
toothLastSecToothTime = curTime2;
|
|
|
|
|
validTrigger = true; //Flag that this pulse was accepted as a valid trigger
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
//addToothLogEntry(curGap, TOOTH_CAM);
|
|
|
|
|
|
|
|
|
|
triggerSecFilterTime = curGap2 >> 1; //Basic 50% filter for the secondary reading
|
|
|
|
@ -1666,9 +1665,9 @@ void triggerSetup_24X(void)
|
|
|
|
|
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
if(initialisationComplete == false) { toothCurrentCount = 25; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the init check to prevent the fuel pump just staying on all the time
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_24X(void)
|
|
|
|
@ -1695,7 +1694,7 @@ void triggerPri_24X(void)
|
|
|
|
|
triggerToothAngle = toothAngles[(toothCurrentCount-1)] - toothAngles[(toothCurrentCount-2)]; //Calculate the last tooth gap in degrees
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
|
|
|
|
|
@ -1778,9 +1777,9 @@ void triggerSetup_Jeep2000(void)
|
|
|
|
|
|
|
|
|
|
MAX_STALL_TIME = (3333UL * 60); //Minimum 50rpm. (3333uS is the time per degree at 50rpm). Largest gap between teeth is 60 degrees.
|
|
|
|
|
if(initialisationComplete == false) { toothCurrentCount = 13; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initial check to prevent the fuel pump just staying on all the time
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_Jeep2000(void)
|
|
|
|
@ -1809,7 +1808,7 @@ void triggerPri_Jeep2000(void)
|
|
|
|
|
|
|
|
|
|
setFilter(curGap); //Recalc the new filter value
|
|
|
|
|
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -1874,9 +1873,9 @@ void triggerSetup_Audi135(void)
|
|
|
|
|
triggerFilterTime = (unsigned long)(1000000 / (MAX_RPM / 60 * 135UL)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_Audi135(void)
|
|
|
|
@ -1894,7 +1893,7 @@ void triggerPri_Audi135(void)
|
|
|
|
|
{
|
|
|
|
|
//We only proceed for every third tooth
|
|
|
|
|
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
toothSystemLastToothTime = curTime;
|
|
|
|
|
toothSystemCount = 0;
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
@ -1989,8 +1988,8 @@ void triggerSetup_HondaD17(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 360 / 12; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_HondaD17(void)
|
|
|
|
@ -2000,7 +1999,7 @@ void triggerPri_HondaD17(void)
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
if( (toothCurrentCount == 13) && (currentStatus.hasSync == true) )
|
|
|
|
@ -2092,8 +2091,8 @@ void triggerSetup_Miata9905(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 90; //The number of degrees that passes from tooth to tooth (primary)
|
|
|
|
|
toothCurrentCount = 99; //Fake tooth count represents no sync
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
triggerActualTeeth = 8;
|
|
|
|
|
|
|
|
|
|
if(initialisationComplete == false) { secondaryToothCount = 0; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initial check to prevent the fuel pump just staying on all the time
|
|
|
|
@ -2121,8 +2120,8 @@ void triggerSetup_Miata9905(void)
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
triggerFilterTime = 1500; //10000 rpm, assuming we're triggering on both edges off the crank tooth.
|
|
|
|
|
triggerSecFilterTime = 0; //Need to figure out something better for this
|
|
|
|
|
decoderHasFixedCrankingTiming = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_HAS_FIXED_CRANKING);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_Miata9905(void)
|
|
|
|
@ -2132,7 +2131,7 @@ void triggerPri_Miata9905(void)
|
|
|
|
|
if ( (curGap >= triggerFilterTime) || (currentStatus.startRevolutions == 0) )
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++;
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
if( (toothCurrentCount == (triggerActualTeeth + 1)) )
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount = 1; //Reset the counter
|
|
|
|
@ -2364,8 +2363,8 @@ void triggerSetup_MazdaAU(void)
|
|
|
|
|
triggerToothAngle = 108; //The number of degrees that passes from tooth to tooth (primary). This is the maximum gap
|
|
|
|
|
toothCurrentCount = 99; //Fake tooth count represents no sync
|
|
|
|
|
secondaryToothCount = 0; //Needed for the cam tooth tracking
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
|
|
|
|
|
toothAngles[0] = 348; //tooth #1
|
|
|
|
|
toothAngles[1] = 96; //tooth #2
|
|
|
|
@ -2375,7 +2374,7 @@ void triggerSetup_MazdaAU(void)
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
triggerFilterTime = 1500; //10000 rpm, assuming we're triggering on both edges off the crank tooth.
|
|
|
|
|
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
|
|
|
|
decoderHasFixedCrankingTiming = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_HAS_FIXED_CRANKING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triggerPri_MazdaAU(void)
|
|
|
|
@ -2384,7 +2383,7 @@ void triggerPri_MazdaAU(void)
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
if ( curGap >= triggerFilterTime )
|
|
|
|
|
{
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothCurrentCount++;
|
|
|
|
|
if( (toothCurrentCount == 1) || (toothCurrentCount == 5) ) //Trigger is on CHANGE, hence 4 pulses = 1 crank rev
|
|
|
|
@ -2516,8 +2515,8 @@ void triggerSetup_non360(void)
|
|
|
|
|
toothCurrentCount = 255; //Default value
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = (1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -2589,8 +2588,8 @@ void triggerSetup_Nissan360(void)
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * 360UL)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = (int)(1000000 / (MAX_RPM / 60 * 2)) / 2; //Same as above, but fixed at 2 teeth on the secondary input and divided by 2 (for cam speed)
|
|
|
|
|
secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
toothCurrentCount = 1;
|
|
|
|
|
triggerToothAngle = 2;
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
@ -2603,7 +2602,7 @@ void triggerPri_Nissan360(void)
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
//if ( curGap < triggerFilterTime ) { return; }
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -2819,11 +2818,11 @@ void triggerSetup_Subaru67(void)
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * 360UL)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = 0;
|
|
|
|
|
secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
toothCurrentCount = 1;
|
|
|
|
|
triggerToothAngle = 2;
|
|
|
|
|
triggerToothAngleIsCorrect = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
toothSystemCount = 0;
|
|
|
|
|
MAX_STALL_TIME = (3333UL * 93); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
|
|
|
|
@ -2849,7 +2848,7 @@ void triggerPri_Subaru67(void)
|
|
|
|
|
//if ( curGap < triggerFilterTime ) { return; }
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
toothSystemCount++; //Used to count the number of primary pulses that have occurred since the last secondary. Is part of the noise filtering system.
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -2888,7 +2887,7 @@ void triggerPri_Subaru67(void)
|
|
|
|
|
default:
|
|
|
|
|
//Almost certainly due to noise or cranking stop/start
|
|
|
|
|
currentStatus.hasSync = false;
|
|
|
|
|
triggerToothAngleIsCorrect = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
currentStatus.syncLossCounter++;
|
|
|
|
|
secondaryToothCount = 0;
|
|
|
|
|
break;
|
|
|
|
@ -2918,7 +2917,7 @@ void triggerPri_Subaru67(void)
|
|
|
|
|
if(toothCurrentCount == 1) { triggerToothAngle = 55; } //Special case for tooth 1
|
|
|
|
|
else if(toothCurrentCount == 2) { triggerToothAngle = 93; } //Special case for tooth 2
|
|
|
|
|
else { triggerToothAngle = toothAngles[(toothCurrentCount-1)] - toothAngles[(toothCurrentCount-2)]; }
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//NEW IGNITION MODE
|
|
|
|
@ -3072,8 +3071,8 @@ void triggerSetup_Daihatsu(void)
|
|
|
|
|
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
triggerFilterTime = 60000000L / MAX_RPM / configPage2.nCylinders; // Minimum time required between teeth
|
|
|
|
|
triggerFilterTime = triggerFilterTime / 2; //Safety margin
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
|
|
|
|
|
MAX_STALL_TIME = (1851UL * triggerToothAngle)*4;//Minimum 90rpm. (1851uS is the time per degree at 90rpm). This uses 90rpm rather than 50rpm due to the potentially very high stall time on a 4 cylinder if we wait that long.
|
|
|
|
|
|
|
|
|
@ -3103,7 +3102,7 @@ void triggerPri_Daihatsu(void)
|
|
|
|
|
//if ( curGap >= triggerFilterTime || (currentStatus.startRevolutions == 0 )
|
|
|
|
|
{
|
|
|
|
|
toothSystemCount++;
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
if (currentStatus.hasSync == true)
|
|
|
|
|
{
|
|
|
|
@ -3233,8 +3232,8 @@ Only rising Edge is used for simplicity.The second input is ignored, as it does
|
|
|
|
|
void triggerSetup_Harley(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 0; // The number of degrees that passes from tooth to tooth, ev. 0. It alternates uneven
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
MAX_STALL_TIME = (3333UL * 60); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
if(initialisationComplete == false) { toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initial check to prevent the fuel pump just staying on all the time
|
|
|
|
|
triggerFilterTime = 1500;
|
|
|
|
@ -3250,7 +3249,7 @@ void triggerPri_Harley(void)
|
|
|
|
|
{
|
|
|
|
|
if ( READ_PRI_TRIGGER() == HIGH) // Has to be the same as in main() trigger-attach, for readability we do it this way.
|
|
|
|
|
{
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
targetGap = lastGap ; //Gap is the Time to next toothtrigger, so we know where we are
|
|
|
|
|
toothCurrentCount++;
|
|
|
|
|
if (curGap > targetGap)
|
|
|
|
@ -3379,8 +3378,8 @@ void triggerSetup_ThirtySixMinus222(void)
|
|
|
|
|
triggerToothAngle = 10; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
triggerActualTeeth = 30; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
|
|
|
|
|
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
|
|
|
|
|
toothLastMinusOneToothTime = 0;
|
|
|
|
|
toothCurrentCount = 0;
|
|
|
|
@ -3396,7 +3395,7 @@ void triggerPri_ThirtySixMinus222(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS)
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
//Begin the missing tooth detection
|
|
|
|
|
//If the time between the current tooth and the last is greater than 2x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after a gap
|
|
|
|
@ -3425,7 +3424,7 @@ void triggerPri_ThirtySixMinus222(void)
|
|
|
|
|
toothCurrentCount++;
|
|
|
|
|
toothCurrentCount++; //Accurately reflect the actual tooth count, including the skipped ones
|
|
|
|
|
}
|
|
|
|
|
triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //The tooth angle is double at this point
|
|
|
|
|
triggerFilterTime = 0; //This is used to prevent a condition where serious intermittent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -3462,7 +3461,7 @@ void triggerPri_ThirtySixMinus222(void)
|
|
|
|
|
//Filter can only be recalculated for the regular teeth, not the missing one.
|
|
|
|
|
setFilter(curGap);
|
|
|
|
|
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
toothSystemCount = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3491,11 +3490,11 @@ uint16_t getRPM_ThirtySixMinus222(void)
|
|
|
|
|
if( currentStatus.RPM < currentStatus.crankRPM)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if( (configPage2.nCylinders == 4) && (toothCurrentCount != 19) && (toothCurrentCount != 16) && (toothCurrentCount != 34) && (triggerToothAngleIsCorrect == true) )
|
|
|
|
|
if( (configPage2.nCylinders == 4) && (toothCurrentCount != 19) && (toothCurrentCount != 16) && (toothCurrentCount != 34) && (BIT_CHECK(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT)) )
|
|
|
|
|
{
|
|
|
|
|
tempRPM = crankingGetRPM(36, 360);
|
|
|
|
|
}
|
|
|
|
|
else if( (configPage2.nCylinders == 6) && (toothCurrentCount != 9) && (toothCurrentCount != 12) && (toothCurrentCount != 33) && (triggerToothAngleIsCorrect == true) )
|
|
|
|
|
else if( (configPage2.nCylinders == 6) && (toothCurrentCount != 9) && (toothCurrentCount != 12) && (toothCurrentCount != 33) && (BIT_CHECK(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT)) )
|
|
|
|
|
{
|
|
|
|
|
tempRPM = crankingGetRPM(36, 360);
|
|
|
|
|
}
|
|
|
|
@ -3561,8 +3560,8 @@ void triggerSetup_ThirtySixMinus21(void)
|
|
|
|
|
triggerToothAngle = 10; //The number of degrees that passes from tooth to tooth
|
|
|
|
|
triggerActualTeeth = 33; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt. Not Used
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
checkSyncToothCount = (configPage4.triggerTeeth) >> 1; //50% of the total teeth.
|
|
|
|
|
toothLastMinusOneToothTime = 0;
|
|
|
|
|
toothCurrentCount = 0;
|
|
|
|
@ -3578,7 +3577,7 @@ void triggerPri_ThirtySixMinus21(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS)
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
//Begin the missing tooth detection
|
|
|
|
|
//If the time between the current tooth and the last is greater than 2x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after a gap
|
|
|
|
@ -3603,7 +3602,7 @@ void triggerPri_ThirtySixMinus21(void)
|
|
|
|
|
currentStatus.hasSync = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
triggerToothAngleIsCorrect = false; //The tooth angle is double at this point
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //The tooth angle is double at this point
|
|
|
|
|
triggerFilterTime = 0; //This is used to prevent a condition where serious intermittent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -3623,7 +3622,7 @@ void triggerPri_ThirtySixMinus21(void)
|
|
|
|
|
//Filter can only be recalculated for the regular teeth, not the missing one.
|
|
|
|
|
setFilter(curGap);
|
|
|
|
|
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3651,7 +3650,7 @@ uint16_t getRPM_ThirtySixMinus21(void)
|
|
|
|
|
uint16_t tempRPM = 0;
|
|
|
|
|
if( currentStatus.RPM < currentStatus.crankRPM)
|
|
|
|
|
{
|
|
|
|
|
if( (toothCurrentCount != 20) && (triggerToothAngleIsCorrect == true) )
|
|
|
|
|
if( (toothCurrentCount != 20) && (BIT_CHECK(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT)) )
|
|
|
|
|
{
|
|
|
|
|
tempRPM = crankingGetRPM(36, 360);
|
|
|
|
|
}
|
|
|
|
@ -3694,11 +3693,11 @@ void triggerSetup_420a(void)
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * 360UL)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = 0;
|
|
|
|
|
secondaryToothCount = 0; //Initially set to 0 prior to calculating the secondary window duration
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
toothCurrentCount = 1;
|
|
|
|
|
triggerToothAngle = 20; //Is only correct for the 4 short pulses before each TDC
|
|
|
|
|
triggerToothAngleIsCorrect = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
toothSystemCount = 0;
|
|
|
|
|
MAX_STALL_TIME = (3333UL * 93); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
|
|
|
|
@ -3727,7 +3726,7 @@ void triggerPri_420a(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS)
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
if( (toothLastToothTime == 0) || (toothLastMinusOneToothTime == 0) ) { curGap = 0; }
|
|
|
|
|
|
|
|
|
@ -3744,7 +3743,7 @@ void triggerPri_420a(void)
|
|
|
|
|
//setFilter(curGap);
|
|
|
|
|
triggerFilterTime = 0;
|
|
|
|
|
|
|
|
|
|
triggerToothAngleIsCorrect = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -3880,7 +3879,7 @@ void triggerPri_Webber(void)
|
|
|
|
|
toothCurrentCount++; //Increment the tooth counter
|
|
|
|
|
if (checkSyncToothCount > 0) { checkSyncToothCount++; }
|
|
|
|
|
if ( triggerSecFilterTime <= curGap ) { triggerSecFilterTime = curGap + (curGap>>1); } //150% crank tooth
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
|
|
|
|
|
toothLastMinusOneToothTime = toothLastToothTime;
|
|
|
|
|
toothLastToothTime = curTime;
|
|
|
|
@ -3992,8 +3991,8 @@ void triggerSetup_FordST170(void)
|
|
|
|
|
|
|
|
|
|
triggerSecFilterTime = 1000000 * 60 / MAX_RPM / 8 / 2; //Cam pattern is 8-3, so 2 nearest teeth are 90 deg crank angle apart. Cam can be advanced by 60 deg, so going from fully retarded to fully advanced closes the gap to 30 deg. Zetec cam pulleys aren't keyed from factory, so I subtracted additional 10 deg to avoid filter to be too aggressive. And there you have it 720/20=36.
|
|
|
|
|
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
checkSyncToothCount = (36) >> 1; //50% of the total teeth.
|
|
|
|
|
toothLastMinusOneToothTime = 0;
|
|
|
|
|
toothCurrentCount = 0;
|
|
|
|
@ -4145,9 +4144,9 @@ void triggerSetup_DRZ400(void)
|
|
|
|
|
toothCurrentCount = 255; //Default value
|
|
|
|
|
triggerFilterTime = (1000000 / (MAX_RPM / 60 * configPage4.triggerTeeth)); //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 discarded as noise
|
|
|
|
|
triggerSecFilterTime = (1000000 / (MAX_RPM / 60 * 2)); //Same as above, but fixed at 2 teeth on the secondary input
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
triggerToothAngleIsCorrect = true; //This is always true for this pattern
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //This is always true for this pattern
|
|
|
|
|
MAX_STALL_TIME = (3333UL * triggerToothAngle); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -4190,8 +4189,8 @@ The 6 and 8-cyl cam decoder uses the amount of teeth in the two previous groups
|
|
|
|
|
|
|
|
|
|
void triggerSetup_NGC(void)
|
|
|
|
|
{
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = true;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
|
|
|
|
|
//Primary trigger
|
|
|
|
|
configPage4.triggerTeeth = 36; //The number of teeth on the wheel incl missing teeth.
|
|
|
|
@ -4254,7 +4253,7 @@ void triggerPri_NGC(void)
|
|
|
|
|
if ( curGap >= triggerFilterTime ) //Pulses should never be less than triggerFilterTime, so if they are it means a false trigger.
|
|
|
|
|
{
|
|
|
|
|
toothCurrentCount++;
|
|
|
|
|
validTrigger = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
bool isMissingTooth = false;
|
|
|
|
|
|
|
|
|
|
if ( toothLastToothTime > 0 && toothLastMinusOneToothTime > 0 ) { //Make sure we haven't enough tooth information to calculate missing tooth length
|
|
|
|
@ -4266,7 +4265,7 @@ void triggerPri_NGC(void)
|
|
|
|
|
{
|
|
|
|
|
isMissingTooth = true; //Missing tooth detected
|
|
|
|
|
triggerFilterTime = 0; //This is used to prevent a condition where serious intermittent signals (Eg someone furiously plugging the sensor wire in and out) can leave the filter in an unrecoverable state
|
|
|
|
|
triggerToothAngleIsCorrect = false; //The tooth angle is bigger at this point
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT); //The tooth angle is double at this point
|
|
|
|
|
|
|
|
|
|
// Figure out the polarity of the missing tooth by comparing how far ago the last tooth rose
|
|
|
|
|
if ((toothLastToothRisingTime - toothLastToothTime) < (curTime - toothLastToothRisingTime)) {
|
|
|
|
@ -4328,7 +4327,7 @@ void triggerPri_NGC(void)
|
|
|
|
|
{
|
|
|
|
|
//Regular (non-missing) tooth
|
|
|
|
|
setFilter(curGap);
|
|
|
|
|
triggerToothAngleIsCorrect = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -4467,7 +4466,7 @@ uint16_t getRPM_NGC(void)
|
|
|
|
|
uint16_t tempRPM = 0;
|
|
|
|
|
if( currentStatus.RPM < currentStatus.crankRPM)
|
|
|
|
|
{
|
|
|
|
|
if (triggerToothAngleIsCorrect == true) { tempRPM = crankingGetRPM(36, 360); }
|
|
|
|
|
if (BIT_CHECK(decoderState, BIT_DECODER_TOOTH_ANG_CORRECT)) { tempRPM = crankingGetRPM(36, 360); }
|
|
|
|
|
else { tempRPM = currentStatus.RPM; } //Can't do per tooth RPM if we're at any of the missing teeth as it messes the calculation
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
@ -4578,12 +4577,12 @@ Trigger is based on 'CHANGE' so we get a signal on the up and downward edges of
|
|
|
|
|
void triggerSetup_Vmax(void)
|
|
|
|
|
{
|
|
|
|
|
triggerToothAngle = 0; // The number of degrees that passes from tooth to tooth, ev. 0. It alternates uneven
|
|
|
|
|
secondDerivEnabled = false;
|
|
|
|
|
decoderIsSequential = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_2ND_DERIV);
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_IS_SEQUENTIAL);
|
|
|
|
|
MAX_STALL_TIME = (3333UL * 60); //Minimum 50rpm. (3333uS is the time per degree at 50rpm)
|
|
|
|
|
if(initialisationComplete == false) { toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
|
|
|
|
|
triggerFilterTime = 1500;
|
|
|
|
|
validTrigger = true; // We must start with a valid trigger or we cannot start measuring the lobe width. We only have a false trigger on the lobe up event when it doesn't pass the filter. Then, the lobe width will also not be beasured.
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); // We must start with a valid trigger or we cannot start measuring the lobe width. We only have a false trigger on the lobe up event when it doesn't pass the filter. Then, the lobe width will also not be beasured.
|
|
|
|
|
toothAngles[1] = 0; //tooth #1, these are the absolute tooth positions
|
|
|
|
|
toothAngles[2] = 40; //tooth #2
|
|
|
|
|
toothAngles[3] = 110; //tooth #3
|
|
|
|
@ -4606,10 +4605,10 @@ void triggerPri_Vmax(void)
|
|
|
|
|
curGap2 = curTime;
|
|
|
|
|
curGap = curTime - toothLastToothTime;
|
|
|
|
|
if ( (curGap >= triggerFilterTime) ){
|
|
|
|
|
validTrigger = true;
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
if (toothCurrentCount > 0) // We have sync based on the tooth width.
|
|
|
|
|
{
|
|
|
|
|
validTrigger = true; //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being a valid trigger (ie that it passed filters)
|
|
|
|
|
if (toothCurrentCount==1)
|
|
|
|
|
{
|
|
|
|
|
secondaryToothCount = 1;
|
|
|
|
@ -4662,10 +4661,11 @@ void triggerPri_Vmax(void)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
validTrigger = false;
|
|
|
|
|
BIT_CLEAR(decoderState, BIT_DECODER_VALID_TRIGGER); //Flag this pulse as being an invalid trigger
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (validTrigger == true){// Inverted due to vr conditioner. So this is the falling lobe. We only process if there was a valid trigger.
|
|
|
|
|
else if( BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER) ) // Inverted due to vr conditioner. So this is the falling lobe. We only process if there was a valid trigger.
|
|
|
|
|
{
|
|
|
|
|
curGap3 = curTime - curGap2;
|
|
|
|
|
if (curGap3 > (lastGap * 2)){// Small lobe is 5 degrees, big lobe is 45 degrees. So this should be the wide lobe.
|
|
|
|
|
if (toothCurrentCount == 0 || toothCurrentCount == 6){//Wide should be seen with toothCurrentCount = 0, when there is no sync yet, or toothCurrentCount = 6 when we have done a full revolution.
|
|
|
|
@ -4686,8 +4686,9 @@ void triggerPri_Vmax(void)
|
|
|
|
|
lastGap = curGap3;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (validTrigger == false){
|
|
|
|
|
validTrigger = true;//We reset this every time to ensure we only filter when needed.
|
|
|
|
|
else if( BIT_CHECK(decoderState, BIT_DECODER_VALID_TRIGGER) == false)
|
|
|
|
|
{
|
|
|
|
|
BIT_SET(decoderState, BIT_DECODER_VALID_TRIGGER); //We reset this every time to ensure we only filter when needed.
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|