Re-work logging extensively system wide, MUCH better. This will break MTX and OLV...
[freeems-vanilla.git] / src / decoderInterface.c
blob0f7e2a2f538ac542491880d74727609e09b581db
1 /* FreeEMS - the open source engine management system
3 * Copyright 2011 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!
26 /** @file decoderInterface.c
28 * @ingroup enginePositionRPMDecoders
30 * @brief shared functions used by all decoders
32 * To maximise code reuse and minimise bugs it is strongly recommended that you
33 * use these pre-canned functions to do work required in your decoder.
36 #define DECODER_INTERFACE_C
37 #include "inc/freeEMS.h"
38 #include "inc/decoderInterface.h"
41 /** @brief Reset key state
43 * Reset all important variables to their non-running state.
45 * @todo TODO bring this up to date and/or find a better way to do it.
47 * @param uniqueLossID 0 is reserved for system use, within your decoder never use the same value twice.
48 * @author Fred Cooke
50 void resetToNonRunningState(unsigned char uniqueLossID){
51 KeyUserDebugs.decoderSyncResetCalls++;
53 /* Reset RPM to zero */
54 ticksPerDegree0 = 0;
55 ticksPerDegree1 = 0;
57 /* Ensure tacho reads lowest possible value */
58 engineCyclePeriod = ticksPerCycleAtOneRPM;
60 // Keep track of lost sync in counters
61 if(KeyUserDebugs.decoderFlags & (CAM_SYNC | CRANK_SYNC | COMBUSTION_SYNC)){
62 Counters.decoderSyncLosses++;
63 }else{
64 Counters.decoderSyncStateClears++;
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 &= (CLEAR_CAM_SYNC & CLEAR_CRANK_SYNC & CLEAR_COMBUSTION_SYNC & CLEAR_LAST_PERIOD_VALID & CLEAR_LAST_TIMESTAMP_VALID);
75 perDecoderReset();
76 // TODO more stuff needs resetting here, but only critical things.
80 /** Schedule an ignition output event on port T
82 * @author Fred Cooke
83 * @warning If you do not handle the skipEventFlags then excess advance may occur!
85 void schedulePortTPin(unsigned char outputEventNumber, LongTime timeStamp){
86 unsigned char pin = outputEventPinNumbers[outputEventNumber];
87 unsigned short postReferenceEventDelay = 0;
88 if(skipEventFlags & (1UL << outputEventNumber)){
89 postReferenceEventDelay = decoderMaxCodeTime;
90 skipEventFlags &= ~(1UL << outputEventNumber); // Clear the flag
91 }else{
92 postReferenceEventDelay = postReferenceEventDelays[outputEventNumber];
94 // determine the long and short start times
95 unsigned short startTime = timeStamp.timeShorts[1] + postReferenceEventDelay;
96 // remove this temporarily too, no need for it without the later conditional code
97 unsigned long startTimeLong = timeStamp.timeLong + postReferenceEventDelay;
99 /// @todo TODO Make this more understandable as right now it is difficult to grok.
100 // determine whether or not to reschedule or self schedule assuming pin is currently scheduled
101 unsigned long diff = (injectorMainEndTimes[pin] + injectorSwitchOffCodeTime) - startTimeLong;
102 #define newStartIsAfterOutputEndTimeAndCanSelfSet (diff > LONGHALF)
103 // http://forum.diyefi.org/viewtopic.php?f=8&t=57&p=861#p861
106 fresh code again, five states, 6 possible behaviours:
108 not enabled - sched!!! always
109 enabled and low, ready to turn on - if too close, do nothing, or if far enough away, resched
110 enabled and high, ready to turn off - if too close, resched to turn on, if far enough away, self sched
113 // Is it enabled and about to do *something*?
114 if(TIE & injectorMainOnMasks[pin]){
115 // If configured to do something specific
116 if(*injectorMainControlRegisters[pin] & injectorMainActiveMasks[pin]){
117 // If that something is go high
118 if(*injectorMainControlRegisters[pin] & injectorMainGoHighMasks[pin]){
119 // GO HIGH SHOULD DO NOTHING CEPT COUNTER
120 // if too close, do nothing, or if far enough away, resched
121 // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
122 Counters.pinScheduledAlready++;
123 }else{ // Otherwise it's go low
124 // if too close, resched to turn, ie, stay on... , if far enough away, self sched
125 if(newStartIsAfterOutputEndTimeAndCanSelfSet){
126 // self sched
127 injectorMainStartOffsetHolding[pin] = startTime - *injectorMainTimeRegisters[pin];
128 injectorMainPulseWidthsHolding[pin] = injectorMainPulseWidthsMath[outputEventNumber];
129 outputEventExtendNumberOfRepeatsHolding[pin] = outputEventExtendNumberOfRepeats[outputEventNumber];
130 outputEventExtendRepeatPeriodHolding[pin] = outputEventExtendRepeatPeriod[outputEventNumber];
131 outputEventExtendFinalPeriodHolding[pin] = outputEventExtendFinalPeriod[outputEventNumber];
132 selfSetTimer |= injectorMainOnMasks[pin]; // setup a bit to let the timer interrupt know to set its own new start from a var
133 Counters.pinScheduledToSelfSchedule++;
134 }else{
135 SCHEDULE_ONE_ECT_OUTPUT();
136 Counters.pinScheduledAgainToStayOn++;
139 }else{ // Configured to do nothing, or toggle
140 if(*injectorMainControlRegisters[pin] & injectorMainGoHighMasks[pin]){
141 // TOGGLE SHOULD EARN SOME SORT OF ERROR CONDITION/COUNTER
142 Counters.pinScheduledToToggleError++;
143 }else{
144 // DO NOTHING SHOULD DO THE SAME AS GO HIGH
145 // ie, do nothing
146 // if too close, do nothing, or if far enough away, resched
147 // for now just always do nothing as it's going to fire, and whatever configured got it close enough...
148 Counters.pinScheduledToDoNothing++;
151 }else{ // not enabled, schedule as normal
152 SCHEDULE_ONE_ECT_OUTPUT();
153 Counters.pinScheduledFromCold++;