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
*/
2014-05-06 04:07:49 -07:00
/*
Timers are used for having actions performed repeatedly at a fixed interval ( Eg every 100 ms )
They should not be confused with Schedulers , which are for performing an action once at a given point of time in the future
2014-01-30 20:02:32 -08:00
2014-05-06 04:07:49 -07:00
Timers are typically low resolution ( Compared to Schedulers ) , with maximum frequency currently being approximately every 10 ms
*/
2015-02-14 09:04:00 -08:00
# include "timers.h"
# include "globals.h"
2014-01-30 20:02:32 -08:00
2014-02-06 01:48:19 -08:00
void initialiseTimers ( )
{
2015-04-13 21:41:44 -07:00
//Configure Timer2 for our low-freq interrupt code.
2014-02-06 01:48:19 -08:00
TCCR2B = 0x00 ; //Disbale Timer2 while we set it up
2015-04-13 21:41:44 -07:00
TCNT2 = 131 ; //Preload timer2 with 131 cycles, leaving 125 till overflow. As the timer runs at 125Khz, this causes overflow to occur at 1Khz = 1ms
2014-02-06 01:48:19 -08:00
TIFR2 = 0x00 ; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01 ; //Timer2 Set Overflow Interrupt enabled.
TCCR2A = 0x00 ; //Timer2 Control Reg A: Wave Gen Mode normal
2015-04-13 21:41:44 -07:00
/* Now configure the prescaler to CPU clock divided by 128 = 125Khz */
2015-02-09 05:00:16 -08:00
TCCR2B | = ( 1 < < CS22 ) | ( 1 < < CS20 ) ; // Set bits
TCCR2B & = ~ ( 1 < < CS21 ) ; // Clear bit
2014-01-30 20:02:32 -08:00
}
//Timer2 Overflow Interrupt Vector, called when the timer overflows.
2015-04-13 21:41:44 -07:00
//Executes every ~1ms.
2015-06-05 06:30:37 -07:00
ISR ( TIMER2_OVF_vect , ISR_NOBLOCK )
2014-01-30 20:02:32 -08:00
{
//Increment Loop Counters
2014-05-06 04:07:49 -07:00
loop250ms + + ;
2014-01-30 20:02:32 -08:00
loopSec + + ;
2015-02-09 05:19:58 -08:00
//Overdwell check
targetOverdwellTime = currentLoopTime - ( 1000 * configPage2 . dwellLimit ) ; //Set a target time in the past that all coil charging must have begun after. If the coil charge began before this time, it's been running too long
2015-04-13 21:41:44 -07:00
targetTachoPulseTime = currentLoopTime - ( 1500 ) ;
2015-02-09 05:19:58 -08:00
//Check first whether each spark output is currently on. Only check it's dwell time if it is
2015-09-07 18:17:47 -07:00
if ( ignitionSchedule1 . Status = = RUNNING ) { if ( ignitionSchedule1 . startTime < targetOverdwellTime & & configPage2 . useDwellLim ) { endCoil1Charge ( ) ; } if ( ignitionSchedule1 . startTime < targetTachoPulseTime ) { digitalWrite ( pinTachOut , HIGH ) ; } }
if ( ignitionSchedule2 . Status = = RUNNING ) { if ( ignitionSchedule2 . startTime < targetOverdwellTime & & configPage2 . useDwellLim ) { endCoil2Charge ( ) ; } if ( ignitionSchedule2 . startTime < targetTachoPulseTime ) { digitalWrite ( pinTachOut , HIGH ) ; } }
if ( ignitionSchedule3 . Status = = RUNNING ) { if ( ignitionSchedule3 . startTime < targetOverdwellTime & & configPage2 . useDwellLim ) { endCoil3Charge ( ) ; } if ( ignitionSchedule3 . startTime < targetTachoPulseTime ) { digitalWrite ( pinTachOut , HIGH ) ; } }
if ( ignitionSchedule4 . Status = = RUNNING ) { if ( ignitionSchedule4 . startTime < targetOverdwellTime & & configPage2 . useDwellLim ) { endCoil4Charge ( ) ; } if ( ignitionSchedule4 . startTime < targetTachoPulseTime ) { digitalWrite ( pinTachOut , HIGH ) ; } }
2015-02-09 05:00:16 -08:00
2015-05-29 00:33:00 -07:00
//Check if there's any actions pending for a stepper idle
2015-04-13 21:41:44 -07:00
2015-02-09 05:00:16 -08:00
2015-04-13 21:41:44 -07:00
//Loop executed every 250ms loop (1ms x 250 = 250ms)
2014-05-06 04:07:49 -07:00
//Anything inside this if statement will run every 250ms.
2015-02-09 05:00:16 -08:00
if ( loop250ms = = 250 )
2014-01-30 20:02:32 -08:00
{
2014-05-06 04:07:49 -07:00
loop250ms = 0 ; //Reset Counter.
2014-01-30 20:02:32 -08:00
}
2015-04-13 21:41:44 -07:00
//Loop executed every 1 second (1ms x 1000 = 1000ms)
2015-02-09 05:00:16 -08:00
if ( loopSec = = 1000 )
2014-01-30 20:02:32 -08:00
{
loopSec = 0 ; //Reset counter.
2014-02-06 01:48:19 -08:00
2014-02-17 22:08:55 -08:00
//**************************************************************************************************************************************************
//This updates the runSecs variable
2014-02-06 01:48:19 -08:00
//If the engine is running or cranking, we need ot update the run time counter.
2014-12-23 15:25:51 -08:00
if ( BIT_CHECK ( currentStatus . engine , BIT_ENGINE_RUN ) )
2014-02-06 01:48:19 -08:00
{ //NOTE - There is a potential for a ~1sec gap between engine crank starting and ths runSec number being incremented. This may delay ASE!
if ( currentStatus . runSecs < = 254 ) //Ensure we cap out at 255 and don't overflow. (which would reset ASE)
{ currentStatus . runSecs + + ; } //Increment our run counter by 1 second.
}
2014-02-17 22:08:55 -08:00
//**************************************************************************************************************************************************
//This records the number of main loops the system has completed in the last second
currentStatus . loopsPerSecond = mainLoopCount ;
mainLoopCount = 0 ;
//**************************************************************************************************************************************************
2014-05-08 03:46:38 -07:00
//increament secl (secl is simply a counter that increments every second and is used to track whether the system has unexpectedly reset
currentStatus . secl + + ;
2014-01-30 20:02:32 -08:00
2015-06-02 05:56:18 -07:00
//Check the fan output status
if ( configPage4 . fanEnable = = 1 )
{
fanControl ( ) ; // Fucntion to turn the cooling fan on/off
}
2014-02-18 02:05:13 -08:00
}
2015-04-13 21:41:44 -07:00
//Reset Timer2 to trigger in another ~1ms
TCNT2 = 131 ; //Preload timer2 with 100 cycles, leaving 156 till overflow.
2014-01-30 20:02:32 -08:00
TIFR2 = 0x00 ; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
}