4G63 decoder improvements (+MISRA work)

This commit is contained in:
Josh Stewart 2017-07-24 14:18:25 +10:00
parent be98d2d0d3
commit 11294364bc
2 changed files with 66 additions and 14 deletions

View File

@ -15,6 +15,8 @@ static inline void addToothLogEntry(unsigned long);
static inline uint16_t stdGetRPM();
static inline void setFilter(unsigned long);
static inline int crankingGetRPM(byte);
static inline void doPerToothTiming(uint16_t crankAngle);
void triggerSetup_missingTooth();
void triggerPri_missingTooth();
void triggerSec_missingTooth();

View File

@ -94,11 +94,24 @@ static inline int crankingGetRPM(byte totalTeeth)
revolutionTime = (toothLastToothTime - toothLastMinusOneToothTime) * totalTeeth;
interrupts();
tempRPM = (US_IN_MINUTE / revolutionTime);
if( tempRPM >= (configPage2.crankRPM * 400) ) { tempRPM = currentStatus.RPM; } //Sanity check. This can prevent spiking caused by noise on individual teeth. The new RPM should never be above 4x the cranking setting value (Remembering that this function is only called is the current RPM is less than the cranking setting)
if( tempRPM >= MAX_RPM ) { tempRPM = currentStatus.RPM; } //Sanity check. This can prevent spiking caused by noise on individual teeth. The new RPM should never be above 4x the cranking setting value (Remembering that this function is only called is the current RPM is less than the cranking setting)
}
return tempRPM;
}
/*
On decoders that are enabled for per tooth based timing adjustments, this function performs the timer compare changes on the schedules themselves
For each ignition channel, a check is made whether we're at the relevant tooth and whether that ignition schedule is currently running
Only if both these conditions are met will the schedule be updated with the latest timing information.
*/
static inline void doPerToothTiming(uint16_t crankAngle)
{
if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) ) { IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition2EndTooth) && (ignitionSchedule2.Status == RUNNING) ) { IGN2_COMPARE = IGN2_COUNTER + uS_TO_TIMER_COMPARE( (ignition2EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition3EndTooth) && (ignitionSchedule3.Status == RUNNING) ) { IGN3_COMPARE = IGN3_COUNTER + uS_TO_TIMER_COMPARE( (ignition3EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition4EndTooth) && (ignitionSchedule4.Status == RUNNING) ) { IGN4_COMPARE = IGN4_COUNTER + uS_TO_TIMER_COMPARE( (ignition4EndAngle - crankAngle) * timePerDegree ); }
}
/*
Name: Missing tooth wheel
Desc: A multi-tooth wheel with one of more 'missing' teeth. The first tooth after the missing one is considered number 1 and isthe basis for the trigger angle
@ -165,15 +178,7 @@ void triggerPri_missingTooth()
if(configPage1.perToothIgn == true)
{
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) )
{
IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle) * timePerDegree );
//IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle)*my_timePerDegree - micros_compensation );
}
else if ( (toothCurrentCount == ignition2EndTooth) && (ignitionSchedule2.Status == RUNNING) ) { IGN2_COMPARE = IGN2_COUNTER + uS_TO_TIMER_COMPARE( (ignition2EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition3EndTooth) && (ignitionSchedule3.Status == RUNNING) ) { IGN3_COMPARE = IGN3_COUNTER + uS_TO_TIMER_COMPARE( (ignition3EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition4EndTooth) && (ignitionSchedule4.Status == RUNNING) ) { IGN4_COMPARE = IGN4_COUNTER + uS_TO_TIMER_COMPARE( (ignition4EndAngle - crankAngle) * timePerDegree ); }
doPerToothTiming(crankAngle);
}
}
}
@ -264,6 +269,7 @@ Note: There can be no missing teeth on the primary wheel
void triggerSetup_DualWheel()
{
triggerToothAngle = 360 / configPage2.triggerTeeth; //The number of degrees that passes from tooth to tooth
if(configPage2.TrigSpeed == 1) { triggerToothAngle = 720 / configPage2.triggerTeeth; } //Account for cam speed missing tooth
toothCurrentCount = 255; //Default value
triggerFilterTime = (int)(1000000 / (MAX_RPM / 60 * configPage2.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 disgarded 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)
@ -298,6 +304,13 @@ void triggerPri_DualWheel()
setFilter(curGap); //Recalc the new filter value
}
//EXPERIMENTAL!
if(configPage1.perToothIgn == true)
{
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
doPerToothTiming(crankAngle);
}
} //TRigger filter
@ -371,7 +384,25 @@ int getCrankAngle_DualWheel(int timePerDegree)
void triggerSetEndTeeth_DualWheel()
{
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
if(ignition1EndTooth > configPage2.triggerTeeth) { ignition1EndTooth -= configPage2.triggerTeeth; }
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage2.triggerTeeth; }
if(ignition1EndTooth > triggerActualTeeth) { ignition1EndTooth = triggerActualTeeth; }
ignition2EndTooth = ( (ignition2EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
if(ignition2EndTooth > configPage2.triggerTeeth) { ignition2EndTooth -= configPage2.triggerTeeth; }
if(ignition2EndTooth <= 0) { ignition2EndTooth -= configPage2.triggerTeeth; }
if(ignition2EndTooth > triggerActualTeeth) { ignition2EndTooth = triggerActualTeeth; }
ignition3EndTooth = ( (ignition3EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
if(ignition3EndTooth > configPage2.triggerTeeth) { ignition3EndTooth -= configPage2.triggerTeeth; }
if(ignition3EndTooth <= 0) { ignition3EndTooth -= configPage2.triggerTeeth; }
if(ignition3EndTooth > triggerActualTeeth) { ignition3EndTooth = triggerActualTeeth; }
ignition4EndTooth = ( (ignition4EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
if(ignition4EndTooth > configPage2.triggerTeeth) { ignition4EndTooth -= configPage2.triggerTeeth; }
if(ignition4EndTooth <= 0) { ignition4EndTooth -= configPage2.triggerTeeth; }
if(ignition4EndTooth > triggerActualTeeth) { ignition4EndTooth = triggerActualTeeth; }
}
@ -387,8 +418,10 @@ void triggerSetup_BasicDistributor()
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
triggerFilterTime = 60000000L / MAX_RPM / configPage1.nCylinders; // Minimum time required between teeth
triggerFilterTime = triggerFilterTime / 2; //Safety margin
triggerFilterTime = 0;
secondDerivEnabled = false;
decoderIsSequential = false;
toothCurrentCount = 0; //Default value
if(configPage1.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).
@ -399,7 +432,7 @@ void triggerPri_BasicDistributor()
{
curTime = micros();
curGap = curTime - toothLastToothTime;
if ( curGap >= triggerFilterTime )
if ( (curGap >= triggerFilterTime) )
{
if( (toothCurrentCount == triggerActualTeeth) || (currentStatus.hasSync == false) ) //Check if we're back to the beginning of a revolution
{
@ -425,6 +458,20 @@ void triggerPri_BasicDistributor()
endCoil4Charge();
}
if(configPage1.perToothIgn == true)
{
uint16_t crankAngle = ( (toothCurrentCount-1) * triggerToothAngle ) + configPage2.triggerAngle;
if ( (toothCurrentCount == ignition1EndTooth) && (ignitionSchedule1.Status == RUNNING) )
{
IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle) * timePerDegree );
//IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE( (ignition1EndAngle - crankAngle)*my_timePerDegree - micros_compensation );
}
else if ( (toothCurrentCount == ignition2EndTooth) && (ignitionSchedule2.Status == RUNNING) ) { IGN2_COMPARE = IGN2_COUNTER + uS_TO_TIMER_COMPARE( (ignition2EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition3EndTooth) && (ignitionSchedule3.Status == RUNNING) ) { IGN3_COMPARE = IGN3_COUNTER + uS_TO_TIMER_COMPARE( (ignition3EndAngle - crankAngle) * timePerDegree ); }
else if ( (toothCurrentCount == ignition4EndTooth) && (ignitionSchedule4.Status == RUNNING) ) { IGN4_COMPARE = IGN4_COUNTER + uS_TO_TIMER_COMPARE( (ignition4EndAngle - crankAngle) * timePerDegree ); }
}
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
} //Trigger filter
@ -470,7 +517,10 @@ int getCrankAngle_BasicDistributor(int timePerDegree)
void triggerSetEndTeeth_BasicDistributor()
{
ignition1EndTooth = ( (ignition1EndAngle - configPage2.triggerAngle) / triggerToothAngle ) - 1;
if(ignition1EndTooth > configPage2.triggerTeeth) { ignition1EndTooth -= configPage2.triggerTeeth; }
if(ignition1EndTooth <= 0) { ignition1EndTooth -= configPage2.triggerTeeth; }
if(ignition1EndTooth > triggerActualTeeth) { ignition1EndTooth = triggerActualTeeth; }
}
/* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -631,7 +681,7 @@ void triggerPri_4G63()
{
curTime = micros();
curGap = curTime - toothLastToothTime;
if ( curGap >= triggerFilterTime )
if ( (curGap >= triggerFilterTime) || (currentStatus.startRevolutions == 0) )
{
addToothLogEntry(curGap);
triggerFilterTime = curGap >> 2; //This only applies during non-sync conditions. If there is sync then triggerFilterTime gets changed again below with a better value.
@ -714,7 +764,7 @@ void triggerSec_4G63()
curTime2 = micros();
curGap2 = curTime2 - toothLastSecToothTime;
if ( curGap2 >= triggerSecFilterTime )
if ( (curGap2 >= triggerSecFilterTime) || (currentStatus.startRevolutions == 0) )
{
toothLastSecToothTime = curTime2;