Initial commit of 0.0.18 just as it was released!
[freeems-vanilla.git] / src / inc / injectorISR.c
blob75373b13ef787283242c06bb27a2de21b67ef5ef
1 /* injectorISR.c
3 Copyright 2008 Fred Cooke
5 This file is part of the FreeEMS project.
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.
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.
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/>.
20 We ask that if you make any changes to this file you send them upstream to us at admin@diyefi.org
22 Thank you for choosing FreeEMS to run your engine! */
24 /* 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. */
26 /* Each channel performs the following actions
28 * 1 Clear its interrupt flag
29 * 2 Record its start time
30 * 3 Measure and record its latency
31 * 4 Check to see if its just turned on
32 * 4.1 Copy the channels pulse width to a local variable
33 * 4.2 Determine the minimum pulse width based on code run time const and latency
34 * 4.3 Clamp used pulsewidth inside min and max
35 * 4.4 If used pulse width is larger than the current period of the engines cycle flag as always on
36 * 4.5 Set the action to turn off
37 * 4.6 Increment the time by pulse width
38 * 4.7 If staging required, either, switch them on and sched to turn off, or sched to turn on
39 * 5 Else it has just turned off
40 * 5.1 If staged channel is still on, turn it off
41 * 5.2 If(self schedule flagged) schedule the next start
42 * 5.3 Else disable itself
43 * 6 Calculate and record code run time
44 * 7 Return
47 void InjectorXISR(){
48 /* Clear the interrupt flag for this channel */
49 TFLG = injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER];
51 /* Record the current time as start time */
52 unsigned short TCNTStart = TCNT;
54 /* Record the edge time stamp from the IC register */
55 unsigned short edgeTimeStamp = *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER];
57 /* Calculate and store the latency based on compare time and start time */
58 injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER] = TCNTStart - edgeTimeStamp;
60 /* If rising edge triggered this */
61 if(PTIT & injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER]){ // Stuff for switch on time
63 /* Find out what max and min for pulse width are */
64 unsigned short localPulseWidth = injectorMainPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER];
65 unsigned short localMinimumPulseWidth = injectorSwitchOnCodeTime + injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER];
67 /* 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 */
69 /* Ensure we dont go under minimum pulsewidth */
70 if(localPulseWidth < localMinimumPulseWidth){
71 localPulseWidth = localMinimumPulseWidth;
72 }/* else{ just use the value } */
74 LongTime timeStamp;
76 /* Install the low word */
77 timeStamp.timeShorts[1] = edgeTimeStamp;
78 /* Find out what our timer value means and put it in the high word */
79 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
80 timeStamp.timeShorts[0] = timerExtensionClock + 1;
81 }else{
82 timeStamp.timeShorts[0] = timerExtensionClock;
85 // store the end time for use in the scheduler
86 injectorMainEndTimes[INJECTOR_CHANNEL_NUMBER] = timeStamp.timeLong + localPulseWidth;
88 /* Set the action for compare to switch off FIRST or it might inadvertently PWM the injector during opening... */
89 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainGoLowMasks[INJECTOR_CHANNEL_NUMBER];
91 /* Set the time to turn off again */
92 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += localPulseWidth;
94 /* 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 */
96 /* If staged injection is required, switch on or schedule corresponding staged injector and remember that we did. */
97 if(coreStatusA & STAGED_REQUIRED){
98 if(fixedConfigs1.coreSettingsA & STAGED_START){
99 /* Switch that channel on NOW */
100 STAGEDPORT |= STAGEDXON;
101 stagedOn |= STAGEDXON;
102 }else{
103 /* Schedule the start at a later time */
104 // TODO PIT scheduling of staged start
107 /* Calculate and store code run time */
108 injectorCodeOpenRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart;
109 }else{ // Stuff for switch off time
110 /* If we switched the staged injector on and it's still on, turn it off now. */
111 if(stagedOn & STAGEDXON){
112 STAGEDPORT &= STAGEDXOFF;
113 stagedOn &= STAGEDXOFF;
116 /* Set the action for compare to switch on and the time to next start time, clear the self timer flag */
117 if(selfSetTimer & injectorMainOnMasks[INJECTOR_CHANNEL_NUMBER]){
118 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] = injectorMainStartTimesHolding[INJECTOR_CHANNEL_NUMBER];
119 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] |= injectorMainGoHighMasks[INJECTOR_CHANNEL_NUMBER];
120 selfSetTimer &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER];
121 }else{
122 // Disable interrupts and actions incase the period from this end to the next start is long (saves cpu)
123 TIE &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER];
124 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainDisableMasks[INJECTOR_CHANNEL_NUMBER];
126 /* Calculate and store code run time */
127 injectorCodeCloseRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart;