00001 /* injectorISR.c 00002 00003 Copyright 2008 Fred Cooke 00004 00005 This file is part of the FreeEMS project. 00006 00007 FreeEMS software is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 FreeEMS software is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with any FreeEMS software. If not, see <http://www.gnu.org/licenses/>. 00019 00020 We ask that if you make any changes to this file you send them upstream to us at admin@diyefi.org 00021 00022 Thank you for choosing FreeEMS to run your engine! */ 00023 00024 /* This code is identical between all 6 channels, and thus we only want one copy of it. The X in each macro will be replaced with the real deal appropriate for the channel it is used for at the time. */ 00025 00026 /* Each channel performs the following actions 00027 * 00028 * 1 Clear its interrupt flag 00029 * 2 Record its start time 00030 * 3 Measure and record its latency 00031 * 4 Check to see if its just turned on 00032 * 4.1 Copy the channels pulse width to a local variable 00033 * 4.2 Determine the minimum pulse width based on code run time const and latency 00034 * 4.3 Clamp used pulsewidth inside min and max 00035 * 4.4 If used pulse width is larger than the current period of the engines cycle flag as always on 00036 * 4.5 Set the action to turn off 00037 * 4.6 Increment the time by pulse width 00038 * 4.7 If staging required, either, switch them on and sched to turn off, or sched to turn on 00039 * 5 Else it has just turned off 00040 * 5.1 If staged channel is still on, turn it off 00041 * 5.2 If(self schedule flagged) schedule the next start 00042 * 5.3 Else disable itself 00043 * 6 Calculate and record code run time 00044 * 7 Return 00045 */ 00046 00047 void InjectorXISR(){ 00048 /* Clear the interrupt flag for this channel */ 00049 TFLG = injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER]; 00050 00051 /* Record the current time as start time */ 00052 unsigned short TCNTStart = TCNT; 00053 00054 /* Record the edge time stamp from the IC register */ 00055 unsigned short edgeTimeStamp = *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER]; 00056 00057 /* Calculate and store the latency based on compare time and start time */ 00058 injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER] = TCNTStart - edgeTimeStamp; 00059 00060 /* If rising edge triggered this */ 00061 if(PTIT & injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER]){ // Stuff for switch on time 00062 00063 /* Find out what max and min for pulse width are */ 00064 unsigned short localPulseWidth = injectorMainPulseWidths[INJECTOR_CHANNEL_NUMBER + realTimeUseInjectionOffset]; 00065 unsigned short localMinimumPulseWidth = injectorSwitchOnCodeTime + injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER]; 00066 00067 /* TODO *maybe* instead of checking min and increasing pulse, just force it straight off if diff between start and now+const is greater than desired pulsewidth */ 00068 00069 /* Ensure we dont go under minimum pulsewidth */ 00070 if(localPulseWidth < localMinimumPulseWidth){ 00071 localPulseWidth = localMinimumPulseWidth; 00072 }/* else{ just use the value } */ 00073 00074 LongTime timeStamp; 00075 00076 /* Install the low word */ 00077 timeStamp.timeShorts[1] = edgeTimeStamp; 00078 /* Find out what our timer value means and put it in the high word */ 00079 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */ 00080 timeStamp.timeShorts[0] = timerExtensionClock + 1; 00081 }else{ 00082 timeStamp.timeShorts[0] = timerExtensionClock; 00083 } 00084 00085 // store the end time for use in the scheduler 00086 injectorMainEndTimes[INJECTOR_CHANNEL_NUMBER] = timeStamp.timeLong + localPulseWidth; 00087 00088 /* Set the action for compare to switch off FIRST or it might inadvertently PWM the injector during opening... */ 00089 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainGoLowMasks[INJECTOR_CHANNEL_NUMBER]; 00090 00091 /* Set the time to turn off again */ 00092 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += localPulseWidth; 00093 00094 /* This is the point we actually want the time to, but because the code is so simple, it can't help but be a nice short time */ 00095 00096 /* If staged injection is required, switch on or schedule corresponding staged injector and remember that we did. */ 00097 if(coreStatusA & STAGED_REQUIRED){ 00098 if(fixedConfigs.coreSettingsA & STAGED_START){ 00099 /* Switch that channel on NOW */ 00100 STAGEDPORT |= STAGEDXON; 00101 stagedOn |= STAGEDXON; 00102 }else{ 00103 /* Schedule the start at a later time */ 00104 // TODO PIT scheduling of staged start 00105 } 00106 } 00107 /* Calculate and store code run time */ 00108 injectorCodeOpenRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart; 00109 }else{ // Stuff for switch off time 00110 /* If we switched the staged injector on and it's still on, turn it off now. */ 00111 if(stagedOn & STAGEDXON){ 00112 STAGEDPORT &= STAGEDXOFF; 00113 stagedOn &= STAGEDXOFF; 00114 } 00115 00116 /* Set the action for compare to switch on and the time to next start time, clear the self timer flag */ 00117 if(selfSetTimer & injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER]){ 00118 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] = injectorMainStartTimesHolding[INJECTOR_CHANNEL_NUMBER]; 00119 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] |= injectorMainGoHighMasks[INJECTOR_CHANNEL_NUMBER]; 00120 selfSetTimer &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER]; 00121 }else{ 00122 // Disable interrupts and actions incase the period from this end to the next start is long (saves cpu) 00123 TIE &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER]; 00124 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainDisableMasks[INJECTOR_CHANNEL_NUMBER]; 00125 } 00126 /* Calculate and store code run time */ 00127 injectorCodeCloseRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart; 00128 } 00129 }