FreeEMS  0.2.0-SNAPSHOT-282-g9efc524
decoderInterface.c
Go to the documentation of this file.
1 /* FreeEMS - the open source engine management system
2  *
3  * Copyright 2011-2014 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  * @ingroup enginePositionRPMDecoders
30  *
31  * @brief shared functions used by all decoders
32  *
33  * To maximise code reuse and minimise bugs it is strongly recommended that you
34  * use these pre-canned functions to do work required in your decoder.
35  */
36 
37 
38 #define DECODER_INTERFACE_C
39 #include "inc/freeEMS.h"
40 #include "inc/decoderInterface.h"
41 
42 
43 /// @brief Loop over all schedules descheduling them as we go.
45  unsigned char i;
46  for(i = 0; i < MAX_NUMBER_OF_OUTPUT_EVENTS; i++){
48  }
49 }
50 
51 
52 /** @brief Reset key state
53  *
54  * Reset all important variables to their non-running state.
55  *
56  * @todo TODO bring this up to date and/or find a better way to do it.
57  *
58  * @param uniqueLossID 0 is reserved for system use, within your decoder never use the same value twice.
59  */
60 void resetToNonRunningState(unsigned char uniqueLossID){
61  if(uniqueLossID){
63  }
64 
65  // Reset the safe re-sync counters.
66  if(fixedConfigs2.decoderSettings.syncConfirmationsRunning == 0xFF){ // Prevent overflow to zero
68  }else{ // Ensure at least 1 cycle is confirmed
70  }
72 
73  /* Reset RPM to zero */
74  ticksPerDegree0 = 0;
75  ticksPerDegree1 = 0;
76 
77  // Keep track of lost sync in counters
81  }else{
83  }
84  }else{
86  }
87 
88  // record unique loss ID
89  KeyUserDebugs.syncLostWithThisID = uniqueLossID;
90 
91  // record current event and then clear it
94 
95  /* Clear all sync flags to lost state */
96  KeyUserDebugs.decoderFlags = 0; // Nothing should use this except for us anyway!
98 
99  // Unschedule everything right now
100  descheduleAll();
101 }
102 
103 
104 /** Schedule an ignition output event on port T
105  *
106  * @warning If you do not handle the skipEventFlags then excess advance may occur!
107  */
108 void schedulePortTPin(unsigned char outputEventNumber, LongTime timeStamp){
109  unsigned char pin = fixedConfigs1.schedulingSettings.outputEventPinNumbers[outputEventNumber];
110  unsigned short postReferenceEventDelay = 0;
111  if(skipEventFlags & (1UL << outputEventNumber)){
112  postReferenceEventDelay = decoderMaxCodeTime;
113  skipEventFlags &= ~(1UL << outputEventNumber); // Clear the flag
114  }else{
115  postReferenceEventDelay = outputEventDelayFinalPeriod[outputEventNumber];
116  }
117  // determine the long and short start times
118  unsigned short startTime = timeStamp.timeShorts[1] + postReferenceEventDelay;
119  // remove this temporarily too, no need for it without the later conditional code
120  unsigned long startTimeLong = timeStamp.timeLong + postReferenceEventDelay;
121 
122  /// @todo TODO Make this more understandable as right now it is difficult to grok.
123  // determine whether or not to reschedule or self schedule assuming pin is currently scheduled
124  unsigned long diff = (ectMainEndTimes[pin] + ectSwitchOffCodeTime) - startTimeLong;
125 #define newStartIsAfterOutputEndTimeAndCanSelfSet (diff > LONGHALF)
126 // http://forum.diyefi.org/viewtopic.php?f=8&t=57&p=861#p861
127 
128 /*
129  fresh code again, five states, 6 possible behaviours:
130 
131  not enabled - sched!!! always
132  enabled and low, ready to turn on - if too close, do nothing, or if far enough away, resched
133  enabled and high, ready to turn off - if too close, resched to turn on, if far enough away, self sched
134 */
135 
136  // Is it enabled and about to do *something*?
137  if(TIE & ectMainOnMasks[pin]){
138  // If configured to do something specific
140  // If that something is go high
142  // GO HIGH SHOULD DO NOTHING CEPT COUNTER
143  // if too close, do nothing, or if far enough away, resched
144  // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
146  }else{ // Otherwise it's go low
147  // if too close, resched to turn, ie, stay on... , if far enough away, self sched
149  // self sched
150  ectMainStartOffsetHolding[pin] = startTime - *ectMainTimeRegisters[pin];
155  selfSetTimer |= ectMainOnMasks[pin]; // setup a bit to let the timer interrupt know to set its own new start from a var
157  }else{
160  }
161  }
162  }else{ // Configured to do nothing, or toggle
164  // TOGGLE SHOULD EARN SOME SORT OF ERROR CONDITION/COUNTER
166  }else{
167  // DO NOTHING SHOULD DO THE SAME AS GO HIGH
168  // ie, do nothing
169  // if too close, do nothing, or if far enough away, resched
170  // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
172  }
173  }
174  }else{ // not enabled, schedule as normal
177  }
178 
179 #ifdef XGATE // This has to be here because the timing of the ECT stuff is critical and it must run first.
180 #include "xgateScheduler.c"
181 #endif // Also, this should always run so can't be inside the above if/else block.
182 }