FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
injectorISR.c
Go to the documentation of this file.
1 /* FreeEMS - the open source engine management system
2  *
3  * Copyright 2008-2012 Fred Cooke
4  *
5  * This file is part of the FreeEMS project.
6  *
7  * FreeEMS software is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * FreeEMS software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
19  *
20  * We ask that if you make any changes to this file you email them upstream to
21  * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
22  *
23  * Thank you for choosing FreeEMS to run your engine!
24  */
25 
26 
27 /** @file
28  *
29  * @brief Injector ISR shared code
30  *
31  * This code is identical between all 6 channels, and thus we only want one
32  * copy of it. The X in each macro will be replaced with the number that is
33  * appropriate for the channel it is being used for at the time.
34  *
35  * Each channel performs the following actions
36  *
37  * - 1 Clear its interrupt flag
38  * - 2 Record its start time
39  * - 3 Measure and record its latency
40  * - 4 Check to see if its just turned on
41  * - 4.1 Copy the channels pulse width to a local variable
42  * - 4.2 Determine the minimum pulse width based on code run time const and latency
43  * - 4.3 Clamp used pulsewidth inside min and max
44  * - 4.4 If used pulse width is larger than the current period of the engines cycle flag as always on
45  * - 4.5 Set the action to turn off
46  * - 4.6 Increment the time by pulse width
47  * - 4.7 If staging required, either, switch them on and sched to turn off, or sched to turn on
48  * - 5 Else it has just turned off
49  * - 5.1 If staged channel is still on, turn it off
50  * - 5.2 If(self schedule flagged) schedule the next start
51  * - 5.3 Else disable itself
52  * - 6 Calculate and record code run time
53  * - 7 Return
54  *
55  * @see injectionISRs.c
56  */
57 
58 
59 // Courtesy of Dave Cramer
60 #define INJECTOR_MAIN_ON_MASK (BIT2<<INJECTOR_CHANNEL_NUMBER)
61 
62 /** A template function for ECT injector/coil operation.
63  *
64  * Note, this function does not exist in the binary, only in source and the
65  * Doxygen docs. In contrast the 6 real ones only exist in binary and not the
66  * source or Doxygen docs, hence if you want to look at the source, this is the
67  * place to do so.
68  */
69 void InjectorXISR(){
70  /* Clear the interrupt flag for this channel */
72 
73  /* Record the current time as start time */
74  unsigned short TCNTStart = TCNT;
75 
77 
78  /* Record the edge time stamp from the IC register */
80 
81  /* If rising edge triggered this */
82  if(PTIT & INJECTOR_MAIN_ON_MASK){ // Stuff for switch on time
83 
84  /* Find out what max and min for pulse width are */
85  unsigned short localPulseWidth = outputEventPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER];
86  unsigned short localMinimumPulseWidth = ectSwitchOnCodeTime + ectCodeLatencies[INJECTOR_CHANNEL_NUMBER];
87 
88  /** @todo 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 */
89 
90  /* Ensure we dont go under minimum pulsewidth */
91  if(localPulseWidth < localMinimumPulseWidth){
92  localPulseWidth = localMinimumPulseWidth;
93  }/* else{ just use the value } */
94 
96 
97  /* Install the low word */
98  timeStamp.timeShorts[1] = edgeTimeStamp;
99  /* Find out what our timer value means and put it in the high word */
100  if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
101  timeStamp.timeShorts[0] = timerExtensionClock + 1;
102  }else{
103  timeStamp.timeShorts[0] = timerExtensionClock;
104  }
105 
106  // store the end time for use in the scheduler
107  ectMainEndTimes[INJECTOR_CHANNEL_NUMBER] = timeStamp.timeLong + localPulseWidth;
108 
109  /* Set the action for compare to switch off FIRST or it might inadvertently PWM the injector during opening... */
111 
112  /* Set the time to turn off again */
113  *ectMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += localPulseWidth;
114 
115  /* 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 */
116 
118 
119  /* Calculate and store code run time */
121  }else{ // Stuff for switch off time and repeat timer time.
123  if(outputEventExtendNumberOfRepeatsRealtime[INJECTOR_CHANNEL_NUMBER] > 0){
127  }else{
130  // this is already set from the decoder, we're just delaying use of it: outputEventPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER]
132  }
133  }else{ // if set to off action (implicit)
134  /* Set the action for compare to switch on and the time to next start time, clear the self timer flag */
135  if(selfSetTimer & INJECTOR_MAIN_ON_MASK){
136  if(outputEventExtendNumberOfRepeatsHolding[INJECTOR_CHANNEL_NUMBER] > 0){
142  }else{
145  }
149  }else{
150  // Disable interrupts and actions incase the period from this end to the next start is long (saves cpu)
154  }
155  }
156  /* Calculate and store code run time */
158  }
159  /* Calculate and store the latency based on compare time and start time */
161 
163 }