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
*/
2015-02-14 09:04:00 -08:00
# include "scheduler.h"
# include "globals.h"
2013-07-10 04:18:18 -07:00
2013-09-04 17:27:16 -07:00
void initialiseSchedulers ( )
2013-07-10 04:18:18 -07:00
{
2016-07-27 02:31:38 -07:00
nullSchedule . Status = OFF ;
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
2014-01-30 20:02:32 -08:00
// Much help in this from http://arduinomega.blogspot.com.au/2011/05/timer2-and-overflow-interrupt-lets-get.html
2013-09-04 17:27:16 -07:00
//Fuel Schedules, which uses timer 3
2016-06-07 20:11:52 -07:00
TCCR3B = 0x00 ; //Disable Timer3 while we set it up
2013-07-10 04:18:18 -07:00
TCNT3 = 0 ; //Reset Timer Count
2013-09-04 17:27:16 -07:00
TIFR3 = 0x00 ; //Timer3 INT Flag Reg: Clear Timer Overflow Flag
TCCR3A = 0x00 ; //Timer3 Control Reg A: Wave Gen Mode normal
TCCR3B = ( 1 < < CS12 ) ; //Timer3 Control Reg B: Timer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
2015-02-06 02:19:16 -08:00
//TCCR3B = 0x03; //Timer3 Control Reg B: Timer Prescaler set to 64. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
2016-06-26 20:45:51 -07:00
2013-09-04 17:27:16 -07:00
//Ignition Schedules, which uses timer 5
2016-10-17 17:14:37 -07:00
TCCR5B = 0x00 ; //Disable Timer5 while we set it up
2013-09-04 17:27:16 -07:00
TCNT5 = 0 ; //Reset Timer Count
2013-11-13 22:17:58 -08:00
TIFR5 = 0x00 ; //Timer5 INT Flag Reg: Clear Timer Overflow Flag
TCCR5A = 0x00 ; //Timer5 Control Reg A: Wave Gen Mode normal
2015-08-29 04:16:03 -07:00
//TCCR5B = (1 << CS12); //Timer5 Control Reg B: Timer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
2015-09-24 13:24:40 -07:00
TCCR5B = 0x03 ; //aka Divisor = 64 = 490.1Hz
2016-06-26 20:45:51 -07:00
2013-11-13 22:17:58 -08:00
//The remaining Schedules (Schedules 4 for fuel and ignition) use Timer4
2016-06-07 20:11:52 -07:00
TCCR4B = 0x00 ; //Disable Timer4 while we set it up
2013-11-13 22:17:58 -08:00
TCNT4 = 0 ; //Reset Timer Count
TIFR4 = 0x00 ; //Timer4 INT Flag Reg: Clear Timer Overflow Flag
TCCR4A = 0x00 ; //Timer4 Control Reg A: Wave Gen Mode normal
2017-01-29 22:10:17 -08:00
TCCR4B = ( 1 < < CS12 ) ; //Timer4 Control Reg B: aka Divisor = 256 = 122.5HzTimer Prescaler set to 256. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
2017-02-28 19:44:25 -08:00
# elif defined (CORE_TEENSY)
2016-10-15 03:52:20 -07:00
2016-11-22 16:51:12 -08:00
//FlexTimer 0 is used for 4 ignition and 4 injection schedules. There are 8 channels on this module, so no other timers are needed
FTM0_MODE | = FTM_MODE_WPDIS ; // Write Protection Disable
FTM0_MODE | = FTM_MODE_FTMEN ; //Flex Timer module enable
FTM0_MODE | = FTM_MODE_INIT ;
FTM0_SC = 0x00 ; // Set this to zero before changing the modulus
FTM0_CNTIN = 0x0000 ; //Shouldn't be needed, but just in case
FTM0_CNT = 0x0000 ; // Reset the count to zero
FTM0_MOD = 0xFFFF ; // max modulus = 65535
2017-01-10 22:38:59 -08:00
//FlexTimer 1 is used for schedules on channel 5+. Currently only channel 5 is used, but will likely be expanded later
FTM1_MODE | = FTM_MODE_WPDIS ; // Write Protection Disable
FTM1_MODE | = FTM_MODE_FTMEN ; //Flex Timer module enable
FTM1_MODE | = FTM_MODE_INIT ;
FTM1_SC = 0x00 ; // Set this to zero before changing the modulus
FTM1_CNTIN = 0x0000 ; //Shouldn't be needed, but just in case
FTM1_CNT = 0x0000 ; // Reset the count to zero
FTM1_MOD = 0xFFFF ; // max modulus = 65535
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
/*
2017-01-10 22:38:59 -08:00
* Enable the clock for FTM0 / 1
2016-11-22 16:51:12 -08:00
* 00 No clock selected . Disables the FTM counter .
* 01 System clock
* 10 Fixed frequency clock
* 11 External clock
2017-01-29 22:10:17 -08:00
*/
2016-11-22 16:51:12 -08:00
FTM0_SC | = FTM_SC_CLKS ( 0 b1 ) ;
2017-01-10 22:38:59 -08:00
FTM1_SC | = FTM_SC_CLKS ( 0 b1 ) ;
2016-11-22 16:51:12 -08:00
2017-01-29 22:10:17 -08:00
/*
* Set Prescaler
2016-11-22 16:51:12 -08:00
* This is the slowest that the timer can be clocked ( Without used the slow timer , which is too slow ) . It results in ticks of 2.13333 uS on the teensy 3.5 :
* 60000000 Hz = F_BUS
* 128 * 1000000u S / F_BUS = 2.133 uS
2017-01-29 22:10:17 -08:00
*
2016-11-22 16:51:12 -08:00
* 000 = Divide by 1
* 001 Divide by 2
* 010 Divide by 4
* 011 Divide by 8
* 100 Divide by 16
* 101 Divide by 32
* 110 Divide by 64
* 111 Divide by 128
*/
FTM0_SC | = FTM_SC_PS ( 0 b111 ) ;
2017-01-10 22:38:59 -08:00
FTM1_SC | = FTM_SC_PS ( 0 b111 ) ;
2016-11-22 16:51:12 -08:00
2017-01-29 22:10:17 -08:00
//Setup the channels (See Pg 1014 of K64 DS).
2016-11-22 16:51:12 -08:00
//FTM0_C0SC &= ~FTM_CSC_ELSB; //Probably not needed as power on state should be 0
//FTM0_C0SC &= ~FTM_CSC_ELSA; //Probably not needed as power on state should be 0
//FTM0_C0SC &= ~FTM_CSC_DMA; //Probably not needed as power on state should be 0
FTM0_C0SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C0SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C0SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C1SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C1SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C1SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C2SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C2SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C2SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C3SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C3SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C3SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C4SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C4SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C4SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C5SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C5SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C5SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C6SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C6SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C6SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-29 22:10:17 -08:00
2016-11-22 16:51:12 -08:00
FTM0_C7SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM0_C7SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM0_C7SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-02-20 02:34:28 -08:00
//Do the same, but on flex timer 3 (Used for channels 5-8)
FTM3_C0SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C0SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C0SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C1SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C1SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C1SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C2SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C2SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C2SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C3SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C3SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C3SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C4SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C4SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C4SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C5SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C5SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C5SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C6SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C6SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C6SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
FTM3_C7SC & = ~ FTM_CSC_MSB ; //According to Pg 965 of the K64 datasheet, this should not be needed as MSB is reset to 0 upon reset, but the channel interrupt fails to fire without it
FTM3_C7SC | = FTM_CSC_MSA ; //Enable Compare mode
FTM3_C7SC | = FTM_CSC_CHIE ; //Enable channel compare interrupt
2017-01-10 22:38:59 -08:00
2016-11-22 16:51:12 -08:00
// enable IRQ Interrupt
NVIC_ENABLE_IRQ ( IRQ_FTM0 ) ;
2017-01-10 22:38:59 -08:00
NVIC_ENABLE_IRQ ( IRQ_FTM1 ) ;
2017-01-29 22:10:17 -08:00
2016-10-06 23:34:27 -07:00
# endif
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 ;
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 ;
ignitionSchedule1 . Status = OFF ;
ignitionSchedule2 . Status = OFF ;
ignitionSchedule3 . Status = OFF ;
ignitionSchedule4 . Status = OFF ;
2016-12-28 03:52:00 -08:00
ignitionSchedule5 . Status = OFF ;
2017-01-29 22:10:17 -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 ;
2017-01-29 22:10:17 -08:00
2013-07-10 04:18:18 -07: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
*/
2013-09-04 17:27:16 -07:00
void setFuelSchedule1 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2013-07-10 04:18:18 -07:00
{
2013-09-04 17:27:16 -07:00
if ( fuelSchedule1 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2017-01-29 22:10:17 -08:00
2013-09-04 17:27:16 -07:00
fuelSchedule1 . StartCallback = startCallback ; //Name the start callback function
2014-01-09 23:54:33 -08:00
fuelSchedule1 . EndCallback = endCallback ; //Name the end callback function
2016-07-27 02:31:38 -07:00
fuelSchedule1 . duration = duration ;
/*
2016-11-22 16:51:12 -08:00
* The following must be enclosed in the noInterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
2016-07-27 02:31:38 -07:00
* We need to calculate the value to reset the timer to ( preload ) in order to achieve the desired overflow time
2017-01-29 22:10:17 -08:00
* As the timer is ticking every 16u S ( Time per Tick = ( Prescale ) * ( 1 / Frequency ) )
2016-07-27 02:31:38 -07:00
* unsigned int absoluteTimeout = TCNT3 + ( timeout / 16 ) ; //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts ( ) ;
2016-10-09 06:06:52 -07:00
fuelSchedule1 . startCompare = FUEL1_COUNTER + ( timeout > > 4 ) ; //As above, but with bit shift instead of / 16
2016-07-27 02:31:38 -07:00
fuelSchedule1 . endCompare = fuelSchedule1 . startCompare + ( duration > > 4 ) ;
fuelSchedule1 . Status = PENDING ; //Turn this schedule on
fuelSchedule1 . schedulesSet + + ; //Increment the number of times this schedule has been set
2016-12-28 03:54:15 -08:00
/*if(channel5InjEnabled) { FUEL1_COMPARE = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, FUEL1_COUNTER); } //Schedule 1 shares a timer with schedule 5
else { timer3Aqueue [ 0 ] = & fuelSchedule1 ; timer3Aqueue [ 1 ] = & fuelSchedule1 ; timer3Aqueue [ 2 ] = & fuelSchedule1 ; timer3Aqueue [ 3 ] = & fuelSchedule1 ; FUEL1_COMPARE = fuelSchedule1 . startCompare ; } */
timer3Aqueue [ 0 ] = & fuelSchedule1 ; timer3Aqueue [ 1 ] = & fuelSchedule1 ; timer3Aqueue [ 2 ] = & fuelSchedule1 ; timer3Aqueue [ 3 ] = & fuelSchedule1 ; FUEL1_COMPARE = fuelSchedule1 . startCompare ;
2016-07-27 02:31:38 -07:00
interrupts ( ) ;
2016-10-09 06:06:52 -07:00
FUEL1_TIMER_ENABLE ( ) ;
2013-07-10 04:18:18 -07:00
}
2013-09-04 17:27:16 -07:00
void setFuelSchedule2 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( fuelSchedule2 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2017-01-29 22:10:17 -08:00
2013-09-04 17:27:16 -07:00
fuelSchedule2 . StartCallback = startCallback ; //Name the start callback function
2014-01-09 23:54:33 -08:00
fuelSchedule2 . EndCallback = endCallback ; //Name the end callback function
2016-07-27 02:31:38 -07:00
fuelSchedule2 . duration = duration ;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
* We need to calculate the value to reset the timer to ( preload ) in order to achieve the desired overflow time
2017-01-29 22:10:17 -08:00
* As the timer is ticking every 16u S ( Time per Tick = ( Prescale ) * ( 1 / Frequency ) )
2016-07-27 02:31:38 -07:00
* unsigned int absoluteTimeout = TCNT3 + ( timeout / 16 ) ; //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts ( ) ;
2016-10-09 06:06:52 -07:00
fuelSchedule2 . startCompare = FUEL2_COUNTER + ( timeout > > 4 ) ; //As above, but with bit shift instead of / 16
2016-07-27 02:31:38 -07:00
fuelSchedule2 . endCompare = fuelSchedule2 . startCompare + ( duration > > 4 ) ;
2016-10-09 06:06:52 -07:00
FUEL2_COMPARE = fuelSchedule2 . startCompare ; //Use the B copmare unit of timer 3
2016-07-27 02:31:38 -07:00
fuelSchedule2 . Status = PENDING ; //Turn this schedule on
fuelSchedule2 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
2016-10-09 06:06:52 -07:00
FUEL2_TIMER_ENABLE ( ) ;
2013-09-04 17:27:16 -07:00
}
2013-11-13 22:17:58 -08:00
void setFuelSchedule3 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( fuelSchedule3 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2016-10-06 23:34:27 -07:00
fuelSchedule3 . StartCallback = startCallback ; //Name the start callback function
fuelSchedule3 . EndCallback = endCallback ; //Name the end callback function
fuelSchedule3 . duration = duration ;
2017-01-29 22:10:17 -08:00
2016-10-06 23:34:27 -07:00
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
* We need to calculate the value to reset the timer to ( preload ) in order to achieve the desired overflow time
2017-01-29 22:10:17 -08:00
* As the timer is ticking every 16u S ( Time per Tick = ( Prescale ) * ( 1 / Frequency ) )
2016-10-06 23:34:27 -07:00
* unsigned int absoluteTimeout = TCNT3 + ( timeout / 16 ) ; //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts ( ) ;
2016-10-09 06:06:52 -07:00
fuelSchedule3 . startCompare = FUEL3_COUNTER + ( timeout > > 4 ) ; //As above, but with bit shift instead of / 16
2016-06-26 20:45:51 -07:00
fuelSchedule3 . endCompare = fuelSchedule3 . startCompare + ( duration > > 4 ) ;
2016-10-09 06:06:52 -07:00
FUEL3_COMPARE = fuelSchedule3 . startCompare ; //Use the C copmare unit of timer 3
2013-11-13 22:17:58 -08:00
fuelSchedule3 . Status = PENDING ; //Turn this schedule on
2016-06-26 20:45:51 -07:00
fuelSchedule3 . schedulesSet + + ; //Increment the number of times this schedule has been set
2016-10-06 23:34:27 -07:00
interrupts ( ) ;
2016-10-09 06:06:52 -07:00
FUEL3_TIMER_ENABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
void setFuelSchedule4 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) ) //Uses timer 4 compare B
{
if ( fuelSchedule4 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2017-01-29 22:10:17 -08:00
2016-10-06 23:34:27 -07:00
fuelSchedule4 . StartCallback = startCallback ; //Name the start callback function
fuelSchedule4 . EndCallback = endCallback ; //Name the end callback function
fuelSchedule4 . duration = duration ;
2017-01-29 22:10:17 -08:00
2016-10-06 23:34:27 -07:00
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
* We need to calculate the value to reset the timer to ( preload ) in order to achieve the desired overflow time
2017-01-29 22:10:17 -08:00
* As the timer is ticking every 16u S ( Time per Tick = ( Prescale ) * ( 1 / Frequency ) )
2016-10-06 23:34:27 -07:00
* unsigned int absoluteTimeout = TCNT3 + ( timeout / 16 ) ; //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
*/
noInterrupts ( ) ;
2016-10-09 06:06:52 -07:00
fuelSchedule4 . startCompare = FUEL4_COUNTER + ( timeout > > 4 ) ;
2016-08-30 23:54:36 -07:00
fuelSchedule4 . endCompare = fuelSchedule4 . startCompare + ( duration > > 4 ) ;
2016-10-09 06:06:52 -07:00
FUEL4_COMPARE = fuelSchedule4 . startCompare ; //Use the C copmare unit of timer 3
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = PENDING ; //Turn this schedule on
2016-06-26 20:45:51 -07:00
fuelSchedule4 . schedulesSet + + ; //Increment the number of times this schedule has been set
2016-10-06 23:34:27 -07:00
interrupts ( ) ;
2016-10-09 06:06:52 -07:00
FUEL4_TIMER_ENABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2016-06-26 20:45:51 -07:00
void setFuelSchedule5 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( fuelSchedule5 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2017-01-29 22:10:17 -08:00
2016-06-26 20:45:51 -07:00
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
2017-01-29 22:10:17 -08:00
//As the timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
2016-07-27 02:31:38 -07:00
//unsigned int absoluteTimeout = TCNT3 + (timeout / 16); //Each tick occurs every 16uS with the 256 prescaler, so divide the timeout by 16 to get ther required number of ticks. Add this to the current tick count to get the target time. This will automatically overflow as required
2016-06-26 20:45:51 -07:00
fuelSchedule5 . StartCallback = startCallback ; //Name the start callback function
fuelSchedule5 . EndCallback = endCallback ; //Name the end callback function
2016-07-27 02:31:38 -07:00
fuelSchedule5 . duration = duration ;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
*/
2016-10-06 23:34:27 -07:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
2016-07-27 02:31:38 -07:00
noInterrupts ( ) ;
fuelSchedule5 . startCompare = TCNT3 + ( timeout > > 4 ) ; //As above, but with bit shift instead of / 16
fuelSchedule5 . endCompare = fuelSchedule5 . startCompare + ( duration > > 4 ) ;
2016-06-26 20:45:51 -07:00
fuelSchedule5 . Status = PENDING ; //Turn this schedule on
2016-07-27 02:31:38 -07:00
fuelSchedule5 . schedulesSet + + ; //Increment the number of times this schedule has been set
OCR3A = setQueue ( timer3Aqueue , & fuelSchedule1 , & fuelSchedule5 , TCNT3 ) ; //Schedule 1 shares a timer with schedule 5
interrupts ( ) ;
TIMSK3 | = ( 1 < < OCIE3A ) ; //Turn on the A compare unit (ie turn on the interrupt)
2016-10-06 23:34:27 -07:00
# endif
2016-06-26 20:45:51 -07:00
}
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 ) ( ) )
{
if ( ignitionSchedule1 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
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
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
2016-11-25 07:43:57 -08:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout = 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 appliedcausing erratic behaviour such as erroneous sparking.
2016-11-21 03:06:41 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2016-11-25 07:43:57 -08:00
ignitionSchedule1 . startCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
ignitionSchedule1 . endCompare = ignitionSchedule1 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2016-10-09 06:06:52 -07:00
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
}
void setIgnitionSchedule2 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2013-07-10 04:18:18 -07:00
{
2013-09-04 17:27:16 -07:00
if ( ignitionSchedule2 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
2017-01-29 22:10:17 -08: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
//As the timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
2016-11-25 07:43:57 -08:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout = 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 appliedcausing erratic behaviour such as erroneous sparking.
2017-01-29 22:10:17 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2016-11-25 07:43:57 -08:00
ignitionSchedule2 . startCompare = IGN2_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
ignitionSchedule2 . endCompare = ignitionSchedule2 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2016-10-09 06:06:52 -07:00
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
}
2013-11-13 22:17:58 -08:00
void setIgnitionSchedule3 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( ignitionSchedule3 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
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
//The timer is ticking every 4uS (Time per Tick = (Prescale)*(1/Frequency))
2016-11-25 07:43:57 -08:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout = 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 appliedcausing erratic behaviour such as erroneous sparking.
2017-01-29 22:10:17 -08:00
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
2016-11-25 07:43:57 -08:00
ignitionSchedule3 . startCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
ignitionSchedule3 . endCompare = ignitionSchedule3 . startCompare + uS_TO_TIMER_COMPARE ( duration ) ;
2016-10-09 06:06:52 -07:00
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
}
void setIgnitionSchedule4 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
if ( ignitionSchedule4 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
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
2013-11-13 22:17:58 -08:00
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
2015-11-29 00:53:41 -08:00
//The timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
//Note this is different to the other ignition timers
2016-11-25 07:43:57 -08:00
if ( timeout > MAX_TIMER_PERIOD ) { timeout = 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 appliedcausing erratic behaviour such as erroneous sparking.
2016-10-09 06:06:52 -07:00
noInterrupts ( ) ;
ignitionSchedule4 . startCompare = IGN4_COUNTER + ( timeout > > 4 ) ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
ignitionSchedule4 . endCompare = ignitionSchedule4 . startCompare + ( duration > > 4 ) ;
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
}
2016-07-24 02:32:26 -07:00
void setIgnitionSchedule5 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
2016-12-28 03:52:00 -08:00
if ( ignitionSchedule5 . Status = = RUNNING ) { return ; } //Check that we're not already part way through a schedule
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
2016-12-28 03:52:00 -08:00
//We need to calculate the value to reset the timer to (preload) in order to achieve the desired overflow time
//The timer is ticking every 16uS (Time per Tick = (Prescale)*(1/Frequency))
//Note this is different to the other ignition timers
if ( timeout > MAX_TIMER_PERIOD ) { timeout = 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 appliedcausing erratic behaviour such as erroneous sparking.
noInterrupts ( ) ;
ignitionSchedule5 . startCompare = IGN5_COUNTER + ( timeout > > 4 ) ; //As there is a tick every 4uS, there are timeout/4 ticks until the interrupt should be triggered ( >>2 divides by 4)
ignitionSchedule5 . endCompare = ignitionSchedule5 . startCompare + ( duration > > 4 ) ;
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
}
2017-01-29 22:10:17 -08:00
2016-07-27 02:31:38 -07:00
/*******************************************************************************************************************************************************************************************************/
2013-11-13 22:17:58 -08:00
//This function (All 8 ISR functions that are below) gets called when either the start time or the duration time are reached
2013-09-04 17:27:16 -07:00
//This calls the relevant callback function (startCallback or endCallback) depending on the status of the schedule.
//If the startCallback function is called, we put the scheduler into RUNNING state
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
2016-06-26 20:45:51 -07:00
ISR ( TIMER3_COMPA_vect , ISR_NOBLOCK ) //fuelSchedules 1 and 5
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline 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
{
2016-10-09 22:58:19 -07:00
if ( timer3Aqueue [ 0 ] - > Status = = OFF ) { FUEL1_TIMER_DISABLE ( ) ; return ; } //Safety check. Turn off this output compare unit and return without performing any action
2016-07-27 02:31:38 -07:00
if ( timer3Aqueue [ 0 ] - > Status = = PENDING ) //Check to see if this schedule is turn on
2013-07-10 04:18:18 -07:00
{
2016-07-27 02:31:38 -07:00
timer3Aqueue [ 0 ] - > StartCallback ( ) ;
timer3Aqueue [ 0 ] - > Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2016-10-09 22:58:19 -07:00
FUEL1_COMPARE = popQueue ( timer3Aqueue ) ;
2013-07-10 04:18:18 -07:00
}
2016-07-27 02:31:38 -07:00
else if ( timer3Aqueue [ 0 ] - > Status = = RUNNING )
2013-07-10 04:18:18 -07:00
{
2016-07-27 02:31:38 -07:00
timer3Aqueue [ 0 ] - > EndCallback ( ) ;
timer3Aqueue [ 0 ] - > Status = OFF ; //Turn off the schedule
timer3Aqueue [ 0 ] - > schedulesSet = 0 ;
2016-10-09 22:58:19 -07:00
FUEL1_COMPARE = popQueue ( timer3Aqueue ) ;
2013-07-10 04:18:18 -07:00
}
}
2016-07-27 02:31:38 -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
2015-06-05 06:30:37 -07:00
ISR ( TIMER3_COMPB_vect , ISR_NOBLOCK ) //fuelSchedule2
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline 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
{
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
{
2013-09-04 17:27:16 -07:00
fuelSchedule2 . StartCallback ( ) ;
fuelSchedule2 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2016-10-09 22:58:19 -07:00
FUEL2_COMPARE = fuelSchedule2 . endCompare ;
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
{
2013-09-04 17:27:16 -07:00
fuelSchedule2 . EndCallback ( ) ;
fuelSchedule2 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule2 . schedulesSet = 0 ;
2016-10-09 22:58:19 -07:00
FUEL2_TIMER_DISABLE ( ) ;
2013-07-10 04:18:18 -07:00
}
2013-11-13 22:17:58 -08:00
}
2016-07-27 02:31:38 -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
2015-06-05 06:30:37 -07:00
ISR ( TIMER3_COMPC_vect , ISR_NOBLOCK ) //fuelSchedule3
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline 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
{
if ( fuelSchedule3 . Status = = PENDING ) //Check to see if this schedule is turn on
{
fuelSchedule3 . StartCallback ( ) ;
fuelSchedule3 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2016-10-09 22:58:19 -07:00
FUEL3_COMPARE = fuelSchedule3 . endCompare ;
2013-11-13 22:17:58 -08:00
}
else if ( fuelSchedule3 . Status = = RUNNING )
{
fuelSchedule3 . EndCallback ( ) ;
fuelSchedule3 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule3 . schedulesSet = 0 ;
2016-10-09 22:58:19 -07:00
FUEL3_TIMER_DISABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
}
2017-01-29 22:10:17 -08: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
2015-06-05 06:30:37 -07:00
ISR ( TIMER4_COMPB_vect , ISR_NOBLOCK ) //fuelSchedule4
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline 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
{
if ( fuelSchedule4 . Status = = PENDING ) //Check to see if this schedule is turn on
{
fuelSchedule4 . StartCallback ( ) ;
fuelSchedule4 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
2016-10-09 22:58:19 -07:00
FUEL4_COMPARE = fuelSchedule4 . endCompare ;
2013-11-13 22:17:58 -08:00
}
else if ( fuelSchedule4 . Status = = RUNNING )
{
fuelSchedule4 . EndCallback ( ) ;
fuelSchedule4 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule4 . schedulesSet = 0 ;
2017-01-29 22:10:17 -08:00
FUEL4_TIMER_DISABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2013-09-04 17:27:16 -07:00
}
2017-01-29 22:10:17 -08: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
2016-11-22 17:07:10 -08:00
ISR ( TIMER5_COMPA_vect ) //ignitionSchedule1
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline void ignitionSchedule1Interrupt ( ) //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
{
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 ( ) ;
2017-01-17 22:37:55 -08:00
ign1LastRev = currentStatus . startRevolutions ;
2016-10-09 06:06:52 -07:00
IGN1_COMPARE = ignitionSchedule1 . endCompare ; //OCR5A = TCNT5 + (ignitionSchedule1.duration >> 2); //Divide by 4
2013-09-04 17:27:16 -07:00
}
else if ( ignitionSchedule1 . Status = = RUNNING )
{
2014-12-08 20:31:48 -08:00
ignitionSchedule1 . EndCallback ( ) ;
2016-11-21 03:06:41 -08:00
ignitionSchedule1 . Status = OFF ; //Turn off the schedule
ignitionSchedule1 . schedulesSet = 0 ;
2015-02-05 13:11:33 -08:00
ignitionCount + = 1 ; //Increment the igintion counter
2016-10-09 06:06:52 -07:00
IGN1_TIMER_DISABLE ( ) ;
2013-09-04 17:27:16 -07:00
}
}
2017-01-29 22:10:17 -08: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
2016-11-22 17:07:10 -08:00
ISR ( TIMER5_COMPB_vect ) //ignitionSchedule2
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline void ignitionSchedule2Interrupt ( ) //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
{
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 ( ) ;
2017-01-17 22:37:55 -08:00
ign2LastRev = currentStatus . startRevolutions ;
2016-10-09 06:06:52 -07:00
IGN2_COMPARE = ignitionSchedule2 . endCompare ; //OCR5B = TCNT5 + (ignitionSchedule2.duration >> 2);
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 ;
2015-02-05 13:11:33 -08:00
ignitionCount + = 1 ; //Increment the igintion counter
2016-10-09 06:06:52 -07:00
IGN2_TIMER_DISABLE ( ) ;
2013-09-04 17:27:16 -07:00
}
2013-11-13 22:17:58 -08:00
}
2017-01-29 22:10:17 -08: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
2016-11-22 17:07:10 -08:00
ISR ( TIMER5_COMPC_vect ) //ignitionSchedule3
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline void ignitionSchedule3Interrupt ( ) //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
{
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 ( ) ;
2017-01-17 22:37:55 -08:00
ign3LastRev = currentStatus . startRevolutions ;
2016-10-09 22:58:19 -07:00
IGN3_COMPARE = ignitionSchedule3 . endCompare ; //OCR5C = TCNT5 + (ignitionSchedule3.duration >> 2);
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 ;
2015-02-05 13:11:33 -08:00
ignitionCount + = 1 ; //Increment the igintion counter
2016-10-09 22:58:19 -07:00
IGN3_TIMER_DISABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
}
2017-01-29 22:10:17 -08: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
2016-11-22 17:07:10 -08:00
ISR ( TIMER4_COMPA_vect ) //ignitionSchedule4
2016-10-09 22:58:19 -07:00
# elif defined (CORE_TEENSY)
2016-11-25 07:43:57 -08:00
static inline void ignitionSchedule4Interrupt ( ) //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
{
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 ( ) ;
2017-01-17 22:37:55 -08:00
ign4LastRev = currentStatus . startRevolutions ;
2016-10-09 22:58:19 -07:00
IGN4_COMPARE = ignitionSchedule4 . endCompare ; //OCR4A = TCNT4 + (ignitionSchedule4.duration >> 4); //Divide by 16
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 ;
2015-02-05 13:11:33 -08:00
ignitionCount + = 1 ; //Increment the igintion counter
2016-10-09 22:58:19 -07:00
IGN4_TIMER_DISABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2013-07-10 04:18:18 -07:00
}
2016-11-25 07:43:57 -08:00
2016-12-28 03:52:00 -08:00
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) //AVR chips use the ISR for this
ISR ( TIMER1_COMPC_vect ) //ignitionSchedule5
# elif defined (CORE_TEENSY)
static inline void ignitionSchedule5Interrupt ( ) //Most ARM chips can simply call a function
# 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 ( ) ;
2017-01-17 22:37:55 -08:00
ign5LastRev = currentStatus . startRevolutions ;
2016-12-28 03:52:00 -08:00
IGN5_COMPARE = ignitionSchedule5 . endCompare ;
}
else if ( ignitionSchedule5 . Status = = RUNNING )
{
ignitionSchedule5 . Status = OFF ; //Turn off the schedule
ignitionSchedule5 . EndCallback ( ) ;
ignitionSchedule5 . schedulesSet = 0 ;
ignitionCount + = 1 ; //Increment the igintion counter
IGN5_TIMER_DISABLE ( ) ;
}
}
2017-01-29 22:10:17 -08:00
2016-12-28 03:52:00 -08:00
2016-11-26 03:10:41 -08:00
# if defined(CORE_TEENSY)
2017-01-29 22:10:17 -08:00
void ftm0_isr ( void )
2016-11-25 07:43:57 -08:00
{
2017-01-29 22:10:17 -08:00
if ( FTM0_C0SC & FTM_CSC_CHF ) { FTM0_C0SC & = ~ FTM_CSC_CHF ; fuelSchedule1Interrupt ( ) ; }
else if ( FTM0_C1SC & FTM_CSC_CHF ) { FTM0_C1SC & = ~ FTM_CSC_CHF ; fuelSchedule2Interrupt ( ) ; }
else if ( FTM0_C2SC & FTM_CSC_CHF ) { FTM0_C2SC & = ~ FTM_CSC_CHF ; fuelSchedule3Interrupt ( ) ; }
else if ( FTM0_C3SC & FTM_CSC_CHF ) { FTM0_C3SC & = ~ FTM_CSC_CHF ; fuelSchedule4Interrupt ( ) ; }
2016-11-25 07:43:57 -08:00
else if ( FTM0_C4SC & FTM_CSC_CHF ) { FTM0_C4SC & = ~ FTM_CSC_CHF ; ignitionSchedule1Interrupt ( ) ; }
else if ( FTM0_C5SC & FTM_CSC_CHF ) { FTM0_C5SC & = ~ FTM_CSC_CHF ; ignitionSchedule2Interrupt ( ) ; }
else if ( FTM0_C6SC & FTM_CSC_CHF ) { FTM0_C6SC & = ~ FTM_CSC_CHF ; ignitionSchedule3Interrupt ( ) ; }
else if ( FTM0_C7SC & FTM_CSC_CHF ) { FTM0_C7SC & = ~ FTM_CSC_CHF ; ignitionSchedule4Interrupt ( ) ; }
}
# endif