#include "inc/freeEMS.h"
#include "inc/interrupts.h"
#include "inc/utils.h"
Go to the source code of this file.
Defines | |
#define | ticksPerMinute 75000000 |
Functions | |
void | PrimaryRPMISR () |
void | SecondaryRPMISR () |
Use the rising and falling edges................... |
This file contains the two interrupt service routines required for to build cleanly. However, only the first one is used due to the simple nature of it.
The functional ISR just blindly injects fuel for every input it receives. Thus a perfectly clean input is absolutely essential at this time.
Supported engines include: B230F
Definition in file Simple.c.
#define ticksPerMinute 75000000 |
Referenced by PrimaryRPMISR().
void PrimaryRPMISR | ( | void | ) |
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.
Definition at line 68 of file Simple.c.
References ADCArrays, CALC_FUEL_IGN, Clocks, coreStatusA, Counters, engineCyclePeriod, injectorMainControlRegisters, injectorMainEnableMasks, injectorMainEndTimes, injectorMainOnMasks, injectorMainStartTimesHolding, injectorMainTimeRegisters, injectorMinimumPulseWidth, injectorSwitchOffCodeTime, ISRLatencyVars, lastPrimaryPulseTimeStamp, LONGHALF, masterPulseWidth, mathSampleTimeStampRecord, PORTJ, PRIMARY_SYNC, ISRLatencyVar::primaryInputLatency, RuntimeVar::primaryInputLeadingRuntime, RuntimeVar::primaryInputTrailingRuntime, primaryLeadingEdgeTimeStamp, Counter::primaryTeethSeen, PTIT, RPMRecord, RuntimeVars, sampleEachADC(), selfSetTimer, Counter::syncedADCreadings, TC0, TCNT, TFLG, TFLGOF, ticksPerMinute, TIE, timeBetweenSuccessivePrimaryPulses, LongTime::timeLong, Clock::timeoutADCreadingClock, timerExtensionClock, LongTime::timeShorts, totalAngleAfterReferenceInjection, and trailingEdgeSecondaryRPMInputCodeTime.
00068 { 00069 /* Clear the interrupt flag for this input compare channel */ 00070 TFLG = 0x01; 00071 00072 /* Save all relevant available data here */ 00073 unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00074 unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */ 00075 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00076 00077 // set as synced for volvo always as loss of sync not actually possible 00078 coreStatusA |= PRIMARY_SYNC; 00079 00080 /* Calculate the latency in ticks */ 00081 ISRLatencyVars.primaryInputLatency = codeStartTimeStamp - edgeTimeStamp; 00082 00083 if(PTITCurrentState & 0x01){ 00084 /* Echo input condition on J7 */ 00085 PORTJ |= 0x80; 00086 00087 Counters.primaryTeethSeen++; 00088 00089 LongTime timeStamp; 00090 00091 /* Install the low word */ 00092 timeStamp.timeShorts[1] = edgeTimeStamp; 00093 /* Find out what our timer value means and put it in the high word */ 00094 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */ 00095 timeStamp.timeShorts[0] = timerExtensionClock + 1; 00096 }else{ 00097 timeStamp.timeShorts[0] = timerExtensionClock; 00098 } 00099 00100 // temporary data from inputs 00101 primaryLeadingEdgeTimeStamp = timeStamp.timeLong; 00102 timeBetweenSuccessivePrimaryPulses = primaryLeadingEdgeTimeStamp - lastPrimaryPulseTimeStamp; 00103 lastPrimaryPulseTimeStamp = primaryLeadingEdgeTimeStamp; 00104 00105 #define ticksPerMinute 75000000 // this is correct. 00106 00107 *RPMRecord = (unsigned short) (ticksPerMinute / timeBetweenSuccessivePrimaryPulses); 00108 00109 // TODO sample ADCs on teeth other than that used by the scheduler in order to minimise peak run time and get clean signals 00110 sampleEachADC(ADCArrays); 00111 Counters.syncedADCreadings++; 00112 *mathSampleTimeStampRecord = TCNT; 00113 00114 /* Set flag to say calc required */ 00115 coreStatusA |= CALC_FUEL_IGN; 00116 00117 /* Reset the clock for reading timeout */ 00118 Clocks.timeoutADCreadingClock = 0; 00119 00120 if(masterPulseWidth > injectorMinimumPulseWidth){ // use reference PW to decide. spark needs moving outside this area though TODO 00121 /* Determine if half the cycle is bigger than short-max */ 00122 unsigned short maxAngleAfter; 00123 if((engineCyclePeriod >> 1) > 0xFFFF){ 00124 maxAngleAfter = 0xFFFF; 00125 }else{ 00126 maxAngleAfter = (unsigned short)(engineCyclePeriod >> 1); 00127 } 00128 00129 /* Check advance to ensure it is less than 1/2 of the previous engine cycle and more than codetime away */ 00130 unsigned short advance; 00131 if(totalAngleAfterReferenceInjection > maxAngleAfter){ // if too big, make it max 00132 advance = maxAngleAfter; 00133 }else if(totalAngleAfterReferenceInjection < trailingEdgeSecondaryRPMInputCodeTime){ // if too small, make it min 00134 advance = trailingEdgeSecondaryRPMInputCodeTime; 00135 }else{ // else use it as is 00136 advance = totalAngleAfterReferenceInjection; 00137 } 00138 00139 // determine the long and short start times 00140 unsigned short startTime = edgeTimeStamp + advance; 00141 unsigned long startTimeLong = timeStamp.timeLong + advance; 00142 00143 /* Determine the channels to schedule */ 00144 unsigned char fuelChannel = 0;//(primaryPulsesPerSecondaryPulse / 2) - 1; 00145 00146 // determine whether or not to reschedule 00147 unsigned char reschedule = 0; 00148 unsigned long diff = startTimeLong - (injectorMainEndTimes[fuelChannel] + injectorSwitchOffCodeTime); 00149 if(diff > LONGHALF){ 00150 reschedule = 1; // http://www.diyefi.org/forum/viewtopic.php?f=8&t=57&p=861#p861 00151 } 00152 00153 // schedule the appropriate channel 00154 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 */ 00155 *injectorMainControlRegisters[fuelChannel] |= injectorMainEnableMasks[fuelChannel]; 00156 *injectorMainTimeRegisters[fuelChannel] = startTime; 00157 TIE |= injectorMainOnMasks[fuelChannel]; 00158 TFLG = injectorMainOnMasks[fuelChannel]; 00159 }else{ 00160 injectorMainStartTimesHolding[fuelChannel] = startTime; 00161 selfSetTimer |= injectorMainOnMasks[fuelChannel]; // setup a bit to let the timer interrupt know to set its own new start from a var 00162 } 00163 } 00164 RuntimeVars.primaryInputLeadingRuntime = TCNT - codeStartTimeStamp; 00165 }else{ 00166 PORTJ &= 0x7F; 00167 RuntimeVars.primaryInputTrailingRuntime = TCNT - codeStartTimeStamp; 00168 } 00169 }
void SecondaryRPMISR | ( | void | ) |
Use the rising and falling edges...................
Secondary RPM ISR
Unused in this decoder.
Definition at line 176 of file Simple.c.
References Counters, ISRLatencyVars, lastSecondaryPulseLeadingTimeStamp, lastSecondaryPulseTrailingTimeStamp, lengthOfSecondaryLowPulses, PORTJ, PTIT, ISRLatencyVar::secondaryInputLatency, Counter::secondaryTeethSeen, TC1, TCNT, TFLG, TFLGOF, LongTime::timeLong, timerExtensionClock, and LongTime::timeShorts.
00176 { 00177 /* Clear the interrupt flag for this input compare channel */ 00178 TFLG = 0x02; 00179 00180 /* Save all relevant available data here */ 00181 unsigned short codeStartTimeStamp = TCNT; /* Save the current timer count */ 00182 unsigned short edgeTimeStamp = TC1; /* Save the timestamp */ 00183 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */ 00184 // unsigned short PORTS_BACurrentState = PORTS_BA; /* Save ignition output state */ 00185 00186 /* Calculate the latency in ticks */ 00187 ISRLatencyVars.secondaryInputLatency = codeStartTimeStamp - edgeTimeStamp; 00188 00195 LongTime timeStamp; 00196 00197 /* Install the low word */ 00198 timeStamp.timeShorts[1] = edgeTimeStamp; 00199 /* Find out what our timer value means and put it in the high word */ 00200 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */ 00201 timeStamp.timeShorts[0] = timerExtensionClock + 1; 00202 }else{ 00203 timeStamp.timeShorts[0] = timerExtensionClock; 00204 } 00205 00206 /* The LM1815 variable reluctance sensor amplifier allows the output to be 00207 * pulled high starting at the center of a tooth. So, what we see as the 00208 * start of a tooth is actually the centre of a physical tooth. Because 00209 * tooth shape, profile and spacing may vary this is the only reliable edge 00210 * for us to schedule from, hence the trailing edge code is very simple. 00211 */ 00212 if(PTITCurrentState & 0x02){ 00213 // echo input condition 00214 PORTJ |= 0x40; 00215 00216 Counters.secondaryTeethSeen++; 00217 00218 /* leading code 00219 * 00220 * subtract lastTrailing from currentLeading 00221 * record currentLeading as lastLeading 00222 * 00223 * record pw as highDuration 00224 */ 00225 lengthOfSecondaryLowPulses = timeStamp.timeLong - lastSecondaryPulseTrailingTimeStamp; 00226 lastSecondaryPulseLeadingTimeStamp = timeStamp.timeLong; 00227 }else{ 00228 00229 /* trailing code 00230 * 00231 * subtract lastLeading from currentTrailing 00232 * record currentTrailing as lastTrailing 00233 * 00234 * record pw as lowDuration 00235 */ 00236 // lengthOfSecondaryHighPulses = timeStamp.timeLong - lastSecondaryPulseLeadingTimeStamp; 00237 lastSecondaryPulseTrailingTimeStamp = timeStamp.timeLong; 00238 00239 PORTJ &= 0xBF; 00240 } 00241 }