FreeEMS
0.2.0-SNAPSHOT-282-g9efc524
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
src
main
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.
44
void
descheduleAll
(){
45
unsigned
char
i;
46
for
(i = 0; i <
MAX_NUMBER_OF_OUTPUT_EVENTS
; i++){
47
outputEventInputEventNumbers
[i] = 0xFF;
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){
62
KeyUserDebugs
.
syncResetCalls
++;
63
}
64
65
// Reset the safe re-sync counters.
66
if
(
fixedConfigs2
.
decoderSettings
.
syncConfirmationsRunning
== 0xFF){
// Prevent overflow to zero
67
syncConfirmationsRunningCounter
= 0xFF;
68
}
else
{
// Ensure at least 1 cycle is confirmed
69
syncConfirmationsRunningCounter
=
fixedConfigs2
.
decoderSettings
.
syncConfirmationsRunning
+ 1;
70
}
71
syncConfirmationsStartingCounter
=
fixedConfigs2
.
decoderSettings
.
syncConfirmationsStarting
;
72
73
/* Reset RPM to zero */
74
ticksPerDegree0
= 0;
75
ticksPerDegree1
= 0;
76
77
// Keep track of lost sync in counters
78
if
(
KeyUserDebugs
.
decoderFlags
& (
CAM_SYNC
|
CRANK_SYNC
|
COMBUSTION_SYNC
)){
79
if
(
KeyUserDebugs
.
decoderFlags
&
OK_TO_SCHEDULE
){
80
FLAG_AND_INC_FLAGGABLE
(
FLAG_DECODER_SYNC_LOSSES_OFFSET
);
81
}
else
{
82
FLAG_AND_INC_FLAGGABLE
(
FLAG_DECODER_SYNCS_NOT_CONFIRMED_OFFSET
);
83
}
84
}
else
{
85
FLAG_AND_INC_FLAGGABLE
(
FLAG_DECODER_SYNC_STATE_CLEARS_OFFSET
);
86
}
87
88
// record unique loss ID
89
KeyUserDebugs
.
syncLostWithThisID
= uniqueLossID;
90
91
// record current event and then clear it
92
KeyUserDebugs
.
syncLostOnThisEvent
=
KeyUserDebugs
.
currentEvent
;
93
KeyUserDebugs
.
currentEvent
= 0;
94
95
/* Clear all sync flags to lost state */
96
KeyUserDebugs
.
decoderFlags
= 0;
// Nothing should use this except for us anyway!
97
perDecoderReset
();
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
139
if
(*
ectMainControlRegisters
[pin] &
ectMainActiveMasks
[pin]){
140
// If that something is go high
141
if
(*
ectMainControlRegisters
[pin] &
ectMainGoHighMasks
[pin]){
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...
145
Counters
.
pinScheduledAlready
++;
146
}
else
{
// Otherwise it's go low
147
// if too close, resched to turn, ie, stay on... , if far enough away, self sched
148
if
(
newStartIsAfterOutputEndTimeAndCanSelfSet
){
149
// self sched
150
ectMainStartOffsetHolding
[pin] = startTime - *
ectMainTimeRegisters
[pin];
151
outputEventPulseWidthsHolding
[pin] =
outputEventPulseWidthsMath
[outputEventNumber];
152
outputEventExtendNumberOfRepeatsHolding
[pin] =
outputEventExtendNumberOfRepeats
[outputEventNumber];
153
outputEventExtendRepeatPeriodHolding
[pin] =
outputEventExtendRepeatPeriod
[outputEventNumber];
154
outputEventDelayFinalPeriodHolding
[pin] =
outputEventDelayFinalPeriod
[outputEventNumber];
155
selfSetTimer
|=
ectMainOnMasks
[pin];
// setup a bit to let the timer interrupt know to set its own new start from a var
156
Counters
.
pinScheduledToSelfSchedule
++;
157
}
else
{
158
SCHEDULE_ONE_ECT_OUTPUT
();
159
Counters
.
pinScheduledAgainToStayOn
++;
160
}
161
}
162
}
else
{
// Configured to do nothing, or toggle
163
if
(*
ectMainControlRegisters
[pin] &
ectMainGoHighMasks
[pin]){
164
// TOGGLE SHOULD EARN SOME SORT OF ERROR CONDITION/COUNTER
165
Counters
.
pinScheduledToToggleError
++;
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...
171
Counters
.
pinScheduledToDoNothing
++;
172
}
173
}
174
}
else
{
// not enabled, schedule as normal
175
SCHEDULE_ONE_ECT_OUTPUT
();
176
Counters
.
pinScheduledFromCold
++;
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
}
Generated on Fri May 22 2015 10:24:04 for FreeEMS by
1.8.1.2