injectorISR.c

Go to the documentation of this file.
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 = injectorMainPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER];
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(fixedConfigs1.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 }

Generated on Mon Dec 22 21:29:18 2008 for freeems by  doxygen 1.5.2