Remove custom datalog file and search path hack now redundant due to fully customisab...
[freeems-vanilla.git] / src / inc / injectorISR.c
blobf8be1707390be2b49ff7b1bac6cba8c318271fa4
1 /* FreeEMS - the open source engine management system
3 * Copyright 2008-2012 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 email them upstream to
21 * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
23 * Thank you for choosing FreeEMS to run your engine!
27 /** @file
29 * @brief Injector ISR shared code
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.
35 * Each channel performs the following actions
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
55 * @see injectionISRs.c
59 // Courtesy of Dave Cramer
60 #define INJECTOR_MAIN_ON_MASK (BIT2<<INJECTOR_CHANNEL_NUMBER)
62 /** A template function for ECT injector/coil operation.
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.
69 void InjectorXISR(){
70 /* Clear the interrupt flag for this channel */
71 TFLG = INJECTOR_MAIN_ON_MASK;
73 /* Record the current time as start time */
74 unsigned short TCNTStart = TCNT;
76 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT2, PORTB);
78 /* Record the edge time stamp from the IC register */
79 unsigned short edgeTimeStamp = *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER];
81 /* If rising edge triggered this */
82 if(PTIT & INJECTOR_MAIN_ON_MASK){ // Stuff for switch on time
84 /* Find out what max and min for pulse width are */
85 unsigned short localPulseWidth = outputEventPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER];
86 unsigned short localMinimumPulseWidth = injectorSwitchOnCodeTime + injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER];
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 */
90 /* Ensure we dont go under minimum pulsewidth */
91 if(localPulseWidth < localMinimumPulseWidth){
92 localPulseWidth = localMinimumPulseWidth;
93 }/* else{ just use the value } */
95 LongTime timeStamp;
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;
106 // store the end time for use in the scheduler
107 injectorMainEndTimes[INJECTOR_CHANNEL_NUMBER] = timeStamp.timeLong + localPulseWidth;
109 /* Set the action for compare to switch off FIRST or it might inadvertently PWM the injector during opening... */
110 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainGoLowMasks[INJECTOR_CHANNEL_NUMBER];
112 /* Set the time to turn off again */
113 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += localPulseWidth;
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 */
117 Counters.injectorSwitchOns++;
119 /* Calculate and store code run time */
120 injectorCodeOpenRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart;
121 }else{ // Stuff for switch off time and repeat timer time.
122 if(!(*injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] & injectorMainEnableMasks[INJECTOR_CHANNEL_NUMBER])){ // set to no action
123 if(outputEventExtendNumberOfRepeatsRealtime[INJECTOR_CHANNEL_NUMBER] > 0){
124 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += outputEventExtendRepeatPeriodRealtime[INJECTOR_CHANNEL_NUMBER];
125 outputEventExtendNumberOfRepeatsRealtime[INJECTOR_CHANNEL_NUMBER]--;
126 Counters.injectorTimerExtensions++;
127 }else{
128 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] |= injectorMainEnableMasks[INJECTOR_CHANNEL_NUMBER];
129 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += outputEventDelayFinalPeriodRealtime[INJECTOR_CHANNEL_NUMBER];
130 // this is already set from the decoder, we're just delaying use of it: outputEventPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER]
131 Counters.injectorTimerExtensionFinals++;
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){
137 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainDisableMasks[INJECTOR_CHANNEL_NUMBER];
138 outputEventExtendNumberOfRepeatsRealtime[INJECTOR_CHANNEL_NUMBER] = outputEventExtendNumberOfRepeatsHolding[INJECTOR_CHANNEL_NUMBER];
139 outputEventExtendRepeatPeriodRealtime[INJECTOR_CHANNEL_NUMBER] = outputEventExtendRepeatPeriodHolding[INJECTOR_CHANNEL_NUMBER];
140 outputEventDelayFinalPeriodRealtime[INJECTOR_CHANNEL_NUMBER] = outputEventDelayFinalPeriodHolding[INJECTOR_CHANNEL_NUMBER];
141 Counters.injectorSelfScheduleExtensions++;
142 }else{
143 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] |= injectorMainGoHighMasks[INJECTOR_CHANNEL_NUMBER];
144 Counters.injectorSelfSchedules++;
146 *injectorMainTimeRegisters[INJECTOR_CHANNEL_NUMBER] += injectorMainStartOffsetHolding[INJECTOR_CHANNEL_NUMBER];
147 outputEventPulseWidthsRealtime[INJECTOR_CHANNEL_NUMBER] = outputEventPulseWidthsHolding[INJECTOR_CHANNEL_NUMBER];
148 selfSetTimer &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER];
149 }else{
150 // Disable interrupts and actions incase the period from this end to the next start is long (saves cpu)
151 TIE &= injectorMainOffMasks[INJECTOR_CHANNEL_NUMBER];
152 *injectorMainControlRegisters[INJECTOR_CHANNEL_NUMBER] &= injectorMainDisableMasks[INJECTOR_CHANNEL_NUMBER];
153 Counters.injectorSwitchOffs++;
156 /* Calculate and store code run time */
157 injectorCodeCloseRuntimes[INJECTOR_CHANNEL_NUMBER] = TCNT - TCNTStart;
159 /* Calculate and store the latency based on compare time and start time */
160 injectorCodeLatencies[INJECTOR_CHANNEL_NUMBER] = TCNTStart - edgeTimeStamp;
162 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT2, PORTB);