FreeEMS  0.2.0-SNAPSHOT-282-g9efc524
Macros | Typedefs | Functions
interrupts.h File Reference

All interrupt handler declarations. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define INT   __attribute__((interrupt))
#define ATOMIC_START()   __asm__ __volatile__ ("sei") /* set global interrupt mask */
#define ATOMIC_END()   __asm__ __volatile__ ("cli") /* clear global interrupt mask */
#define VECTORS   __attribute__ ((section (".vectors")))

Typedefs

typedef void(* interruptTable )(void)

Functions

void _start (void)
void UISR (void) INT TEXT1
 Unimplemented Interrupt Handler.
void Injector1ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void Injector2ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void Injector3ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void Injector4ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void Injector5ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void Injector6ISR (void) INT TEXT1
 This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.
void PrimaryRPMISR (void) INT TEXT1
 RPM ISRs, IC timer for engine position and RPM.
void SecondaryRPMISR (void) INT TEXT1
 RPM ISRs, IC timer for engine position and RPM.
void TimerOverflow (void) INT TEXT1
 ECT overflow handler.
void ModDownCtrISR (void) INT TEXT1
void IgnitionDwellISR (void) INT TEXT1
void IgnitionFireISR (void) INT TEXT1
void StagedOnISR (void) INT TEXT1
void StagedOffISR (void) INT TEXT1
void PortPISR (void) INT TEXT1
 Port P pins ISR.
void PortHISR (void) INT TEXT1
 Port H pins ISR.
void PortJISR (void) INT TEXT1
 Port J pins ISR.
void IRQISR (void) INT TEXT1
 IRQ/PE1 pin ISR.
void XIRQISR (void) INT TEXT1
 XIRQ/PE0 pin ISR.
void RTIISR (void) INT TEXT1
 Real Time Interrupt Handler.
void SCI0ISR (void) INT TEXT1
 Serial Communication Interface 0 ISR.
void LowVoltageISR (void) INT TEXT1
 Low Voltage Counter.
void VRegAPIISR (void) INT TEXT1
void PLLLockISR (void) INT TEXT1
 PLL Lock Lost/Gained.
void SelfClockISR (void) INT TEXT1
 Self Clock Mode Entered/Exited.
void SpuriousISR (void) INT TEXT1
 Spurious Interrupt Handler.
void UnimplOpcodeISR (void) INT TEXT1
 Unimplemented Opcode Handler.
void RAMViolationISR (void) INT TEXT1
 CPU RAM Access Violation Handler.
void XGATEErrorISR (void) INT TEXT1
 XGATE Software Error Handler.

Detailed Description

All interrupt handler declarations.

All of the declarations for ISR functions are done here because they are all used in one place and it doesn't make sense to spread them out over N files for N functions. ISR headers only exist where there is a requirement for local variables and constants etc.

Definition in file interrupts.h.

Macro Definition Documentation

#define INT   __attribute__((interrupt))

Definition at line 52 of file interrupts.h.

#define ATOMIC_START ( )    __asm__ __volatile__ ("sei") /* set global interrupt mask */

Definition at line 59 of file interrupts.h.

Referenced by decodePacketAndRespond(), init(), main(), performSimpleGPIO(), and scheduleOutputs().

#define ATOMIC_END ( )    __asm__ __volatile__ ("cli") /* clear global interrupt mask */

Definition at line 60 of file interrupts.h.

Referenced by decodePacketAndRespond(), init(), main(), performSimpleGPIO(), and scheduleOutputs().

#define VECTORS   __attribute__ ((section (".vectors")))

Definition at line 63 of file interrupts.h.

Typedef Documentation

typedef void(* interruptTable)(void)

Definition at line 124 of file interrupts.h.

Function Documentation

void _start ( void  )

Referenced by decodePacketAndRespond().

Here is the caller graph for this function:

void UISR ( void  )

Unimplemented Interrupt Handler.

Unimplemented interrupt service routine for calls we weren't expecting. Currently this simply counts bad calls like any other event type.

Todo:

TODO Split this into its own file, create one for each, and clear flags for all, and increment shared counter as is.

TODO Currently not a problem, but as indirectly pointed out by johntramp, if no flag clearing is being done, then this code will run continuously, which is not a good idea...

Definition at line 52 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, and PORTB.

void Injector1ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c
void Injector2ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c

void Injector3ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c

