Mostly complete 5 cylinder scheduling

This commit is contained in:
Josh Stewart 2016-07-27 19:31:38 +10:00
parent 0490cdcdb1
commit 9111c5ec86
3 changed files with 200 additions and 107 deletions

View File

@ -63,10 +63,9 @@ struct Schedule {
unsigned int endCompare;
};
struct timerCompareManager {
volatile Schedule *currentSchedule;
volatile Schedule *nextSchedule;
};
Schedule *timer3Aqueue[4];
Schedule *timer3Bqueue[4];
Schedule *timer3Cqueue[4];
Schedule fuelSchedule1;
Schedule fuelSchedule2;
@ -85,8 +84,51 @@ Schedule ignitionSchedule6;
Schedule ignitionSchedule7;
Schedule ignitionSchedule8;
timerCompareManager timer3compareA;
timerCompareManager timer3compareB;
timerCompareManager timer3compareC;
Schedule nullSchedule; //This is placed at the end of the queue. It's status will always be set to OFF and hence will never perform any action within an ISR
static inline unsigned int setQueue(Schedule *queue[], Schedule *schedule1, Schedule *schedule2, unsigned int CNT)
{
//Create an array of all the upcoming targets, relative to the current count on the timer
unsigned int tmpQueue[4];
tmpQueue[0] = schedule1->startCompare - CNT;
tmpQueue[1] = schedule1->endCompare - CNT;
tmpQueue[2] = schedule2->startCompare - CNT;
tmpQueue[3] = schedule2->endCompare - CNT;
//Set the initial queue state. This order matches the tmpQueue order
queue[0] = schedule1;
queue[1] = schedule1;
queue[2] = schedule2;
queue[3] = schedule2;
//Sort the queues. Both queues are kept in sync.
//This implementes a sorting networking based on the Bose-Nelson swap algorithm
//See:
#define SWAP(x,y) if(tmpQueue[y] < tmpQueue[x]) { unsigned int tmp = tmpQueue[x]; tmpQueue[x] = tmpQueue[y]; tmpQueue[y] = tmp; Schedule *tmpS = queue[x]; queue[x] = queue[y]; queue[y] = tmpS; }
//SWAP(0, 1); //Likely not needed
//SWAP(2, 3); //Likely not needed
SWAP(1, 3);
SWAP(1, 2);
//Return the next compare time in the queue
return tmpQueue[0] + CNT; //Return the
}
/*
* Moves all the Schedules in a queue forward one position.
* The current item (0) is discarded
* The final queue slot is set to nullSchedule to indicate that no action should be taken
*/
static inline unsigned int popQueue(Schedule *queue[])
{
queue[0] = queue[1];
queue[1] = queue[2];
queue[2] = queue[3];
queue[3] = &nullSchedule;
if( queue[0]->Status == PENDING ) { return queue[0]->startCompare; }
else { return queue[0]->endCompare; }
}
#endif // SCHEDULER_H

View File

