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
2023-10-06 14:25:26 -07:00
FuelSchedule fuelSchedule1 ( FUEL1_COUNTER , FUEL1_COMPARE , FUEL1_TIMER_DISABLE , FUEL1_TIMER_ENABLE ) ;
FuelSchedule fuelSchedule2 ( FUEL2_COUNTER , FUEL2_COMPARE , FUEL2_TIMER_DISABLE , FUEL2_TIMER_ENABLE ) ;
FuelSchedule fuelSchedule3 ( FUEL3_COUNTER , FUEL3_COMPARE , FUEL3_TIMER_DISABLE , FUEL3_TIMER_ENABLE ) ;
FuelSchedule fuelSchedule4 ( FUEL4_COUNTER , FUEL4_COMPARE , FUEL4_TIMER_DISABLE , FUEL4_TIMER_ENABLE ) ;
2023-10-05 21:07:12 -07:00
# if (INJ_CHANNELS >= 5)
2023-10-06 14:25:26 -07:00
FuelSchedule fuelSchedule5 ( FUEL5_COUNTER , FUEL5_COMPARE , FUEL5_TIMER_DISABLE , FUEL5_TIMER_ENABLE ) ;
2023-10-05 21:07:12 -07:00
# endif
# if (INJ_CHANNELS >= 6)
2023-10-06 14:25:26 -07:00
FuelSchedule fuelSchedule6 ( FUEL6_COUNTER , FUEL6_COMPARE , FUEL6_TIMER_DISABLE , FUEL6_TIMER_ENABLE ) ;
2023-10-05 21:07:12 -07:00
# endif
# if (INJ_CHANNELS >= 7)
2023-10-06 14:25:26 -07:00
FuelSchedule fuelSchedule7 ( FUEL7_COUNTER , FUEL7_COMPARE , FUEL7_TIMER_DISABLE , FUEL7_TIMER_ENABLE ) ;
2023-10-05 21:07:12 -07:00
# endif
# if (INJ_CHANNELS >= 8)
2023-10-06 14:25:26 -07:00
FuelSchedule fuelSchedule8 ( FUEL8_COUNTER , FUEL8_COMPARE , FUEL8_TIMER_DISABLE , FUEL8_TIMER_ENABLE ) ;
# endif
IgnitionSchedule ignitionSchedule1 ( IGN1_COUNTER , IGN1_COMPARE , IGN1_TIMER_DISABLE , IGN1_TIMER_ENABLE ) ;
IgnitionSchedule ignitionSchedule2 ( IGN2_COUNTER , IGN2_COMPARE , IGN2_TIMER_DISABLE , IGN2_TIMER_ENABLE ) ;
IgnitionSchedule ignitionSchedule3 ( IGN3_COUNTER , IGN3_COMPARE , IGN3_TIMER_DISABLE , IGN3_TIMER_ENABLE ) ;
IgnitionSchedule ignitionSchedule4 ( IGN4_COUNTER , IGN4_COMPARE , IGN4_TIMER_DISABLE , IGN4_TIMER_ENABLE ) ;
IgnitionSchedule ignitionSchedule5 ( IGN5_COUNTER , IGN5_COMPARE , IGN5_TIMER_DISABLE , IGN5_TIMER_ENABLE ) ;
# if IGN_CHANNELS >= 6
IgnitionSchedule ignitionSchedule6 ( IGN6_COUNTER , IGN6_COMPARE , IGN6_TIMER_DISABLE , IGN6_TIMER_ENABLE ) ;
# endif
# if IGN_CHANNELS >= 7
IgnitionSchedule ignitionSchedule7 ( IGN7_COUNTER , IGN7_COMPARE , IGN7_TIMER_DISABLE , IGN7_TIMER_ENABLE ) ;
# endif
# if IGN_CHANNELS >= 8
IgnitionSchedule ignitionSchedule8 ( IGN8_COUNTER , IGN8_COMPARE , IGN8_TIMER_DISABLE , IGN8_TIMER_ENABLE ) ;
# endif
2016-10-06 23:34:27 -07:00
2023-10-06 14:25:26 -07:00
void initialiseSchedulers ( )
{
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 ;
2023-10-06 14:25:26 -07:00
# if INJ_CHANNELS >= 5
2016-10-06 23:34:27 -07:00
fuelSchedule5 . Status = OFF ;
2023-10-06 14:25:26 -07:00
# endif
# if INJ_CHANNELS >= 6
2018-01-22 21:14:03 -08:00
fuelSchedule6 . Status = OFF ;
2023-10-06 14:25:26 -07:00
# endif
# if INJ_CHANNELS >= 7
2018-01-22 21:14:03 -08:00
fuelSchedule7 . Status = OFF ;
2023-10-06 14:25:26 -07:00
# endif
# if INJ_CHANNELS >= 8
2018-01-22 21:14:03 -08:00
fuelSchedule8 . Status = OFF ;
2023-10-06 14:25:26 -07:00
# endif
2018-01-22 21:14:03 -08:00
2016-10-06 23:34:27 -07:00
ignitionSchedule1 . Status = OFF ;
2019-03-05 23:17:33 -08:00
IGN1_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
ignitionSchedule2 . Status = OFF ;
2019-03-05 23:17:33 -08:00
IGN2_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
ignitionSchedule3 . Status = OFF ;
2019-03-05 23:17:33 -08:00
IGN3_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
ignitionSchedule4 . Status = OFF ;
2019-03-05 23:17:33 -08:00
IGN4_TIMER_ENABLE ( ) ;
2022-06-26 16:30:40 -07:00
# if (IGN_CHANNELS >= 5)
2023-10-06 14:25:26 -07:00
ignitionSchedule5 . Status = OFF ;
2020-02-27 15:22:33 -08:00
IGN5_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 6
ignitionSchedule6 . Status = OFF ;
2020-02-27 15:22:33 -08:00
IGN6_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 7
ignitionSchedule7 . Status = OFF ;
2020-02-27 15:22:33 -08:00
IGN7_TIMER_ENABLE ( ) ;
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 8
ignitionSchedule8 . Status = OFF ;
2020-02-27 15:22:33 -08:00
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
2023-10-06 14:25:26 -07:00
fuelSchedule1 . pStartFunction = nullCallback ;
fuelSchedule1 . pEndFunction = nullCallback ;
fuelSchedule2 . pStartFunction = nullCallback ;
fuelSchedule2 . pEndFunction = nullCallback ;
fuelSchedule3 . pStartFunction = nullCallback ;
fuelSchedule3 . pEndFunction = nullCallback ;
fuelSchedule4 . pStartFunction = nullCallback ;
fuelSchedule4 . pEndFunction = nullCallback ;
# if (INJ_CHANNELS >= 5)
fuelSchedule5 . pStartFunction = nullCallback ;
fuelSchedule5 . pEndFunction = nullCallback ;
# endif
# if (INJ_CHANNELS >= 6)
fuelSchedule6 . pStartFunction = nullCallback ;
fuelSchedule6 . pEndFunction = nullCallback ;
# endif
# if (INJ_CHANNELS >= 7)
fuelSchedule7 . pStartFunction = nullCallback ;
fuelSchedule7 . pEndFunction = nullCallback ;
# endif
# if (INJ_CHANNELS >= 8)
fuelSchedule8 . pStartFunction = nullCallback ;
fuelSchedule8 . pEndFunction = nullCallback ;
# endif
ignitionSchedule1 . pStartCallback = nullCallback ;
ignitionSchedule1 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition1StartAngle = 0 ;
ignition1EndAngle = 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) */
2023-10-06 14:25:26 -07:00
ignitionSchedule2 . pStartCallback = nullCallback ;
ignitionSchedule2 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition2StartAngle = 0 ;
ignition2EndAngle = 0 ;
channel2IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
2023-10-06 14:25:26 -07:00
ignitionSchedule3 . pStartCallback = nullCallback ;
ignitionSchedule3 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition3StartAngle = 0 ;
ignition3EndAngle = 0 ;
channel3IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
2023-10-06 14:25:26 -07:00
ignitionSchedule4 . pStartCallback = nullCallback ;
ignitionSchedule4 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition4StartAngle = 0 ;
ignition4EndAngle = 0 ;
channel4IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
# if (IGN_CHANNELS >= 5)
2023-10-06 14:25:26 -07:00
ignitionSchedule5 . pStartCallback = nullCallback ;
ignitionSchedule5 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition5StartAngle = 0 ;
ignition5EndAngle = 0 ;
channel5IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
# endif
# if (IGN_CHANNELS >= 6)
2023-10-06 14:25:26 -07:00
ignitionSchedule6 . pStartCallback = nullCallback ;
ignitionSchedule6 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition6StartAngle = 0 ;
ignition6EndAngle = 0 ;
channel6IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
# endif
# if (IGN_CHANNELS >= 7)
2023-10-06 14:25:26 -07:00
ignitionSchedule7 . pStartCallback = nullCallback ;
ignitionSchedule7 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition7StartAngle = 0 ;
ignition7EndAngle = 0 ;
channel7IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
# endif
# if (IGN_CHANNELS >= 8)
2023-10-06 14:25:26 -07:00
ignitionSchedule8 . pStartCallback = nullCallback ;
ignitionSchedule8 . pEndCallback = nullCallback ;
2023-06-25 19:13:53 -07:00
ignition8StartAngle = 0 ;
ignition8EndAngle = 0 ;
channel8IgnDegrees = 0 ; /**< The number of crank degrees until cylinder 2 (and 5/6/7/8) is at TDC */
# endif
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 */
# if (INJ_CHANNELS >= 5)
channel5InjDegrees = 0 ; /**< The number of crank degrees until cylinder 5 is at TDC */
# endif
# if (INJ_CHANNELS >= 6)
channel6InjDegrees = 0 ; /**< The number of crank degrees until cylinder 6 is at TDC */
# endif
# if (INJ_CHANNELS >= 7)
channel7InjDegrees = 0 ; /**< The number of crank degrees until cylinder 7 is at TDC */
# endif
# if (INJ_CHANNELS >= 8)
channel8InjDegrees = 0 ; /**< The number of crank degrees until cylinder 8 is at TDC */
# endif
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-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
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
{
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
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
}
2023-10-06 14:25:26 -07:00
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
{
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
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
}
}
2023-10-06 14:25:26 -07:00
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
{
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
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
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
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
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
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
2023-10-06 14:25:26 -07:00
void setIgnitionSchedule1 ( unsigned long timeout , unsigned long duration )
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 . 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 ;
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-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
2023-10-06 00:10:20 -07:00
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 ( ) ;
}
}
2023-10-06 14:25:26 -07:00
void setIgnitionSchedule2 ( unsigned long timeout , unsigned long duration )
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 . 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-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
}
2023-10-06 14:25:26 -07:00
void setIgnitionSchedule3 ( unsigned long timeout , unsigned long duration )
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 . 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-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
}
2023-10-06 14:25:26 -07:00
void setIgnitionSchedule4 ( unsigned long timeout , unsigned long duration )
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 . 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-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
}
2023-10-06 14:25:26 -07:00
void setIgnitionSchedule5 ( unsigned long timeout , unsigned long duration )
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 . 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
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
}
2023-10-06 14:25:26 -07:00
# if IGN_CHANNELS >= 6
void setIgnitionSchedule6 ( unsigned long timeout , unsigned long duration )
2018-03-17 16:37:31 -07:00
{
if ( ignitionSchedule6 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
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
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
}
}
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 7
void setIgnitionSchedule7 ( unsigned long timeout , unsigned long duration )
2018-03-17 16:37:31 -07:00
{
if ( ignitionSchedule7 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
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
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
}
}
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 8
void setIgnitionSchedule8 ( unsigned long timeout , unsigned long duration )
2018-03-17 16:37:31 -07:00
{
if ( ignitionSchedule8 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
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
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
}
}
2023-10-06 14:25:26 -07:00
# endif
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
}
}
2023-10-06 14:25:26 -07:00
// Shared ISR function for all fuel timers.
// This is completely inlined into the ISR - there is no function call
// overhead.
static inline __attribute__ ( ( always_inline ) ) void fuelScheduleISR ( FuelSchedule & schedule )
{
if ( schedule . Status = = PENDING ) //Check to see if this schedule is turn on
{
schedule . pStartFunction ( ) ;
schedule . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
SET_COMPARE ( schedule . compare , schedule . counter + uS_TO_TIMER_COMPARE ( schedule . duration ) ) ; //Doing this here prevents a potential overflow on restarts
}
else if ( schedule . Status = = RUNNING )
{
schedule . pEndFunction ( ) ;
schedule . Status = OFF ; //Turn off the schedule
//If there is a next schedule queued up, activate it
if ( schedule . hasNextSchedule = = true )
{
SET_COMPARE ( schedule . compare , schedule . nextStartCompare ) ;
SET_COMPARE ( schedule . endCompare , schedule . nextEndCompare ) ;
schedule . Status = PENDING ;
schedule . hasNextSchedule = false ;
}
else
{
schedule . pTimerDisable ( ) ;
}
}
else if ( schedule . Status = = OFF )
{
schedule . pTimerDisable ( ) ; //Safety check. Turn off this output compare unit and return without performing any action
}
}
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
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-10-06 14:25:26 -07:00
void fuelSchedule1Interrupt ( ) //Most ARM chips can simply call a function
2016-10-06 23:34:27 -07:00
# endif
2013-07-10 04:18:18 -07:00
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule1 ) ;
2013-07-10 04:18:18 -07:00
}
2016-07-27 02:31:38 -07:00
2023-10-06 14:25:26 -07:00
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-10-06 14:25:26 -07:00
void fuelSchedule2Interrupt ( ) //Most ARM chips can simply call a function
2016-10-06 23:34:27 -07:00
# endif
2013-07-10 04:18:18 -07:00
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule2 ) ;
2013-11-13 22:17:58 -08:00
}
2016-07-27 02:31:38 -07:00
2023-10-06 14:25:26 -07:00
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-10-06 14:25:26 -07:00
void fuelSchedule3Interrupt ( ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule3 ) ;
2013-11-13 22:17:58 -08:00
}
2017-01-29 22:10:17 -08:00
2023-10-06 14:25:26 -07:00
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-10-06 14:25:26 -07:00
void fuelSchedule4Interrupt ( ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule4 ) ;
2013-09-04 17:27:16 -07:00
}
2017-01-29 22:10:17 -08:00
2023-10-06 14:25:26 -07:00
# if INJ_CHANNELS >= 5
2018-03-17 16:37:31 -07: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-10-06 14:25:26 -07:00
void fuelSchedule5Interrupt ( ) //Most ARM chips can simply call a function
2018-03-17 16:37:31 -07:00
# endif
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule5 ) ;
2018-03-17 16:37:31 -07:00
}
# endif
2023-10-06 14:25:26 -07:00
# if INJ_CHANNELS >= 6
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-10-06 14:25:26 -07:00
void fuelSchedule6Interrupt ( ) //Most ARM chips can simply call a function
2018-01-22 21:14:03 -08:00
# endif
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule6 ) ;
2018-01-22 21:14:03 -08:00
}
# endif
2023-10-06 14:25:26 -07:00
# if INJ_CHANNELS >= 7
2018-03-17 16:37:31 -07:00
# 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-10-06 14:25:26 -07:00
void fuelSchedule7Interrupt ( ) //Most ARM chips can simply call a function
2018-03-17 16:37:31 -07:00
# endif
{
2023-10-06 14:25:26 -07:00
fuelScheduleISR ( fuelSchedule7 ) ;
2018-03-17 16:37:31 -07:00
}
# endif
2023-10-06 14:25:26 -07:00
# if INJ_CHANNELS >= 8
2018-03-17 16:37:31 -07:00
# 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-10-06 14:25:26 -07:00
void fuelSchedule8Interrupt ( ) //Most ARM chips can simply call a function
2018-03-17 16:37:31 -07:00
# endif
2023-10-06 14:25:26 -07:00
{
fuelScheduleISR ( fuelSchedule8 ) ;
}
# endif
// Shared ISR function for all ignition timers.
// This is completely inlined into the ISR - there is no function call
// overhead.
static inline __attribute__ ( ( always_inline ) ) void ignitionScheduleISR ( IgnitionSchedule & schedule )
2018-03-17 16:37:31 -07:00
{
2023-10-06 14:25:26 -07:00
if ( schedule . Status = = PENDING ) //Check to see if this schedule is turn on
2018-03-17 16:37:31 -07:00
{
2023-10-06 14:25:26 -07:00
schedule . pStartCallback ( ) ;
schedule . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
schedule . startTime = micros ( ) ;
if ( schedule . endScheduleSetByDecoder = = true ) { SET_COMPARE ( schedule . compare , schedule . endCompare ) ; }
else { SET_COMPARE ( schedule . compare , schedule . counter + uS_TO_TIMER_COMPARE ( schedule . duration ) ) ; } //Doing this here prevents a potential overflow on restarts
2018-03-17 16:37:31 -07:00
}
2023-10-06 14:25:26 -07:00
else if ( schedule . Status = = RUNNING )
2018-03-17 16:37:31 -07:00
{
2023-10-06 14:25:26 -07:00
schedule . pEndCallback ( ) ;
schedule . Status = OFF ; //Turn off the schedule
schedule . endScheduleSetByDecoder = false ;
ignitionCount = ignitionCount + 1 ; //Increment the ignition counter
currentStatus . actualDwell = DWELL_AVERAGE ( ( micros ( ) - schedule . startTime ) ) ;
//If there is a next schedule queued up, activate it
if ( schedule . hasNextSchedule = = true )
{
SET_COMPARE ( schedule . compare , schedule . nextStartCompare ) ;
schedule . Status = PENDING ;
schedule . hasNextSchedule = false ;
}
else
{
schedule . pTimerDisable ( ) ;
}
}
else if ( schedule . Status = = OFF )
{
//Catch any spurious interrupts. This really shouldn't ever be called, but there as a safety
schedule . pTimerDisable ( ) ;
2018-03-17 16:37:31 -07:00
}
}
# 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-10-06 14:25:26 -07:00
void ignitionSchedule1Interrupt ( void ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-09-04 17:27:16 -07:00
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule1 ) ;
2013-09-04 17:27:16 -07:00
}
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# 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-10-06 14:25:26 -07:00
void ignitionSchedule2Interrupt ( void ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-09-04 17:27:16 -07:00
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule2 ) ;
2013-11-13 22:17:58 -08:00
}
2017-01-29 22:10:17 -08:00
2018-03-17 16:37:31 -07:00
# 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-10-06 14:25:26 -07:00
void ignitionSchedule3Interrupt ( void ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule3 ) ;
2013-11-13 22:17:58 -08:00
}
2017-01-29 22:10:17 -08:00
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-10-06 14:25:26 -07:00
void ignitionSchedule4Interrupt ( void ) //Most ARM chips can simply call a function
2016-06-26 20:45:51 -07:00
# endif
2013-11-13 22:17:58 -08:00
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule4 ) ;
2013-07-10 04:18:18 -07:00
}
2016-11-25 07:43:57 -08:00
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-10-06 14:25:26 -07:00
void ignitionSchedule5Interrupt ( void ) //Most ARM chips can simply call a function
2016-12-28 03:52:00 -08:00
# endif
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule5 ) ;
2016-12-28 03:52:00 -08:00
}
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-10-06 14:25:26 -07:00
void ignitionSchedule6Interrupt ( void ) //Most ARM chips can simply call a function
2019-01-26 13:56:27 -08:00
# endif
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule6 ) ;
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-10-06 14:25:26 -07:00
void ignitionSchedule7Interrupt ( void ) //Most ARM chips can simply call a function
2019-01-26 13:56:27 -08:00
# endif
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule7 ) ;
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-10-06 14:25:26 -07:00
void ignitionSchedule8Interrupt ( void ) //Most ARM chips can simply call a function
2019-01-26 13:56:27 -08:00
# endif
{
2023-10-06 14:25:26 -07:00
ignitionScheduleISR ( ignitionSchedule8 ) ;
2019-01-26 13:56:27 -08:00
}
# endif
2023-08-21 21:38:17 -07:00
void disablePendingFuelSchedule ( byte channel )
{
2023-08-27 18:21:55 -07:00
noInterrupts ( ) ;
2023-08-21 21:38:17 -07:00
switch ( channel )
{
2023-08-25 16:04:57 -07:00
case 0 :
2023-08-21 21:38:17 -07:00
if ( fuelSchedule1 . Status = = PENDING ) { fuelSchedule1 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 1 :
2023-08-21 21:38:17 -07:00
if ( fuelSchedule2 . Status = = PENDING ) { fuelSchedule2 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 2 :
2023-08-21 21:38:17 -07:00
if ( fuelSchedule3 . Status = = PENDING ) { fuelSchedule3 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 3 :
2023-08-21 21:38:17 -07:00
if ( fuelSchedule4 . Status = = PENDING ) { fuelSchedule4 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 4 :
2023-10-06 14:25:26 -07:00
# if (INJ_CHANNELS >= 5)
2023-08-21 21:38:17 -07:00
if ( fuelSchedule5 . Status = = PENDING ) { fuelSchedule5 . Status = OFF ; }
2023-10-06 14:25:26 -07:00
# endif
2023-08-21 21:38:17 -07:00
break ;
2023-08-25 16:04:57 -07:00
case 5 :
2023-10-06 14:25:26 -07:00
# if (INJ_CHANNELS >= 6)
2023-08-21 21:38:17 -07:00
if ( fuelSchedule6 . Status = = PENDING ) { fuelSchedule6 . Status = OFF ; }
2023-10-06 14:25:26 -07:00
# endif
2023-08-21 21:38:17 -07:00
break ;
2023-08-25 16:04:57 -07:00
case 6 :
2023-10-06 14:25:26 -07:00
# if (INJ_CHANNELS >= 7)
2023-08-21 21:38:17 -07:00
if ( fuelSchedule7 . Status = = PENDING ) { fuelSchedule7 . Status = OFF ; }
2023-10-06 14:25:26 -07:00
# endif
2023-08-21 21:38:17 -07:00
break ;
2023-08-25 16:04:57 -07:00
case 7 :
2023-10-06 14:25:26 -07:00
# if (INJ_CHANNELS >= 8)
2023-08-21 21:38:17 -07:00
if ( fuelSchedule8 . Status = = PENDING ) { fuelSchedule8 . Status = OFF ; }
2023-10-06 14:25:26 -07:00
# endif
2023-08-21 21:38:17 -07:00
break ;
}
2023-08-27 18:21:55 -07:00
interrupts ( ) ;
2023-08-21 21:38:17 -07:00
}
void disablePendingIgnSchedule ( byte channel )
{
2023-08-27 18:21:55 -07:00
noInterrupts ( ) ;
2023-08-21 21:38:17 -07:00
switch ( channel )
{
2023-08-25 16:04:57 -07:00
case 0 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule1 . Status = = PENDING ) { ignitionSchedule1 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 1 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule2 . Status = = PENDING ) { ignitionSchedule2 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 2 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule3 . Status = = PENDING ) { ignitionSchedule3 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 3 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule4 . Status = = PENDING ) { ignitionSchedule4 . Status = OFF ; }
break ;
2023-08-25 16:04:57 -07:00
case 4 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule5 . Status = = PENDING ) { ignitionSchedule5 . Status = OFF ; }
break ;
2023-10-06 14:25:26 -07:00
# if IGN_CHANNELS >= 6
case 6 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule6 . Status = = PENDING ) { ignitionSchedule6 . Status = OFF ; }
break ;
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 7
case 7 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule7 . Status = = PENDING ) { ignitionSchedule7 . Status = OFF ; }
break ;
2023-10-06 14:25:26 -07:00
# endif
# if IGN_CHANNELS >= 8
case 8 :
2023-08-21 21:38:17 -07:00
if ( ignitionSchedule8 . Status = = PENDING ) { ignitionSchedule8 . Status = OFF ; }
break ;
2023-10-06 14:25:26 -07:00
# endif
2023-08-21 21:38:17 -07:00
}
2023-08-27 18:21:55 -07:00
interrupts ( ) ;
2023-08-21 21:38:17 -07:00
}