void Injector4ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c

void Injector5ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c

void Injector6ISR ( void  )

This ISR is expanded from InjectorXISR via include statement, and macro definitions, so are the othe 5 below.

See Also
injectorISR.c
injectionISRs.c

void PrimaryRPMISR ( void  )

RPM ISRs, IC timer for engine position and RPM.

There are multiple copies of this interrupt handler, each is linked with the rest of the code once such that if there are N decoder implementations and/or variants, then there are N loadable binaries produced after a full build.

For details on any specific decoder implementation, see the documentation for that specific file.

Definition at line 85 of file BenchTest.c.

References decoderSetting::accelerationInputEventTimeTolerance, accumulatorRegisterCount, ADCBuffers, AMBIGUOUS_COUNT, ANGLE_FACTOR, angleOfSingleIteration, BackwardNarrow, BASTARD_CUMULATIVE_SYNC_LOSS_ID_BASE, BASTARD_SYNC_LOSS_ID_BASE, BIT0, CALC_FUEL_IGN, CAM_SYNC, CLEAR_BENCH_TEST_ON, Clocks, COMBUSTION_SYNC, coreStatusA, CoreVars, COUNT_OF_EVENTS_IMPOSSIBLY_HIGH_NOISE, Counters, cumulativeBastardTeeth, cumulativeBastardTeethEroderCounter, KeyUserDebug::currentEvent, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, decoderSetting::decelerationInputEventTimeTolerance, DECODER_BENCHMARKS, KeyUserDebug::decoderFlags, decoderMaxCodeTime, fixedConfig2::decoderSettings, doubleHighSeen, edgeTimeStamp, eventAngles, fixedConfigs2, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, KeyUserDebug::inputEventTimeTolerance, KeyUserDebugs, LAST_MATCH_VALID, LAST_PERIOD_VALID, LAST_TIMESTAMP_VALID, LAST_TPD_VALID, lastAccumulatorCount, lastEventTimeStamp, lastInterEventPeriod, twoPairs::lastPair, lastPARegisterReading, lastPrimaryEventTimeStamp, lastPrimaryTicksPerDegree, lastSecondaryEventTimeStamp, lastTicksPerDegree, MaskBySumPattern, MatchedPair, MatchedPairMatchedPair, MatchedPairNarrowWide, MAX_BASTARD_TEETH, MAX_CUMULATIVE_BASTARD_TEETH, MISSING_TEETH, decoderSetting::missingToothTolerance, NarrowBackward, NarrowWide, NarrowWideWideNarrow, NBIT0, noiseAppearedWayTooEarlyAsIfItWasAVRToothButWasnt, NUMBER_OF_REAL_EVENTS, NUMBER_OF_WHEEL_EVENTS, numberOfRealEvents, NumberOfTwinMatchedPairs, OK_TO_SCHEDULE, outputEventDelayFinalPeriod, outputEventInputEventNumbers, outputEventPulseWidthsMath, PACN1, match::pairs, match::pattern, PORTB, PRIMARY_EVENT_ARRIVED_TOO_EARLY, PRIMARY_EVENT_ARRIVED_TOO_LATE, KeyUserDebug::primaryTeethSeen, PTIT, resetToNonRunningState(), CoreVar::RPM, sampleEachADC(), schedulePortTPin(), KeyUserDebug::secondaryTeethSeen, SET_SYNC_LEVEL_TO, SHORTMAX, STATE_MISMATCH_IN_PRIMARY_RPM_ISR, Counter::syncedADCreadings, TC0, TEST_MODE_DODGY_MISSING_TOOTH, TEST_MODE_ITERATIONS, TEST_MODE_REVOLUTIONS, TEST_MODE_TIME_UNITS_HOURS, TEST_MODE_TIME_UNITS_MINUTES, TEST_MODE_TIME_UNITS_SECONDS, testEventsPerCycle, testMode, testNumberOfCycles, testNumberOfMissing, testTicksPerEvent, TFLG, TFLGOF, twoPairs::thisPair, ticks_per_degree_multiplier, ticksPerDegreeRecord, TIE, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, timeStamp, totalEventAngleRange, unknownLeadingEdges, WideNarrow, WideNarrowMatchedPair, windowCounts, windowsPerAllowedCumulativeBastardTooth, windowState, yourSyncToleranceIsLooserThanAWellYouGetTheIdea, yourSyncToleranceIsTighterThanAWellYouGetTheIdea, yourVRSensorHasALoosePlugFixIt, and KeyUserDebug::zsp7.

