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).
2017-06-20 20:00:58 -07:00
//The are probably not needed as power on state should be 0
//FTM0_C0SC &= ~FTM_CSC_ELSB;
//FTM0_C0SC &= ~FTM_CSC_ELSA;
//FTM0_C0SC &= ~FTM_CSC_DMA;
2016-11-22 16:51:12 -08:00
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
2017-03-29 00:11:16 -07:00
# elif defined(CORE_STM32)
2017-08-27 21:35:49 -07:00
# if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
//see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
Timer1 . setPrescaleFactor ( ( HAL_RCC_GetHCLKFreq ( ) * 2U ) - 1 ) ; //2us resolution
Timer2 . setPrescaleFactor ( ( HAL_RCC_GetHCLKFreq ( ) * 2U ) - 1 ) ; //2us resolution
Timer3 . setPrescaleFactor ( ( HAL_RCC_GetHCLKFreq ( ) * 2U ) - 1 ) ; //2us resolution
Timer2 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 2 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 3 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( 4 , TIMER_OUTPUT_COMPARE ) ;
2017-10-18 23:02:43 -07:00
Timer1 . setMode ( 1 , TIMER_OUTPUT_COMPARE ) ;
2017-08-27 21:35:49 -07:00
# else //libmaple core aka STM32DUINO
//see https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/754bc2969921f1ef262bd69e7faca80b19db7524/STM32F1/system/libmaple/include/libmaple/timer.h#L444
//(CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
//Timer2 to 4 is on APB1, Timer1 on APB2. http://www.st.com/resource/en/datasheet/stm32f103cb.pdf sheet 12
Timer1 . setPrescaleFactor ( ( 72 * 2U ) - 1 ) ; //2us resolution
Timer2 . setPrescaleFactor ( ( 36 * 2U ) - 1 ) ; //2us resolution
Timer3 . setPrescaleFactor ( ( 36 * 2U ) - 1 ) ; //2us resolution
Timer2 . setMode ( TIMER_CH1 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( TIMER_CH2 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( TIMER_CH3 , TIMER_OUTPUT_COMPARE ) ;
Timer2 . setMode ( TIMER_CH4 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( TIMER_CH1 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( TIMER_CH2 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( TIMER_CH3 , TIMER_OUTPUT_COMPARE ) ;
Timer3 . setMode ( TIMER_CH4 , TIMER_OUTPUT_COMPARE ) ;
# endif
2017-04-21 07:30:13 -07:00
Timer2 . attachInterrupt ( 1 , fuelSchedule1Interrupt ) ;
Timer2 . attachInterrupt ( 2 , fuelSchedule2Interrupt ) ;
Timer2 . attachInterrupt ( 3 , fuelSchedule3Interrupt ) ;
Timer2 . attachInterrupt ( 4 , fuelSchedule4Interrupt ) ;
Timer3 . attachInterrupt ( 1 , ignitionSchedule1Interrupt ) ;
Timer3 . attachInterrupt ( 2 , ignitionSchedule2Interrupt ) ;
Timer3 . attachInterrupt ( 3 , ignitionSchedule3Interrupt ) ;
Timer3 . attachInterrupt ( 4 , ignitionSchedule4Interrupt ) ;
2017-08-27 21:35:49 -07:00
Timer1 . attachInterrupt ( 1 , ignitionSchedule5Interrupt ) ;
2017-03-29 00:11:16 -07:00
2017-08-27 21:35:49 -07:00
Timer1 . resume ( ) ;
Timer2 . resume ( ) ;
Timer3 . resume ( ) ;
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
*/
2017-06-13 19:15:26 -07:00
//void setFuelSchedule1(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
void setFuelSchedule1 ( unsigned long timeout , unsigned long duration )
2017-06-20 20:00:58 -07:00
{
if ( fuelSchedule1 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-07-10 04:18:18 -07:00
{
2017-06-20 20:00:58 -07:00
//Callbacks no longer used, but retained for now:
//fuelSchedule1.StartCallback = startCallback;
//fuelSchedule1.EndCallback = endCallback;
2016-07-27 02:31:38 -07:00
fuelSchedule1 . duration = duration ;
2017-10-18 23:02:43 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
2017-10-24 05:31:42 -07:00
if ( timeout > MAX_TIMER_PERIOD_SLOW ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( MAX_TIMER_PERIOD_SLOW - 1 ) ) ; } // If the timeout is >16x (Each tick represents 16uS) the maximum allowed value of unsigned int (65535), the timer compare value will overflow when appliedcausing erratic behaviour such as erroneous sparking.
2017-10-18 23:02:43 -07:00
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( timeout ) ; } //Normal case
2017-06-20 20:00:58 -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 ( ) ;
2017-10-18 23:02:43 -07:00
fuelSchedule1 . startCompare = FUEL1_COUNTER + timeout_timer_compare ;
2017-06-20 20:00:58 -07:00
fuelSchedule1 . endCompare = fuelSchedule1 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule1 . Status = PENDING ; //Turn this schedule on
fuelSchedule1 . schedulesSet + + ; //Increment the number of times this schedule has been set
//Schedule 1 shares a timer with schedule 5
//if(channel5InjEnabled) { FUEL1_COMPARE = setQueue(timer3Aqueue, &fuelSchedule1, &fuelSchedule5, FUEL1_COUNTER); }
//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 ;
interrupts ( ) ;
FUEL1_TIMER_ENABLE ( ) ;
}
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
fuelSchedule1 . nextStartCompare = FUEL1_COUNTER + uS_TO_TIMER_COMPARE_SLOW ( timeout ) ;
fuelSchedule1 . nextEndCompare = fuelSchedule1 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule1 . hasNextSchedule = true ;
2013-07-10 04:18:18 -07:00
}
2017-06-20 20:00:58 -07:00
}
2017-06-13 19:15:26 -07:00
void setFuelSchedule2 ( unsigned long timeout , unsigned long duration )
2017-06-20 20:00:58 -07:00
{
if ( fuelSchedule2 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-09-04 17:27:16 -07:00
{
2017-06-20 20:00:58 -07:00
//Callbacks no longer used, but retained for now:
//fuelSchedule2.StartCallback = startCallback;
//fuelSchedule2.EndCallback = endCallback;
2016-07-27 02:31:38 -07:00
fuelSchedule2 . duration = duration ;
2017-10-18 23:02:43 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
if ( timeout > MAX_TIMER_PERIOD_SLOW ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( MAX_TIMER_PERIOD - 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.
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( timeout ) ; } //Normal case
2017-06-20 20:00:58 -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 ( ) ;
2017-10-18 23:02:43 -07:00
fuelSchedule2 . startCompare = FUEL2_COUNTER + timeout_timer_compare ;
2017-06-20 20:00:58 -07:00
fuelSchedule2 . endCompare = fuelSchedule2 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
FUEL2_COMPARE = fuelSchedule2 . startCompare ; //Use the B compare unit of timer 3
fuelSchedule2 . Status = PENDING ; //Turn this schedule on
fuelSchedule2 . schedulesSet + + ; //Increment the number of times this schedule has been set
interrupts ( ) ;
FUEL2_TIMER_ENABLE ( ) ;
}
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
fuelSchedule2 . nextStartCompare = FUEL2_COUNTER + uS_TO_TIMER_COMPARE_SLOW ( timeout ) ;
fuelSchedule2 . nextEndCompare = fuelSchedule2 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule2 . hasNextSchedule = true ;
2013-09-04 17:27:16 -07:00
}
2017-06-20 20:00:58 -07:00
}
2017-06-13 19:15:26 -07:00
//void setFuelSchedule3(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
void setFuelSchedule3 ( unsigned long timeout , unsigned long duration )
2017-06-20 20:00:58 -07:00
{
if ( fuelSchedule3 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2017-06-20 20:00:58 -07:00
//Callbacks no longer used, but retained for now:
//fuelSchedule3.StartCallback = startCallback;
//fuelSchedule3.EndCallback = endCallback;
2016-10-06 23:34:27 -07:00
fuelSchedule3 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-10-18 23:02:43 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
if ( timeout > MAX_TIMER_PERIOD_SLOW ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( MAX_TIMER_PERIOD - 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.
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( timeout ) ; } //Normal case
2017-06-20 20:00:58 -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
2016-10-06 23:34:27 -07:00
noInterrupts ( ) ;
2017-10-18 23:02:43 -07:00
fuelSchedule3 . startCompare = FUEL3_COUNTER + timeout_timer_compare ;
2017-03-29 00:11:16 -07:00
fuelSchedule3 . endCompare = fuelSchedule3 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
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
}
2017-06-20 20:00:58 -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
fuelSchedule3 . nextStartCompare = FUEL3_COUNTER + uS_TO_TIMER_COMPARE_SLOW ( timeout ) ;
fuelSchedule3 . nextEndCompare = fuelSchedule3 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule3 . hasNextSchedule = true ;
}
}
//void setFuelSchedule4(void (*startCallback)(), unsigned long timeout, unsigned long duration, void(*endCallback)())
2017-06-13 19:15:26 -07:00
void setFuelSchedule4 ( unsigned long timeout , unsigned long duration ) //Uses timer 4 compare B
2017-06-20 20:00:58 -07:00
{
if ( fuelSchedule4 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2017-06-20 20:00:58 -07:00
//Callbacks no longer used, but retained for now:
//fuelSchedule4.StartCallback = startCallback;
//fuelSchedule4.EndCallback = endCallback;
2016-10-06 23:34:27 -07:00
fuelSchedule4 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-10-18 23:02:43 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
if ( timeout > MAX_TIMER_PERIOD_SLOW ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( MAX_TIMER_PERIOD - 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.
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( timeout ) ; } //Normal case
2017-06-20 20:00:58 -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
2016-10-06 23:34:27 -07:00
noInterrupts ( ) ;
2017-10-18 23:02:43 -07:00
fuelSchedule4 . startCompare = FUEL4_COUNTER + timeout_timer_compare ;
2017-03-29 00:11:16 -07:00
fuelSchedule4 . endCompare = fuelSchedule4 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
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
}
2017-06-20 20:00:58 -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
fuelSchedule4 . nextStartCompare = FUEL4_COUNTER + uS_TO_TIMER_COMPARE_SLOW ( timeout ) ;
fuelSchedule4 . nextEndCompare = fuelSchedule4 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule4 . hasNextSchedule = true ;
}
}
2016-06-26 20:45:51 -07:00
void setFuelSchedule5 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
{
2017-06-20 20:00:58 -07:00
if ( fuelSchedule5 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
{
fuelSchedule5 . StartCallback = startCallback ; //Name the start callback function
fuelSchedule5 . EndCallback = endCallback ; //Name the end callback function
fuelSchedule5 . duration = duration ;
/*
* The following must be enclosed in the noIntterupts block to avoid contention caused if the relevant interrupts fires before the state is fully set
*/
# if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
noInterrupts ( ) ;
fuelSchedule5 . startCompare = TCNT3 + ( timeout > > 4 ) ; //As above, but with bit shift instead of / 16
fuelSchedule5 . endCompare = fuelSchedule5 . startCompare + ( duration > > 4 ) ;
fuelSchedule5 . Status = PENDING ; //Turn this schedule on
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)
# endif
}
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_SLOW ( timeout ) ;
fuelSchedule5 . nextEndCompare = fuelSchedule5 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
fuelSchedule5 . hasNextSchedule = true ;
}
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 ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule1 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-09-04 17:27:16 -07:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule1 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule1 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule1 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 20:00:58 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
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 appliedcausing erratic behaviour such as erroneous sparking.
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)
2016-11-25 07:43:57 -08:00
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
}
2017-06-20 20:00:58 -07:00
}
2017-10-24 05:31:42 -07:00
static inline void refreshIgnitionSchedule1 ( unsigned long timeToEnd )
{
if ( ( ignitionSchedule1 . Status = = RUNNING ) & & ( timeToEnd < ignitionSchedule1 . duration ) )
{
noInterrupts ( ) ;
ignitionSchedule1 . endCompare = IGN1_COUNTER + uS_TO_TIMER_COMPARE ( timeToEnd ) ;
IGN1_COMPARE = ignitionSchedule1 . endCompare ;
interrupts ( ) ;
}
}
2013-09-04 17:27:16 -07:00
void setIgnitionSchedule2 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule2 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-07-10 04:18:18 -07:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule2 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule2 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule2 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
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 appliedcausing erratic behaviour such as erroneous sparking.
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)
2016-11-25 07:43:57 -08:00
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
}
2017-06-20 20:00:58 -07:00
}
2013-11-13 22:17:58 -08:00
void setIgnitionSchedule3 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule3 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule3 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule3 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule3 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
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 appliedcausing erratic behaviour such as erroneous sparking.
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)
2016-11-25 07:43:57 -08:00
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
}
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
ignitionSchedule3 . nextStartCompare = IGN3_COUNTER + uS_TO_TIMER_COMPARE ( timeout ) ;
ignitionSchedule3 . nextEndCompare = ignitionSchedule3 . nextStartCompare + uS_TO_TIMER_COMPARE ( duration ) ;
ignitionSchedule3 . hasNextSchedule = true ;
}
2017-06-20 20:00:58 -07:00
}
2013-11-13 22:17:58 -08:00
void setIgnitionSchedule4 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule4 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2013-11-13 22:17:58 -08:00
{
2016-10-09 06:06:52 -07:00
ignitionSchedule4 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule4 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule4 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( 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.
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( 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 ;
2017-03-29 00:11:16 -07:00
ignitionSchedule4 . endCompare = ignitionSchedule4 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
2016-10-09 06:06:52 -07:00
IGN4_COMPARE = ignitionSchedule4 . startCompare ;
2013-11-13 22:17:58 -08:00
ignitionSchedule4 . Status = PENDING ; //Turn this schedule on
2016-11-21 03:06:41 -08:00
ignitionSchedule4 . schedulesSet + + ;
2016-10-09 06:06:52 -07:00
interrupts ( ) ;
2017-01-29 22:10:17 -08:00
IGN4_TIMER_ENABLE ( ) ;
2013-11-13 22:17:58 -08:00
}
2017-08-30 19:09:13 -07:00
else
{
//If the schedule is already running, we can set the next schedule so it is ready to go
//This is required in cases of high rpm and high DC where there otherwise would not be enough time to set the schedule
ignitionSchedule4 . nextStartCompare = IGN4_COUNTER + uS_TO_TIMER_COMPARE_SLOW ( timeout ) ;
ignitionSchedule4 . nextEndCompare = ignitionSchedule4 . nextStartCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
ignitionSchedule4 . hasNextSchedule = true ;
}
2017-06-20 20:00:58 -07:00
}
2016-07-24 02:32:26 -07:00
void setIgnitionSchedule5 ( void ( * startCallback ) ( ) , unsigned long timeout , unsigned long duration , void ( * endCallback ) ( ) )
2017-06-20 20:00:58 -07:00
{
if ( ignitionSchedule5 . Status ! = RUNNING ) //Check that we're not already part way through a schedule
2016-07-24 02:32:26 -07:00
{
2016-10-09 22:58:19 -07:00
ignitionSchedule5 . StartCallback = startCallback ; //Name the start callback function
ignitionSchedule5 . EndCallback = endCallback ; //Name the start callback function
ignitionSchedule5 . duration = duration ;
2017-01-29 22:10:17 -08:00
2017-06-20 22:34:41 -07:00
//Need to check that the timeout doesn't exceed the overflow
uint16_t timeout_timer_compare ;
if ( timeout > MAX_TIMER_PERIOD ) { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( ( 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.
else { timeout_timer_compare = uS_TO_TIMER_COMPARE_SLOW ( 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 ;
2017-03-29 00:11:16 -07:00
ignitionSchedule5 . endCompare = ignitionSchedule5 . startCompare + uS_TO_TIMER_COMPARE_SLOW ( duration ) ;
2016-12-28 03:52:00 -08:00
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-06-20 20:00:58 -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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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
{
2017-06-20 20:00:58 -07:00
if ( fuelSchedule1 . Status = = PENDING ) //Check to see if this schedule is turn on
2013-07-10 04:18:18 -07:00
{
2017-06-20 20:00:58 -07:00
//To use timer queue, change fuelShedule1 to timer3Aqueue[0];
2017-06-13 19:15:26 -07:00
if ( configPage1 . injLayout = = INJ_SEMISEQUENTIAL ) { openInjector1and4 ( ) ; }
else { openInjector1 ( ) ; }
2017-06-20 20:00:58 -07:00
fuelSchedule1 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
FUEL1_COMPARE = fuelSchedule1 . endCompare ;
2013-07-10 04:18:18 -07:00
}
2017-06-20 20:00:58 -07:00
else if ( fuelSchedule1 . Status = = RUNNING )
2013-07-10 04:18:18 -07:00
{
2017-06-13 19:15:26 -07:00
//timer3Aqueue[0]->EndCallback();
if ( configPage1 . injLayout = = INJ_SEMISEQUENTIAL ) { closeInjector1and4 ( ) ; }
else { closeInjector1 ( ) ; }
2017-06-20 20:00:58 -07:00
fuelSchedule1 . Status = OFF ; //Turn off the schedule
fuelSchedule1 . schedulesSet = 0 ;
//FUEL1_COMPARE = fuelSchedule1.endCompare;
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule1 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
FUEL1_COMPARE = fuelSchedule1 . nextStartCompare ;
fuelSchedule1 . endCompare = fuelSchedule1 . nextEndCompare ;
fuelSchedule1 . Status = PENDING ;
fuelSchedule1 . schedulesSet = 1 ;
fuelSchedule1 . hasNextSchedule = false ;
}
else { FUEL1_TIMER_DISABLE ( ) ; }
2013-07-10 04:18:18 -07:00
}
2017-06-20 20:00:58 -07:00
else if ( fuelSchedule1 . Status = = OFF ) { FUEL1_TIMER_DISABLE ( ) ; } //Safety check. Turn off this output compare unit and return without performing any action
2013-07-10 04:18:18 -07:00
}
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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
{
2017-06-13 19:15:26 -07:00
//fuelSchedule2.StartCallback();
if ( configPage1 . injLayout = = INJ_SEMISEQUENTIAL ) { openInjector2and3 ( ) ; }
else { openInjector2 ( ) ; }
2013-09-04 17:27:16 -07:00
fuelSchedule2 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
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
{
2017-06-13 19:15:26 -07:00
//fuelSchedule2.EndCallback();
if ( configPage1 . injLayout = = INJ_SEMISEQUENTIAL ) { closeInjector2and3 ( ) ; }
else { closeInjector2 ( ) ; }
2013-09-04 17:27:16 -07:00
fuelSchedule2 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule2 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule2 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
FUEL2_COMPARE = fuelSchedule2 . nextStartCompare ;
fuelSchedule2 . endCompare = fuelSchedule2 . nextEndCompare ;
fuelSchedule2 . Status = PENDING ;
fuelSchedule2 . schedulesSet = 1 ;
fuelSchedule2 . hasNextSchedule = false ;
}
else { FUEL2_TIMER_DISABLE ( ) ; }
2013-07-10 04:18:18 -07:00
}
2013-11-13 22:17:58 -08:00
}
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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
{
2017-06-13 19:15:26 -07:00
//fuelSchedule3.StartCallback();
//Hack for 5 cylinder
if ( channel5InjEnabled ) { openInjector3and5 ( ) ; }
else { openInjector3 ( ) ; }
2013-11-13 22:17:58 -08:00
fuelSchedule3 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
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 )
{
2017-06-13 19:15:26 -07:00
//fuelSchedule3.EndCallback();
//Hack for 5 cylinder
if ( channel5InjEnabled ) { closeInjector3and5 ( ) ; }
else { closeInjector3and5 ( ) ; }
2013-11-13 22:17:58 -08:00
fuelSchedule3 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule3 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule3 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
FUEL3_COMPARE = fuelSchedule3 . nextStartCompare ;
fuelSchedule3 . endCompare = fuelSchedule3 . nextEndCompare ;
fuelSchedule3 . Status = PENDING ;
fuelSchedule3 . schedulesSet = 1 ;
fuelSchedule3 . hasNextSchedule = false ;
}
else { FUEL3_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
}
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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
{
2017-06-13 19:15:26 -07:00
//fuelSchedule4.StartCallback();
openInjector4 ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = RUNNING ; //Set the status to be in progress (ie The start callback has been called, but not the end callback)
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 )
{
2017-06-13 19:15:26 -07:00
//fuelSchedule4.EndCallback();
closeInjector4 ( ) ;
2013-11-13 22:17:58 -08:00
fuelSchedule4 . Status = OFF ; //Turn off the schedule
2016-06-26 20:45:51 -07:00
fuelSchedule4 . schedulesSet = 0 ;
2017-06-20 20:00:58 -07:00
//If there is a next schedule queued up, activate it
2017-06-20 22:34:41 -07:00
if ( fuelSchedule4 . hasNextSchedule = = true )
2017-06-20 20:00:58 -07:00
{
FUEL4_COMPARE = fuelSchedule4 . nextStartCompare ;
fuelSchedule4 . endCompare = fuelSchedule4 . nextEndCompare ;
fuelSchedule4 . Status = PENDING ;
fuelSchedule4 . schedulesSet = 1 ;
fuelSchedule4 . hasNextSchedule = false ;
}
else { FUEL4_TIMER_DISABLE ( ) ; }
2013-11-13 22:17:58 -08:00
}
2013-09-04 17:27:16 -07:00
}
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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-06-20 20:00:58 -07:00
IGN1_COMPARE = ignitionSchedule1 . endCompare ;
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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 ( ) ;
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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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 ( ) ;
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
2017-08-30 19:09:13 -07:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule3 . hasNextSchedule = = true )
{
IGN3_COMPARE = ignitionSchedule3 . nextStartCompare ;
ignitionSchedule3 . endCompare = ignitionSchedule3 . nextEndCompare ;
ignitionSchedule3 . Status = PENDING ;
ignitionSchedule3 . schedulesSet = 1 ;
ignitionSchedule3 . hasNextSchedule = false ;
}
else { 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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
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-06-20 20:00:58 -07:00
IGN4_COMPARE = ignitionSchedule4 . endCompare ;
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
2017-08-30 19:09:13 -07:00
//If there is a next schedule queued up, activate it
if ( ignitionSchedule4 . hasNextSchedule = = true )
{
IGN4_COMPARE = ignitionSchedule4 . nextStartCompare ;
ignitionSchedule4 . endCompare = ignitionSchedule4 . nextEndCompare ;
ignitionSchedule4 . Status = PENDING ;
ignitionSchedule4 . schedulesSet = 1 ;
ignitionSchedule4 . hasNextSchedule = false ;
}
else { 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
2017-03-22 23:19:18 -07:00
# elif defined (CORE_TEENSY) || defined(CORE_STM32)
2016-12-28 03:52:00 -08:00
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 ( ) ;
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-06-20 20:00:58 -07:00
//Use separate variables for each test to ensure conversion to bool
bool interrupt1 = ( FTM0_C0SC & FTM_CSC_CHF ) ;
bool interrupt2 = ( FTM0_C1SC & FTM_CSC_CHF ) ;
bool interrupt3 = ( FTM0_C2SC & FTM_CSC_CHF ) ;
bool interrupt4 = ( FTM0_C3SC & FTM_CSC_CHF ) ;
bool interrupt5 = ( FTM0_C4SC & FTM_CSC_CHF ) ;
bool interrupt6 = ( FTM0_C5SC & FTM_CSC_CHF ) ;
bool interrupt7 = ( FTM0_C6SC & FTM_CSC_CHF ) ;
bool interrupt8 = ( FTM0_C7SC & FTM_CSC_CHF ) ;
if ( interrupt1 ) { FTM0_C0SC & = ~ FTM_CSC_CHF ; fuelSchedule1Interrupt ( ) ; }
else if ( interrupt2 ) { FTM0_C1SC & = ~ FTM_CSC_CHF ; fuelSchedule2Interrupt ( ) ; }
else if ( interrupt3 ) { FTM0_C2SC & = ~ FTM_CSC_CHF ; fuelSchedule3Interrupt ( ) ; }
else if ( interrupt4 ) { FTM0_C3SC & = ~ FTM_CSC_CHF ; fuelSchedule4Interrupt ( ) ; }
else if ( interrupt5 ) { FTM0_C4SC & = ~ FTM_CSC_CHF ; ignitionSchedule1Interrupt ( ) ; }
else if ( interrupt6 ) { FTM0_C5SC & = ~ FTM_CSC_CHF ; ignitionSchedule2Interrupt ( ) ; }
else if ( interrupt7 ) { FTM0_C6SC & = ~ FTM_CSC_CHF ; ignitionSchedule3Interrupt ( ) ; }
else if ( interrupt8 ) { FTM0_C7SC & = ~ FTM_CSC_CHF ; ignitionSchedule4Interrupt ( ) ; }
2016-11-25 07:43:57 -08:00
}
2017-08-02 19:29:05 -07:00
# endif