2015-05-28 16:49:44 -07:00
/*
Speeduino - Simple engine management for the Arduino Mega 2560 platform
Copyright ( C ) Josh Stewart
A full copy of the license may be found in the projects root directory
*/
2021-06-21 22:30:52 -07:00
/** @file
* Injector and Ignition ( on / off ) scheduling ( functions ) .
* There is usually 8 functions for cylinders 1 - 8 with same naming pattern .
*
* # # Scheduling structures
*
* Structures @ ref FuelSchedule and @ ref Schedule describe ( from scheduler . h ) describe the scheduling info for Fuel and Ignition respectively .
* They contain duration , current activity status , start timing , end timing , callbacks to carry out action , etc .
*
* # # Scheduling Functions
*
* For Injection :
* - setFuelSchedule * ( tout , dur ) - * * Setup * * schedule for ( next ) injection on the channel
* - inj * StartFunction ( ) - Execute * * start * * of injection ( Interrupt handler )
* - inj * EndFunction ( ) - Execute * * end * * of injection ( interrupt handler )
*
* For Ignition ( has more complex schedule setup ) :
* - setIgnitionSchedule * ( cb_st , tout , dur , cb_end ) - * * Setup * * schedule for ( next ) ignition on the channel
* - ign * StartFunction ( ) - Execute * * start * * of ignition ( Interrupt handler )
* - ign * EndFunction ( ) - Execute * * end * * of ignition ( Interrupt handler )
*/
2015-02-14 09:04:00 -08:00
# include "globals.h"
2018-08-13 19:46:39 -07:00
# include "scheduler.h"
# include "scheduledIO.h"
2021-11-11 20:11:42 -08:00
# include "timers.h"
2023-04-26 21:43:04 -07:00
# include "schedule_calcs.h"
2018-08-13 19:46:39 -07:00
2020-01-29 21:17:20 -08:00
FuelSchedule fuelSchedule1 ;
FuelSchedule fuelSchedule2 ;
FuelSchedule fuelSchedule3 ;
FuelSchedule fuelSchedule4 ;
FuelSchedule fuelSchedule5 ;
FuelSchedule fuelSchedule6 ;
FuelSchedule fuelSchedule7 ;
FuelSchedule fuelSchedule8 ;
Schedule ignitionSchedule1 ;
Schedule ignitionSchedule2 ;
Schedule ignitionSchedule3 ;
Schedule ignitionSchedule4 ;
Schedule ignitionSchedule5 ;
Schedule ignitionSchedule6 ;
Schedule ignitionSchedule7 ;
Schedule ignitionSchedule8 ;
2013-07-10 04:18:18 -07:00
2022-11-05 15:43:29 -07:00
void ( * inj1StartFunction ) ( void ) ;
void ( * inj1EndFunction ) ( void ) ;
void ( * inj2StartFunction ) ( void ) ;
void ( * inj2EndFunction ) ( void ) ;
void ( * inj3StartFunction ) ( void ) ;
void ( * inj3EndFunction ) ( void ) ;
void ( * inj4StartFunction ) ( void ) ;
void ( * inj4EndFunction ) ( void ) ;
void ( * inj5StartFunction ) ( void ) ;
void ( * inj5EndFunction ) ( void ) ;
void ( * inj6StartFunction ) ( void ) ;
void ( * inj6EndFunction ) ( void ) ;
void ( * inj7StartFunction ) ( void ) ;
void ( * inj7EndFunction ) ( void ) ;
void ( * inj8StartFunction ) ( void ) ;
void ( * inj8EndFunction ) ( void ) ;
void ( * ign1StartFunction ) ( void ) ;
void ( * ign1EndFunction ) ( void ) ;
void ( * ign2StartFunction ) ( void ) ;
void ( * ign2EndFunction ) ( void ) ;
void ( * ign3StartFunction ) ( void ) ;
void ( * ign3EndFunction ) ( void ) ;
void ( * ign4StartFunction ) ( void ) ;
void ( * ign4EndFunction ) ( void ) ;
void ( * ign5StartFunction ) ( void ) ;
void ( * ign5EndFunction ) ( void ) ;
void ( * ign6StartFunction ) ( void ) ;
void ( * ign6EndFunction ) ( void ) ;
void ( * ign7StartFunction ) ( void ) ;
void ( * ign7EndFunction ) ( void ) ;
void ( * ign8StartFunction ) ( void ) ;
void ( * ign8EndFunction ) ( void ) ;
void initialiseSchedulers ( void )
2019-01-21 13:56:25 -08:00
{
2019-11-11 20:04:36 -08:00
//nullSchedule.Status = OFF;
2016-10-06 23:34:27 -07:00
2017-01-29 22:10:17 -08:00
fuelSchedule1 . Status = OFF ;
2016-10-06 23:34:27 -07:00
fuelSchedule2 . Status = OFF ;
fuelSchedule3 . Status = OFF ;
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = OFF ;
2016-10-06 23:34:27 -07:00
fuelSchedule5 . Status = OFF ;
2018-01-22 21:14:03 -08:00
fuelSchedule6 . Status = OFF ;
fuelSchedule7 . Status = OFF ;
fuelSchedule8 . Status = OFF ;
2016-06-26 20:45:51 -07:00
2016-10-06 23:34:27 -07:00
fuelSchedule1 . schedulesSet = 0 ;
fuelSchedule2 . schedulesSet = 0 ;
fuelSchedule3 . schedulesSet = 0 ;
2016-06-26 20:45:51 -07:00
fuelSchedule4 . schedulesSet = 0 ;
2016-10-06 23:34:27 -07:00
fuelSchedule5 . schedulesSet = 0 ;
2018-01-22 21:14:03 -08:00
fuelSchedule6 . schedulesSet = 0 ;
fuelSchedule7 . schedulesSet = 0 ;
fuelSchedule8 . schedulesSet = 0 ;
2016-10-06 23:34:27 -07:00
ignitionSchedule1 . Status = OFF ;
ignitionSchedule2 . Status = OFF ;
ignitionSchedule3 . Status = OFF ;
ignitionSchedule4 . Status = OFF ;
2016-12-28 03:52:00 -08:00
ignitionSchedule5 . Status = OFF ;
2018-01-22 21:14:03 -08:00
ignitionSchedule6 . Status = OFF ;
ignitionSchedule7 . Status = OFF ;
ignitionSchedule8 . Status = OFF ;
2017-01-29 22:10:17 -08:00
2019-03-05 23:17:33 -08:00
IGN1_TIMER_ENABLE ( ) ;
IGN2_TIMER_ENABLE ( ) ;
IGN3_TIMER_ENABLE ( ) ;
IGN4_TIMER_ENABLE ( ) ;
2022-06-26 16:30:40 -07:00
# if (IGN_CHANNELS >= 5)
2020-02-27 15:22:33 -08:00
IGN5_TIMER_ENABLE ( ) ;
IGN6_TIMER_ENABLE ( ) ;
IGN7_TIMER_ENABLE ( ) ;
IGN8_TIMER_ENABLE ( ) ;
2022-06-26 16:30:40 -07:00
# endif
FUEL1_TIMER_ENABLE ( ) ;
FUEL2_TIMER_ENABLE ( ) ;
FUEL3_TIMER_ENABLE ( ) ;
FUEL4_TIMER_ENABLE ( ) ;
# if (INJ_CHANNELS >= 5)
FUEL5_TIMER_ENABLE ( ) ;
FUEL6_TIMER_ENABLE ( ) ;
FUEL7_TIMER_ENABLE ( ) ;
FUEL8_TIMER_ENABLE ( ) ;
# endif
2019-03-05 23:17:33 -08:00
2016-10-06 23:34:27 -07:00
ignitionSchedule1 . schedulesSet = 0 ;
ignitionSchedule2 . schedulesSet = 0 ;
ignitionSchedule3 . schedulesSet = 0 ;
ignitionSchedule4 . schedulesSet = 0 ;
2016-12-28 03:52:00 -08:00
ignitionSchedule5 . schedulesSet = 0 ;
2018-01-22 21:14:03 -08:00
ignitionSchedule6 . schedulesSet = 0 ;
ignitionSchedule7 . schedulesSet = 0 ;
ignitionSchedule8 . schedulesSet = 0 ;
2023-04-26 21:43:04 -07:00
ignition1StartAngle = 0 ;
ignition2StartAngle = 0 ;
ignition3StartAngle = 0 ;
ignition4StartAngle = 0 ;
ignition5StartAngle = 0 ;
ignition6StartAngle = 0 ;
ignition7StartAngle = 0 ;
ignition8StartAngle = 0 ;
channel1IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
channel2IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
channel3IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
channel4IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
channel5IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 5 is at TDC */
channel6IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 6 is at TDC */
channel7IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 7 is at TDC */
channel8IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 8 is at TDC */
channel1InjDegrees = 0 ; /**< The number of crank degrees until cylinder 1 is at TDC (This is obviously 0 for virtually ALL engines, but there's some weird ones) */
channel2InjDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
channel3InjDegrees = 0 ; /**< The number of crank degrees until cylinder 3 (and 5/6/7/8) is at TDC */
channel4InjDegrees = 0 ; /**< The number of crank degrees until cylinder 4 (and 5/6/7/8) is at TDC */
channel5InjDegrees = 0 ; /**< The number of crank degrees until cylinder 5 is at TDC */
channel6InjDegrees = 0 ; /**< The number of crank degrees until cylinder 6 is at TDC */
channel7InjDegrees = 0 ; /**< The number of crank degrees until cylinder 7 is at TDC */
channel8InjDegrees = 0 ; /**< The number of crank degrees until cylinder 8 is at TDC */
2023-05-07 02:42:09 -07:00
inj1StartFunction = nullCallback ;
inj1EndFunction = nullCallback ;
inj2StartFunction = nullCallback ;
inj2EndFunction = nullCallback ;
inj3StartFunction = nullCallback ;
inj3EndFunction = nullCallback ;
inj4StartFunction = nullCallback ;
inj4EndFunction = nullCallback ;
inj5StartFunction = nullCallback ;
inj5EndFunction = nullCallback ;
inj6StartFunction = nullCallback ;
inj6EndFunction = nullCallback ;
inj7StartFunction = nullCallback ;
inj7EndFunction = nullCallback ;
inj8StartFunction = nullCallback ;
inj8EndFunction = nullCallback ;
ign1StartFunction = nullCallback ;
ign1EndFunction = nullCallback ;
ign2StartFunction = nullCallback ;
ign2EndFunction = nullCallback ;
ign3StartFunction = nullCallback ;
ign3EndFunction = nullCallback ;
ign4StartFunction = nullCallback ;
ign4EndFunction = nullCallback ;
ign5StartFunction = nullCallback ;
ign5EndFunction = nullCallback ;
ign6StartFunction = nullCallback ;
ign6EndFunction = nullCallback ;
ign7StartFunction = nullCallback ;
ign7EndFunction = nullCallback ;
ign8StartFunction = nullCallback ;
ign8EndFunction = nullCallback ;
2019-01-21 13:56:25 -08:00
}
2017-01-29 22:10:17 -08:00
2013-07-10 04:18:18 -07:00
/*
2013-11-13 22:17:58 -08:00
These 8 function turn a schedule on , provides the time to start and the duration and gives it callback functions .
All 8 functions operate the same , just on different schedules
2013-07-10 04:18:18 -07:00
Args :
2013-09-04 17:27:16 -07:00
startCallback : The function to be called once the timeout is reached
2013-11-13 22:17:58 -08:00
timeout : The number of uS in the future that the startCallback should be triggered
2013-09-04 17:27:16 -07:00
duration : The number of uS after startCallback is called before endCallback is called
2013-09-03 05:26:08 -07:00
endCallback : This function is called once the duration time has been reached
2013-07-10 04:18:18 -07:00
*/
2018-01-22 21:14:03 -08:00
2020-02-02 14:07:37 -08:00
//Experimental new generic function. This is NOT yet ready and functional
2018-01-22 21:14:03 -08:00
void setFuelSchedule ( struct Schedule * targetSchedule , unsigned long timeout , unsigned long duration )
{
if ( targetSchedule - > Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
targetSchedule - > duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2018-02-04 14:39:46 -08:00
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
2018-01-22 21:14:03 -08:00
//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 ( ) ;
2020-02-02 14:07:37 -08:00
//targetSchedule->startCompare = *targetSchedule->counter + timeout_timer_compare;
2020-02-02 22:35:29 -08:00
targetSchedule - > startCompare = FUEL1_COUNTER + timeout_timer_compare ; //Insert correct counter HERE!
2018-02-04 14:39:46 -08:00
targetSchedule - > endCompare = targetSchedule - > startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2018-01-22 21:14:03 -08:00
targetSchedule - > Status = PENDING ; //Turn this schedule on
targetSchedule - > schedulesSet + + ; //Increment the number of times this schedule has been set
2020-02-02 14:07:37 -08:00
//*targetSchedule->compare = targetSchedule->startCompare;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL1_COMPARE , targetSchedule - > startCompare ) ; //Insert corrector compare HERE!
2018-01-22 21:14:03 -08:00
interrupts ( ) ;
FUEL1_TIMER_ENABLE ( ) ;
}
else
{
//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
2020-02-02 14:07:37 -08:00
//targetSchedule->nextStartCompare = *targetSchedule->counter + uS_TO_TIMER_COMPARE(timeout);
2018-02-04 14:39:46 -08:00
targetSchedule - > nextEndCompare = targetSchedule - > nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2018-01-22 21:14:03 -08:00
targetSchedule - > hasNextSchedule = true ;
}
}
2017-06-13 19:15:26 -07:00
//void setFuelSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
2020-03-31 23:03:11 -07:00
void setFuelSchedule1 ( unsigned long timeout , unsigned long duration ) //Uses timer 3 compare A
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
2019-11-06 20:01:28 -08:00
//if(timeout < MAX_TIMER_PERIOD)
2013-07-10 04:18:18 -07:00
{
2018-02-04 23:05:36 -08:00
if ( fuelSchedule1 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
//Need to check that the timeout doesn't exceed the overflow
2019-11-06 20:01:28 -08:00
if ( ( timeout + duration ) < MAX_TIMER_PERIOD )
{
fuelSchedule1 . duration = duration ;
//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 ( ) ;
fuelSchedule1 . startCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule1 . endCompare = fuelSchedule1 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule1 . Status = PENDING ; //Turn this schedule on
fuelSchedule1 . schedulesSet + + ; //Increment the number of times this schedule has been set
//Schedule 1 shares a timer with schedule 5
2021-11-11 20:11:42 -08:00
//if(channel5InjEnabled) { SET_COMPARE(FUEL1_COMPARE, setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, FUEL1_COUNTER) ); }
//else { timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1; SET_COMPARE(FUEL1_COMPARE, fuelSchedule1.startCompare); }
2019-11-06 20:01:28 -08:00
//timer3Aqueue[0] = &fuelSchedule1; timer3Aqueue[1] = &fuelSchedule1; timer3Aqueue[2] = &fuelSchedule1; timer3Aqueue[3] = &fuelSchedule1;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL1_COMPARE , fuelSchedule1 . startCompare ) ;
2019-11-06 20:01:28 -08:00
interrupts ( ) ;
FUEL1_TIMER_ENABLE ( ) ;
}
2018-02-04 23:05:36 -08:00
}
else
{
//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
2019-11-06 20:01:28 -08:00
if ( ( timeout + duration ) < MAX_TIMER_PERIOD )
{
noInterrupts ( ) ;
fuelSchedule1 . nextStartCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule1 . nextEndCompare = fuelSchedule1 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule1 . duration = duration ;
fuelSchedule1 . hasNextSchedule = true ;
interrupts ( ) ;
}
2018-02-04 23:05:36 -08:00
} //Schedule is RUNNING
} //Timeout less than threshold
2017-06-20 20:00:58 -07:00
}
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
void setFuelSchedule2 ( unsigned long timeout , unsigned long duration ) //Uses timer 3 compare B
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
2019-08-22 17:18:07 -07:00
if ( timeout < MAX_TIMER_PERIOD )
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
if ( fuelSchedule2 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
//Callbacks no longer used, but retained for now:
//fuelSchedule2.StartCallback = startCallback;
//fuelSchedule2.EndCallback = endCallback;
fuelSchedule2 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-02-04 23:05:36 -08:00
//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 ( ) ;
fuelSchedule2 . startCompare = FUEL2_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
fuelSchedule2 . endCompare = fuelSchedule2 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL2_COMPARE , fuelSchedule2 . startCompare ) ; //Use the B compare unit of timer 3
2018-02-04 23:05:36 -08:00
fuelSchedule2 . Status = PENDING ; //Turn this schedule on
fuelSchedule2 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL2_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-08-22 17:18:07 -07:00
fuelSchedule2 . nextStartCompare = FUEL2_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule2 . nextEndCompare = fuelSchedule2 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2018-02-04 23:05:36 -08:00
fuelSchedule2 . hasNextSchedule = true ;
}
2013-09-04 17:27:16 -07:00
}
2017-06-20 20:00:58 -07:00
}
2017-06-13 19:15:26 -07:00
//void setFuelSchedule3(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
2020-03-31 23:03:11 -07:00
void setFuelSchedule3 ( unsigned long timeout , unsigned long duration ) //Uses timer 3 compare C
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
2019-08-22 17:18:07 -07:00
if ( timeout < MAX_TIMER_PERIOD )
2017-06-20 20:00:58 -07:00
{
2020-03-31 23:03:11 -07:00
if ( fuelSchedule3 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2018-02-04 23:05:36 -08:00
{
//Callbacks no longer used, but retained for now:
//fuelSchedule3.StartCallback = startCallback;
//fuelSchedule3.EndCallback = endCallback;
fuelSchedule3 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-02-04 23:05:36 -08:00
//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 ( ) ;
fuelSchedule3 . startCompare = FUEL3_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
fuelSchedule3 . endCompare = fuelSchedule3 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL3_COMPARE , fuelSchedule3 . startCompare ) ; //Use the C compare unit of timer 3
2018-02-04 23:05:36 -08:00
fuelSchedule3 . Status = PENDING ; //Turn this schedule on
fuelSchedule3 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL3_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-08-22 17:18:07 -07:00
fuelSchedule3 . nextStartCompare = FUEL3_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule3 . nextEndCompare = fuelSchedule3 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2018-02-04 23:05:36 -08:00
fuelSchedule3 . hasNextSchedule = true ;
}
2017-06-20 20:00:58 -07:00
}
}
//void setFuelSchedule4(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
2017-06-13 19:15:26 -07:00
void setFuelSchedule4 ( unsigned long timeout , unsigned long duration ) //Uses timer 4 compare B
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
2019-08-22 17:18:07 -07:00
if ( timeout < MAX_TIMER_PERIOD )
2017-06-20 20:00:58 -07:00
{
2018-02-04 23:05:36 -08:00
if ( fuelSchedule4 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
//Callbacks no longer used, but retained for now:
//fuelSchedule4.StartCallback = startCallback;
//fuelSchedule4.EndCallback = endCallback;
fuelSchedule4 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-02-04 23:05:36 -08:00
//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 ( ) ;
fuelSchedule4 . startCompare = FUEL4_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
fuelSchedule4 . endCompare = fuelSchedule4 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL4_COMPARE , fuelSchedule4 . startCompare ) ; //Use the B compare unit of timer 4
2018-02-04 23:05:36 -08:00
fuelSchedule4 . Status = PENDING ; //Turn this schedule on
fuelSchedule4 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL4_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-08-22 17:18:07 -07:00
fuelSchedule4 . nextStartCompare = FUEL4_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule4 . nextEndCompare = fuelSchedule4 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2018-02-04 23:05:36 -08:00
fuelSchedule4 . hasNextSchedule = true ;
}
2017-06-20 20:00:58 -07:00
}
}
2018-01-22 21:14:03 -08:00
2018-03-17 23:26:12 -07:00
# if INJ_CHANNELS >= 5
2020-03-31 23:03:11 -07:00
void setFuelSchedule5 ( unsigned long timeout , unsigned long duration ) //Uses timer 4 compare C
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
if ( timeout < MAX_TIMER_PERIOD )
2016-06-26 20:45:51 -07:00
{
2020-03-31 23:03:11 -07:00
if ( fuelSchedule5 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
fuelSchedule5 . duration = duration ;
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2020-03-31 23:03:11 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2019-11-11 22:10:32 -08:00
2020-03-31 23:03:11 -07:00
//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 ( ) ;
fuelSchedule5 . startCompare = FUEL5_COUNTER + timeout_timer_compare ;
fuelSchedule5 . endCompare = fuelSchedule5 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL5_COMPARE , fuelSchedule5 . startCompare ) ; //Use the C compare unit of timer 4
2020-03-31 23:03:11 -07:00
fuelSchedule5 . Status = PENDING ; //Turn this schedule on
fuelSchedule5 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL5_TIMER_ENABLE ( ) ;
}
else
{
//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
fuelSchedule5 . nextStartCompare = FUEL5_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule5 . nextEndCompare = fuelSchedule5 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule5 . hasNextSchedule = true ;
}
2018-01-22 21:14:03 -08:00
}
}
2018-03-17 23:26:12 -07:00
# endif
2018-01-22 21:14:03 -08:00
# if INJ_CHANNELS >= 6
2020-03-31 23:03:11 -07:00
void setFuelSchedule6 ( unsigned long timeout , unsigned long duration ) //Uses timer 4 compare A
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
if ( timeout < MAX_TIMER_PERIOD )
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
if ( fuelSchedule6 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
fuelSchedule6 . duration = duration ;
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2020-03-31 23:03:11 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//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 ( ) ;
fuelSchedule6 . startCompare = FUEL6_COUNTER + timeout_timer_compare ;
fuelSchedule6 . endCompare = fuelSchedule6 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL6_COMPARE , fuelSchedule6 . startCompare ) ; //Use the A compare unit of timer 4
2020-03-31 23:03:11 -07:00
fuelSchedule6 . Status = PENDING ; //Turn this schedule on
fuelSchedule6 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL6_TIMER_ENABLE ( ) ;
}
else
{
//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
fuelSchedule6 . nextStartCompare = FUEL6_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule6 . nextEndCompare = fuelSchedule6 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule6 . hasNextSchedule = true ;
}
2018-01-22 21:14:03 -08:00
}
}
# endif
# if INJ_CHANNELS >= 7
2020-03-31 23:03:11 -07:00
void setFuelSchedule7 ( unsigned long timeout , unsigned long duration ) //Uses timer 5 compare C
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
if ( timeout < MAX_TIMER_PERIOD )
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
if ( fuelSchedule7 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
fuelSchedule7 . duration = duration ;
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2020-03-31 23:03:11 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//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 ( ) ;
fuelSchedule7 . startCompare = FUEL7_COUNTER + timeout_timer_compare ;
fuelSchedule7 . endCompare = fuelSchedule7 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL7_COMPARE , fuelSchedule7 . startCompare ) ; //Use the C compare unit of timer 5
2020-03-31 23:03:11 -07:00
fuelSchedule7 . Status = PENDING ; //Turn this schedule on
fuelSchedule7 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL7_TIMER_ENABLE ( ) ;
}
else
{
//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
fuelSchedule7 . nextStartCompare = FUEL7_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule7 . nextEndCompare = fuelSchedule7 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule7 . hasNextSchedule = true ;
}
2018-01-22 21:14:03 -08:00
}
}
# endif
# if INJ_CHANNELS >= 8
2020-03-31 23:03:11 -07:00
void setFuelSchedule8 ( unsigned long timeout , unsigned long duration ) //Uses timer 5 compare B
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
//Check whether timeout exceeds the maximum future time. This can potentially occur on sequential setups when below ~115rpm
if ( timeout < MAX_TIMER_PERIOD )
2018-01-22 21:14:03 -08:00
{
2020-03-31 23:03:11 -07:00
if ( fuelSchedule8 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
fuelSchedule8 . duration = duration ;
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2020-03-31 23:03:11 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-01-22 21:14:03 -08:00
2020-03-31 23:03:11 -07:00
//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 ( ) ;
fuelSchedule8 . startCompare = FUEL8_COUNTER + timeout_timer_compare ;
fuelSchedule8 . endCompare = fuelSchedule8 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL8_COMPARE , fuelSchedule8 . startCompare ) ; //Use the B compare unit of timer 5
2020-03-31 23:03:11 -07:00
fuelSchedule8 . Status = PENDING ; //Turn this schedule on
fuelSchedule8 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL8_TIMER_ENABLE ( ) ;
}
else
{
//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
fuelSchedule8 . nextStartCompare = FUEL8_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
fuelSchedule8 . nextEndCompare = fuelSchedule8 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
fuelSchedule8 . hasNextSchedule = true ;
}
2018-01-22 21:14:03 -08:00
}
}
# endif
2013-09-04 17:27:16 -07:00
//Ignition schedulers use Timer 5
void setIgnitionSchedule1 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule1 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-09-04 17:27:16 -07:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule1 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule1 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule1 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 20:00:58 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2018-08-07 22:17:09 -07:00
//timeout -= (micros() - lastCrankAngleCalc);
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2017-06-20 20:00:58 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2016-11-21 03:06:41 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2017-06-20 20:00:58 -07:00
ignitionSchedule1 . startCompare = IGN1_COUNTER + timeout_timer_compare ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
2018-08-13 19:46:39 -07:00
if ( ignitionSchedule1 . endScheduleSetByDecoder = = false ) { ignitionSchedule1 . endCompare = ignitionSchedule1 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN1_COMPARE , ignitionSchedule1 . startCompare ) ;
2013-09-04 17:27:16 -07:00
ignitionSchedule1 . Status = PENDING ; //Turn this schedule on
2016-11-21 03:06:41 -08:00
ignitionSchedule1 . schedulesSet + + ;
2016-10-09 06:06:52 -07:00
interrupts ( ) ;
IGN1_TIMER_ENABLE ( ) ;
2013-09-04 17:27:16 -07:00
}
2019-12-18 18:23:11 -08:00
else
{
//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
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule1 . nextStartCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule1 . nextEndCompare = ignitionSchedule1 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule1 . hasNextSchedule = true ;
}
}
2017-06-20 20:00:58 -07:00
}
2017-10-24 05:31:42 -07:00
2020-02-03 14:19:43 -08:00
inline void refreshIgnitionSchedule1 ( unsigned long timeToEnd )
2017-10-24 05:31:42 -07:00
{
if ( ( ignitionSchedule1 . Status = = RUNNING ) & & ( timeToEnd < ignitionSchedule1 . duration ) )
2017-12-04 14:15:17 -08:00
//Must have the threshold check here otherwise it can cause a condition where the compare fires twice, once after the other, both for the end
//if( (timeToEnd < ignitionSchedule1.duration) && (timeToEnd > IGNITION_REFRESH_THRESHOLD) )
2017-10-24 05:31:42 -07:00
{
noInterrupts ( ) ;
2018-09-04 00:07:21 -07:00
ignitionSchedule1 . endCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE ( timeToEnd ) ;
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN1_COMPARE , ignitionSchedule1 . endCompare ) ;
2017-10-24 05:31:42 -07:00
interrupts ( ) ;
}
}
2013-09-04 17:27:16 -07:00
void setIgnitionSchedule2 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule2 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-07-10 04:18:18 -07:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule2 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule2 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule2 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2017-06-20 22:34:41 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2017-01-29 22:10:17 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2017-06-20 22:34:41 -07:00
ignitionSchedule2 . startCompare = IGN2_COUNTER + timeout_timer_compare ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
2018-08-13 19:46:39 -07:00
if ( ignitionSchedule2 . endScheduleSetByDecoder = = false ) { ignitionSchedule2 . endCompare = ignitionSchedule2 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN2_COMPARE , ignitionSchedule2 . startCompare ) ;
2013-09-04 17:27:16 -07:00
ignitionSchedule2 . Status = PENDING ; //Turn this schedule on
2016-11-21 03:06:41 -08:00
ignitionSchedule2 . schedulesSet + + ;
2016-10-09 06:06:52 -07:00
interrupts ( ) ;
2016-10-15 03:52:20 -07:00
IGN2_TIMER_ENABLE ( ) ;
2013-07-10 04:18:18 -07:00
}
2019-12-18 18:23:11 -08:00
else
{
//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
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule2 . nextStartCompare = IGN2_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule2 . nextEndCompare = ignitionSchedule2 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule2 . hasNextSchedule = true ;
}
}
2017-06-20 20:00:58 -07:00
}
2013-11-13 22:17:58 -08:00
void setIgnitionSchedule3 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule3 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule3 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule3 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule3 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2017-06-20 22:34:41 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2017-01-29 22:10:17 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2017-06-20 22:34:41 -07:00
ignitionSchedule3 . startCompare = IGN3_COUNTER + timeout_timer_compare ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
2018-08-13 19:46:39 -07:00
if ( ignitionSchedule3 . endScheduleSetByDecoder = = false ) { ignitionSchedule3 . endCompare = ignitionSchedule3 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN3_COMPARE , ignitionSchedule3 . startCompare ) ;
2013-11-13 22:17:58 -08:00
ignitionSchedule3 . Status = PENDING ; //Turn this schedule on
2016-11-21 03:06:41 -08:00
ignitionSchedule3 . schedulesSet + + ;
2016-10-09 06:06:52 -07:00
interrupts ( ) ;
2017-01-29 22:10:17 -08:00
IGN3_TIMER_ENABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2017-08-30 19:09:13 -07:00
else
{
//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
2019-12-18 18:23:11 -08:00
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule3 . nextStartCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule3 . nextEndCompare = ignitionSchedule3 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule3 . hasNextSchedule = true ;
}
2017-08-30 19:09:13 -07:00
}
2017-06-20 20:00:58 -07:00
}
2013-11-13 22:17:58 -08:00
void setIgnitionSchedule4 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule4 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule4 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule4 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule4 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2017-06-20 22:34:41 -07:00
ignitionSchedule4 . startCompare = IGN4_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
if ( ignitionSchedule4 . endScheduleSetByDecoder = = false ) { ignitionSchedule4 . endCompare = ignitionSchedule4 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN4_COMPARE , ignitionSchedule4 . startCompare ) ;
2013-11-13 22:17:58 -08:00
ignitionSchedule4 . Status = PENDING ; //Turn this schedule on
2016-11-21 03:06:41 -08:00
ignitionSchedule4 . schedulesSet + + ;
2016-10-09 06:06:52 -07:00
interrupts ( ) ;
2017-01-29 22:10:17 -08:00
IGN4_TIMER_ENABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2017-08-30 19:09:13 -07:00
else
{
//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
2019-12-18 18:23:11 -08:00
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule4 . nextStartCompare = IGN4_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule4 . nextEndCompare = ignitionSchedule4 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule4 . hasNextSchedule = true ;
}
2017-08-30 19:09:13 -07:00
}
2017-06-20 20:00:58 -07:00
}
2016-07-24 02:32:26 -07:00
void setIgnitionSchedule5 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
2020-03-31 23:03:11 -07:00
if ( ignitionSchedule5 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2016-07-24 02:32:26 -07:00
{
2016-10-09 22:58:19 -07:00
ignitionSchedule5 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule5 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule5 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2016-12-28 03:52:00 -08:00
noInterrupts ( ) ;
2017-06-20 22:34:41 -07:00
ignitionSchedule5 . startCompare = IGN5_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
if ( ignitionSchedule5 . endScheduleSetByDecoder = = false ) { ignitionSchedule5 . endCompare = ignitionSchedule5 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN5_COMPARE , ignitionSchedule5 . startCompare ) ;
2016-07-24 02:32:26 -07:00
ignitionSchedule5 . Status = PENDING ; //Turn this schedule on
2016-12-28 03:52:00 -08:00
ignitionSchedule5 . schedulesSet + + ;
interrupts ( ) ;
2017-01-29 22:10:17 -08:00
IGN5_TIMER_ENABLE ( ) ;
2016-07-24 02:32:26 -07:00
}
2019-12-18 18:23:11 -08:00
else
{
//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
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule5 . nextStartCompare = IGN5_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule5 . nextEndCompare = ignitionSchedule5 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule5 . hasNextSchedule = true ;
}
}
2017-06-20 20:00:58 -07:00
}
2018-03-17 16:37:31 -07:00
void setIgnitionSchedule6 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( ignitionSchedule6 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
ignitionSchedule6 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule6 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule6 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-03-17 16:37:31 -07:00
noInterrupts ( ) ;
ignitionSchedule6 . startCompare = IGN6_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
if ( ignitionSchedule6 . endScheduleSetByDecoder = = false ) { ignitionSchedule6 . endCompare = ignitionSchedule6 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN6_COMPARE , ignitionSchedule6 . startCompare ) ;
2018-03-17 16:37:31 -07:00
ignitionSchedule6 . Status = PENDING ; //Turn this schedule on
ignitionSchedule6 . schedulesSet + + ;
interrupts ( ) ;
IGN6_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-12-18 18:23:11 -08:00
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule6 . nextStartCompare = IGN6_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule6 . nextEndCompare = ignitionSchedule6 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule6 . hasNextSchedule = true ;
}
2018-03-17 16:37:31 -07:00
}
}
void setIgnitionSchedule7 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( ignitionSchedule7 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
ignitionSchedule7 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule7 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule7 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-03-17 16:37:31 -07:00
noInterrupts ( ) ;
2020-03-16 13:33:50 -07:00
ignitionSchedule7 . startCompare = IGN7_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
if ( ignitionSchedule7 . endScheduleSetByDecoder = = false ) { ignitionSchedule7 . endCompare = ignitionSchedule7 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN7_COMPARE , ignitionSchedule7 . startCompare ) ;
2018-03-17 16:37:31 -07:00
ignitionSchedule7 . Status = PENDING ; //Turn this schedule on
ignitionSchedule7 . schedulesSet + + ;
interrupts ( ) ;
IGN7_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-12-18 18:23:11 -08:00
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule7 . nextStartCompare = IGN7_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule7 . nextEndCompare = ignitionSchedule7 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule7 . hasNextSchedule = true ;
}
2018-03-17 16:37:31 -07:00
}
}
void setIgnitionSchedule8 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( ignitionSchedule8 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
ignitionSchedule8 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule8 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule8 . duration = duration ;
//Need to check that the timeout doesn't exceed the overflow
2021-11-11 20:11:42 -08:00
COMPARE_TYPE timeout_timer_compare ;
2022-04-10 17:49:58 -07:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE ( ( MAX_TIMER_PERIOD - 1 ) ) ; } // If the timeout is >4x (Each tick represents 4uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when applied causing erratic behaviour such as erroneous sparking.
2019-08-22 17:18:07 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE ( timeout ) ; } //Normal case
2018-03-17 16:37:31 -07:00
noInterrupts ( ) ;
ignitionSchedule8 . startCompare = IGN8_COUNTER + timeout_timer_compare ;
2019-08-22 17:18:07 -07:00
if ( ignitionSchedule8 . endScheduleSetByDecoder = = false ) { ignitionSchedule8 . endCompare = ignitionSchedule8 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ; } //The .endCompare value is also set by the per tooth timing in decoders.ino. The check here is so that it's not getting overridden.
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN8_COMPARE , ignitionSchedule8 . startCompare ) ;
2018-03-17 16:37:31 -07:00
ignitionSchedule8 . Status = PENDING ; //Turn this schedule on
ignitionSchedule8 . schedulesSet + + ;
interrupts ( ) ;
IGN8_TIMER_ENABLE ( ) ;
}
else
{
//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
2019-12-18 18:23:11 -08:00
if ( timeout < MAX_TIMER_PERIOD )
{
ignitionSchedule8 . nextStartCompare = IGN8_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule8 . nextEndCompare = ignitionSchedule8 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule8 . hasNextSchedule = true ;
}
2018-03-17 16:37:31 -07:00
}
}
2021-06-21 22:30:52 -07:00
/** Perform the injector priming pulses.
* Set these to run at an arbitrary time in the future ( 100u s ) .
* The prime pulse value is in ms * 10 , so need to multiple by 100 to get to uS
*/
2022-11-05 15:43:29 -07:00
extern void beginInjectorPriming ( void )
2020-07-04 21:28:57 -07:00
{
unsigned long primingValue = table2D_getValue ( & PrimingPulseTable , currentStatus . coolant + CALIBRATION_TEMPERATURE_OFFSET ) ;
if ( ( primingValue > 0 ) & & ( currentStatus . TPS < configPage4 . floodClear ) )
{
2022-04-10 17:49:58 -07:00
primingValue = primingValue * 100 * 5 ; //to achieve long enough priming pulses, the values in tuner studio are divided by 0.5 instead of 0.1, so multiplier of 5 is required.
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 1 ) { setFuelSchedule1 ( 100 , primingValue ) ; }
2020-07-06 05:17:56 -07:00
# if (INJ_CHANNELS >= 2)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 2 ) { setFuelSchedule2 ( 100 , primingValue ) ; }
2020-07-06 05:17:56 -07:00
# endif
# if (INJ_CHANNELS >= 3)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 3 ) { setFuelSchedule3 ( 100 , primingValue ) ; }
2020-07-06 05:17:56 -07:00
# endif
# if (INJ_CHANNELS >= 4)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 4 ) { setFuelSchedule4 ( 100 , primingValue ) ; }
2020-07-06 05:17:56 -07:00
# endif
2020-07-04 21:28:57 -07:00
# if (INJ_CHANNELS >= 5)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 5 ) { setFuelSchedule5 ( 100 , primingValue ) ; }
2020-07-04 21:28:57 -07:00
# endif
# if (INJ_CHANNELS >= 6)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 6 ) { setFuelSchedule6 ( 100 , primingValue ) ; }
2020-07-04 21:28:57 -07:00
# endif
# if (INJ_CHANNELS >= 7)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 7 ) { setFuelSchedule7 ( 100 , primingValue ) ; }
2020-07-04 21:28:57 -07:00
# endif
# if (INJ_CHANNELS >= 8)
2023-06-25 17:46:11 -07:00
if ( maxInjOutputs > = 8 ) { setFuelSchedule8 ( 100 , primingValue ) ; }
2020-07-04 21:28:57 -07:00
# endif
}
}
2016-07-27 02:31:38 -07:00
/*******************************************************************************************************************************************************************************************************/
2021-06-21 22:30:52 -07:00
/** fuelSchedule*Interrupt (All 8 ISR functions below) get called (as timed interrupts) when either the start time or the duration time are reached.
* This calls the relevant callback function ( startCallback or endCallback ) depending on the status ( PENDING = > Needs to run , RUNNING = > Needs to stop ) of the schedule .
* The status of schedule is managed here based on startCallback / endCallback function called :
* - startCallback - change scheduler into RUNNING state
* - endCallback - change scheduler into OFF state ( or PENDING if schedule . hasNextSchedule is set )
*/
2013-09-08 03:01:47 -07:00
//Timer3A (fuel schedule 1) Compare Vector
2020-02-27 15:22:33 -08:00
# if (INJ_CHANNELS >= 1)
2016-10-06 23:34:27 -07:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
//fuelSchedules 1 and 5
ISR ( TIMER3_COMPA_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule1Interrupt ( void )
2016-10-06 23:34:27 -07:00
# endif
2013-07-10 04:18:18 -07:00
{
2017-06-20 20:00:58 -07:00
if ( fuelSchedule1 . Status = = PENDING ) //Check to see if this schedule is turn on
2013-07-10 04:18:18 -07:00
{
2017-06-20 20:00:58 -07:00
//To use timer queue, change fuelShedule1 to timer3Aqueue[0];
2020-03-31 23:03:11 -07:00
inj1StartFunction ( ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule1 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL1_COMPARE , FUEL1_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule1 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2013-07-10 04:18:18 -07:00
}
2017-06-20 20:00:58 -07:00
else if ( fuelSchedule1 . Status = = RUNNING )
2013-07-10 04:18:18 -07:00
{
2017-06-13 19:15:26 -07:00
//timer3Aqueue[0]->EndCallback();
2020-03-31 23:03:11 -07:00
inj1EndFunction ( ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule1 . Status = OFF ; //Turn off the schedule
fuelSchedule1 . schedulesSet = 0 ;
2021-11-11 20:11:42 -08:00
//SET_COMPARE(FUEL1_COMPARE, fuelSchedule1.endCompare);
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule1 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL1_COMPARE , fuelSchedule1 . nextStartCompare ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule1 . endCompare = fuelSchedule1 . nextEndCompare ;
fuelSchedule1 . Status = PENDING ;
fuelSchedule1 . schedulesSet = 1 ;
fuelSchedule1 . hasNextSchedule = false ;
}
else { FUEL1_TIMER_DISABLE ( ) ; }
2013-07-10 04:18:18 -07:00
}
2017-06-20 20:00:58 -07:00
else if ( fuelSchedule1 . Status = = OFF ) { FUEL1_TIMER_DISABLE ( ) ; } //Safety check. Turn off this output compare unit and return without performing any action
2013-07-10 04:18:18 -07:00
}
2020-02-27 15:22:33 -08:00
# endif
2016-07-27 02:31:38 -07:00
2020-02-27 15:22:33 -08:00
# if (INJ_CHANNELS >= 2)
2016-10-06 23:34:27 -07:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER3_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule2Interrupt ( void )
2016-10-06 23:34:27 -07:00
# endif
2013-07-10 04:18:18 -07:00
{
2013-09-04 17:27:16 -07:00
if ( fuelSchedule2 . Status = = PENDING ) //Check to see if this schedule is turn on
2013-07-10 04:18:18 -07:00
{
2017-06-13 19:15:26 -07:00
//fuelSchedule2.StartCallback();
2020-03-31 23:03:11 -07:00
inj2StartFunction ( ) ;
2013-09-04 17:27:16 -07:00
fuelSchedule2 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL2_COMPARE , FUEL2_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule2 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2013-07-10 04:18:18 -07:00
}
2013-09-04 17:27:16 -07:00
else if ( fuelSchedule2 . Status = = RUNNING )
2013-07-10 04:18:18 -07:00
{
2017-06-13 19:15:26 -07:00
//fuelSchedule2.EndCallback();
2020-03-31 23:03:11 -07:00
inj2EndFunction ( ) ;
2013-09-04 17:27:16 -07:00
fuelSchedule2 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule2 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule2 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL2_COMPARE , fuelSchedule2 . nextStartCompare ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule2 . endCompare = fuelSchedule2 . nextEndCompare ;
fuelSchedule2 . Status = PENDING ;
fuelSchedule2 . schedulesSet = 1 ;
fuelSchedule2 . hasNextSchedule = false ;
}
else { FUEL2_TIMER_DISABLE ( ) ; }
2013-07-10 04:18:18 -07:00
}
2013-11-13 22:17:58 -08:00
}
2020-02-27 15:22:33 -08:00
# endif
2016-07-27 02:31:38 -07:00
2020-02-27 15:22:33 -08:00
# if (INJ_CHANNELS >= 3)
2016-10-03 18:50:09 -07:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER3_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule3Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
if ( fuelSchedule3 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2017-06-13 19:15:26 -07:00
//fuelSchedule3.StartCallback();
2020-03-31 23:03:11 -07:00
inj3StartFunction ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule3 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL3_COMPARE , FUEL3_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule3 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2013-11-13 22:17:58 -08:00
}
else if ( fuelSchedule3 . Status = = RUNNING )
{
2017-06-13 19:15:26 -07:00
//fuelSchedule3.EndCallback();
2020-03-31 23:03:11 -07:00
inj3EndFunction ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule3 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule3 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule3 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL3_COMPARE , fuelSchedule3 . nextStartCompare ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule3 . endCompare = fuelSchedule3 . nextEndCompare ;
fuelSchedule3 . Status = PENDING ;
fuelSchedule3 . schedulesSet = 1 ;
fuelSchedule3 . hasNextSchedule = false ;
}
else { FUEL3_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
}
2020-02-27 15:22:33 -08:00
# endif
2017-01-29 22:10:17 -08:00
2020-02-27 15:22:33 -08:00
# if (INJ_CHANNELS >= 4)
2016-10-03 18:50:09 -07:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule4Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
if ( fuelSchedule4 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2017-06-13 19:15:26 -07:00
//fuelSchedule4.StartCallback();
2020-03-31 23:03:11 -07:00
inj4StartFunction ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL4_COMPARE , FUEL4_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule4 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2013-11-13 22:17:58 -08:00
}
else if ( fuelSchedule4 . Status = = RUNNING )
{
2017-06-13 19:15:26 -07:00
//fuelSchedule4.EndCallback();
2020-03-31 23:03:11 -07:00
inj4EndFunction ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule4 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule4 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL4_COMPARE , fuelSchedule4 . nextStartCompare ) ;
2017-06-20 20:00:58 -07:00
fuelSchedule4 . endCompare = fuelSchedule4 . nextEndCompare ;
fuelSchedule4 . Status = PENDING ;
fuelSchedule4 . schedulesSet = 1 ;
fuelSchedule4 . hasNextSchedule = false ;
}
else { FUEL4_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
2013-09-04 17:27:16 -07:00
}
2020-02-27 15:22:33 -08:00
# endif
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# if (INJ_CHANNELS >= 5)
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule5Interrupt ( void )
2018-03-17 16:37:31 -07:00
# endif
{
if ( fuelSchedule5 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2020-03-31 23:03:11 -07:00
inj5StartFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule5 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL5_COMPARE , FUEL5_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule5 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2018-03-17 16:37:31 -07:00
}
else if ( fuelSchedule5 . Status = = RUNNING )
{
2020-03-31 23:03:11 -07:00
inj5EndFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule5 . Status = OFF ; //Turn off the schedule
fuelSchedule5 . schedulesSet = 0 ;
//If there is a next schedule queued up, activate it
if ( fuelSchedule5 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL5_COMPARE , fuelSchedule5 . nextStartCompare ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule5 . endCompare = fuelSchedule5 . nextEndCompare ;
fuelSchedule5 . Status = PENDING ;
fuelSchedule5 . schedulesSet = 1 ;
fuelSchedule5 . hasNextSchedule = false ;
}
else { FUEL5_TIMER_DISABLE ( ) ; }
}
}
# endif
2018-01-22 21:14:03 -08:00
# if (INJ_CHANNELS >= 6)
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPA_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule6Interrupt ( void )
2018-01-22 21:14:03 -08:00
# endif
{
if ( fuelSchedule6 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2020-03-31 23:03:11 -07:00
//fuelSchedule6.StartCallback();
inj6StartFunction ( ) ;
2018-01-22 21:14:03 -08:00
fuelSchedule6 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL6_COMPARE , FUEL6_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule6 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2018-01-22 21:14:03 -08:00
}
else if ( fuelSchedule6 . Status = = RUNNING )
{
2020-03-31 23:03:11 -07:00
//fuelSchedule6.EndCallback();
inj6EndFunction ( ) ;
2018-01-22 21:14:03 -08:00
fuelSchedule6 . Status = OFF ; //Turn off the schedule
fuelSchedule6 . schedulesSet = 0 ;
//If there is a next schedule queued up, activate it
if ( fuelSchedule6 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL6_COMPARE , fuelSchedule6 . nextStartCompare ) ;
2018-01-22 21:14:03 -08:00
fuelSchedule6 . endCompare = fuelSchedule6 . nextEndCompare ;
fuelSchedule6 . Status = PENDING ;
fuelSchedule6 . schedulesSet = 1 ;
fuelSchedule6 . hasNextSchedule = false ;
}
else { FUEL6_TIMER_DISABLE ( ) ; }
}
}
# endif
2018-03-17 16:37:31 -07:00
# if (INJ_CHANNELS >= 7)
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER5_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule7Interrupt ( void )
2018-03-17 16:37:31 -07:00
# endif
{
if ( fuelSchedule7 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2020-03-31 23:03:11 -07:00
//fuelSchedule7.StartCallback();
inj7StartFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule7 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL7_COMPARE , FUEL7_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule7 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2018-03-17 16:37:31 -07:00
}
else if ( fuelSchedule7 . Status = = RUNNING )
{
2020-03-31 23:03:11 -07:00
//fuelSchedule7.EndCallback();
inj7EndFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule7 . Status = OFF ; //Turn off the schedule
fuelSchedule7 . schedulesSet = 0 ;
//If there is a next schedule queued up, activate it
if ( fuelSchedule7 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL7_COMPARE , fuelSchedule7 . nextStartCompare ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule7 . endCompare = fuelSchedule7 . nextEndCompare ;
fuelSchedule7 . Status = PENDING ;
fuelSchedule7 . schedulesSet = 1 ;
fuelSchedule7 . hasNextSchedule = false ;
}
else { FUEL7_TIMER_DISABLE ( ) ; }
}
}
# endif
# if (INJ_CHANNELS >= 8)
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER5_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void fuelSchedule8Interrupt ( void )
2018-03-17 16:37:31 -07:00
# endif
{
if ( fuelSchedule8 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2020-03-31 23:03:11 -07:00
//fuelSchedule8.StartCallback();
inj8StartFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule8 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL8_COMPARE , FUEL8_COUNTER + uS_TO_TIMER_COMPARE ( fuelSchedule8 . duration ) ) ; //Doing this here prevents a potential overflow on restarts
2018-03-17 16:37:31 -07:00
}
else if ( fuelSchedule8 . Status = = RUNNING )
{
2020-03-31 23:03:11 -07:00
//fuelSchedule8.EndCallback();
inj8EndFunction ( ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule8 . Status = OFF ; //Turn off the schedule
fuelSchedule8 . schedulesSet = 0 ;
//If there is a next schedule queued up, activate it
if ( fuelSchedule8 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( FUEL8_COMPARE , fuelSchedule8 . nextStartCompare ) ;
2018-03-17 16:37:31 -07:00
fuelSchedule8 . endCompare = fuelSchedule8 . nextEndCompare ;
fuelSchedule8 . Status = PENDING ;
fuelSchedule8 . schedulesSet = 1 ;
fuelSchedule8 . hasNextSchedule = false ;
}
else { FUEL8_TIMER_DISABLE ( ) ; }
}
}
# endif
# if IGN_CHANNELS >= 1
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER5_COMPA_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule1Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-09-04 17:27:16 -07:00
{
if ( ignitionSchedule1 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2016-10-09 06:06:52 -07:00
ignitionSchedule1 . StartCallback ( ) ;
2013-09-04 17:27:16 -07:00
ignitionSchedule1 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2015-11-24 20:38:22 -08:00
ignitionSchedule1 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule1 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN1_COMPARE , ignitionSchedule1 . endCompare ) ; }
else { SET_COMPARE ( IGN1_COMPARE , IGN1_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule1 . duration ) ) ; } //Doing this here prevents a potential overflow on restarts
2018-01-03 01:48:35 -08:00
}
2013-09-04 17:27:16 -07:00
else if ( ignitionSchedule1 . Status = = RUNNING )
{
2018-09-06 17:38:31 -07:00
ignitionSchedule1 . EndCallback ( ) ;
2016-11-21 03:06:41 -08:00
ignitionSchedule1 . Status = OFF ; //Turn off the schedule
ignitionSchedule1 . schedulesSet = 0 ;
2018-08-13 19:46:39 -07:00
ignitionSchedule1 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule1 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule1 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN1_COMPARE , ignitionSchedule1 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule1 . Status = PENDING ;
ignitionSchedule1 . schedulesSet = 1 ;
ignitionSchedule1 . hasNextSchedule = false ;
}
else { IGN1_TIMER_DISABLE ( ) ; }
2013-09-04 17:27:16 -07:00
}
2019-03-05 23:17:33 -08:00
else if ( ignitionSchedule1 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN1_TIMER_DISABLE ( ) ;
}
2013-09-04 17:27:16 -07:00
}
2018-03-17 16:37:31 -07:00
# endif
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# if IGN_CHANNELS >= 2
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER5_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule2Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-09-04 17:27:16 -07:00
{
if ( ignitionSchedule2 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2016-10-09 06:06:52 -07:00
ignitionSchedule2 . StartCallback ( ) ;
2013-09-04 17:27:16 -07:00
ignitionSchedule2 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2015-11-29 00:47:43 -08:00
ignitionSchedule2 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule2 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN2_COMPARE , ignitionSchedule2 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
else { SET_COMPARE ( IGN2_COMPARE , IGN2_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule2 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2013-09-04 17:27:16 -07:00
}
else if ( ignitionSchedule2 . Status = = RUNNING )
{
2014-12-18 16:25:53 -08:00
ignitionSchedule2 . Status = OFF ; //Turn off the schedule
ignitionSchedule2 . EndCallback ( ) ;
2016-11-21 03:06:41 -08:00
ignitionSchedule2 . schedulesSet = 0 ;
2018-08-13 19:46:39 -07:00
ignitionSchedule2 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule2 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule2 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN2_COMPARE , ignitionSchedule2 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule2 . Status = PENDING ;
ignitionSchedule2 . schedulesSet = 1 ;
ignitionSchedule2 . hasNextSchedule = false ;
}
else { IGN2_TIMER_DISABLE ( ) ; }
2013-09-04 17:27:16 -07:00
}
2019-03-05 23:17:33 -08:00
else if ( ignitionSchedule2 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN2_TIMER_DISABLE ( ) ;
}
2013-11-13 22:17:58 -08:00
}
2018-03-17 16:37:31 -07:00
# endif
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# if IGN_CHANNELS >= 3
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER5_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule3Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
if ( ignitionSchedule3 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2016-10-09 22:58:19 -07:00
ignitionSchedule3 . StartCallback ( ) ;
2013-11-13 22:17:58 -08:00
ignitionSchedule3 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2015-12-30 21:25:57 -08:00
ignitionSchedule3 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule3 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN3_COMPARE , ignitionSchedule3 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
else { SET_COMPARE ( IGN3_COMPARE , IGN3_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule3 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2013-11-13 22:17:58 -08:00
}
else if ( ignitionSchedule3 . Status = = RUNNING )
{
ignitionSchedule3 . Status = OFF ; //Turn off the schedule
2015-02-05 13:11:33 -08:00
ignitionSchedule3 . EndCallback ( ) ;
2016-11-21 03:06:41 -08:00
ignitionSchedule3 . schedulesSet = 0 ;
2018-08-13 19:46:39 -07:00
ignitionSchedule3 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule3 . startTime ) ) ;
2017-08-30 19:09:13 -07:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule3 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN3_COMPARE , ignitionSchedule3 . nextStartCompare ) ;
2017-08-30 19:09:13 -07:00
ignitionSchedule3 . Status = PENDING ;
ignitionSchedule3 . schedulesSet = 1 ;
ignitionSchedule3 . hasNextSchedule = false ;
}
else { IGN3_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
2019-03-05 23:17:33 -08:00
else if ( ignitionSchedule3 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN3_TIMER_DISABLE ( ) ;
}
2013-11-13 22:17:58 -08:00
}
2018-03-17 16:37:31 -07:00
# endif
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# if IGN_CHANNELS >= 4
2018-01-22 21:14:03 -08:00
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPA_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule4Interrupt ( void )
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
if ( ignitionSchedule4 . Status = = PENDING ) //Check to see if this schedule is turn on
{
2016-10-09 22:58:19 -07:00
ignitionSchedule4 . StartCallback ( ) ;
2013-11-13 22:17:58 -08:00
ignitionSchedule4 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2015-12-30 21:25:57 -08:00
ignitionSchedule4 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule4 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN4_COMPARE , ignitionSchedule4 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
2022-06-26 17:39:14 -07:00
else { SET_COMPARE ( IGN4_COMPARE , IGN4_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule4 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2013-11-13 22:17:58 -08:00
}
else if ( ignitionSchedule4 . Status = = RUNNING )
{
ignitionSchedule4 . Status = OFF ; //Turn off the schedule
2015-02-05 13:11:33 -08:00
ignitionSchedule4 . EndCallback ( ) ;
2016-11-21 03:06:41 -08:00
ignitionSchedule4 . schedulesSet = 0 ;
2018-08-13 19:46:39 -07:00
ignitionSchedule4 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule4 . startTime ) ) ;
2017-08-30 19:09:13 -07:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule4 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN4_COMPARE , ignitionSchedule4 . nextStartCompare ) ;
2017-08-30 19:09:13 -07:00
ignitionSchedule4 . Status = PENDING ;
ignitionSchedule4 . schedulesSet = 1 ;
ignitionSchedule4 . hasNextSchedule = false ;
}
else { IGN4_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
2019-03-05 23:17:33 -08:00
else if ( ignitionSchedule4 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN4_TIMER_DISABLE ( ) ;
}
2013-07-10 04:18:18 -07:00
}
2018-03-17 16:37:31 -07:00
# endif
2016-11-25 07:43:57 -08:00
2018-03-17 16:37:31 -07:00
# if IGN_CHANNELS >= 5
2019-01-26 13:56:27 -08:00
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-18 02:15:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule5Interrupt ( void )
2016-12-28 03:52:00 -08:00
# endif
{
if ( ignitionSchedule5 . Status = = PENDING ) //Check to see if this schedule is turn on
{
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 ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule5 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN5_COMPARE , ignitionSchedule5 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
2022-06-26 17:39:14 -07:00
else { SET_COMPARE ( IGN5_COMPARE , IGN5_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule5 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2016-12-28 03:52:00 -08:00
}
else if ( ignitionSchedule5 . Status = = RUNNING )
{
2019-12-18 18:23:11 -08:00
ignitionSchedule5 . Status = OFF ; //Turn off the schedule
ignitionSchedule5 . EndCallback ( ) ;
ignitionSchedule5 . schedulesSet = 0 ;
ignitionSchedule5 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule5 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule5 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN5_COMPARE , ignitionSchedule5 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule5 . Status = PENDING ;
ignitionSchedule5 . schedulesSet = 1 ;
ignitionSchedule5 . hasNextSchedule = false ;
}
else { IGN5_TIMER_DISABLE ( ) ; }
}
else if ( ignitionSchedule5 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN5_TIMER_DISABLE ( ) ;
2016-12-28 03:52:00 -08:00
}
}
2018-03-17 16:37:31 -07:00
# endif
2017-01-29 22:10:17 -08:00
2019-01-26 13:56:27 -08:00
# if IGN_CHANNELS >= 6
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER4_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-26 13:56:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule6Interrupt ( void )
2019-01-26 13:56:27 -08:00
# endif
{
if ( ignitionSchedule6 . Status = = PENDING ) //Check to see if this schedule is turn on
{
ignitionSchedule6 . StartCallback ( ) ;
ignitionSchedule6 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule6 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule6 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN6_COMPARE , ignitionSchedule6 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
2022-06-26 17:39:14 -07:00
else { SET_COMPARE ( IGN6_COMPARE , IGN6_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule6 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2019-01-26 13:56:27 -08:00
}
else if ( ignitionSchedule6 . Status = = RUNNING )
{
2019-12-18 18:23:11 -08:00
ignitionSchedule6 . Status = OFF ; //Turn off the schedule
ignitionSchedule6 . EndCallback ( ) ;
ignitionSchedule6 . schedulesSet = 0 ;
ignitionSchedule6 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule6 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule6 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN6_COMPARE , ignitionSchedule6 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule6 . Status = PENDING ;
ignitionSchedule6 . schedulesSet = 1 ;
ignitionSchedule6 . hasNextSchedule = false ;
}
else { IGN6_TIMER_DISABLE ( ) ; }
}
else if ( ignitionSchedule6 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN6_TIMER_DISABLE ( ) ;
2019-01-26 13:56:27 -08:00
}
}
# endif
# if IGN_CHANNELS >= 7
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER3_COMPC_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-26 13:56:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule7Interrupt ( void )
2019-01-26 13:56:27 -08:00
# endif
{
if ( ignitionSchedule7 . Status = = PENDING ) //Check to see if this schedule is turn on
{
ignitionSchedule7 . StartCallback ( ) ;
ignitionSchedule7 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule7 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule7 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN7_COMPARE , ignitionSchedule7 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
2022-06-26 17:39:14 -07:00
else { SET_COMPARE ( IGN7_COMPARE , IGN7_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule7 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2019-01-26 13:56:27 -08:00
}
else if ( ignitionSchedule7 . Status = = RUNNING )
{
2019-12-18 18:23:11 -08:00
ignitionSchedule7 . Status = OFF ; //Turn off the schedule
ignitionSchedule7 . EndCallback ( ) ;
ignitionSchedule7 . schedulesSet = 0 ;
ignitionSchedule7 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule7 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule7 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN7_COMPARE , ignitionSchedule7 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule7 . Status = PENDING ;
ignitionSchedule7 . schedulesSet = 1 ;
ignitionSchedule7 . hasNextSchedule = false ;
}
else { IGN7_TIMER_DISABLE ( ) ; }
}
else if ( ignitionSchedule7 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN7_TIMER_DISABLE ( ) ;
2019-01-26 13:56:27 -08:00
}
}
# endif
# if IGN_CHANNELS >= 8
# if defined(CORE_AVR) //AVR chips use the ISR for this
2022-11-05 15:43:29 -07:00
ISR ( TIMER3_COMPB_vect ) //cppcheck-suppress misra-c2012-8.2
2019-01-26 13:56:27 -08:00
# else
2023-04-23 22:33:02 -07:00
inline void ignitionSchedule8Interrupt ( void )
2019-01-26 13:56:27 -08:00
# endif
{
if ( ignitionSchedule8 . Status = = PENDING ) //Check to see if this schedule is turn on
{
ignitionSchedule8 . StartCallback ( ) ;
ignitionSchedule8 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
ignitionSchedule8 . startTime = micros ( ) ;
2021-11-11 20:11:42 -08:00
if ( ignitionSchedule8 . endScheduleSetByDecoder = = true ) { SET_COMPARE ( IGN8_COMPARE , ignitionSchedule8 . endCompare ) ; } //If the decoder has set the end compare value, assign it to the next compare
2022-06-26 17:39:14 -07:00
else { SET_COMPARE ( IGN8_COMPARE , IGN8_COUNTER + uS_TO_TIMER_COMPARE ( ignitionSchedule8 . duration ) ) ; } //If the decoder based timing isn't set, doing this here prevents a potential overflow that can occur at low RPMs
2019-01-26 13:56:27 -08:00
}
else if ( ignitionSchedule8 . Status = = RUNNING )
{
2019-12-18 18:23:11 -08:00
ignitionSchedule8 . Status = OFF ; //Turn off the schedule
ignitionSchedule8 . EndCallback ( ) ;
ignitionSchedule8 . schedulesSet = 0 ;
ignitionSchedule8 . endScheduleSetByDecoder = false ;
2022-04-10 17:49:58 -07:00
ignitionCount + = 1 ; //Increment the ignition counter
2023-05-21 20:37:40 -07:00
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - ignitionSchedule8 . startTime ) ) ;
2019-12-18 18:23:11 -08:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule8 . hasNextSchedule = = true )
{
2021-11-11 20:11:42 -08:00
SET_COMPARE ( IGN8_COMPARE , ignitionSchedule8 . nextStartCompare ) ;
2019-12-18 18:23:11 -08:00
ignitionSchedule8 . Status = PENDING ;
ignitionSchedule8 . schedulesSet = 1 ;
ignitionSchedule8 . hasNextSchedule = false ;
}
else { IGN8_TIMER_DISABLE ( ) ; }
}
else if ( ignitionSchedule8 . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
IGN8_TIMER_DISABLE ( ) ;
2019-01-26 13:56:27 -08:00
}
}
# endif