This graph shows which files directly or indirectly include this file:
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 |
void | Injector1ISR (void) INT |
void | Injector2ISR (void) INT |
void | Injector3ISR (void) INT |
void | Injector4ISR (void) INT |
void | Injector5ISR (void) INT |
void | Injector6ISR (void) INT |
void | PrimaryRPMISR (void) INT |
void | SecondaryRPMISR (void) INT |
void | TimerOverflow (void) INT |
void | ModDownCtrISR (void) INT |
void | IgnitionDwellISR (void) INT |
void | IgnitionFireISR (void) INT |
void | StagedOnISR (void) INT |
void | StagedOffISR (void) INT |
void | PortPISR (void) INT |
void | PortHISR (void) INT |
void | PortJISR (void) INT |
void | IRQISR (void) INT |
void | XIRQISR (void) INT |
void | RTIISR (void) INT |
void | SCI0ISR (void) INT |
void | LowVoltageISR (void) INT |
void | VRegAPIISR (void) INT |
#define ATOMIC_END | ( | ) | __asm__ __volatile__ ("cli") |
#define ATOMIC_START | ( | ) | __asm__ __volatile__ ("sei") |
#define INT __attribute__((interrupt)) |
Definition at line 35 of file interrupts.h.
#define VECTORS __attribute__ ((section (".vectors"))) |
Definition at line 46 of file interrupts.h.
typedef void(* ) interruptTable(void) |
Definition at line 84 of file interrupts.h.
void _start | ( | void | ) |
Referenced by decodePacketAndBuildResponse().
void IgnitionDwellISR | ( | void | ) |
Definition at line 47 of file ignitionISRs.c.
References fixedConfig::combustionEventsPerEngineCycle, DWELL_DISABLE, DWELL_ENABLE, dwellQueueLength, dwellStartMasks, fixedConfigs, nextDwellChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedDwellOffsets.
00048 { 00049 // clear flag 00050 PITTF = DWELL_ENABLE; 00051 00052 // start dwelling asap 00053 PORTS_BA |= dwellStartMasks[nextDwellChannel]; 00054 00055 if(dwellQueueLength == 0){ 00056 // turn off the int 00057 PITINTE &= DWELL_DISABLE; 00058 00059 // disable channels 00060 PITCE &= DWELL_DISABLE; 00061 }else{ 00062 // reduce queue length by one 00063 dwellQueueLength--; 00064 00065 // increment channel counter to next channel 00066 if(nextDwellChannel < (fixedConfigs.combustionEventsPerEngineCycle - 1)){ 00067 nextDwellChannel++; // if not the last channel, increment 00068 }else{ 00069 nextDwellChannel = 0; // if the last channel, reset to zero 00070 } 00071 00072 // 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. 00073 if(dwellQueueLength > 0){ 00074 if(dwellQueueLength > 8){ // TODO ???? why 8 ???? 12 or combustion events per... or ? 00075 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00076 PORTS |= 0x20; 00077 }else{ 00078 // load the timer if the index is good 00079 PITLD0 = queuedDwellOffsets[dwellQueueLength - 1]; 00080 } 00081 } 00082 } 00083 00084 // blink a led 00085 PORTS ^= 0x80; 00086 }
void IgnitionFireISR | ( | void | ) |
Definition at line 89 of file ignitionISRs.c.
References fixedConfig::combustionEventsPerEngineCycle, fixedConfigs, IGNITION_DISABLE, IGNITION_ENABLE, ignitionMasks, ignitionQueueLength, nextIgnitionChannel, PITCE, PITINTE, PITLD0, PITTF, PORTS, PORTS_BA, and queuedIgnitionOffsets.
00090 { 00091 // clear flag 00092 PITTF = IGNITION_ENABLE; 00093 00094 // fire the coil asap 00095 PORTS_BA &= ignitionMasks[nextIgnitionChannel]; 00096 00097 if(ignitionQueueLength == 0){ 00098 // turn off the int 00099 PITINTE &= IGNITION_DISABLE; 00100 00101 // disable channels 00102 PITCE &= IGNITION_DISABLE ; 00103 }else{ 00104 // reduce queue length by one 00105 ignitionQueueLength--; 00106 00107 // increment channel counter to next channel 00108 if(nextIgnitionChannel < (fixedConfigs.combustionEventsPerEngineCycle - 1)){ 00109 nextIgnitionChannel++; // if not the last channel, increment 00110 }else{ 00111 nextIgnitionChannel = 0; // if the last channel, reset to zero 00112 } 00113 00114 // 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. 00115 if(ignitionQueueLength > 0){ 00116 if(ignitionQueueLength > fixedConfigs.combustionEventsPerEngineCycle){ // TODO as above!!!!!!!!!! 00117 //throw a nasty error of some sort for index out of range issue that should never occur (for now just light a LED) 00118 PORTS |= 0x10; 00119 }else{ 00120 // load the timer if the index is good 00121 PITLD0 = queuedIgnitionOffsets[ignitionQueueLength - 1]; 00122 } 00123 } 00124 } 00125 00126 // blink a led 00127 PORTS ^= 0x40; 00128 }
void Injector1ISR | ( | void | ) |
void Injector2ISR | ( | void | ) |
void Injector3ISR | ( | void | ) |
void Injector4ISR | ( | void | ) |
void Injector5ISR | ( | void | ) |
void Injector6ISR | ( | void | ) |
void IRQISR | ( | void | ) |
Definition at line 157 of file miscISRs.c.
References Counters, and Counter::UISRCounter.
00157 { 00158 /* Clear the flag */ 00159 // ?? TODO 00160 00161 /* Increment the unimplemnted ISR execution counter */ 00162 Counters.UISRCounter++; 00163 }
void LowVoltageISR | ( | void | ) |
Definition at line 175 of file miscISRs.c.
References Counters, Counter::lowVoltISRCounter, and VREGCTRL.
00175 { 00176 /* Clear the flag */ 00177 VREGCTRL |= 0x01; 00178 00179 /* Increment the counter */ 00180 Counters.lowVoltISRCounter++; 00181 }
void ModDownCtrISR | ( | void | ) |
Definition at line 118 of file realtimeISRs.c.
References engineCyclePeriod, fixedConfigs, MCCNT, MCFLG, PORTA, tachoPeriod, fixedConfig::tachoTotalFactor, and ticksPerCycleAtOneRPM.
00119 { 00120 /* Clear the modulus down counter interrupt flag */ 00121 MCFLG = 0x80; 00122 00123 /* If the rpm isn't genuine go ultra slow */ 00124 if(engineCyclePeriod == ticksPerCycleAtOneRPM){ 00125 tachoPeriod = 65535; 00126 }else{ 00127 /* Use engine cycle period to setup the frequency of this counter and thereby act as a tacho out */ 00128 tachoPeriod = (unsigned long)engineCyclePeriod / fixedConfigs.tachoTotalFactor; 00129 } 00130 /* Set the count down value */ 00131 MCCNT = tachoPeriod; 00132 00133 /* Bit bang the output port */ 00134 PORTA ^= 0x40; // SM pin (A6) 00135 }
void PortHISR | ( | void | ) |
Definition at line 50 of file miscISRs.c.
References ONES, PIFH, PORTA, and portHDebounce.
00051 { 00052 // // read the interrupt flags to a variable 00053 // unsigned char portHFlags = PIFH; 00054 // portHFlags &= 0xF8; // mask out the other bits 00055 // 00056 // /* Clear all port H flags (we only want one at a time) */ 00057 PIFH = ONES; 00058 // 00059 // // Toggle a LED so we can see if the code ran 00060 PORTA ^= 0x80; // Fuel pump pin (A7) 00061 // 00062 // debounce 00063 if(portHDebounce == 0){ 00064 portHDebounce = 2; 00065 }else{ 00066 return; 00067 } 00068 // 00069 // // find out which pin triggered it, clear the flag, perform the action. 00070 // switch(portHFlags) 00071 // { 00072 // case 0x80 : // Increment cylinder count and set port count appropriately. 00073 // switch (configs.combustionEventsPerEngineCycle) { 00074 // case 1 : 00075 // configs.combustionEventsPerEngineCycle = 2; 00076 // configs.ports = 2; 00077 // break; 00078 // case 2 : 00079 // configs.combustionEventsPerEngineCycle = 3; 00080 // configs.ports = 3; 00081 // break; 00082 // case 3 : 00083 // configs.combustionEventsPerEngineCycle = 4; 00084 // configs.ports = 4; 00085 // break; 00086 // case 4 : 00087 // configs.combustionEventsPerEngineCycle = 5; 00088 // configs.ports = 5; 00089 // break; 00090 // case 5 : 00091 // configs.combustionEventsPerEngineCycle = 6; 00092 // configs.ports = 6; 00093 // break; 00094 // case 6 : 00095 // configs.combustionEventsPerEngineCycle = 8; 00096 // configs.ports = 4; 00097 // break; 00098 // case 8 : 00099 // configs.combustionEventsPerEngineCycle = 10; 00100 // configs.ports = 5; 00101 // break; 00102 // case 10 : 00103 // configs.combustionEventsPerEngineCycle = 12; 00104 // configs.ports = 6; 00105 // break; 00106 // case 12 : 00107 // configs.combustionEventsPerEngineCycle = 1; 00108 // configs.ports = 1; 00109 // break; 00110 // } 00111 // break; 00112 // case 0x40 : // Injection output enable/disable 00113 // if(coreSettingsA & FUEL_CUT){ 00114 // coreSettingsA &= FUEL_CUT_OFF; 00115 // }else{ 00116 // coreSettingsA |= FUEL_CUT; 00117 // } 00118 // break; 00119 // case 0x20 : // Ignition output enable/disable 00120 // if(coreSettingsA & HARD_SPARK_CUT){ 00121 // coreSettingsA &= HARD_SPARK_CUT_OFF; 00122 // }else{ 00123 // coreSettingsA |= HARD_SPARK_CUT; 00124 // } 00125 // break; 00126 // case 0x10 : // Staged injection enable/disable 00127 // if(coreSettingsA & STAGED_ON){ 00128 // coreSettingsA &= STAGED_OFF; 00129 // }else{ 00130 // coreSettingsA |= STAGED_ON; 00131 // } 00132 // break; 00133 // case 0x08 : // Staged injection start sched/fixed 00134 // if(coreSettingsA & STAGED_START){ 00135 // coreSettingsA &= CLEAR_STAGED_START; 00136 // }else{ 00137 // coreSettingsA |= STAGED_START; 00138 // } 00139 // break; 00140 // case 0x04 : // Staged injection end sched/fixed 00141 // if(coreSettingsA & STAGED_END){ 00142 // coreSettingsA &= CLEAR_STAGED_END; 00143 // }else{ 00144 // coreSettingsA |= STAGED_END; 00145 // } 00146 // break; 00147 // case 0x02 : // free input 00148 // break; 00149 // case 0x01 : // free input 00150 // break; 00151 // default : // Two or more pressed, nothing to do except wait for another button press 00152 // break; 00153 // } 00154 }
void PortJISR | ( | void | ) |
Definition at line 42 of file miscISRs.c.
References Counters, ONES, PIFJ, and Counter::UISRCounter.
00042 { 00043 /* Clear all port H flags (we only want one at a time) */ 00044 PIFJ = ONES; 00045 /* Increment the unimplemnted ISR execution counter */ 00046 Counters.UISRCounter++; 00047 }
void PortPISR | ( | void | ) |
Definition at line 34 of file miscISRs.c.
References Counters, ONES, PIFP, and Counter::UISRCounter.
00034 { 00035 /* Clear all port P flags (we only want one at a time) */ 00036 PIFP = ONES; 00037 /* Increment the unimplemnted ISR execution counter */ 00038 Counters.UISRCounter++; 00039 } /* Port P interrupt service routine */
void PrimaryRPMISR | ( | void | ) |
Definition at line 48 of file enginePositionISRs.c.
References ADCArrays, CALC_FUEL_IGN, CLEAR_PRIMARY_SYNC, Clocks, fixedConfig::combustionEventsPerEngineCycle, fixedConfig::coreSettingsA, coreStatusA, Counters, DWELL_ENABLE, dwellQueueLength, engineCyclePeriod, fixedConfigs, IGNITION_ENABLE, ignitionQueueLength, injectorMainControlRegisters, injectorMainEnableMasks, injectorMainEndTimes, injectorMainOnMasks, injectorMainPulseWidths, injectorMainStartTimesHolding, injectorMainTimeRegisters, injectorMinimumPulseWidth, injectorSwitchOffCodeTime, ISRLatencyVars, lastPrimaryPulseTimeStamp, LONGHALF, Counter::lostCrankSyncCounter, masterPulseWidth, ISRLatencyVar::mathSampleTimeStamp, nextDwellChannel, nextIgnitionChannel, PITCE, PITCNT0, PITCNT1, PITINTE, PITLD0, PITLD1, PITTF, PORTJ, PRIMARY_POLARITY, PRIMARY_SYNC, ISRLatencyVar::primaryInputLatency, RuntimeVar::primaryInputLeadingRuntime, RuntimeVar::primaryInputTrailingRuntime, primaryLeadingEdgeTimeStamp, primaryPulsesPerSecondaryPulse, Counter::primaryTeethCounter, primaryTeethDroppedFromLackOfSync, PTIT, queuedDwellOffsets, queuedIgnitionOffsets, recordADCBank, RPM, RuntimeVars, sampleLoopADC(), selfSetTimer, Counter::syncedADCreadingCounter, TC0, TCNT, TFLG, TFLGOF, ticksPerCycleAtOneRPMx2, TIE, timeBetweenSuccessivePrimaryPulses, timeBetweenSuccessivePrimaryPulsesBuffer, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, totalAngleAfterReferenceInjection, and trailingEdgeSecondaryRPMInputCodeTime.
00049 { 00050 /* Clear the interrupt flag for this input compare channel */ 00051 TFLG = 0x01; 00052 00053 /* Save all relevant available data here */ 00054 unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00055 unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */ 00056 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00057 // unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */ 00058 00059 /* Calculate the latency in ticks */ 00060 ISRLatencyVars.primaryInputLatency = codeStartTimeStamp - edgeTimeStamp; 00061 00062 // TODO discard narrow ones! test for tooth width and tooth period 00063 00064 /* Set up edges as per config */ 00065 unsigned char risingEdge; 00066 if(fixedConfigs.coreSettingsA & PRIMARY_POLARITY){ 00067 risingEdge = PTITCurrentState & 0x01; 00068 }else{ 00069 risingEdge = !(PTITCurrentState & 0x01); 00070 } 00071 00072 if(risingEdge){ 00073 /* Echo input condition on J7 */ 00074 PORTJ |= 0x80; 00075 00076 // increment crank pulses TODO this needs to be wrapped in tooth period and width checking 00077 primaryPulsesPerSecondaryPulse++; 00078 00079 // calculate rough rpm (this will be wrong when the var is used correctly) 00080 RPM[recordADCBank] = ticksPerCycleAtOneRPMx2 / engineCyclePeriod; /* 0.8us ticks, 150mil = 2 x 60 seconds, times rpm scale factor of 2 */ 00081 00082 // don't run until the second trigger has come in and the period is correct (VERY temporary) 00083 if(!(coreStatusA & PRIMARY_SYNC)){ 00084 primaryTeethDroppedFromLackOfSync++; 00085 return; 00086 } 00087 00088 LongTime timeStamp; 00089 00090 /* Install the low word */ 00091 timeStamp.timeShorts[1] = edgeTimeStamp; 00092 /* Find out what our timer value means and put it in the high word */ 00093 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */ 00094 timeStamp.timeShorts[0] = timerExtensionClock + 1; 00095 }else{ 00096 timeStamp.timeShorts[0] = timerExtensionClock; 00097 } 00098 00099 // temporary data from inputs 00100 primaryLeadingEdgeTimeStamp = edgeTimeStamp; 00101 timeBetweenSuccessivePrimaryPulses = lastPrimaryPulseTimeStamp - primaryLeadingEdgeTimeStamp; 00102 lastPrimaryPulseTimeStamp = primaryLeadingEdgeTimeStamp; 00103 timeBetweenSuccessivePrimaryPulsesBuffer = (timeBetweenSuccessivePrimaryPulses >> 1) + (timeBetweenSuccessivePrimaryPulsesBuffer >> 1); 00104 00105 // TODO make scheduling either fixed from boot with a limited range, OR preferrably if its practical scheduled on the fly to allow arbitrary advance and retard of both fuel and ignition. 00106 00107 /* Check for loss of sync by too high a count */ 00108 if(primaryPulsesPerSecondaryPulse > 12){ 00109 /* Increment the lost sync count */ 00110 Counters.lostCrankSyncCounter++; 00111 00112 /* Clear synced status */ 00113 coreStatusA &= CLEAR_PRIMARY_SYNC; 00114 00115 /* Reset the count of teeth */ 00116 primaryPulsesPerSecondaryPulse = 0; 00117 00118 /* Get the hell out of here before we do something bad */ 00119 return; 00120 } 00121 00122 // CAUTION came to me lying in bed half asleep idea : 00123 00124 // TODO move tooth selection to the calc loop in main such that this routine just iterates through an array of events and schedules those that are destined for this tooth. 00125 00126 // if ign enabled 00127 // iterate through ignition first, schedule all of those 00128 // iterate through dwell next, schedule all of those 00129 // if fuel enabled 00130 // iterate through main fuel next, schedule all of those 00131 // if staging enabled and required 00132 // iterate through staged fuel last, 00133 00134 // TODO should make for a clean compact scheduling implementation. the fuel code doesn't care when/how it has started in the past, and hopefully ign will be the same. 00135 00136 // this will be done with an array and per tooth check in future 00137 if((primaryPulsesPerSecondaryPulse % 2) == 0){ 00138 00139 // TODO sample ADCs on teeth other than that used by the scheduler in order to minimise peak run time and get clean signals 00140 sampleLoopADC(&ADCArrays); 00141 Counters.syncedADCreadingCounter++; 00142 ISRLatencyVars.mathSampleTimeStamp[recordADCBank] = TCNT; 00143 00144 /* Set flag to say calc required */ 00145 coreStatusA |= CALC_FUEL_IGN; 00146 00147 /* Reset the clock for reading timeout */ 00148 Clocks.timeoutADCreadingClock = 0; 00149 00150 if(masterPulseWidth > injectorMinimumPulseWidth){ // use reference PW to decide. spark needs moving outside this area though TODO 00151 /* Determine if half the cycle is bigger than short-max */ 00152 unsigned short maxAngleAfter; 00153 if((engineCyclePeriod >> 1) > 0xFFFF){ 00154 maxAngleAfter = 0xFFFF; 00155 }else{ 00156 maxAngleAfter = (unsigned short)(engineCyclePeriod >> 1); 00157 } 00158 00159 /* Check advance to ensure it is less than 1/2 of the previous engine cycle and more than codetime away */ 00160 unsigned short advance; 00161 if(totalAngleAfterReferenceInjection > maxAngleAfter){ // if too big, make it max 00162 advance = maxAngleAfter; 00163 }else if(totalAngleAfterReferenceInjection < trailingEdgeSecondaryRPMInputCodeTime){ // if too small, make it min 00164 advance = trailingEdgeSecondaryRPMInputCodeTime; 00165 }else{ // else use it as is 00166 advance = totalAngleAfterReferenceInjection; 00167 } 00168 00169 // determine the long and short start times 00170 unsigned short startTime = primaryLeadingEdgeTimeStamp + advance; 00171 unsigned long startTimeLong = timeStamp.timeLong + advance; 00172 00173 /* Determine the channels to schedule */ 00174 unsigned char fuelChannel = (primaryPulsesPerSecondaryPulse / 2) - 1; 00175 unsigned char ignitionChannel = (primaryPulsesPerSecondaryPulse / 2) - 1; 00176 00177 if(fuelChannel > 5 || ignitionChannel > 5){ 00178 // send("bad fuel : "); 00179 // sendUC(fuelChannel); 00180 // send("bad ign : "); 00181 // sendUC(ignitionChannel); 00182 return; 00183 } 00184 00185 // determine whether or not to reschedule 00186 unsigned char reschedule = 0; 00187 unsigned long diff = startTimeLong - (injectorMainEndTimes[fuelChannel] + injectorSwitchOffCodeTime); 00188 if(diff > LONGHALF){ 00189 reschedule = 1; // http://www.diyefi.org/forum/viewtopic.php?f=8&t=57&p=861#p861 00190 } 00191 00192 // schedule the appropriate channel 00193 if(!(*injectorMainControlRegisters[fuelChannel] & injectorMainEnableMasks[fuelChannel]) || reschedule){ /* If the timer isn't still running, or if its set too long, set it to start again at the right time soon */ 00194 *injectorMainControlRegisters[fuelChannel] |= injectorMainEnableMasks[fuelChannel]; 00195 *injectorMainTimeRegisters[fuelChannel] = startTime; 00196 TIE |= injectorMainOnMasks[fuelChannel]; 00197 TFLG = injectorMainOnMasks[fuelChannel]; 00198 }else{ 00199 injectorMainStartTimesHolding[fuelChannel] = startTime; 00200 selfSetTimer |= injectorMainOnMasks[fuelChannel]; // setup a bit to let the timer interrupt know to set its own new start from a var 00201 } 00202 00203 // TODO advance/retard/dwell numbers all need range checking etc done. some of this should be done in the calculator section, and some here. currently none is done at all and for that reason, this will not work in a real system yet, if it works at all. 00204 // as do array indexs here and in the ISRs... 00205 00206 00207 // TODO implement mechanism for dropping a cylinder in event of over queueing or spark cut/round robin 00208 // important as ignition sequence disrupted when this occurs as it stands. 00209 00210 // TODO check queue length checks to ensure we dont count up to somewhere we can never count down from. This could be causing the hanging long phenomina 00211 00212 // DWELL 00213 00214 // If dwell is not currently enabled, set it all up 00215 if(!(PITCE & DWELL_ENABLE)){ 00216 /* Schedule Dwell event (do this first because it comes earliest. */ 00217 // set the channel to fire 00218 nextDwellChannel = ignitionChannel; 00219 00220 // set the time 00221 PITLD0 = advance; 00222 // PITLD0 = ignitionAdvances[ignitionChannel + outputBankIgnitionOffset] - currentDwell[outputBank]; BAD for various reasons! 00223 00224 // clear the flags first as they apparently become set any old time whether enabled or not. 00225 PITTF |= DWELL_ENABLE; 00226 00227 // turn on the ints 00228 PITINTE |= DWELL_ENABLE; 00229 00230 // clear the flags first as they apparently become set any old time whether enabled or not. 00231 PITTF |= DWELL_ENABLE; 00232 00233 // enable channels 00234 PITCE |= DWELL_ENABLE; 00235 }else if(dwellQueueLength == 0){ 00236 // load time offset such that next period is correct 00237 PITLD0 = (advance - PITCNT0); 00238 00239 // increment queue length 00240 dwellQueueLength++; 00241 }else if(dwellQueueLength > fixedConfigs.combustionEventsPerEngineCycle){ //TODO sensible figures here for array index OOBE 00242 // do nothing, or increment a counter or something similar. 00243 }else{ 00244 unsigned short sumOfDwells = PITLD0; 00245 // add up the prequeued time periods 00246 00247 // queue = 1 pitld is all 00248 // queue = 2 one from 0 index of array AND pitld 00249 00250 unsigned char index = 0; 00251 while(index < (dwellQueueLength -1)){ 00252 sumOfDwells += queuedDwellOffsets[index]; 00253 index++; 00254 } 00255 // for(index = 0;index < (dwellQueueLength -1);index++){ // is this right? 00256 // sumOfDwells += queuedDwellOffsets[index]; 00257 // } 00258 00259 // store time offset in appropriate array location 00260 queuedDwellOffsets[dwellQueueLength - 1] = advance - (PITCNT0 + sumOfDwells); 00261 00262 // increment queue length from one or more 00263 dwellQueueLength++; 00264 } 00265 00266 // IGNITION experimental stuff 00267 00268 // If ignition is not currently enabled, set it all up 00269 if(!(PITCE & IGNITION_ENABLE)){ 00270 /* Schedule Ignition event (do this first because it comes earliest. */ 00271 // set the channel to fire 00272 nextIgnitionChannel = ignitionChannel; 00273 00274 // figure out the time to set the delay reg to 00275 PITLD1 = advance + injectorMainPulseWidths[fuelChannel]; 00276 // PITLD1 = ignitionAdvances[ignitionChannel + outputBankIgnitionOffset]; 00277 00278 // clear the flags first as they apparently become set any old time whether enabled or not. 00279 PITTF |= IGNITION_ENABLE; 00280 00281 // turn on the ints 00282 PITINTE |= IGNITION_ENABLE; 00283 00284 // clear the flags first as they apparently become set any old time whether enabled or not. 00285 PITTF |= IGNITION_ENABLE; 00286 00287 // enable channels 00288 PITCE |= IGNITION_ENABLE; 00289 }else if(ignitionQueueLength == 0){ 00290 // load timer register 00291 PITLD1 = ((advance + injectorMainPulseWidths[fuelChannel]) - PITCNT1); 00292 00293 // increment to 1 00294 ignitionQueueLength++; 00295 }else if(ignitionQueueLength > fixedConfigs.combustionEventsPerEngineCycle){ //TODO sensible figures here for array index OOBE 00296 // do nothing, or increment a counter or something similar. 00297 }else{ 00298 unsigned short sumOfIgnitions = PITLD1; 00299 // add up the prequeued time periods 00300 00301 // queue = 1 pitld is all 00302 // queue = 2 one from 0 index of array AND pitld 00303 00304 00305 unsigned char index = 0; 00306 while(index < (ignitionQueueLength - 1)){ 00307 sumOfIgnitions += queuedIgnitionOffsets[index]; 00308 index++; 00309 } 00310 // for(index = 0;index < (ignitionQueueLength -1);index++){ // is this right? 00311 // sumOfIgnitions += queuedIgnitionOffsets[index]; 00312 // } 00313 00314 // store time offset in appropriate array location 00315 queuedIgnitionOffsets[ignitionQueueLength - 1] = advance - (PITCNT1 + sumOfIgnitions); 00316 00317 // increment from 1 or more 00318 ignitionQueueLength++; 00319 } 00320 } 00321 } 00322 RuntimeVars.primaryInputLeadingRuntime = TCNT - codeStartTimeStamp; 00323 }else{ 00324 PORTJ &= 0x7F; 00325 RuntimeVars.primaryInputTrailingRuntime = TCNT - codeStartTimeStamp; 00326 } 00327 00328 Counters.primaryTeethCounter++; 00329 // suss out rpm and accurate TDC reference 00330 00331 // if you say it quick, it doesn't sound like much : 00332 // schedule fuel and ign based on spark cut and fuel cut and timing vars and status vars config vars 00333 }
Here is the call graph for this function:
void RTIISR | ( | void | ) |
Definition at line 32 of file realtimeISRs.c.
References Clocks, coreStatusA, CRGFLG, fixedConfigs, FORCE_READING, Clock::millisToTenths, portHDebounce, PORTP, fixedConfig::readingTimeout, Clock::realTimeClockMain, Clock::realTimeClockMillis, Clock::realTimeClockMinutes, Clock::realTimeClockSeconds, Clock::realTimeClockTenths, RuntimeVar::RTCRuntime, RuntimeVars, Clock::secondsToMinutes, TCNT, Clock::tenthsToSeconds, and Clock::timeoutADCreadingClock.
00033 { 00034 /* Clear the RTI flag */ 00035 CRGFLG = 0x80; 00036 00037 /* Record time stamp for code run time reporting */ 00038 unsigned short startTimeRTI = TCNT; 00039 00040 /* Increment the counter */ 00041 Clocks.realTimeClockMain++; 00042 00043 /* 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 */ 00044 00045 // TODO add content to eighths of a milli RTC ? 00046 00047 /* Every 8th RTI execution is one milli */ 00048 if(Clocks.realTimeClockMain % 8 == 0){ 00049 /* Increment the milli counter */ 00050 Clocks.realTimeClockMillis++; 00051 00052 /* Increment the milli roll over variable */ 00053 Clocks.millisToTenths++; 00054 00055 /* Perform all tasks that are once per millisecond here or preferably main */ 00056 Clocks.timeoutADCreadingClock++; 00057 if(Clocks.timeoutADCreadingClock > fixedConfigs.readingTimeout){ 00058 /* Set force read adc flag */ 00059 coreStatusA |= FORCE_READING; 00060 Clocks.timeoutADCreadingClock = 0; 00061 } 00062 00063 /* Every 100 millis is one tenth */ 00064 if(Clocks.millisToTenths % 100 == 0){ 00065 /* Increment the tenths counter */ 00066 Clocks.realTimeClockTenths++; 00067 00068 /* Increment the tenths roll over variable */ 00069 Clocks.tenthsToSeconds++; 00070 00071 /* Reset the millis roll over variable */ 00072 Clocks.millisToTenths = 0; 00073 00074 /* Perform all tasks that are once per tenth of a second here or preferably main */ 00075 // decrement port H debounce variable till it's zero again. 00076 if(portHDebounce != 0){ 00077 portHDebounce -= 1; 00078 } 00079 00080 /* Every 10 tenths is one second */ 00081 if(Clocks.tenthsToSeconds % 10 == 0){ 00082 /* Increment the seconds counter */ 00083 Clocks.realTimeClockSeconds++; 00084 00085 /* Increment the seconds roll over variable */ 00086 Clocks.secondsToMinutes++; 00087 00088 /* Reset the tenths roll over variable */ 00089 Clocks.tenthsToSeconds = 0; 00090 /* Perform all tasks that are once per second here or preferably main */ 00091 00092 /* Flash the user LED as a "heartbeat" to let new users know it's alive */ 00093 PORTP ^= 0x80; 00094 00095 /* Every 60 seconds is one minute, 65535 minutes is enough for us :-) */ 00096 if(Clocks.secondsToMinutes % 60 == 0){ 00097 /* Increment the minutes counter */ 00098 Clocks.realTimeClockMinutes++; 00099 00100 /* Potentially put an hours field in here and below, but that would be excessive */ 00101 // TODO add hours RTC ? 00102 00103 /* Reset the seconds roll over variable */ 00104 Clocks.secondsToMinutes = 0; 00105 00106 /* Perform all tasks that are once per minute here or preferably main */ 00107 // TODO add content in minutes RTC ? 00108 00109 /* Hours if statement here if we do hours which we probably won't */ 00110 } 00111 } 00112 } 00113 } 00114 RuntimeVars.RTCRuntime = TCNT - startTimeRTI; 00115 }
void SCI0ISR | ( | void | ) |
Definition at line 92 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, 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::serialChecksumMismatchCounter, Counter::serialEscapePairMismatchCounter, Counter::serialFramingErrorCounter, RuntimeVar::serialISRRuntime, Counter::serialNoiseErrorCounter, Counter::serialOverrunErrorCounter, Counter::serialPacketOverLengthCounter, Counter::serialParityErrorCounter, Counter::serialStartInsidePacketCounter, START_BYTE, STOP_BYTE, TCNT, TXBufferCurrentPositionSCI0, TXBufferInUseFlags, TXByteEscaped, and TXPacketLengthToSendSCI0.
00092 { 00093 /* Read the flags register */ 00094 unsigned char flags = SCI0SR1; 00095 /* Note: Combined with reading or writing the data register this also clears the flags. */ 00096 00097 /* Start counting */ 00098 unsigned short start = TCNT; 00099 00100 /* If the RX interrupt is enabled check RX related flags */ 00101 if(SCI0CR2 & SCICR2_RX_ISR_ENABLE){ 00102 /* Grab the received byte from the register */ 00103 unsigned char rawByte = SCI0DRL; 00104 00105 PORTB |= BIT0; 00106 00107 /* Record error conditions always */ 00108 unsigned char resetOnError = 0; 00109 /* If there is noise on the receive line record it */ 00110 if(flags & SCISR1_RX_NOISE){ 00111 Counters.serialNoiseErrorCounter++; 00112 resetOnError++; 00113 }/* If an overrun occurs record it */ 00114 if(flags & SCISR1_RX_OVERRUN){ 00115 Counters.serialOverrunErrorCounter++; 00116 resetOnError++; 00117 }/* If a framing error occurs record it */ 00118 if(flags & SCISR1_RX_FRAMING){ 00119 Counters.serialFramingErrorCounter++; 00120 resetOnError++; 00121 }/* If a parity error occurs record it */ 00122 if(flags & SCISR1_RX_PARITY){ 00123 Counters.serialParityErrorCounter++; 00124 resetOnError++; 00125 } 00126 00127 /* Drop out because of error flags */ 00128 if(resetOnError){ 00129 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00130 PORTB |= BIT1; 00131 return; 00132 } 00133 00134 /* If there is data waiting to be received */ 00135 if(flags & SCISR1_RX_REGISTER_FULL){ 00136 PORTB |= BIT2; 00137 /* Look for a start bresetReceiveStateyte to indicate a new packet */ 00138 if(rawByte == START_BYTE){ 00139 PORTB |= BIT3; 00140 /* If another interface is using it (Note, clear flag, not normal) */ 00141 if(RXBufferContentSourceID & COM_CLEAR_SCI0_INTERFACE_ID){ 00142 /* Turn off our reception */ 00143 SCI0CR2 &= SCICR2_RX_DISABLE; 00144 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00145 PORTB |= BIT4; 00146 }else{ 00147 PORTB |= BIT5; 00148 /* If we are using it */ 00149 if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00150 /* Increment the counter */ 00151 Counters.serialStartInsidePacketCounter++; 00152 } 00153 /* Reset to us using it unless someone else was */ 00154 resetReceiveState(COM_SET_SCI0_INTERFACE_ID); 00155 } 00156 }else if(RXPacketLengthReceived >= RX_BUFFER_SIZE){ 00157 /* Buffer was full, record and reset */ 00158 Counters.serialPacketOverLengthCounter++; 00159 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00160 PORTB |= BIT6; 00161 }else if(RXBufferContentSourceID & COM_SET_SCI0_INTERFACE_ID){ 00162 if(RXStateFlags & RX_SCI_ESCAPED_NEXT){ 00163 PORTB |= BIT7; 00164 /* Clear escaped byte next flag, thanks Karsten! ((~ != !) == (! ~= ~)) == LOL */ 00165 RXStateFlags &= RX_SCI_NOT_ESCAPED_NEXT; 00166 00167 if(rawByte == ESCAPED_ESCAPE_BYTE){ 00168 /* Store and checksum escape byte */ 00169 receiveAndIncrement(ESCAPE_BYTE); 00170 }else if(rawByte == ESCAPED_START_BYTE){ 00171 /* Store and checksum start byte */ 00172 receiveAndIncrement(START_BYTE); 00173 }else if(rawByte == ESCAPED_STOP_BYTE){ 00174 /* Store and checksum stop byte */ 00175 receiveAndIncrement(STOP_BYTE); 00176 }else{ 00177 /* Otherwise reset and record as data is bad */ 00178 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00179 Counters.serialEscapePairMismatchCounter++; 00180 } 00181 }else if(rawByte == ESCAPE_BYTE){ 00182 PORTA |= BIT0; 00183 /* Set flag to indicate that the next byte should be un-escaped. */ 00184 RXStateFlags |= RX_SCI_ESCAPED_NEXT; 00185 }else if(rawByte == STOP_BYTE){ 00186 PORTA |= BIT1; 00187 /* Turn off reception */ 00188 SCI0CR2 &= SCICR2_RX_DISABLE; 00189 SCI0CR2 &= SCICR2_RX_ISR_DISABLE; 00190 00191 /* Bring the checksum back to where it should be */ 00192 unsigned char RXReceivedChecksum = (unsigned char)*(RXBufferCurrentPosition - 1); 00193 RXCalculatedChecksum -= RXReceivedChecksum; 00194 00195 /* Check that the checksum matches */ 00196 if(RXCalculatedChecksum == RXReceivedChecksum){ 00197 /* If it's OK set process flag */ 00198 RXStateFlags |= RX_READY_TO_PROCESS; 00199 PORTA |= BIT2; 00200 }else{ 00201 PORTA |= BIT3; 00202 /* Otherwise reset the state and record it */ 00203 resetReceiveState(CLEAR_ALL_SOURCE_ID_FLAGS); 00204 Counters.serialChecksumMismatchCounter++; 00205 } 00206 }else{ 00207 PORTA |= BIT4; 00208 /* If it isn't special process it! */ 00209 receiveAndIncrement(rawByte); 00210 } 00211 }else{ 00212 /* Do nothing : drop the byte */ 00213 PORTA |= BIT5; 00214 } 00215 } 00216 } 00217 00218 /* If the TX interrupt is enabled check the register empty flag. */ 00219 if((SCI0CR2 & SCICR2_TX_ISR_ENABLE) && (flags & SCISR1_TX_REGISTER_EMPTY)){ 00220 /* Get the byte to be sent from the buffer */ 00221 unsigned char rawValue = *TXBufferCurrentPositionSCI0; 00222 00223 if(TXPacketLengthToSendSCI0 > 0){ 00224 if(TXByteEscaped == 0){ 00225 /* If the raw value needs to be escaped */ 00226 if(rawValue == ESCAPE_BYTE){ 00227 SCI0DRL = ESCAPE_BYTE; 00228 TXByteEscaped = ESCAPED_ESCAPE_BYTE; 00229 }else if(rawValue == START_BYTE){ 00230 SCI0DRL = ESCAPE_BYTE; 00231 TXByteEscaped = ESCAPED_START_BYTE; 00232 }else if(rawValue == STOP_BYTE){ 00233 SCI0DRL = ESCAPE_BYTE; 00234 TXByteEscaped = ESCAPED_STOP_BYTE; 00235 }else{ /* Otherwise just send it */ 00236 sendAndIncrement(rawValue); 00237 } 00238 }else{ 00239 sendAndIncrement(TXByteEscaped); 00240 TXByteEscaped = 0; 00241 } 00242 }else{ /* Length is zero */ 00243 /* Turn off transmission interrupt */ 00244 SCI0CR2 &= SCICR2_TX_ISR_DISABLE; 00245 /* Send the stop byte */ 00246 SCI0DRL = STOP_BYTE; 00247 /* Clear the TX in progress flag */ 00248 TXBufferInUseFlags &= COM_CLEAR_SCI0_INTERFACE_ID; 00249 } 00250 } 00251 00252 /* Record how long the operation took */ 00253 RuntimeVars.serialISRRuntime = TCNT - start; 00254 }
Here is the call graph for this function:
void SecondaryRPMISR | ( | void | ) |
Definition at line 335 of file enginePositionISRs.c.
References CLEAR_PRIMARY_SYNC, fixedConfig::coreSettingsA, coreStatusA, Counters, engineCyclePeriod, fixedConfigs, ISRLatencyVars, lastSecondaryOddTimeStamp, Counter::lostCrankSyncCounter, PORTJ, PORTM, PRIMARY_SYNC, primaryPulsesPerSecondaryPulse, primaryPulsesPerSecondaryPulseBuffer, PTIT, RuntimeVars, SECONDARY_POLARITY, ISRLatencyVar::secondaryInputLatency, RuntimeVar::secondaryInputLeadingRuntime, RuntimeVar::secondaryInputTrailingRuntime, Counter::secondaryTeethCounter, TC1, TCNT, TFLG, TFLGOF, LongTime::timeLong, timerExtensionClock, and LongTime::timeShorts.
00336 { 00337 /* Clear the interrupt flag for this input compare channel */ 00338 TFLG = 0x02; 00339 00340 /* Save all relevant available data here */ 00341 unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00342 unsigned short edgeTimeStamp = TC1; /* Save the timestamp */ 00343 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00344 // unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */ 00345 00346 /* Calculate the latency in ticks */ 00347 ISRLatencyVars.secondaryInputLatency = codeStartTimeStamp - edgeTimeStamp; 00348 00349 // TODO discard narrow ones! test for tooth width and tooth period 00350 00351 /* Set up edges as per config */ 00352 unsigned char risingEdge; 00353 if(fixedConfigs.coreSettingsA & SECONDARY_POLARITY){ 00354 risingEdge = PTITCurrentState & 0x02; 00355 }else{ 00356 risingEdge = !(PTITCurrentState & 0x02); 00357 } 00358 00359 if(risingEdge){ 00360 // echo input condition 00361 PORTJ |= 0x40; 00362 00363 // display the crank pulses 00364 PORTM = (char)primaryPulsesPerSecondaryPulseBuffer; 00365 00366 primaryPulsesPerSecondaryPulseBuffer = primaryPulsesPerSecondaryPulse; 00367 primaryPulsesPerSecondaryPulse = 0; 00368 00369 // if we didn't get the right number of pulses drop sync and start over 00370 if((primaryPulsesPerSecondaryPulseBuffer != 12) && (coreStatusA & PRIMARY_SYNC)){ 00371 coreStatusA &= CLEAR_PRIMARY_SYNC; 00372 Counters.lostCrankSyncCounter++; 00373 } 00374 00375 LongTime timeStamp; 00376 00377 /* Install the low word */ 00378 timeStamp.timeShorts[1] = edgeTimeStamp; 00379 /* Find out what our timer value means and put it in the high word */ 00380 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */ 00381 timeStamp.timeShorts[0] = timerExtensionClock + 1; 00382 }else{ 00383 timeStamp.timeShorts[0] = timerExtensionClock; 00384 } 00385 00386 // get the data we actually want 00387 engineCyclePeriod = 2 * (timeStamp.timeLong - lastSecondaryOddTimeStamp); // save the engine cycle period 00388 lastSecondaryOddTimeStamp = timeStamp.timeLong; // save this stamp for next time round 00389 00390 // Because this is our only reference, each time we get this pulse, we know where we are at (simple mode so far) 00391 coreStatusA |= PRIMARY_SYNC; 00392 RuntimeVars.secondaryInputLeadingRuntime = TCNT - codeStartTimeStamp; 00393 }else{ 00394 PORTJ &= 0xBF; 00395 RuntimeVars.secondaryInputTrailingRuntime = TCNT - codeStartTimeStamp; 00396 } 00397 00398 Counters.secondaryTeethCounter++; 00399 // suss out phase/engine cycle reference showing which bank we are on 00400 00401 /* If the flag is not cleared at the beginning then the interrupt gets rescheduled while it is running, hence it can't be done at the end of the ISR */ 00402 }
void StagedOffISR | ( | void | ) |
Definition at line 52 of file injectionISRs.c.
References PITINTE.
00052 { 00053 // clear the flag 00054 PITINTE |= 0x08; 00055 00056 // bit bang off the correct injector channel 00057 // TODO figure out which channel and switch it 00058 // TODO set the flag for that channel 00059 00060 // if there are other staged channels pending, schedule them and adjust the data 00061 // TODO 00062 00063 /* Clear the PIT3 flag */ 00064 // TODO 00065 }
void StagedOnISR | ( | void | ) |
Definition at line 31 of file injectionISRs.c.
References fixedConfig::coreSettingsA, fixedConfigs, PITINTE, and STAGED_END.
00031 { 00032 // clear the flag 00033 PITINTE |= 0x04; 00034 00035 // bit bang on the correct injector channel 00036 // TODO figure out which channel and switch it 00037 // TODO set the flag for that channel 00038 00039 // if there are other staged channels pending, schedule them and adjust the data 00040 // TODO 00041 00042 /* If staged injection needs the end point scheduled, do it now (otherwise it will turn off naturally with the main injector) */ 00043 if(!(fixedConfigs.coreSettingsA & STAGED_END)){ 00044 // TODO schedule the end of staged injection with PIT 3 00045 } 00046 00047 /* Clear the PIT2 flag */ 00048 // TODO 00049 }
void TimerOverflow | ( | void | ) |
Definition at line 138 of file realtimeISRs.c.
References TFLGOF, and timerExtensionClock.
00138 { 00139 /* Increment the timer extension variable */ 00140 timerExtensionClock++; 00141 00142 /* Clear the timer overflow interrupt flag */ 00143 TFLGOF = 0x80; 00144 }
void UISR | ( | void | ) |
Definition at line 29 of file miscISRs.c.
References Counters, and Counter::UISRCounter.
00029 { 00030 /* Increment the unimplemnted ISR execution counter */ 00031 Counters.UISRCounter++; 00032 }
void VRegAPIISR | ( | void | ) |
void XIRQISR | ( | void | ) |
Definition at line 166 of file miscISRs.c.
References Counters, and Counter::UISRCounter.
00166 { 00167 /* Clear the flag */ 00168 // ?? TODO 00169 00170 /* Increment the unimplemnted ISR execution counter */ 00171 Counters.UISRCounter++; 00172 }