{
TFLG = 0x01;
unsigned short edgeTimeStamp = TC0;
/* Reset the clock for reading timeout */
// call sched output with args
/* Install the low word */
timeStamp.timeShorts[1] = edgeTimeStamp;
/* Find out what our timer value means and put it in the high word */
if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
timeStamp.timeShorts[0] = timerExtensionClock + 1;
}else{
}
unsigned char shouldFire = 1;
// unsigned long localPeriod = 0; // mutlifire or busy wait, if doing this, check last period for some min, and if too small, shrink second to last and increase last
// unsigned short localPeriod = 0; // normal mode
// Disable the interrupt again, to be enabled by a serial trigger
TIE &= NBIT0;
return;
}
}
// TODO make this more sophisticated
// Disable the interrupt again, to be enabled by a serial trigger
TIE &= NBIT0;
return;
}
}
// Grab updated time period
// Output the sync pulse only once per "engine cycle"
// Schedule the cam pulse
}else{
}
// Generate crank strength signal
unsigned char fakeCurrentEvent = 0;
fakeCurrentEvent = KeyUserDebugs.currentEvent - (testEventsPerCycle/2);
}else{
fakeCurrentEvent = KeyUserDebugs.currentEvent;
}
// Schedule the main teeth, or not
if(fakeCurrentEvent < testNumberOfMissing){
}else{
unsigned short singleWidth = testTicksPerEvent/2;
// See if this is the last one before the gap
// Migrate this to a safeMultiply() inline function
unsigned long wideWideWidth = (unsigned long)singleWidth * (testNumberOfMissing + 1);
if(wideWideWidth < SHORTMAX){
outputEventPulseWidthsMath[0] = (unsigned short)wideWideWidth;
}else{
}
}else{
outputEventPulseWidthsMath[0] = singleWidth;
}
}
// sub modes of different patterns, use scheduler for this by setting the ADC array up and probing/triggering/touching/poking/starting/
// switch statement for selecting different const arrays of angles, use busy wait, or multiple interrupt to do larger gaps for lower rpms/coarse events
// perhaps accept the pattern in the input packet and busy wait on some "run completed" flag before returning and freeing the buffer.
// TEMP de-configure timers and leave shouldFire zeroed.
TIE &= NBIT0;
// reset all timer modes for first time around, then check for timer >= requested value, check appropriate units of time, obviously...
// TEMP de-configure timers and leave shouldFire zeroed.
TIE &= NBIT0;
// ditto
// TEMP de-configure timers and leave shouldFire zeroed.
TIE &= NBIT0;
// ditto again
// TEMP de-configure timers and leave shouldFire zeroed.
TIE &= NBIT0;
}else{
// de-configure timers and leave shouldFire zeroed.
TIE &= NBIT0;
}
if(shouldFire){
// configuration for multiple periods setup here?
// fire outputs here
unsigned char channel;
for(channel = 0;channel < 6;channel++){
schedulePortTPin(channel, timeStamp);
}
}
}
}

Here is the call graph for this function:

void SecondaryRPMISR ( void  )

RPM ISRs, IC timer for engine position and RPM.

There are multiple copies of this interrupt handler, each is linked with the rest of the code once such that if there are N decoder implementations and/or variants, then there are N loadable binaries produced after a full build.For details on any specific decoder implementation, see the documentation for that specific file.

Definition at line 146 of file EvenTeeth-Xand1.c.