@ -9,6 +9,8 @@ A full copy of the license may be found in the projects root directory
void initialiseSchedulers()
{
nullSchedule.Status = OFF;
// Much help in this from http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html
//Fuel Schedules, which uses timer 3
TCCR3B = 0x00; //Disable Timer3 while we set it up
@ -63,40 +65,53 @@ timeout: The number of uS in the future that the startCallback should be trigger
duration: The number of uS after startCallback is called before endCallback is called
endCallback: This function is called once the duration time has been reached
*/
volatile bool flip = 0;
void setFuelSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
if(fuelSchedule1.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
//unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
fuelSchedule1.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule1.endCompare = fuelSchedule1.startCompare + (duration >> 4);
OCR3A = fuelSchedule1.startCompare;
fuelSchedule1.duration = duration;
fuelSchedule1.StartCallback = startCallback; //Name the start callback function
fuelSchedule1.EndCallback = endCallback; //Name the end callback function
fuelSchedule1.Status = PENDING; //Turn this schedule on
timer3compareA.currentSchedule = &fuelSchedule1;
fuelSchedule1.schedulesSet++; //Increment the number of times this schedule has been set
TIMSK3 |= (1 << OCIE3A); //Turn on the C compare unit (ie turn on the interrupt)
fuelSchedule1.duration = duration;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
* We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
* As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
* unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts();
fuelSchedule1.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule1.endCompare = fuelSchedule1.startCompare + (duration >> 4);
fuelSchedule1.Status = PENDING; //Turn this schedule on
fuelSchedule1.schedulesSet++; //Increment the number of times this schedule has been set
if(channel5InjEnabled) { OCR3A = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, TCNT3); } //Schedule 1 shares a timer with schedule 5
else { timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1; OCR3A = fuelSchedule1.startCompare; }
interrupts();
TIMSK3 |= (1 << OCIE3A); //Turn on the A compare unit (ie turn on the interrupt)
}
void setFuelSchedule2(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
if(fuelSchedule2.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
//unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
fuelSchedule2.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule2.endCompare = fuelSchedule2.startCompare + (duration >> 4);
OCR3B = fuelSchedule2.startCompare; //Use the B copmare unit of timer 3
fuelSchedule2.duration = duration;
fuelSchedule2.StartCallback = startCallback; //Name the start callback function
fuelSchedule2.EndCallback = endCallback; //Name the end callback function
fuelSchedule2.Status = PENDING; //Turn this schedule on
fuelSchedule2.schedulesSet++; //Increment the number of times this schedule has been set
TIMSK3 |= (1 << OCIE3B); //Turn on the B compare unit (ie turn on the interrupt)
fuelSchedule2.duration = duration;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
* We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
* As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
* unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts();
fuelSchedule2.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule2.endCompare = fuelSchedule2.startCompare + (duration >> 4);
OCR3B = fuelSchedule2.startCompare; //Use the B copmare unit of timer 3
fuelSchedule2.Status = PENDING; //Turn this schedule on
fuelSchedule2.schedulesSet++; //Increment the number of times this schedule has been set
interrupts();
TIMSK3 |= (1 << OCIE3B); //Turn on the B compare unit (ie turn on the interrupt)
}
void setFuelSchedule3(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
@ -138,20 +153,22 @@ void setFuelSchedule5(void (*startCallback)(), unsigned long timeout, unsigned l
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
fuelSchedule5.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule5.endCompare = fuelSchedule5.startCompare + (duration >> 4);
if(fuelSchedule5.startCompare < OCR3A)
{
OCR3A = fuelSchedule5.startCompare;
timer3compareA.currentSchedule = &fuelSchedule5;
}
fuelSchedule5.duration = duration;
//unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
fuelSchedule5.StartCallback = startCallback; //Name the start callback function
fuelSchedule5.EndCallback = endCallback; //Name the end callback function
fuelSchedule5.duration = duration;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
*/
noInterrupts();
fuelSchedule5.startCompare = TCNT3 + (timeout >> 4); //As above, but with bit shift instead of / 16
fuelSchedule5.endCompare = fuelSchedule5.startCompare + (duration >> 4);
fuelSchedule5.Status = PENDING; //Turn this schedule on
TIMSK3 |= (1 << OCIE3A); //Turn on the C compare unit (ie turn on the interrupt)
fuelSchedule5.schedulesSet++; //Increment the number of times this schedule has been set
OCR3A = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, TCNT3); //Schedule 1 shares a timer with schedule 5
interrupts();
TIMSK3 |= (1 << OCIE3A); //Turn on the A compare unit (ie turn on the interrupt)
}
//Ignition schedulers use Timer 5
void setIgnitionSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
@ -214,6 +231,7 @@ void setIgnitionSchedule4(void (*startCallback)(), unsigned long timeout, unsign
}
void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
{
return;
if(ignitionSchedule1.Status == RUNNING) { return; } //Check that we're not already part way through a schedule
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
@ -227,41 +245,30 @@ void setIgnitionSchedule5(void (*startCallback)(), unsigned long timeout, unsign
TIMSK5 |= (1 << OCIE5A); //Turn on the A compare unit (ie turn on the interrupt)
}
/*******************************************************************************************************************************************************************************************************/
//This function (All 8 ISR functions that are below) gets called when either the start time or the duration time are reached
//This calls the relevant callback function (startCallback or endCallback) depending on the status of the schedule.
//If the startCallback function is called, we put the scheduler into RUNNING state
//Timer3A (fuel schedule 1) Compare Vector
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER3_COMPA_vect, ISR_NOBLOCK) //fuelSchedules 1 and 5
#else
void timer3compareAinterrupt() //Most ARM chips can simply call a function
#endif
{
if (timer3compareA.currentSchedule == 0) { return; } //Safety check
if (timer3compareA.currentSchedule->Status == PENDING) //Check to see if this schedule is turn on
if (timer3Aqueue[0]->Status == OFF) { TIMSK3 &= ~(1 << OCIE3A); return; } //Safety check. Turn off this output compare unit and return without performing any action
if (timer3Aqueue[0]->Status == PENDING) //Check to see if this schedule is turn on
{
timer3compareA.currentSchedule->StartCallback();
timer3compareA.currentSchedule->Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
OCR3A = timer3compareA.currentSchedule->endCompare;
//timer3compareA.currentSchedule = timer3compareA.nextSchedule;
//timer3compareA.nextSchedule = 0;
timer3Aqueue[0]->StartCallback();
timer3Aqueue[0]->Status = RUNNING; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
OCR3A = popQueue(timer3Aqueue);
}
else if (fuelSchedule1.Status == RUNNING)
else if (timer3Aqueue[0]->Status == RUNNING)
{
fuelSchedule1.EndCallback();
fuelSchedule1.Status = OFF; //Turn off the schedule
fuelSchedule1.schedulesSet = 0;
TIMSK3 &= ~(1 << OCIE3A); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
timer3Aqueue[0]->EndCallback();
timer3Aqueue[0]->Status = OFF; //Turn off the schedule
timer3Aqueue[0]->schedulesSet = 0;
OCR3A = popQueue(timer3Aqueue);
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER3_COMPB_vect, ISR_NOBLOCK) //fuelSchedule2
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
void timer3compareBinterrupt() //Most ARM chips can simply call a function
#endif
{
if (fuelSchedule2.Status == PENDING) //Check to see if this schedule is turn on
{
@ -277,6 +284,7 @@ void timer3compareBinterrupt() //Most ARM chips can simply call a function
TIMSK3 &= ~(1 << OCIE3B); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER3_COMPC_vect, ISR_NOBLOCK) //fuelSchedule3
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
@ -297,6 +305,7 @@ void timer3compareCinterrupt() //Most ARM chips can simply call a function
TIMSK3 &= ~(1 << OCIE3C); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER4_COMPB_vect, ISR_NOBLOCK) //fuelSchedule4
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
@ -317,6 +326,7 @@ void timer4compareBinterrupt() //Most ARM chips can simply call a function
TIMSK4 &= ~(1 << OCIE4B); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER5_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule1
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
@ -340,6 +350,7 @@ void timer5compareAinterrupt() //Most ARM chips can simply call a function
TIMSK5 &= ~(1 << OCIE5A); //Turn off this output compare unit
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER5_COMPB_vect, ISR_NOBLOCK) //ignitionSchedule2
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
@ -363,6 +374,7 @@ void timer5compareBinterrupt() //Most ARM chips can simply call a function
TIMSK5 &= ~(1 << OCIE5B); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER5_COMPC_vect, ISR_NOBLOCK) //ignitionSchedule3
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)
@ -386,6 +398,7 @@ void timer5compareCinterrupt() //Most ARM chips can simply call a function
TIMSK5 &= ~(1 << OCIE5C); //Turn off this output compare unit (This simply writes 0 to the OCIE3A bit of TIMSK3)
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER4_COMPA_vect, ISR_NOBLOCK) //ignitionSchedule4
#elif defined (CORE_TEENSY) && defined (__MK20DX256__)

View File

@ -825,7 +825,7 @@ void loop()
readIAT();
readO2();
readBat();
vvtControl();
boostControl(); //Most boost tends to run at about 30Hz, so placing it here ensures a new target time is fetched frequently enough
idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient.
@ -976,6 +976,17 @@ void loop()
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;}
break;
//5 cylinders
case 5:
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
if(injector2StartAngle > CRANK_ANGLE_MAX) {injector2StartAngle -= CRANK_ANGLE_MAX;}
injector3StartAngle = (configPage1.inj3Ang + channel3InjDegrees - ( PWdivTimerPerDegree ));
if(injector3StartAngle > CRANK_ANGLE_MAX) {injector3StartAngle -= CRANK_ANGLE_MAX;}
injector4StartAngle = (configPage1.inj4Ang + channel4InjDegrees - ( PWdivTimerPerDegree ));
if(injector4StartAngle > CRANK_ANGLE_MAX) {injector4StartAngle -= CRANK_ANGLE_MAX;}
injector5StartAngle = (configPage1.inj1Ang + channel5InjDegrees - ( PWdivTimerPerDegree ));
if(injector5StartAngle > CRANK_ANGLE_MAX) {injector5StartAngle -= CRANK_ANGLE_MAX;}
break;
//6 cylinders
case 6:
injector2StartAngle = (configPage1.inj2Ang + channel2InjDegrees - ( PWdivTimerPerDegree ));
@ -1105,57 +1116,83 @@ void loop()
| This will very likely need to be rewritten when sequential is enabled
|------------------------------------------------------------------------------------------
*/
tempCrankAngle = crankAngle - channel2InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector2StartAngle - channel2InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule2.schedulesSet == 0) { tempStartAngle += 360; }
if ( (tempStartAngle > tempCrankAngle) && channel2InjEnabled)
{
if (configPage1.injLayout == 1)
{
setFuelSchedule2(openInjector2and3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector2and3
);
if(channel2InjEnabled)
{
tempCrankAngle = crankAngle - channel2InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector2StartAngle - channel2InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule2.schedulesSet == 0) { tempStartAngle += 360; }
if ( tempStartAngle > tempCrankAngle )
{
if (configPage1.injLayout == 1)
{
setFuelSchedule2(openInjector2and3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector2and3
);
}
else
{
setFuelSchedule2(openInjector2,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector2
);
}
}
else
{
setFuelSchedule2(openInjector2,
}
if(channel3InjEnabled)
{
tempCrankAngle = crankAngle - channel3InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector3StartAngle - channel3InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule3.schedulesSet == 0) { tempStartAngle += 360; }
if ( tempStartAngle > tempCrankAngle )
{
setFuelSchedule3(openInjector3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector2
closeInjector3
);
}
}
tempCrankAngle = crankAngle - channel3InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector3StartAngle - channel3InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule3.schedulesSet == 0) { tempStartAngle += 360; }
if ( (tempStartAngle > tempCrankAngle) && channel3InjEnabled)
{
setFuelSchedule3(openInjector3,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector3
);
if(channel4InjEnabled)
{
tempCrankAngle = crankAngle - channel4InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector4StartAngle - channel4InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule4.schedulesSet == 0) { tempStartAngle += 360; }
if ( tempStartAngle > tempCrankAngle )
{
setFuelSchedule4(openInjector4,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector4
);
}
}
tempCrankAngle = crankAngle - channel4InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector4StartAngle - channel4InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule4.schedulesSet == 0) { tempStartAngle += 360; }
if ( (tempStartAngle > tempCrankAngle) && channel4InjEnabled)
{
setFuelSchedule4(openInjector4,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector4
);
//if(channel5InjEnabled)
{
tempCrankAngle = crankAngle - channel5InjDegrees;
if( tempCrankAngle < 0) { tempCrankAngle += CRANK_ANGLE_MAX; }
tempStartAngle = injector5StartAngle - channel5InjDegrees;
if ( tempStartAngle < 0) { tempStartAngle += CRANK_ANGLE_MAX; }
if (tempStartAngle <= tempCrankAngle && fuelSchedule5.schedulesSet == 0) { tempStartAngle += 360; }
if ( tempStartAngle > tempCrankAngle )
{
setFuelSchedule5(openInjector5,
((unsigned long)(tempStartAngle - tempCrankAngle) * (unsigned long)timePerDegree),
(unsigned long)currentStatus.PW,
closeInjector5
);
}
}
}
//***********************************************************************************************
@ -1171,6 +1208,7 @@ void loop()
if(ignitionOn && !currentStatus.launchingHard && !BIT_CHECK(currentStatus.spark, BIT_SPARK_BOOSTCUT) && !BIT_CHECK(currentStatus.spark, BIT_SPARK_HRDLIM))
{
//if ( (ignition1StartAngle > crankAngle))// && ign1LastRev != startRevolutions)
//if ((ignition1StartAngle > crankAngle) == 0)
//if ((ignition1StartAngle < crankAngle))