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