#if defined(CORE_AVR) //AVR chips use the ISR for this
//Configure Timer2 for our low-freq interrupt code.
TCCR2B=0x00;//Disbale Timer2 while we set it up
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
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
/* Now configure the prescaler to CPU clock divided by 128 = 125Khz */
TCCR2B|=(1<<CS22)|(1<<CS20);// Set bits
TCCR2B&=~(1<<CS21);// Clear bit
//Enable the watchdog timer for 2 second resets (Good reference: https://tushev.org/articles/arduino/5/arduino-and-watchdog-timer)
//Boooooooooo WDT is currently broken on Mega 2560 bootloaders :(
//wdt_enable(WDTO_2S);
#elif defined (CORE_TEENSY)
//Uses the PIT timer on Teensy.
lowResTimer.begin(oneMSInterval,1000);
#elif defined(CORE_STM32)
Timer4.setPeriod(1000);// Set up period
// Set up an interrupt
Timer4.setMode(1,TIMER_OUTPUT_COMPARE);
Timer4.attachInterrupt(1,oneMSInterval);
Timer4.resume();//Start Timer
#endif
#if defined(CORE_STM32)
pinMode(LED_BUILTIN,OUTPUT);
#endif
dwellLimit_uS=(1000*configPage2.dwellLimit);
lastRPM_100ms=0;
}
//Timer2 Overflow Interrupt Vector, called when the timer overflows.
//Executes every ~1ms.
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //AVR chips use the ISR for this
ISR(TIMER2_OVF_vect,ISR_NOBLOCK)
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
voidoneMSInterval()//Most ARM chips can simply call a function
#endif
{
//Increment Loop Counters
loop33ms++;
loop66ms++;
loop100ms++;
loop250ms++;
loopSec++;
unsignedlongtargetOverdwellTime;
//Overdwell check
targetOverdwellTime=micros()-dwellLimit_uS;//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
boolisCrankLocked=configPage2.ignCranklock&&(currentStatus.RPM<currentStatus.crankRPM);//Dwell limiter is disabled during cranking on setups using the locked cranking timing. WE HAVE to do the RPM check here as relying on the engine cranking bit can be potentially too slow in updating
//Check first whether each spark output is currently on. Only check it's dwell time if it is
fanControl();// Fucntion to turn the cooling fan on/off
}
//Check whether fuel pump priming is complete
if(!fpPrimed)
{
if(currentStatus.secl>=configPage1.fpPrime)
{
fpPrimed=true;//Mark the priming as being completed
if(currentStatus.RPM==0){digitalWrite(pinFuelPump,LOW);fuelPumpOn=false;}//If we reach here then the priming is complete, however only turn off the fuel pump if the engine isn't running
//Set the flex reading (if enabled). The flexCounter is updated with every pulse from the sensor. If cleared once per second, we get a frequency reading
if(configPage1.flexEnabled==true)
{
if(flexCounter<50)
{
currentStatus.ethanolPct=0;//Standard GM Continental sensor reads from 50Hz (0 ethanol) to 150Hz (Pure ethanol). Subtracting 50 from the frequency therefore gives the ethanol percentage.
flexCounter=0;
}
elseif(flexCounter>151)//1 pulse buffer
{
if(flexCounter<169)
{
currentStatus.ethanolPct=100;
flexCounter=0;
}
else
{
//This indicates an error condition. Spec of the sensor is that errors are above 170Hz)
currentStatus.ethanolPct=0;
flexCounter=0;
}
}
else
{
currentStatus.ethanolPct=flexCounter-50;//Standard GM Continental sensor reads from 50Hz (0 ethanol) to 150Hz (Pure ethanol). Subtracting 50 from the frequency therefore gives the ethanol percentage.