1 /* FreeEMS - the open source engine management system
3 * Copyright 2011-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!
29 * @ingroup enginePositionRPMDecoders
31 * @brief shared functions used by all decoders
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.
38 #define DECODER_INTERFACE_C
39 #include "inc/freeEMS.h"
40 #include "inc/decoderInterface.h"
43 /** @brief Reset key state
45 * Reset all important variables to their non-running state.
47 * @todo TODO bring this up to date and/or find a better way to do it.
49 * @param uniqueLossID 0 is reserved for system use, within your decoder never use the same value twice.
51 void resetToNonRunningState(unsigned char uniqueLossID
){
53 KeyUserDebugs
.syncResetCalls
++;
56 /* Reset RPM to zero */
60 // Keep track of lost sync in counters
61 if(KeyUserDebugs
.decoderFlags
& (CAM_SYNC
| CRANK_SYNC
| COMBUSTION_SYNC
)){
62 FLAG_AND_INC_FLAGGABLE(FLAG_DECODER_SYNC_LOSSES_OFFSET
);
64 FLAG_AND_INC_FLAGGABLE(FLAG_DECODER_SYNC_STATE_CLEARS_OFFSET
);
67 // record unique loss ID
68 KeyUserDebugs
.syncLostWithThisID
= uniqueLossID
;
70 // record current event
71 KeyUserDebugs
.syncLostOnThisEvent
= KeyUserDebugs
.currentEvent
;
73 /* Clear all sync flags to lost state */
74 KeyUserDebugs
.decoderFlags
= 0; // Nothing should use this except for us anyway!
76 // TODO more stuff needs resetting here, but only critical things.
80 /** Schedule an ignition output event on port T
82 * @warning If you do not handle the skipEventFlags then excess advance may occur!
84 void schedulePortTPin(unsigned char outputEventNumber
, LongTime timeStamp
){
85 unsigned char pin
= fixedConfigs1
.schedulingSettings
.outputEventPinNumbers
[outputEventNumber
];
86 unsigned short postReferenceEventDelay
= 0;
87 if(skipEventFlags
& (1UL << outputEventNumber
)){
88 postReferenceEventDelay
= decoderMaxCodeTime
;
89 skipEventFlags
&= ~(1UL << outputEventNumber
); // Clear the flag
91 postReferenceEventDelay
= outputEventDelayFinalPeriod
[outputEventNumber
];
93 // determine the long and short start times
94 unsigned short startTime
= timeStamp
.timeShorts
[1] + postReferenceEventDelay
;
95 // remove this temporarily too, no need for it without the later conditional code
96 unsigned long startTimeLong
= timeStamp
.timeLong
+ postReferenceEventDelay
;
98 /// @todo TODO Make this more understandable as right now it is difficult to grok.
99 // determine whether or not to reschedule or self schedule assuming pin is currently scheduled
100 unsigned long diff
= (injectorMainEndTimes
[pin
] + injectorSwitchOffCodeTime
) - startTimeLong
;
101 #define newStartIsAfterOutputEndTimeAndCanSelfSet (diff > LONGHALF)
102 // http://forum.diyefi.org/viewtopic.php?f=8&t=57&p=861#p861
105 fresh code again, five states, 6 possible behaviours:
107 not enabled - sched!!! always
108 enabled and low, ready to turn on - if too close, do nothing, or if far enough away, resched
109 enabled and high, ready to turn off - if too close, resched to turn on, if far enough away, self sched
112 // Is it enabled and about to do *something*?
113 if(TIE
& injectorMainOnMasks
[pin
]){
114 // If configured to do something specific
115 if(*injectorMainControlRegisters
[pin
] & injectorMainActiveMasks
[pin
]){
116 // If that something is go high
117 if(*injectorMainControlRegisters
[pin
] & injectorMainGoHighMasks
[pin
]){
118 // GO HIGH SHOULD DO NOTHING CEPT COUNTER
119 // if too close, do nothing, or if far enough away, resched
120 // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
121 Counters
.pinScheduledAlready
++;
122 }else{ // Otherwise it's go low
123 // if too close, resched to turn, ie, stay on... , if far enough away, self sched
124 if(newStartIsAfterOutputEndTimeAndCanSelfSet
){
126 injectorMainStartOffsetHolding
[pin
] = startTime
- *injectorMainTimeRegisters
[pin
];
127 outputEventPulseWidthsHolding
[pin
] = outputEventPulseWidthsMath
[outputEventNumber
];
128 outputEventExtendNumberOfRepeatsHolding
[pin
] = outputEventExtendNumberOfRepeats
[outputEventNumber
];
129 outputEventExtendRepeatPeriodHolding
[pin
] = outputEventExtendRepeatPeriod
[outputEventNumber
];
130 outputEventDelayFinalPeriodHolding
[pin
] = outputEventDelayFinalPeriod
[outputEventNumber
];
131 selfSetTimer
|= injectorMainOnMasks
[pin
]; // setup a bit to let the timer interrupt know to set its own new start from a var
132 Counters
.pinScheduledToSelfSchedule
++;
134 SCHEDULE_ONE_ECT_OUTPUT();
135 Counters
.pinScheduledAgainToStayOn
++;
138 }else{ // Configured to do nothing, or toggle
139 if(*injectorMainControlRegisters
[pin
] & injectorMainGoHighMasks
[pin
]){
140 // TOGGLE SHOULD EARN SOME SORT OF ERROR CONDITION/COUNTER
141 Counters
.pinScheduledToToggleError
++;
143 // DO NOTHING SHOULD DO THE SAME AS GO HIGH
145 // if too close, do nothing, or if far enough away, resched
146 // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
147 Counters
.pinScheduledToDoNothing
++;
150 }else{ // not enabled, schedule as normal
151 SCHEDULE_ONE_ECT_OUTPUT();
152 Counters
.pinScheduledFromCold
++;
155 #ifdef XGATE // This has to be here because the timing of the ECT stuff is critical and it must run first.
156 #include "xgateScheduler.c"
157 #endif // Also, this should always run so can't be inside the above if/else block.