All interrupt handler declarations. More...
Go to the source code of this file.
Defines | |
#define | INT __attribute__((interrupt)) |
#define | ATOMIC_START() __asm__ __volatile__ ("sei") |
#define | ATOMIC_END() __asm__ __volatile__ ("cli") |
#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 |
Injector1ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | Injector2ISR (void) INT TEXT1 |
Injector2ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | Injector3ISR (void) INT TEXT1 |
Injector3ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | Injector4ISR (void) INT TEXT1 |
Injector4ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | Injector5ISR (void) INT TEXT1 |
Injector5ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | Injector6ISR (void) INT TEXT1 |
Injector6ISR is expanded from InjectorXISR via include statement, and macro definition(s). | |
void | PrimaryRPMISR (void) INT TEXT1 |
void | SecondaryRPMISR (void) INT TEXT1 |
Use the rising and falling edges................... | |
void | TimerOverflow (void) INT TEXT1 |
ECT overflow handler. | |
void | ModDownCtrISR (void) INT TEXT1 |
Tacho pulse generator. | |
void | IgnitionDwellISR (void) INT TEXT1 |
Ignition dwell control. | |
void | IgnitionFireISR (void) INT TEXT1 |
Ignition discharge control. | |
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 |
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.
#define ATOMIC_END | ( | ) | __asm__ __volatile__ ("cli") |
Definition at line 61 of file interrupts.h.
#define ATOMIC_START | ( | ) | __asm__ __volatile__ ("sei") |
Definition at line 60 of file interrupts.h.
#define INT __attribute__((interrupt)) |
Definition at line 53 of file interrupts.h.
#define VECTORS __attribute__ ((section (".vectors"))) |
Definition at line 64 of file interrupts.h.
typedef void(* interruptTable)(void) |
Definition at line 107 of file interrupts.h.
void _start | ( | void | ) |
Referenced by decodePacketAndRespond().
void IgnitionDwellISR | ( | void | ) |
Ignition dwell control.
This function turns ignition pins on to dwell when required.
Definition at line 73 of file ignitionISRs.c.
References engineSetting::combustionEventsPerEngineCycle, DWELL_DISABLE, DWELL_ENABLE, dwellQueueLength, dwellStartMasks, fixedConfig1::engineSettings, fixedConfigs1, nextDwellChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedDwellOffsets.
00074 { 00075 // clear flag 00076 PITTF = DWELL_ENABLE; 00077 00078 // start dwelling asap 00079 PORTS_BA |= dwellStartMasks[nextDwellChannel]; 00080 00081 if(dwellQueueLength == 0){ 00082 // turn off the int 00083 PITINTE &= DWELL_DISABLE; 00084 00085 // disable channels 00086 PITCE &= DWELL_DISABLE; 00087 }else{ 00088 // reduce queue length by one 00089 dwellQueueLength--; 00090 00091 // increment channel counter to next channel 00092 if(nextDwellChannel < (fixedConfigs1.engineSettings.combustionEventsPerEngineCycle - 1)){ 00093 nextDwellChannel++; // if not the last channel, increment 00094 }else{ 00095 nextDwellChannel = 0; // if the last channel, reset to zero 00096 } 00097 00098 // if the queue length after decrement is greater than 0 then we need to load the timer, if it is zero and we decremented, the timer was already loaded. 00099 if(dwellQueueLength > 0){ 00100 if(dwellQueueLength > 8){ // TODO ???? why 8 ???? 12 or combustion events per... or ? 00101 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00102 PORTS |= 0x20; 00103 }else{ 00104 // load the timer if the index is good 00105 PITLD0 = queuedDwellOffsets[dwellQueueLength - 1]; 00106 } 00107 } 00108 } 00109 00110 // blink a led 00111 PORTS ^= 0x80; 00112 }
void IgnitionFireISR | ( | void | ) |
Ignition discharge control.
This function turns ignition pins off to discharge when required.
Definition at line 123 of file ignitionISRs.c.
References engineSetting::combustionEventsPerEngineCycle, fixedConfig1::engineSettings, fixedConfigs1, IGNITION_DISABLE, IGNITION_ENABLE, ignitionMasks, ignitionQueueLength, nextIgnitionChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedIgnitionOffsets.
00124 { 00125 // clear flag 00126 PITTF = IGNITION_ENABLE; 00127 00128 // fire the coil asap 00129 PORTS_BA &= ignitionMasks[nextIgnitionChannel]; 00130 00131 if(ignitionQueueLength == 0){ 00132 // turn off the int 00133 PITINTE &= IGNITION_DISABLE; 00134 00135 // disable channels 00136 PITCE &= IGNITION_DISABLE ; 00137 }else{ 00138 // reduce queue length by one 00139 ignitionQueueLength--; 00140 00141 // increment channel counter to next channel 00142 if(nextIgnitionChannel < (fixedConfigs1.engineSettings.combustionEventsPerEngineCycle - 1)){ 00143 nextIgnitionChannel++; // if not the last channel, increment 00144 }else{ 00145 nextIgnitionChannel = 0; // if the last channel, reset to zero 00146 } 00147 00148 // if the queue length after decrement is greater than 0 then we need to load the timer, if it is zero and we decremented, the timer was already loaded. 00149 if(ignitionQueueLength > 0){ 00150 if(ignitionQueueLength > fixedConfigs1.engineSettings.combustionEventsPerEngineCycle){ // TODO as above!!!!!!!!!! 00151 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00152 PORTS |= 0x10; 00153 }else{ 00154 // load the timer if the index is good 00155 PITLD0 = queuedIgnitionOffsets[ignitionQueueLength - 1]; 00156 } 00157 } 00158 } 00159 00160 // blink a led 00161 PORTS ^= 0x40; 00162 }
void Injector1ISR | ( | void | ) |
Injector1ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void Injector2ISR | ( | void | ) |
Injector2ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void Injector3ISR | ( | void | ) |
Injector3ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void Injector4ISR | ( | void | ) |
Injector4ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void Injector5ISR | ( | void | ) |
Injector5ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void Injector6ISR | ( | void | ) |
Injector6ISR is expanded from InjectorXISR via include statement, and macro definition(s).
void IRQISR | ( | void | ) |
IRQ/PE1 pin ISR.
Interrupt handler for edge events on the IRQ/PE1 pin. Not currently used.
Definition at line 203 of file miscISRs.c.
References Counter::callsToUISRs, and Counters.
00203 { 00204 /* Clear the flag */ 00205 // ?? TODO 00206 00207 /* Increment the unimplemented ISR execution counter */ 00208 Counters.callsToUISRs++; 00209 }
void LowVoltageISR | ( | void | ) |
Low Voltage Counter.
Count how often our voltage drops lower than it should without resetting.
Definition at line 233 of file miscISRs.c.
References Counters, Counter::lowVoltageConditions, and VREGCTRL.
00233 { 00234 /* Clear the flag */ 00235 VREGCTRL |= 0x01; 00236 00237 /* Increment the counter */ 00238 Counters.lowVoltageConditions++; 00239 }
void ModDownCtrISR | ( | void | ) |
Tacho pulse generator.
Currently this is being used to generate a variable frequency tachometer output. Although this is a bit of a waste of a timer resource it does allow tachometers that were intended for engines with a different cylinder count to be used where it would otherwise not be possible.
Definition at line 150 of file realtimeISRs.c.
References engineCyclePeriod, fixedConfigs1, MCCNT, MCFLG, PORTA, tachoPeriod, fixedConfig1::tachoSettings, tachoSetting::tachoTotalFactor, and ticksPerCycleAtOneRPM.
00150 { 00151 /* Clear the modulus down counter interrupt flag */ 00152 MCFLG = 0x80; 00153 00154 /* If the rpm isn't genuine go ultra slow */ 00155 if(engineCyclePeriod == ticksPerCycleAtOneRPM){ 00156 tachoPeriod = 65535; 00157 }else{ 00158 /* Use engine cycle period to setup the frequency of this counter and thereby act as a tacho out */ 00159 tachoPeriod = (unsigned long)engineCyclePeriod / fixedConfigs1.tachoSettings.tachoTotalFactor; 00160 } 00161 /* Set the count down value */ 00162 MCCNT = tachoPeriod; 00163 00164 /* Bit bang the output port */ 00165 PORTA ^= 0x40; // SM pin (A6) 00166 }
void PortHISR | ( | void | ) |
Port H pins ISR.
Interrupt handler for edge events on port H pins. Not currently used.
Definition at line 90 of file miscISRs.c.
References ONES, PIFH, PORTA, and portHDebounce.
00091 { 00092 // // read the interrupt flags to a variable 00093 // unsigned char portHFlags = PIFH; 00094 // portHFlags &= 0xF8; // mask out the other bits 00095 // 00096 // /* Clear all port H flags (we only want one at a time) */ 00097 PIFH = ONES; 00098 // 00099 // // Toggle a LED so we can see if the code ran 00100 PORTA ^= 0x80; // Fuel pump pin (A7) 00101 // 00102 // debounce 00103 if(portHDebounce == 0){ 00104 portHDebounce = 2; 00105 }else{ 00106 return; 00107 } 00108 // 00109 // // find out which pin triggered it, clear the flag, perform the action. 00110 // switch(portHFlags) 00111 // { 00112 // case 0x80 : // Increment cylinder count and set port count appropriately. 00113 // switch (configs.combustionEventsPerEngineCycle) { 00114 // case 1 : 00115 // configs.combustionEventsPerEngineCycle = 2; 00116 // configs.ports = 2; 00117 // break; 00118 // case 2 : 00119 // configs.combustionEventsPerEngineCycle = 3; 00120 // configs.ports = 3; 00121 // break; 00122 // case 3 : 00123 // configs.combustionEventsPerEngineCycle = 4; 00124 // configs.ports = 4; 00125 // break; 00126 // case 4 : 00127 // configs.combustionEventsPerEngineCycle = 5; 00128 // configs.ports = 5; 00129 // break; 00130 // case 5 : 00131 // configs.combustionEventsPerEngineCycle = 6; 00132 // configs.ports = 6; 00133 // break; 00134 // case 6 : 00135 // configs.combustionEventsPerEngineCycle = 8; 00136 // configs.ports = 4; 00137 // break; 00138 // case 8 : 00139 // configs.combustionEventsPerEngineCycle = 10; 00140 // configs.ports = 5; 00141 // break; 00142 // case 10 : 00143 // configs.combustionEventsPerEngineCycle = 12; 00144 // configs.ports = 6; 00145 // break; 00146 // case 12 : 00147 // configs.combustionEventsPerEngineCycle = 1; 00148 // configs.ports = 1; 00149 // break; 00150 // } 00151 // break; 00152 // case 0x40 : // Injection output enable/disable 00153 // if(coreSettingsA & FUEL_CUT){ 00154 // coreSettingsA &= FUEL_CUT_OFF; 00155 // }else{ 00156 // coreSettingsA |= FUEL_CUT; 00157 // } 00158 // break; 00159 // case 0x20 : // Ignition output enable/disable 00160 // if(coreSettingsA & HARD_SPARK_CUT){ 00161 // coreSettingsA &= HARD_SPARK_CUT_OFF; 00162 // }else{ 00163 // coreSettingsA |= HARD_SPARK_CUT; 00164 // } 00165 // break; 00166 // case 0x10 : // Staged injection enable/disable 00167 // if(coreSettingsA & STAGED_ON){ 00168 // coreSettingsA &= STAGED_OFF; 00169 // }else{ 00170 // coreSettingsA |= STAGED_ON; 00171 // } 00172 // break; 00173 // case 0x08 : // Staged injection start sched/fixed 00174 // if(coreSettingsA & STAGED_START){ 00175 // coreSettingsA &= CLEAR_STAGED_START; 00176 // }else{ 00177 // coreSettingsA |= STAGED_START; 00178 // } 00179 // break; 00180 // case 0x04 : // Staged injection end sched/fixed 00181 // if(coreSettingsA & STAGED_END){ 00182 // coreSettingsA &= CLEAR_STAGED_END; 00183 // }else{ 00184 // coreSettingsA |= STAGED_END; 00185 // } 00186 // break; 00187 // case 0x02 : // free input 00188 // break; 00189 // case 0x01 : // free input 00190 // break; 00191 // default : // Two or more pressed, nothing to do except wait for another button press 00192 // break; 00193 // } 00194 }
void PortJISR | ( | void | ) |
Port J pins ISR.
Interrupt handler for edge events on port J pins. Not currently used.
Definition at line 76 of file miscISRs.c.
References Counter::callsToUISRs, Counters, ONES, and PIFJ.
00076 { 00077 /* Clear all port H flags (we only want one at a time) */ 00078 PIFJ = ONES; 00079 /* Increment the unimplemented ISR execution counter */ 00080 Counters.callsToUISRs++; 00081 }
void PortPISR | ( | void | ) |
Port P pins ISR.
Interrupt handler for edge events on port P pins. Not currently used.
Definition at line 62 of file miscISRs.c.
References Counter::callsToUISRs, Counters, ONES, and PIFP.
00062 { 00063 /* Clear all port P flags (we only want one at a time) */ 00064 PIFP = ONES; 00065 /* Increment the unimplemented ISR execution counter */ 00066 Counters.callsToUISRs++; 00067 } /* Port P interrupt service routine */
void PrimaryRPMISR | ( | void | ) |
Primary RPM ISR
Primary RPM ISR
Primary RPM ISR
Primary RPM ISR
Summary of intended engine position capture scheme (out of date as at 3/1/09)
Position/RPM signal interpretation : Discard edges that have arrived too soon (lose sync here?) Check to ensure we haven't lost sync (pulse arrives too late) Compare time stamps of successive edges and calculate RPM Store RPM and position in globals
Schedule events : loop through all events (spark and fuel), schedule those that fall sufficiently after this tooth and before the next one we expect.
Sample ADCs : Grab a unified set of ADC readings at one time in a consistent crank location to eliminate engine cycle dependent noise. Set flag stating that New pulse, advance, etc should be calculated.
TODO bring the above docs up to date with reality
TODO finish this off to a usable standard
Primary RPM ISR
Schedule events : Blindly start fuel pulses for each and every input pulse.
Sample ADCs : Grab a unified set of ADC readings at one time in a consistent crank location to eliminate engine cycle dependent noise. Set flag stating that New pulse, advance, etc should be calculated.
Primary RPM ISR
Definition at line 72 of file LT1-360-8.c.
References ADCArrays, CALC_FUEL_IGN, CLEAR_PRIMARY_SYNC, Clocks, engineSetting::combustionEventsPerEngineCycle, fixedConfig1::coreSettingsA, coreStatusA, Counters, Counter::crankSyncLosses, DWELL_ENABLE, dwellQueueLength, engineCyclePeriod, fixedConfig1::engineSettings, fixedConfigs1, IGNITION_ENABLE, ignitionQueueLength, injectorMainControlRegisters, injectorMainEnableMasks, injectorMainEndTimes, injectorMainOnMasks, injectorMainPulseWidthsRealtime, injectorMainStartTimesHolding, injectorMainTimeRegisters, injectorMinimumPulseWidth, injectorSwitchOffCodeTime, ISRLatencyVars, isSynced, lastPrimaryPulseTimeStamp, LONGHALF, masterPulseWidth, mathSampleTimeStampRecord, nextDwellChannel, nextIgnitionChannel, PITCE, PITCNT0, PITCNT1, PITINTE, PITLD0, PITLD1, PITTF, PORTJ, PORTP, PRIMARY_POLARITY, PRIMARY_SYNC, ISRLatencyVar::primaryInputLatency, RuntimeVar::primaryInputLeadingRuntime, RuntimeVar::primaryInputTrailingRuntime, primaryLeadingEdgeTimeStamp, primaryPulsesPerSecondaryPulse, primaryTeethDroppedFromLackOfSync, PrimaryTeethDuringHigh, PrimaryTeethDuringLow, Counter::primaryTeethSeen, PTIT, queuedDwellOffsets, queuedIgnitionOffsets, RPMRecord, RuntimeVars, sampleEachADC(), selfSetTimer, Counter::syncedADCreadings, TC0, TCNT, TFLG, TFLGOF, ticksPerCycleAtOneRPMx2, ticksPerMinute, TIE, timeBetweenSuccessivePrimaryPulses, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, totalAngleAfterReferenceInjection, trailingEdgeSecondaryRPMInputCodeTime, and VCAS.
00072 { 00073 /* Clear the interrupt flag for this input compare channel */ 00074 TFLG = 0x01; 00075 00076 /* Save all relevant available data here */ 00077 // unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00078 // unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */ 00079 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00080 // unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */ 00081 00082 // unsigned char risingEdge; /* in LT1s case risingEdge means signal is high */ 00083 // if(fixedConfigs1.coreSettingsA & PRIMARY_POLARITY){ 00084 // risingEdge = PTITCurrentState & 0x01; 00085 // }else{ 00086 // risingEdge = !(PTITCurrentState & 0x01); 00087 // } 00088 00089 PORTJ |= 0x80; /* Echo input condition on J7 */ 00090 if(!isSynced){ /* If the CAS is not in sync get window counts so SecondaryRPMISR can set position */ 00091 if (PTITCurrentState & 0x02){ 00092 PrimaryTeethDuringHigh++; /* if low resolution signal is high count number of pulses */ 00093 }else{ 00094 PrimaryTeethDuringLow++; /* if low resolution signal is low count number of pulses */ 00095 } 00096 }else{ /* The CAS is synced and we need to update our 360/5=72 tooth wheel */ 00098 VCAS = VCAS + 10; /* Check/correct for 10deg of CAM movement */ 00100 } 00101 }
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.
Definition at line 53 of file realtimeISRs.c.
References Clocks, coreStatusA, CRGFLG, fixedConfigs2, FORCE_READING, Clock::millisToTenths, portHDebounce, sensorSetting::readingTimeout, Clock::realTimeClockMain, Clock::realTimeClockMillis, Clock::realTimeClockMinutes, Clock::realTimeClockSeconds, Clock::realTimeClockTenths, RuntimeVar::RTCRuntime, RuntimeVars, Clock::secondsToMinutes, fixedConfig2::sensorSettings, ShouldSendLog, TCNT, Clock::tenthsToSeconds, Clock::timeoutADCreadingClock, TRUE, and XGSWT.
00053 { 00054 /* Clear the RTI flag */ 00055 CRGFLG = 0x80; 00056 00057 /* Record time stamp for code run time reporting */ 00058 unsigned short startTimeRTI = TCNT; 00059 00060 /* Increment the counter */ 00061 Clocks.realTimeClockMain++; 00062 00063 /* 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 */ 00064 00065 // TODO add content to eighths of a milli RTC ? 00066 00067 /* Every 8th RTI execution is one milli */ 00068 if(Clocks.realTimeClockMain % 8 == 0){ 00069 /* Increment the milli counter */ 00070 Clocks.realTimeClockMillis++; 00071 00072 /* Increment the milli roll over variable */ 00073 Clocks.millisToTenths++; 00074 00075 /* Perform all tasks that are once per millisecond here or preferably main */ 00076 Clocks.timeoutADCreadingClock++; 00077 if(Clocks.timeoutADCreadingClock > fixedConfigs2.sensorSettings.readingTimeout){ 00078 /* Set force read adc flag */ 00079 coreStatusA |= FORCE_READING; 00080 Clocks.timeoutADCreadingClock = 0; 00081 } 00082 00083 /* Every 100 millis is one tenth */ 00084 if(Clocks.millisToTenths % 100 == 0){ 00085 /* Increment the tenths counter */ 00086 Clocks.realTimeClockTenths++; 00087 00088 /* Increment the tenths roll over variable */ 00089 Clocks.tenthsToSeconds++; 00090 00091 /* Reset the millis roll over variable */ 00092 Clocks.millisToTenths = 0; 00093 00094 /* Perform all tasks that are once per tenth of a second here or preferably main */ 00095 // decrement port H debounce variable till it's zero again. 00096 if(portHDebounce != 0){ 00097 portHDebounce -= 1; 00098 } 00099 00100 /* Every 10 tenths is one second */ 00101 if(Clocks.tenthsToSeconds % 10 == 0){ 00102 /* Increment the seconds counter */ 00103 Clocks.realTimeClockSeconds++; 00104 XGSWT = 0x0101; /* set off software trigger 0 that is handled by xgate */ 00105 00106 /* Increment the seconds roll over variable */ 00107 Clocks.secondsToMinutes++; 00108 00109 /* Reset the tenths roll over variable */ 00110 Clocks.tenthsToSeconds = 0; 00111 /* Perform all tasks that are once per second here or preferably main */ 00112 00113 // temp throttling for log due to tuner performance issues (in the bedroom) 00114 ShouldSendLog = TRUE; 00115 /* Flash the user LED as a "heartbeat" to let new users know it's alive */ 00116 //PORTP ^= 0x80; 00117 00118 /* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */ 00119 if(Clocks.secondsToMinutes % 60 == 0){ 00120 /* Increment the minutes counter */ 00121 Clocks.realTimeClockMinutes++; 00122 00123 /* Potentially put an hours field in here and below, but that would be excessive */ 00124 // TODO add hours RTC ? 00125 00126 /* Reset the seconds roll over variable */ 00127 Clocks.secondsToMinutes = 0; 00128 00129 /* Perform all tasks that are once per minute here or preferably main */ 00130 // TODO add content in minutes RTC ? 00131 00132 /* Hours if statement here if we do hours which we probably won't */ 00133 } 00134 } 00135 } 00136 } 00137 RuntimeVars.RTCRuntime = TCNT - startTimeRTI; 00138 }
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 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 Remove the debug code that uses the IO ports to light LEDs during specific actions.
Definition at line 150 of file commsISRs.c.
References BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, CLEAR_ALL_SOURCE_ID_FLAGS, COM_CLEAR_SCI0_INTERFACE_ID, COM_SET_SCI0_INTERFACE_ID, Counter::commsChecksumMismatches, Counters, ESCAPE_BYTE, ESCAPED_ESCAPE_BYTE, ESCAPED_START_BYTE, ESCAPED_STOP_BYTE, PORTA, PORTB, receiveAndIncrement(), resetReceiveState(), RuntimeVars, RX_BUFFER_SIZE, RX_READY_TO_PROCESS, RX_SCI_ESCAPED_NEXT, RX_SCI_NOT_ESCAPED_NEXT, RXBufferContentSourceID, RXBufferCurrentPosition, RXCalculatedChecksum, RXPacketLengthReceived, RXStateFlags, SCI0CR2, SCI0DRL, SCI0SR1, SCICR2_RX_DISABLE, SCICR2_RX_ISR_DISABLE, SCICR2_RX_ISR_ENABLE, 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, sendAndIncrement(), Counter::serialEscapePairMismatches, Counter::serialFramingErrors, RuntimeVar::serialISRRuntime, Counter::serialNoiseErrors, Counter::serialOverrunErrors, Counter::serialPacketsOverLength, Counter::serialParityErrors, Counter::serialStartsInsideAPacket, START_BYTE, STOP_BYTE, TCNT, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, TXByteEscaped, and TXPacketLengthToSendSCI0.
00150 { 00151 /* Read the flags register */ 00152 unsigned char flags = SCI0SR1; 00153 /* Note: Combined with reading or writing the data register this also clears the flags. */ 00154 00155 /* Start counting */ 00156 unsigned short start = TCNT; 00157 00158 /* If the RX interrupt is enabled check RX related flags */ 00159 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){ 00160 /* Grab the received byte from the register */ 00161 unsigned char rawByte = SCI0DRL; 00162 00163 PORTB |= BIT0; 00164 00165 /* Record error conditions always */ 00166 unsigned char resetOnError = 0; 00167 /* If there is noise on the receive line record it */ 00168 if(flags & SCISR1_RX_NOISE){ 00169 Counters.serialNoiseErrors++; 00170 resetOnError++; 00171 }/* If an overrun occurs record it */ 00172 if(flags & SCISR1_RX_OVERRUN){ 00173 Counters.serialOverrunErrors++; 00174 resetOnError++; 00175 }/* If a framing error occurs record it */ 00176 if(flags & SCISR1_RX_FRAMING){ 00177 Counters.serialFramingErrors++; 00178 resetOnError++; 00179 }/* If a parity error occurs record it */ 00180 if(flags & SCISR1_RX_PARITY){ 00181 Counters.serialParityErrors++; 00182 resetOnError++; 00183 } 00184 00185 /* Drop out because of error flags */ 00186 if(resetOnError){ 00187 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00188 PORTB |= BIT1; 00189 return; 00190 } 00191 00192 /* If there is data waiting to be received */ 00193 if(flags & SCISR1_RX_REGISTER_FULL){ 00194 PORTB |= BIT2; 00195 /* Look for a start bresetReceiveStateyte to indicate a new packet */ 00196 if(rawByte == START_BYTE){ 00197 PORTB |= BIT3; 00198 /* If another interface is using it (Note, clear flag, not normal) */ 00199 if(RXBufferContentSourceID & COM_CLEAR_SCI0_INTERFACE_ID){ 00200 /* Turn off our reception */ 00201 SCI0CR2 &= SCICR2_RX_DISABLE; 00202 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00203 PORTB |= BIT4; 00204 }else{ 00205 PORTB |= BIT5; 00206 /* If we are using it */ 00207 if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00208 /* Increment the counter */ 00209 Counters.serialStartsInsideAPacket++; 00210 } 00211 /* Reset to us using it unless someone else was */ 00212 resetReceiveState(COM_SET_SCI0_INTERFACE_ID); 00213 } 00214 }else if(RXPacketLengthReceived >= RX_BUFFER_SIZE){ 00215 /* Buffer was full, record and reset */ 00216 Counters.serialPacketsOverLength++; 00217 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00218 PORTB |= BIT6; 00219 }else if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00220 if(RXStateFlags & RX_SCI_ESCAPED_NEXT){ 00221 PORTB |= BIT7; 00222 /* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */ 00223 RXStateFlags &= RX_SCI_NOT_ESCAPED_NEXT; 00224 00225 if(rawByte == ESCAPED_ESCAPE_BYTE){ 00226 /* Store and checksum escape byte */ 00227 receiveAndIncrement(ESCAPE_BYTE); 00228 }else if(rawByte == ESCAPED_START_BYTE){ 00229 /* Store and checksum start byte */ 00230 receiveAndIncrement(START_BYTE); 00231 }else if(rawByte == ESCAPED_STOP_BYTE){ 00232 /* Store and checksum stop byte */ 00233 receiveAndIncrement(STOP_BYTE); 00234 }else{ 00235 /* Otherwise reset and record as data is bad */ 00236 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00237 Counters.serialEscapePairMismatches++; 00238 } 00239 }else if(rawByte == ESCAPE_BYTE){ 00240 PORTA |= BIT0; 00241 /* Set flag to indicate that the next byte should be un-escaped. */ 00242 RXStateFlags |= RX_SCI_ESCAPED_NEXT; 00243 }else if(rawByte == STOP_BYTE){ 00244 PORTA |= BIT1; 00245 /* Turn off reception */ 00246 SCI0CR2 &= SCICR2_RX_DISABLE; 00247 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00248 00249 /* Bring the checksum back to where it should be */ 00250 unsigned char RXReceivedChecksum = (unsigned char)*(RXBufferCurrentPosition - 1); 00251 RXCalculatedChecksum -= RXReceivedChecksum; 00252 00253 /* Check that the checksum matches */ 00254 if(RXCalculatedChecksum == RXReceivedChecksum){ 00255 /* If it's OK set process flag */ 00256 RXStateFlags |= RX_READY_TO_PROCESS; 00257 PORTA |= BIT2; 00258 }else{ 00259 PORTA |= BIT3; 00260 /* Otherwise reset the state and record it */ 00261 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00262 Counters.commsChecksumMismatches++; 00263 } 00264 }else{ 00265 PORTA |= BIT4; 00266 /* If it isn't special process it! */ 00267 receiveAndIncrement(rawByte); 00268 } 00269 }else{ 00270 /* Do nothing : drop the byte */ 00271 PORTA |= BIT5; 00272 } 00273 } 00274 } 00275 00276 /* If the TX interrupt is enabled check the register empty flag. */ 00277 if((SCI0CR2 & SCICR2_TX_ISR_ENABLE) && (flags & SCISR1_TX_REGISTER_EMPTY)){ 00278 /* Get the byte to be sent from the buffer */ 00279 unsigned char rawValue = *TXBufferCurrentPositionSCI0; 00280 00281 if(TXPacketLengthToSendSCI0 > 0){ 00282 if(TXByteEscaped == 0){ 00283 /* If the raw value needs to be escaped */ 00284 if(rawValue == ESCAPE_BYTE){ 00285 SCI0DRL = ESCAPE_BYTE; 00286 TXByteEscaped = ESCAPED_ESCAPE_BYTE; 00287 }else if(rawValue == START_BYTE){ 00288 SCI0DRL = ESCAPE_BYTE; 00289 TXByteEscaped = ESCAPED_START_BYTE; 00290 }else if(rawValue == STOP_BYTE){ 00291 SCI0DRL = ESCAPE_BYTE; 00292 TXByteEscaped = ESCAPED_STOP_BYTE; 00293 }else{ /* Otherwise just send it */ 00294 sendAndIncrement(rawValue); 00295 } 00296 }else{ 00297 sendAndIncrement(TXByteEscaped); 00298 TXByteEscaped = 0; 00299 } 00300 }else{ /* Length is zero */ 00301 /* Turn off transmission interrupt */ 00302 SCI0CR2 &= SCICR2_TX_ISR_DISABLE; 00303 /* Send the stop byte */ 00304 SCI0DRL = STOP_BYTE; 00305 while(!(SCI0SR1 & 0x80)){/* Wait for ever until able to send then move on */} 00306 SCI0DRL = STOP_BYTE; // nasty hack that works... means at least one and most 2 stops are sent so stuff works, but is messy... there must be a better way. 00307 /* Clear the TX in progress flag */ 00308 TXBufferInUseFlags &= COM_CLEAR_SCI0_INTERFACE_ID; 00309 } 00310 } 00311 00312 /* Record how long the operation took */ 00313 RuntimeVars.serialISRRuntime = TCNT - start; 00314 }
void SecondaryRPMISR | ( | void | ) |
Use the rising and falling edges...................
Secondary RPM ISR
TODO Docs here!
TODO Add a check for 1 skip pulse of the 8x track, to prevent possible incorrect sync.
TODO Possibly make virtual CAS 16-bit so was can get rid of floating points and use for syncing
Secondary RPM ISR
Secondary RPM ISR
Secondary RPM ISR
Similar to the primary one.
TODO bring this documentation up to date.
TODO finish this off to a usable standard.
Secondary RPM ISR
Unused in this decoder.
Secondary RPM ISR
Definition at line 110 of file LT1-360-8.c.
References changeSyncStatus(), CLEAR_PRIMARY_SYNC, fixedConfig1::coreSettingsA, coreStatusA, Counters, Counter::crankSyncLosses, engineCyclePeriod, fixedConfigs1, ISRLatencyVars, isSynced, lastSecondaryOddTimeStamp, lastSecondaryPulseLeadingTimeStamp, lastSecondaryPulseTrailingTimeStamp, lengthOfSecondaryLowPulses, PORTJ, PORTM, PRIMARY_POLARITY, PRIMARY_SYNC, primaryPulsesPerSecondaryPulse, PrimaryTeethDuringHigh, PrimaryTeethDuringLow, PTIT, RuntimeVars, SECONDARY_POLARITY, ISRLatencyVar::secondaryInputLatency, RuntimeVar::secondaryInputLeadingRuntime, RuntimeVar::secondaryInputTrailingRuntime, Counter::secondaryTeethSeen, TC1, TCNT, TFLG, TFLGOF, LongTime::timeLong, timerExtensionClock, LongTime::timeShorts, and VCAS.
00110 { 00111 /* Clear the interrupt flag for this input compare channel */ 00112 TFLG = 0x02; 00113 00114 /* Save all relevant available data here */ 00115 // unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00116 // unsigned short edgeTimeStamp = TC1; /* Save the timestamp */ 00117 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00118 // unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */ 00119 unsigned char risingEdge; 00120 if(fixedConfigs1.coreSettingsA & PRIMARY_POLARITY){ 00121 risingEdge = PTITCurrentState & 0x01; 00122 }else{ 00123 risingEdge = !(PTITCurrentState & 0x01); 00124 } 00125 PORTJ |= 0x40; /* echo input condition */ 00126 00127 if (!isSynced & risingEdge){ /* If the CAS is not in sync get window counts and set virtual CAS position */ 00128 /* if signal is high that means we can count the lows */ 00129 switch (PrimaryTeethDuringLow){ 00130 case 23: /* wheel is at 0 deg TDC #1, set our virtual CAS to tooth 0 of 720 */ 00131 { 00132 VCAS = 0 ; 00133 changeSyncStatus((unsigned char) 1); 00134 break; 00135 } 00136 case 38: /* wheel is at 90 deg TDC #4, set our virtual CAS to tooth 180 of 720 */ 00137 { 00138 VCAS = 180; 00139 changeSyncStatus((unsigned char) 1); 00140 break; 00141 } 00142 case 33: /* wheel is at 180 deg TDC #6 set our virtual CAS to tooth 360 of 720 */ 00143 { 00144 VCAS = 360; 00145 changeSyncStatus((unsigned char) 1); 00146 break; 00147 } 00148 case 28: /* wheel is at 270 deg TDC #7 set our virtual CAS to tooth 540 of 720 */ 00149 { 00150 VCAS = 540; 00151 changeSyncStatus((unsigned char) 1); 00152 break; 00153 } 00154 default : 00155 { 00156 Counters.crankSyncLosses++; /* use crankSyncLosses variable to store number of invalid count cases while attempting to sync*/ 00157 break; 00158 } 00159 PrimaryTeethDuringLow = 0; /* In any case reset counter */ 00160 } 00161 } 00162 if(!isSynced & !risingEdge){/* if the signal is low that means we can count the highs */ 00163 switch (PrimaryTeethDuringHigh){ /* will need to additional code to off-set the initialization of PACNT since they are not 00164 evenly divisible by 5 */ 00165 case 7: /* wheel is at 52 deg, 7 deg ATDC #8 set our virtual CAS to tooth 104 of 720 */ 00166 { 00167 00168 break; 00169 } 00170 case 12: /* wheel is at 147 deg, 12 deg ATDC #3 set our virtual CAS to tooth 294 of 720 */ 00171 { 00172 00173 break; 00174 } 00175 case 17: /* wheel is at 242 deg, 17 deg ATDC #5 set our virtual CAS to tooth 484 of 720 */ 00176 { 00177 00178 break; 00179 } 00180 case 22: /* wheel is at 337 deg, 22 deg ATDC #2 set our virtual CAS to tooth 674 of 720 */ 00181 { 00182 00183 break; 00184 } 00185 default : 00186 { 00187 Counters.crankSyncLosses++; /* use crankSyncLosses variable to store number of invalid/default count cases while attempting to sync*/ 00188 break; 00189 } 00190 00191 } 00192 PrimaryTeethDuringHigh = 0; /* In any case reset counter */ 00193 } 00194 if(isSynced & risingEdge){ /* We are in sync and need to make sure our counts are good */ 00195 00196 /* System is synced so use adjusted count numbers to check sync */ 00198 } 00199 }
void StagedOffISR | ( | void | ) |
Definition at line 72 of file injectionISRs.c.
References PITINTE.
00072 { 00073 // clear the flag 00074 PITINTE |= 0x08; 00075 00076 // bit bang off the correct injector channel 00077 // TODO figure out which channel and switch it 00078 // TODO set the flag for that channel 00079 00080 // if there are other staged channels pending, schedule them and adjust the data 00081 // TODO 00082 00083 /* Clear the PIT3 flag */ 00084 // TODO 00085 }
void StagedOnISR | ( | void | ) |
Definition at line 51 of file injectionISRs.c.
References fixedConfig1::coreSettingsA, fixedConfigs1, PITINTE, and STAGED_END.
00051 { 00052 // clear the flag 00053 PITINTE |= 0x04; 00054 00055 // bit bang on the correct injector channel 00056 // TODO figure out which channel and switch it 00057 // TODO set the flag for that channel 00058 00059 // if there are other staged channels pending, schedule them and adjust the data 00060 // TODO 00061 00062 /* If staged injection needs the end point scheduled, do it now (otherwise it will turn off naturally with the main injector) */ 00063 if(!(fixedConfigs1.coreSettingsA & STAGED_END)){ 00064 // TODO schedule the end of staged injection with PIT 3 00065 } 00066 00067 /* Clear the PIT2 flag */ 00068 // TODO 00069 }
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.
Definition at line 177 of file realtimeISRs.c.
References TFLGOF, and timerExtensionClock.
00177 { 00178 /* Increment the timer extension variable */ 00179 timerExtensionClock++; 00180 00181 /* Clear the timer overflow interrupt flag */ 00182 TFLGOF = 0x80; 00183 }
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.
Definition at line 50 of file miscISRs.c.
References Counter::callsToUISRs, and Counters.
00050 { 00051 /* Increment the unimplemented ISR execution counter */ 00052 Counters.callsToUISRs++; 00053 }
void VRegAPIISR | ( | void | ) |
void XIRQISR | ( | void | ) |
XIRQ/PE0 pin ISR.
Interrupt handler for edge events on the XIRQ/PE0 pin. Not currently used.
Definition at line 218 of file miscISRs.c.
References Counter::callsToUISRs, and Counters.
00218 { 00219 /* Clear the flag */ 00220 // ?? TODO 00221 00222 /* Increment the unimplemented ISR execution counter */ 00223 Counters.callsToUISRs++; 00224 }