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.
50 void resetToNonRunningState(unsigned char uniqueLossID
){
51 KeyUserDebugs
.decoderSyncResetCalls
++;
53 /* Reset RPM to zero */
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
++;
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
);
76 // TODO more stuff needs resetting here, but only critical things.
80 /** Schedule an ignition output event on port T
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
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
){
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
++;
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
++;
144 // DO NOTHING SHOULD DO THE SAME AS GO HIGH
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
++;