References decoderSetting::accelerationInputEventTimeTolerance, ADCBuffers, BIT0, BIT1, BUG_REACHED_UNREACHABLE_CODE, CALC_FUEL_IGN, CAM_SYNC, camTeethSeen, Clocks, coreStatusA, COUNT_OF_EVENTS_IMPOSSIBLY_HIGH_NOISE, COUNT_OF_EVENTS_IMPOSSIBLY_LOW_NOISE, Counters, crankTeethSinceLastCamTooth, KeyUserDebug::currentEvent, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, decoderSetting::decelerationInputEventTimeTolerance, DECODER_BENCHMARKS, KeyUserDebug::decoderFlags, fixedConfig2::decoderSettings, edgeTimeStamp, eventAngles, fixedConfigs2, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, KeyUserDebug::inputEventTimeTolerance, KeyUserDebugs, LAST_PERIOD_VALID, LAST_TIMESTAMP_VALID, lastEventTimeStamp, lastSecondaryEventTimeStamp, lastTicksPerDegree, NBIT0, NBIT1, NBIT2, numberOfRealEvents, OK_TO_SCHEDULE, PORTB, previousCrankTeethSeen, KeyUserDebug::primaryTeethSeen, PTIT, resetToNonRunningState(), sampleEachADC(), SECONDARY_EVENT_ARRIVED_TOO_EARLY, SECONDARY_EVENT_ARRIVED_TOO_LATE, KeyUserDebug::secondaryTeethSeen, SET_SYNC_LEVEL_TO, STATE_MISMATCH_IN_SECONDARY_RPM_ISR, Counter::syncedADCreadings, TC1, TCTL4, TFLG, TFLGOF, ticks_per_degree_multiplier, ticksPerDegreeRecord, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, and timeStamp.

{
/* Clear the interrupt flag for this input compare channel */
TFLG = 0x02;
/* Save all relevant available data here */
unsigned short edgeTimeStamp = TC1; /* Save the timestamp */
// unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
/* Install the low word */
timeStamp.timeShorts[1] = edgeTimeStamp;
/* Find out what our timer value means and put it in the high word */
if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
timeStamp.timeShorts[0] = timerExtensionClock + 1;
}else{
}
unsigned long thisEventTimeStamp = timeStamp.timeLong;
unsigned long thisInterEventPeriod = 0;
thisInterEventPeriod = thisEventTimeStamp - lastSecondaryEventTimeStamp;
}
// This sets currentEvent to 255 such that when the primary ISR runs it is rolled over to zero!
if(KeyUserDebugs.decoderFlags & CONFIGURED_SYNC){
// If sync not confirmed, register sync point. Must be before the count checks, otherwise loss of sync would result in sync being redeclared.
SET_SYNC_LEVEL_TO(CONFIGURED_SYNC);
}
/* If the count is less than 23, then we know that the electrical pulse that triggered
* this ISR execution was almost certainly in error and it is NOT valid to stay in sync.
*
* If the count is greater than 24, then we know that an electrical noise pulse triggered
* the other interrupt in between and was missed by the time period checks (unlikely, but
* possible) and that, therefore, there could have been a noise pulse on this input too,
* and therefore we don't really know where we are.
*
* In the case where the count is exactly 24 we can only rely on the time period checks in
* the other ISR, which should be sufficient unless poorly setup by a user with too wide
* of a tolerance level.
*
* There is zero point adding relative timing checks to this ISR because by nature, the
* other N teeth have already checked out good timing wise and therefore the average also
* does. Thus if we did check, for it to ever fail it would need to be tighter, and in
* reality it must be more loose due to the larger possible variation over the much much
* larger time frame.
*/
} // ELSE do nothing, and be happy :-)
}else{ // If sync not found, register first sync point, as this is our reference point.
SET_SYNC_LEVEL_TO(CONFIGURED_SYNC);
}
KeyUserDebugs.currentEvent = 0xFF; // TODO reset always, and catch noise induced errors below, this behaviour (now some lines above) may be bad/not fussy enough, or could be good, depending upon determinate nature of the inter event timing between primary and secondary, or not, perhaps move "lose sync or correct sync" as a configuration variable
}

Here is the call graph for this function:

void TimerOverflow ( void  )

ECT overflow handler.

When the ECT free running timer hits 65535 and rolls over, this is run. Its job is to extend the timer to an effective 32 bits for longer measuring much longer periods with the same resolution. Please see section 10.5.5 of the 68HC11 reference manual for more information on this technique!

Warning
The extension var should be incremented before the flag is cleared!

Definition at line 164 of file realtimeISRs.c.

References BIT5, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, NBIT5, PORTB, TFLGOF, and timerExtensionClock.

{
/* Increment the timer extension variable */
DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT5, PORTB); // TODO Should this go after the flag, or before the timer inc??? 6 possibilities here!
/* Clear the timer overflow interrupt flag */
TFLGOF = 0x80;
}
void ModDownCtrISR ( void  )
void IgnitionDwellISR ( void  )
void IgnitionFireISR ( void  )
void StagedOnISR ( void  )
Todo:
TODO This will be handled by XGATE, somehow, in the mean time, move to UISR file along with others.

Definition at line 50 of file injectionISRs.c.

References PITINTE.

{
// clear the flag
PITINTE |= 0x04;
/// @todo TODO This will be handled by XGATE, somehow, in the mean time, move to UISR file along with others.
}
void StagedOffISR ( void  )
Todo:
TODO This will be handled by XGATE, somehow, in the mean time, move to UISR file along with others.

Definition at line 57 of file injectionISRs.c.

References PITINTE.

{
// clear the flag
PITINTE |= 0x08;
/// @todo TODO This will be handled by XGATE, somehow, in the mean time, move to UISR file along with others.
}
void PortPISR ( void  )

Port P pins ISR.

Interrupt handler for edge events on port P pins. Not currently used.

Definition at line 173 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, ONES, PIFP, and PORTB.

void PortHISR ( void  )

Port H pins ISR.

Interrupt handler for edge events on port H pins. Not currently used.

Definition at line 199 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, ONES, PIFH, PORTB, and portHDebounce.

{
// // read the interrupt flags to a variable
// unsigned char portHFlags = PIFH;
// portHFlags &= 0xF8; // mask out the other bits
//
// /* Clear all port H flags (we only want one at a time) */
// Bump this for the time being as this should not be occurring.
// // Toggle a LED so we can see if the code ran
// PO-don't use this-RTA ^= 0x80; // Fuel pump pin (A7)
//
// debounce
if(portHDebounce == 0){
}else{
return;
}
//
// // find out which pin triggered it, clear the flag, perform the action.
// switch(portHFlags)
// {
// case 0x80 : // Increment cylinder count and set port count appropriately.
// switch (configs.combustionEventsPerEngineCycle) {
// case 1 :
// configs.combustionEventsPerEngineCycle = 2;
// configs.ports = 2;
// break;
// case 2 :
// configs.combustionEventsPerEngineCycle = 3;
// configs.ports = 3;
// break;
// case 3 :
// configs.combustionEventsPerEngineCycle = 4;
// configs.ports = 4;
// break;
// case 4 :
// configs.combustionEventsPerEngineCycle = 5;
// configs.ports = 5;
// break;
// case 5 :
// configs.combustionEventsPerEngineCycle = 6;
// configs.ports = 6;
// break;
// case 6 :
// configs.combustionEventsPerEngineCycle = 8;
// configs.ports = 4;
// break;
// case 8 :
// configs.combustionEventsPerEngineCycle = 10;
// configs.ports = 5;
// break;
// case 10 :
// configs.combustionEventsPerEngineCycle = 12;
// configs.ports = 6;
// break;
// case 12 :
// configs.combustionEventsPerEngineCycle = 1;
// configs.ports = 1;
// break;
// }
// break;
// case 0x40 : // Injection output enable/disable
// break;
// case 0x20 : // Ignition output enable/disable
// break;
// case 0x10 : // Staged injection enable/disable
// break;
// case 0x08 : // Staged injection start sched/fixed
// break;
// case 0x04 : // Staged injection end sched/fixed
// break;
// case 0x02 : // free input
// break;
// case 0x01 : // free input
// break;
// default : // Two or more pressed, nothing to do except wait for another button press
// break;
// }
}
void PortJISR ( void  )

Port J pins ISR.

Interrupt handler for edge events on port J pins. Not currently used.

Definition at line 186 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, ONES, PIFJ, and PORTB.

void IRQISR ( void  )

IRQ/PE1 pin ISR.

Interrupt handler for edge events on the IRQ/PE1 pin. Not currently used.

Definition at line 290 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, and PORTB.

void XIRQISR ( void  )

XIRQ/PE0 pin ISR.

Interrupt handler for edge events on the XIRQ/PE0 pin. Not currently used.

Definition at line 303 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_CALLS_TO_UISRS_OFFSET, NBIT7, and PORTB.

void RTIISR ( void  )

Real Time Interrupt Handler.

Handles time keeping, including all internal clocks, and generic periodic tasks that run quickly and must be done on time.

Todo:
TODO refactor this entire file, especially to remove apparently expensive modulus operations which could be replaced with >= instead. Maybe much more.
Todo:
TODO This is too quick to turn off, average 0.5 seconds, which is OK, but fastest = 0seconds which is difficult to understand, needs a flag and to be 1 - 2 with average 1.5.

Definition at line 52 of file realtimeISRs.c.

References BIT3, BIT6, BIT7, CLEAR_FUEL_PUMP_PRIME, Clocks, coreStatusA, CoreVars, CRGFLG, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, fixedConfigs2, FORCE_READING, FUEL_PUMP_PRIME, sensorSetting::fuelPumpPrimePeriod, Clock::millisToTenths, NBIT3, NBIT7, PORTA, PORTB, portHDebounce, sensorSetting::readingTimeout, Clock::realTimeClockMain, Clock::realTimeClockMillis, Clock::realTimeClockMinutes, Clock::realTimeClockSeconds, Clock::realTimeClockTenths, CoreVar::RPM, Clock::secondsToMinutes, fixedConfig2::sensorSettings, Clock::tenthsToSeconds, and Clock::timeoutADCreadingClock.

{
/* Clear the RTI flag */
CRGFLG = 0x80;
/* Increment the counter */
/* This function could be performed without the extra variables by rolling over the main ones at the largest multiples of the next ones, but I'm not sure thats better */
// TODO add content to eighths of a milli RTC ?
/// @todo TODO refactor this entire file, especially to remove apparently expensive modulus operations which could be replaced with >= instead. Maybe much more.
/* Every 8th RTI execution is one milli */
if(Clocks.realTimeClockMain % 8 == 0){
/* Increment the milli counter */
/* Increment the milli roll over variable */
/* Perform all tasks that are once per millisecond here or preferably main */
/* Set force read adc flag */
}else if (CoreVars->RPM > 0){ // turn on very quickly if rpm appears non zero, temp impl...
PORTA |= BIT7;
}
#ifdef XGATE_TESTS
#include "xgateTests.c"
#endif
/* Every 100 millis is one tenth */
if(Clocks.millisToTenths % 100 == 0){
/* Increment the tenths counter */
/* Increment the tenths roll over variable */
/* Reset the millis roll over variable */
/* Perform all tasks that are once per tenth of a second here or preferably main */
// decrement port H debounce variable till it's zero again.
if(portHDebounce != 0){
}
/* Every 10 tenths is one second */
if(Clocks.tenthsToSeconds % 10 == 0){
/* Increment the seconds counter */
/* Increment the seconds roll over variable */
/* Reset the tenths roll over variable */
/* Perform all tasks that are once per second here or preferably main */
// Toggle the CEL on the same pin as the SM load/run switch
PORTA ^= BIT6;
// temp fuel pump prime and safety off impl
}
}else if(CoreVars->RPM == 0){ /// @todo TODO This is too quick to turn off, average 0.5 seconds, which is OK, but fastest = 0seconds which is difficult to understand, needs a flag and to be 1 - 2 with average 1.5.
}
/* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */
if(Clocks.secondsToMinutes % 60 == 0){
/* Increment the minutes counter */
/* Potentially put an hours field in here and below, but that would be excessive */
// TODO add hours RTC ?
/* Reset the seconds roll over variable */
/* Perform all tasks that are once per minute here or preferably main */
// TODO add content in minutes RTC ?
/* Hours if statement here if we do hours which we probably won't */
}
}
}
}
}
void SCI0ISR ( void  )

Serial Communication Interface 0 ISR.

SCI0 ISR handles all interrupts for SCI0 by reading flags and acting appropriately. Its functions are to send raw bytes out over the wire from a buffer and to receive bytes from the wire un-escape them, checksum them and store them in a buffer.

Todo:

TODO Move this code into an include file much like the fuel interrupts such that it can be used for multiple UART SCI devices without duplication.

TODO Fix the init code such that this doesn't run at boot without a serail device attached. Clear buffer maybe? or flag clearing/isr enabling ordering?

Definition at line 109 of file commsISRs.c.

References BIT4, BIT7, CLEAR_ALL_SOURCE_ID_FLAGS, COM_CLEAR_SCI0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, coreStatusA, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, ESCAPE_BYTE, ESCAPED_ESCAPE_BYTE, ESCAPED_START_BYTE, ESCAPED_STOP_BYTE, FLAG_AND_INC_FLAGGABLE, FLAG_SERIAL_ESCAPE_PAIR_MISMATCHES_OFFSET, FLAG_SERIAL_FRAMING_ERRORS_OFFSET, FLAG_SERIAL_NOISE_ERRORS_OFFSET, FLAG_SERIAL_OVERRUN_ERRORS_OFFSET, FLAG_SERIAL_PACKETS_OVER_LENGTH_OFFSET, FLAG_SERIAL_PARITY_ERRORS_OFFSET, FLAG_SERIAL_STARTS_INSIDE_A_PACKET_OFFSET, KeyUserDebugs, NBIT4, NBIT7, PORTB, resetReceiveState(), RX_BUFFER_SIZE, RX_READY_TO_PROCESS, RX_SCI_ESCAPED_NEXT, RX_SCI_NOT_ESCAPED_NEXT, RXBufferContentSourceID, RXBufferCurrentPosition, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_ISR_DISABLE, SCICR2_RX_ISR_ENABLE, SCICR2_TX_DISABLE, SCICR2_TX_ISR_DISABLE, SCICR2_TX_ISR_ENABLE, SCISR1_RX_FRAMING, SCISR1_RX_NOISE, SCISR1_RX_OVERRUN, SCISR1_RX_PARITY, SCISR1_RX_REGISTER_FULL, SCISR1_TX_REGISTER_EMPTY, KeyUserDebug::serialAndCommsCodeErrors, KeyUserDebug::serialHardwareErrors, KeyUserDebug::serialOverrunErrors, START_BYTE, STOP_BYTE, TXBufferCurrentPositionHandler, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, and TXByteEscaped.

{
// OK before flag reading because cleared when SCI0DRL accessed (R or W)
/* Read the flags register */
unsigned char flags = SCI0SR1;
/* Note: Combined with reading or writing the data register this also clears the flags. */
/* If either of these flags is set, we need to read the data to clear the flag */
/* Grab the received byte from the register to clear the flag, whether we want the data or not */
unsigned char rawByte = SCI0DRL;
/* If the RX interrupt is enabled do something useful */
/* If there is noise on the receive line record it */
if(flags & SCISR1_RX_NOISE){
}
/* If a framing error occurs record it */
if(flags & SCISR1_RX_FRAMING){
}
/* If a parity error occurs record it */
if(flags & SCISR1_RX_PARITY){
}
/* If an overrun occurs record it */
if(flags & SCISR1_RX_OVERRUN){
}
}else{ // Process the received data
/* Look for a start byte to indicate a new packet */
if(rawByte == START_BYTE){
/* If another interface is using it (Note, clear flag, not normal) */
/* Turn off our reception */
}else{
/* If we are using it */
/* Increment the counter */
}
/* Reset to us using it unless someone else was */
resetReceiveState(COM_SET_SCI0_INTERFACE_ID);
}
}else if((unsigned short)RXBufferCurrentPosition >= ((unsigned short)&RXBuffer + RX_BUFFER_SIZE)){
/* Buffer was full, record and reset */
/* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */
if(rawByte == ESCAPED_ESCAPE_BYTE){
}else if(rawByte == ESCAPED_START_BYTE){
}else if(rawByte == ESCAPED_STOP_BYTE){
}else{
/* Otherwise reset and record as data is bad */
}
}else if(rawByte == ESCAPE_BYTE){
/* Drop the escape and set the flag to indicate that the next byte should be un-escaped. */
}else if(rawByte == STOP_BYTE){
/* Turn off reception */
}else{
}
} /* ELSE: Do nothing : drop the byte */
}
}
}
/* If the TX interrupt is enabled check the register empty flag. */
/* Get the byte to be sent from the buffer */
unsigned char rawValue = *TXBufferCurrentPositionSCI0;
if(TXByteEscaped == 0){
/* If the raw value needs to be escaped */
if(rawValue == ESCAPE_BYTE){
}else if(rawValue == START_BYTE){
}else if(rawValue == STOP_BYTE){
}else{ /* Otherwise just send it */
SCI0DRL = rawValue;
}
}else{
}
}else{ /* Length is zero */
/* Turn off transmission interrupt */
/* Clear the TX in progress flag */
}else{
/* Send the stop byte */
}
}
}
}

Here is the call graph for this function:

void LowVoltageISR ( void  )

Low Voltage Counter.

Count how often our voltage drops lower than it should without resetting.

Definition at line 316 of file miscISRs.c.

References BIT6, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_LOW_VOLTAGE_CONDITION_OFFSET, NBIT6, PORTB, and VREGCTRL.

void VRegAPIISR ( void  )
void PLLLockISR ( void  )

PLL Lock Lost/Gained.

When the Phase Locked Loop is lost or gained, this is called.

Definition at line 111 of file miscISRs.c.

References BIT7, CRGFLG, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE, FLAG_PHASE_LOCKED_LOOP_LOCK_LOST_OFFSET, KeyUserDebug::ignitionCuts, KeyUserDebug::injectionCuts, KeyUserDebugs, NBIT7, PLL_LOCK_LOST_PRECAUTIONARY, PLLLOCK, PLLLOCKIF, PORTB, resetToNonRunningState(), SELF_CLOCK_MODE_PRECAUTIONARY, and KeyUserDebug::syncLostWithThisID.

{
// Clear the flag
// Check the state of PLL lock
if(CRGFLG & PLLLOCK){ // Recovered
// Re-enable outputs with return of accurate clock
}else{ // Lock lost
// Record the loss of PLL lock
// Force sync loss with special code to prevent engine damage from incorrect timings
// This is required otherwise we never see the self clock code, as it's immediately over-written by our code
// Don't over-write the self clock sync loss ID
}else{
// This means ONLY the PLL lock was lost (at this time)
}
// Disable outputs as a precaution with dodgy clock
}
}

Here is the call graph for this function:

void SelfClockISR ( void  )

Self Clock Mode Entered/Exited.

When the main clock quality drops too low to be used, self clock is entered.

See section 2.6.3 of the device manual for more information.

Definition at line 145 of file miscISRs.c.

References BIT7, CRGFLG, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, enablePLL(), FLAG_AND_INC_FLAGGABLE, FLAG_SELF_CLOCK_MODE_ENTERED_OFFSET, KeyUserDebug::ignitionCuts, KeyUserDebug::injectionCuts, KeyUserDebugs, NBIT7, PORTB, resetToNonRunningState(), SCM, SCMIF, and SELF_CLOCK_MODE_PRECAUTIONARY.

{
// Clear the flag
// Check the state of self clock mode flag
if(CRGFLG & SCM){ // Self Clock Mode
// Record the loss of main clock
// Force sync loss with special code to prevent engine damage from incorrect timings
// Disable outputs as a precaution with dodgy clock
((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnSelfClock = 1;
}else{ // Recovered
// Disabled when falling back to Self Clock Mode, re-enable here
enablePLL(); // Note, busy wait with no limit, danger to the manifold!
// Re-enable outputs with return of accurate clock
((ignitionCutFlags *)&KeyUserDebugs.ignitionCuts)->IgnSelfClock = 0;
}
}

Here is the call graph for this function:

void SpuriousISR ( void  )

Spurious Interrupt Handler.

This is fired when the correct vector for an interrupt can not be determined.

Theoretically this should not happen, and probably indicates a code fault.

Definition at line 64 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE2, FLAG_SPURIOUS_INTERRUPTS_OFFSET, NBIT7, and PORTB.

void UnimplOpcodeISR ( void  )

Unimplemented Opcode Handler.

Unimplemented opcode trap. This should never run and probably indicates an attempt to execute data instead of code, but could be an assembler issue.

Definition at line 76 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE2, FLAG_UNIMPLEMENTED_OPCODES_OFFSET, NBIT7, and PORTB.

void RAMViolationISR ( void  )

CPU RAM Access Violation Handler.

If the CPU tries to access protected XGATE RAM, this is fired.

Definition at line 87 of file miscISRs.c.

References AVIF, BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE2, FLAG_RAM_ACCESS_VIOLATIONS_OFFSET, NBIT7, PORTB, and RAMWPC.

void XGATEErrorISR ( void  )

XGATE Software Error Handler.

If buggy code is being executed on the XGATE, this may fire alerting us to it.

Definition at line 99 of file miscISRs.c.

References BIT7, DEBUG_TURN_PIN_OFF, DEBUG_TURN_PIN_ON, DECODER_BENCHMARKS, FLAG_AND_INC_FLAGGABLE2, FLAG_XGATE_SOFTWARE_ERRORS_OFFSET, NBIT7, PORTB, XGMCTL, XGSWEIF, and XGSWEIFM.