Fix for rare overflow issue that could cause an incorrect pulse width at very low RPM (<200rpm)
This commit is contained in:
parent
33b85f3b9d
commit
dfa48ed250
|
@ -1,4 +1,4 @@
|
|||
;-------------------------------------------------------------------------------
|
||||
;-------------------------------------------------------------------------------
|
||||
#unset CAN_COMMANDS
|
||||
#unset enablehardware_test
|
||||
|
||||
|
|
|
@ -412,8 +412,8 @@ struct Schedule {
|
|||
void (*StartCallback)(); //Start Callback function for schedule
|
||||
void (*EndCallback)(); //Start Callback function for schedule
|
||||
volatile unsigned long startTime; //The system time (in uS) that the schedule started
|
||||
volatile unsigned int startCompare; //The counter value of the timer when this will start
|
||||
volatile unsigned int endCompare;
|
||||
volatile uint16_t startCompare; //The counter value of the timer when this will start
|
||||
volatile uint16_t endCompare;
|
||||
|
||||
unsigned int nextStartCompare;
|
||||
unsigned int nextEndCompare;
|
||||
|
|
|
@ -290,13 +290,13 @@ void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, uns
|
|||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
if (timeout > MAX_TIMER_PERIOD) { timeout_timer_compare = uS_TO_TIMER_COMPARE( (MAX_TIMER_PERIOD - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
noInterrupts();
|
||||
targetSchedule->startCompare = *targetSchedule->counter + timeout_timer_compare;
|
||||
targetSchedule->endCompare = targetSchedule->startCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->endCompare = targetSchedule->startCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
targetSchedule->Status = PENDING; //Turn this schedule on
|
||||
targetSchedule->schedulesSet++; //Increment the number of times this schedule has been set
|
||||
|
||||
|
@ -308,8 +308,8 @@ void setFuelSchedule(struct Schedule *targetSchedule, unsigned long timeout, uns
|
|||
{
|
||||
//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
|
||||
targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
targetSchedule->nextEndCompare = targetSchedule->nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE(timeout);
|
||||
targetSchedule->nextEndCompare = targetSchedule->nextStartCompare + uS_TO_TIMER_COMPARE(duration);
|
||||
targetSchedule->hasNextSchedule = true;
|
||||
}
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ void setFuelSchedule1(unsigned long timeout, unsigned long duration)
|
|||
|
||||
//Need to check that the timeout doesn't exceed the overflow
|
||||
uint16_t timeout_timer_compare;
|
||||
if (timeout > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
if ((timeout+duration) > MAX_TIMER_PERIOD_SLOW) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW( (MAX_TIMER_PERIOD_SLOW - 1 - duration) ); } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
|
||||
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW(timeout); } //Normal case
|
||||
|
||||
//The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupt fires before the state is fully set
|
||||
|
@ -350,7 +350,8 @@ void setFuelSchedule1(unsigned long timeout, unsigned long duration)
|
|||
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
|
||||
fuelSchedule1.nextStartCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW(timeout);
|
||||
fuelSchedule1.nextEndCompare = fuelSchedule1.nextStartCompare + uS_TO_TIMER_COMPARE_SLOW(duration);
|
||||
fuelSchedule1.hasNextSchedule = true;
|
||||
fuelSchedule1.duration = duration;
|
||||
fuelSchedule1.hasNextSchedule = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,7 +767,7 @@ static inline void fuelSchedule1Interrupt() //Most ARM chips can simply call a f
|
|||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector1and4(); }
|
||||
else { openInjector1(); }
|
||||
fuelSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL1_COMPARE = fuelSchedule1.endCompare;
|
||||
FUEL1_COMPARE = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule1.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule1.Status == RUNNING)
|
||||
{
|
||||
|
@ -803,7 +804,7 @@ static inline void fuelSchedule2Interrupt() //Most ARM chips can simply call a f
|
|||
if (configPage2.injLayout == INJ_SEMISEQUENTIAL) { openInjector2and3(); }
|
||||
else { openInjector2(); }
|
||||
fuelSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL2_COMPARE = fuelSchedule2.endCompare;
|
||||
FUEL2_COMPARE = FUEL2_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule2.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule2.Status == RUNNING)
|
||||
{
|
||||
|
@ -839,7 +840,7 @@ static inline void fuelSchedule3Interrupt() //Most ARM chips can simply call a f
|
|||
if(channel5InjEnabled) { openInjector3and5(); }
|
||||
else { openInjector3(); }
|
||||
fuelSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL3_COMPARE = fuelSchedule3.endCompare;
|
||||
FUEL3_COMPARE = FUEL3_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule3.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule3.Status == RUNNING)
|
||||
{
|
||||
|
@ -874,7 +875,7 @@ static inline void fuelSchedule4Interrupt() //Most ARM chips can simply call a f
|
|||
//fuelSchedule4.StartCallback();
|
||||
openInjector4();
|
||||
fuelSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
FUEL4_COMPARE = fuelSchedule4.endCompare;
|
||||
FUEL4_COMPARE = FUEL4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(fuelSchedule4.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (fuelSchedule4.Status == RUNNING)
|
||||
{
|
||||
|
@ -942,11 +943,12 @@ static inline void ignitionSchedule1Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule1.StartCallback();
|
||||
ignitionSchedule1.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule1.startTime = micros();
|
||||
IGN1_COMPARE = ignitionSchedule1.endCompare;
|
||||
//IGN1_COMPARE = ignitionSchedule1.endCompare;
|
||||
IGN1_COMPARE = IGN1_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule1.duration); //Doing this here prevents a potential overflow on restarts
|
||||
//This code is all to do with the staged ignition timing testing. That is, calling this interrupt slightly before the true ignition point and recalculating the end time for more accuracy
|
||||
//IGN1_COMPARE = ignitionSchedule1.endCompare - 50;
|
||||
//ignitionSchedule1.Status = STAGED;
|
||||
}
|
||||
}
|
||||
else if (ignitionSchedule1.Status == STAGED)
|
||||
{
|
||||
int16_t crankAngle = getCrankAngle(timePerDegree);
|
||||
|
@ -980,7 +982,7 @@ static inline void ignitionSchedule2Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule2.StartCallback();
|
||||
ignitionSchedule2.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule2.startTime = micros();
|
||||
IGN2_COMPARE = ignitionSchedule2.endCompare; //OCR5B = TCNT5 + (ignitionSchedule2.duration >> 2);
|
||||
IGN2_COMPARE = IGN2_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule2.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule2.Status == RUNNING)
|
||||
{
|
||||
|
@ -1003,7 +1005,7 @@ static inline void ignitionSchedule3Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule3.StartCallback();
|
||||
ignitionSchedule3.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule3.startTime = micros();
|
||||
IGN3_COMPARE = ignitionSchedule3.endCompare; //OCR5C = TCNT5 + (ignitionSchedule3.duration >> 2);
|
||||
IGN3_COMPARE = IGN3_COUNTER + uS_TO_TIMER_COMPARE(ignitionSchedule3.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule3.Status == RUNNING)
|
||||
{
|
||||
|
@ -1036,7 +1038,7 @@ static inline void ignitionSchedule4Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule4.StartCallback();
|
||||
ignitionSchedule4.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule4.startTime = micros();
|
||||
IGN4_COMPARE = ignitionSchedule4.endCompare;
|
||||
IGN4_COMPARE = IGN4_COUNTER + uS_TO_TIMER_COMPARE_SLOW(ignitionSchedule4.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule4.Status == RUNNING)
|
||||
{
|
||||
|
@ -1069,7 +1071,7 @@ static inline void ignitionSchedule5Interrupt() //Most ARM chips can simply call
|
|||
ignitionSchedule5.StartCallback();
|
||||
ignitionSchedule5.Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
|
||||
ignitionSchedule5.startTime = micros();
|
||||
IGN5_COMPARE = ignitionSchedule5.endCompare;
|
||||
IGN5_COMPARE = IGN5_COUNTER + uS_TO_TIMER_COMPARE_SLOW(ignitionSchedule5.duration); //Doing this here prevents a potential overflow on restarts
|
||||
}
|
||||
else if (ignitionSchedule5.Status == RUNNING)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue