Fast versions of millis() and micros() that use timer5 rather than timer0. Current disabled

This commit is contained in:
Josh Stewart 2018-03-10 14:07:06 +11:00
parent d4f0bdc03e
commit 4183be51f2
8 changed files with 83 additions and 36 deletions

View File

@ -159,7 +159,7 @@ static inline int16_t correctionAccel()
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) )
{
//If it is currently running, check whether it should still be running or whether it's reached it's end time
if( micros() >= currentStatus.TAEEndTime )
if( micros_safe() >= currentStatus.TAEEndTime )
{
//Time to turn enrichment off
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
@ -192,7 +192,7 @@ static inline int16_t correctionAccel()
if (rateOfChange > configPage2.tpsThresh)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.TAEEndTime = micros() + ((unsigned long)configPage2.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
currentStatus.TAEEndTime = micros_safe() + ((unsigned long)configPage2.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = 100 + table2D_getValue(&taeTable, currentStatus.tpsDOT);
}
}
@ -280,7 +280,7 @@ static inline bool correctionDFCO()
static inline byte correctionFlex()
{
byte flexValue = 100;
if (configPage2.flexEnabled == 1)
{
flexValue = table2D_getValue(&flexFuelTable, currentStatus.ethanolPct);

View File

@ -262,11 +262,13 @@ int getCrankAngle_missingTooth(int timePerDegree)
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
tempRevolutionOne = revolutionOne;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = (micros() - tempToothLastToothTime);
//crankAngle += DIV_ROUND_CLOSEST(elapsedTime, timePerDegree);
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -409,6 +411,7 @@ int getCrankAngle_DualWheel(int timePerDegree)
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
tempRevolutionOne = revolutionOne;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Handle case where the secondary tooth was the last one seen
@ -416,7 +419,6 @@ int getCrankAngle_DualWheel(int timePerDegree)
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -550,11 +552,11 @@ int getCrankAngle_BasicDistributor(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -635,6 +637,7 @@ int getCrankAngle_GM7X(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Check if the last tooth seen was the reference tooth (Number 3). All others can be calculated, but tooth 3 has a unique angle
@ -653,7 +656,6 @@ int getCrankAngle_GM7X(int timePerDegree)
}
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -962,12 +964,12 @@ int getCrankAngle_4G63(int timePerDegree)
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
tempToothLastMinusOneToothTime = toothLastMinusOneToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
unsigned long elapsedTime = micros() - tempToothLastToothTime;
//Estimate the number of degrees travelled since the last tooth}
//crankAngle += uSToDegrees(elapsedTime);
unsigned long toothTime = tempToothLastToothTime - tempToothLastMinusOneToothTime;
crankAngle += int((elapsedTime * triggerToothAngle) / toothTime);
@ -1081,6 +1083,7 @@ int getCrankAngle_24X(int timePerDegree)
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
tempRevolutionOne = revolutionOne;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
int crankAngle;
@ -1088,7 +1091,6 @@ int getCrankAngle_24X(int timePerDegree)
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -1186,13 +1188,14 @@ int getCrankAngle_Jeep2000(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
int crankAngle;
if (toothCurrentCount == 0) { crankAngle = 146 + configPage4.triggerAngle; } //This is the special case to handle when the 'last tooth' seen was the cam tooth. 146 is the angle at which the crank tooth goes high.
else { crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle;} //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -1300,6 +1303,7 @@ int getCrankAngle_Audi135(int timePerDegree)
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
tempRevolutionOne = revolutionOne;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Handle case where the secondary tooth was the last one seen
@ -1307,7 +1311,6 @@ int getCrankAngle_Audi135(int timePerDegree)
int crankAngle = ((tempToothCurrentCount - 1) * triggerToothAngle) + configPage4.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -1394,6 +1397,7 @@ int getCrankAngle_HondaD17(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Check if the last tooth seen was the reference tooth 13 (Number 0 here). All others can be calculated, but tooth 3 has a unique angle
@ -1408,7 +1412,6 @@ int getCrankAngle_HondaD17(int timePerDegree)
}
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -1439,7 +1442,7 @@ void triggerSetup_Miata9905()
decoderIsSequential = true;
triggerActualTeeth = 8;
if(initialisationComplete == false) { secondaryToothCount = 0;toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
if(initialisationComplete == false) { secondaryToothCount = 0; toothLastToothTime = micros(); } //Set a startup value here to avoid filter errors when starting. This MUST have the initi check to prevent the fuel pump just staying on all the time
else { toothLastToothTime = 0; }
toothLastMinusOneToothTime = 0;
@ -1532,9 +1535,9 @@ void triggerPri_Miata9905()
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock)
//if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) && configPage4.ignCranklock)
if ( currentStatus.RPM < (currentStatus.crankRPM + 100) && configPage4.ignCranklock)
{
//This operates in waasted spark mode during cranking to align with crank teeth
if( (toothCurrentCount == 1) || (toothCurrentCount == 5) ) { endCoil1Charge(); endCoil3Charge(); }
else if( (toothCurrentCount == 3) || (toothCurrentCount == 7) ) { endCoil2Charge(); endCoil4Charge(); }
}
@ -1607,12 +1610,12 @@ int getCrankAngle_Miata9905(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
unsigned long elapsedTime = micros() - tempToothLastToothTime;
//Estimate the number of degrees travelled since the last tooth}
crankAngle += uSToDegrees(elapsedTime);
if (crankAngle >= 720) { crankAngle -= 720; }
@ -1760,12 +1763,12 @@ int getCrankAngle_MazdaAU(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
//Estimate the number of degrees travelled since the last tooth}
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -1829,6 +1832,7 @@ int getCrankAngle_non360(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Handle case where the secondary tooth was the last one seen
@ -1839,7 +1843,6 @@ int getCrankAngle_non360(int timePerDegree)
crankAngle = (crankAngle / configPage4.TrigAngMul) + configPage4.triggerAngle; //Have to divide by the multiplier to get back to actual crank angle.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -2036,11 +2039,12 @@ int getCrankAngle_Nissan360(int timePerDegree)
tempToothLastToothTime = toothLastToothTime;
tempToothLastMinusOneToothTime = toothLastMinusOneToothTime;
tempToothCurrentCount = toothCurrentCount;
unsigned long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = ( (tempToothCurrentCount - 1) * 2) + configPage4.triggerAngle;
unsigned long halfTooth = (tempToothLastToothTime - tempToothLastMinusOneToothTime) >> 1;
if ( (micros() - tempToothLastToothTime) > halfTooth)
if (elapsedTime > halfTooth)
{
//Means we're over halfway to the next tooth, so add on 1 degree
crankAngle += 1;
@ -2199,12 +2203,12 @@ int getCrankAngle_Subaru67(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = toothAngles[(tempToothCurrentCount - 1)] + configPage4.triggerAngle; //Perform a lookup of the fixed toothAngles array to find what the angle of the last tooth passed was.
//Estimate the number of degrees travelled since the last tooth}
unsigned long elapsedTime = micros() - tempToothLastToothTime;
//Estimate the number of degrees travelled since the last tooth}
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -2363,11 +2367,12 @@ int getCrankAngle_Daihatsu(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
crankAngle = toothAngles[tempToothCurrentCount-1] + configPage4.triggerAngle; //Crank angle of the last tooth seen
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if(elapsedTime < SHRT_MAX ) { crankAngle += div((int)elapsedTime, timePerDegree).quot; } //This option is much faster, but only available for smaller values of elapsedTime
else { crankAngle += ldiv(elapsedTime, timePerDegree).quot; }
@ -2492,6 +2497,7 @@ int getCrankAngle_Harley(int timePerDegree)
noInterrupts();
tempToothCurrentCount = toothCurrentCount;
tempToothLastToothTime = toothLastToothTime;
long elapsedTime = (micros() - tempToothLastToothTime); //micros() is no longer interrupt safe
interrupts();
//Check if the last tooth seen was the reference tooth (Number 3). All others can be calculated, but tooth 3 has a unique angle
@ -2505,7 +2511,6 @@ int getCrankAngle_Harley(int timePerDegree)
}
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
if (elapsedTime < SHRT_MAX ) {
crankAngle += div((int)elapsedTime, timePerDegree).quot; //This option is much faster, but only available for smaller values of elapsedTime
}

View File

@ -12,12 +12,17 @@
#define BOARD_NR_GPIO_PINS 62
#define LED_BUILTIN 13
#define CORE_AVR
//#define TIMER5_MICROS
#elif defined(CORE_TEENSY)
#define BOARD_DIGITAL_GPIO_PINS 34
#define BOARD_NR_GPIO_PINS 34
#elif defined(STM32_MCU_SERIES) || defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__) || defined(STM32F4) || defined(STM32)
#define CORE_STM32
#define word(h, l) ((h << 8) | l) //word() function not defined for this platform in the main library
#ifndef word
#define word(h, l) ((h << 8) | l) //word() function not defined for this platform in the main library
#endif
#if defined (STM32F1) || defined(__STM32F1__)
#define BOARD_DIGITAL_GPIO_PINS 34
#define BOARD_NR_GPIO_PINS 34
@ -34,7 +39,7 @@
#endif
extern "C" char* sbrk(int incr); //Used to freeRam
inline unsigned char digitalPinToInterrupt(unsigned char Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet)
//inline unsigned char digitalPinToInterrupt(unsigned char Interrupt_pin) { return Interrupt_pin; } //This isn't included in the stm32duino libs (yet)
#if defined(ARDUINO_ARCH_STM32) // STM32GENERIC core
#define portOutputRegister(port) (volatile byte *)( &(port->ODR) )
#define portInputRegister(port) (volatile byte *)( &(port->IDR) )
@ -52,6 +57,8 @@
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_CHECK(var,pos) !!((var) & (1<<(pos)))
#define interruptSafe(c) noInterrupts(); c interrupts(); //Wraps any code between nointerrupt and interrupt calls
#define MS_IN_MINUTE 60000
#define US_IN_MINUTE 60000000
@ -253,6 +260,8 @@ int ignition4EndAngle = 0;
//This is used across multiple files
unsigned long revolutionTime; //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
volatile unsigned long timer5_overflow_count = 0; //Increments every time counter 5 overflows. Used for the fast version of micros()
volatile unsigned long ms_counter = 0; //A counter that increments once per ms
//This needs to be here because using the config page directly can prevent burning the setting
byte resetControl = RESET_CONTROL_DISABLED;

View File

@ -319,7 +319,7 @@ static inline byte isStepperHomed()
digitalWrite(pinStepperDir, STEPPER_BACKWARD); //Sets stepper direction to backwards
digitalWrite(pinStepperEnable, LOW); //Enable the DRV8825
digitalWrite(pinStepperStep, HIGH);
idleStepper.stepStartTime = micros();
idleStepper.stepStartTime = micros_safe();
idleStepper.stepperStatus = STEPPING;
completedHomeSteps++;
idleOn = true;
@ -339,13 +339,13 @@ static inline byte checkForStepping()
bool isStepping = false;
if( (idleStepper.stepperStatus == STEPPING) || (idleStepper.stepperStatus == COOLING) )
{
if(micros() > (idleStepper.stepStartTime + iacStepTime) )
if(micros_safe() > (idleStepper.stepStartTime + iacStepTime) )
{
if(idleStepper.stepperStatus == STEPPING)
{
//Means we're currently in a step, but it needs to be turned off
digitalWrite(pinStepperStep, LOW); //Turn off the step
idleStepper.stepStartTime = micros();
idleStepper.stepStartTime = micros_safe();
idleStepper.stepperStatus = COOLING; //'Cooling' is the time the stepper needs to sit in LOW state before the next step can be made
isStepping = true;
}
@ -377,7 +377,7 @@ static inline void doStep()
digitalWrite(pinStepperEnable, LOW); //Enable the DRV8825
digitalWrite(pinStepperStep, HIGH);
idleStepper.stepStartTime = micros();
idleStepper.stepStartTime = micros_safe();
idleStepper.stepperStatus = STEPPING;
idleOn = true;
}

View File

@ -21,7 +21,7 @@ void initialiseSchedulers()
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
//TCCR3B = 0x03; //Timer3 Control Reg B: Timer Prescaler set to 64. Refer to http://www.instructables.com/files/orig/F3T/TIKL/H3WSA4V7/F3TTIKLH3WSA4V7.jpg
//Ignition Schedules, which uses timer 5
//Ignition Schedules, which uses timer 5. This is also used by the fast version of micros(). If the speed of this timer is changed from 4uS ticks, that MUST be changed as well. See globals.h and timers.ino
TCCR5B = 0x00; //Disable Timer5 while we set it up
TCNT5 = 0; //Reset Timer Count
TIFR5 = 0x00; //Timer5 INT Flag Reg: Clear Timer Overflow Flag
@ -29,6 +29,11 @@ void initialiseSchedulers()
//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
TCCR5B = 0x03; //aka Divisor = 64 = 490.1Hz
#if defined(TIMER5_MICROS)
TIMSK5 |= (1 << TOIE5); //Enable the timer5 overflow interrupt (See timers.ino for ISR)
TIMSK0 &= ~_BV(TOIE0); // disable timer0 overflow interrupt
#endif
//The remaining Schedules (Schedules 4 for fuel and ignition) use Timer4
TCCR4B = 0x00; //Disable Timer4 while we set it up
TCNT4 = 0; //Reset Timer Count

View File

@ -762,7 +762,7 @@ void loop()
// if (configPage2.displayType && (mainLoopCount & 255) == 1) { updateDisplay();}
previousLoopTime = currentLoopTime;
currentLoopTime = micros();
currentLoopTime = micros_safe();
unsigned long timeToLastTooth = (currentLoopTime - toothLastToothTime);
if ( (timeToLastTooth < MAX_STALL_TIME) || (toothLastToothTime > currentLoopTime) ) //Check how long ago the last tooth was seen compared to now. If it was more than half a second ago then the engine is probably stopped. toothLastToothTime can be greater than currentLoopTime if a pulse occurs between getting the lastest time and doing the comparison
{
@ -1069,7 +1069,8 @@ void loop()
}
else
{
long rpm_adjust = ((long)(micros() - toothOneTime) * (long)currentStatus.rpmDOT) / 1000000; //Take into account any likely accleration that has occurred since the last full revolution completed
interruptSafe(long elapsedTime = (micros() - toothOneTime);) //micros() is no longer interrupt safe
long rpm_adjust = (elapsedTime * (long)currentStatus.rpmDOT) / 1000000; //Take into account any likely accleration that has occurred since the last full revolution completed
timePerDegree = ldiv( 166666L, currentStatus.RPM + rpm_adjust).quot; //There is a small amount of rounding in this calculation, however it is less than 0.001 of a uS (Faster as ldiv than / )
}

View File

@ -29,6 +29,14 @@ volatile unsigned int dwellLimit_uS;
volatile uint16_t lastRPM_100ms; //Need to record this for rpmDOT calculation
volatile uint16_t last250msLoopCount = 1000; //Set to effectively random number on startup. Just need this to be different to what mainLoopCount equals initially (Probably 0)
#if defined(TIMER5_MICROS)
#define micros() (((timer5_overflow_count << 16) + TCNT5) * 4) //Fast version of micros() that uses the 4uS tick of timer5. See timers.ino for the overflow ISR of timer5
#define millis() (ms_counter) //Replaces the standard millis() function with this macro. It is both faster and more accurate. See timers.ino for its counter increment.
static inline unsigned long micros_safe(); //A version of micros() that is interrupt safe
#else
#define micros_safe() micros() //If the timer5 method is not used, the micros_safe() macro is simply an alias for the normal micros()
#endif
#if defined (CORE_TEENSY)
IntervalTimer lowResTimer;
void oneMSInterval();

View File

@ -63,11 +63,12 @@ void initialiseTimers()
//Timer2 Overflow Interrupt Vector, called when the timer overflows.
//Executes every ~1ms.
#if defined(CORE_AVR) //AVR chips use the ISR for this
ISR(TIMER2_OVF_vect, ISR_NOBLOCK)
ISR(TIMER2_OVF_vect)
#elif defined (CORE_TEENSY) || defined(CORE_STM32)
void oneMSInterval() //Most ARM chips can simply call a function
#endif
{
ms_counter++;
//Increment Loop Counters
loop33ms++;
@ -223,3 +224,21 @@ void oneMSInterval() //Most ARM chips can simply call a function
TIFR2 = 0x00; //Timer2 INT Flag Reg: Clear Timer Overflow Flag
#endif
}
#if defined(TIMER5_MICROS)
//This is used by the fast version of micros(). We just need to increment the timer overflow counter
ISR(TIMER5_OVF_vect)
{
++timer5_overflow_count;
}
static inline unsigned long micros_safe()
{
unsigned long newMicros;
noInterrupts();
newMicros = micros();
interrupts();
return newMicros;
}
#endif