Fix wrong edges in even teeth decoder and remove superfluous old logic. This includes...
[freeems-vanilla.git] / src / main / decoders / code / EvenTeeth-Xand1.c
blobf2bd1f5a3e4a0ef0764468c269e61f2411d5de5f
1 /* FreeEMS - the open source engine management system
3 * Copyright 2011-2013 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!
27 /** @file
29 * @ingroup interruptHandlers
30 * @ingroup enginePositionRPMDecoders
32 * @brief For evenly spaced teeth on the cam or crank with a single second input.
34 * Fill out a data reverse header and include this file. Sync is provided by the
35 * second input allowing a sequential and/or COP/CNP setup to be used.
37 * VR edition with only one edge used!
41 void decoderInitPreliminary(){
42 // Set PT0 and PT1 to only capture on rising
43 TCTL4 = 0x05; // 0000 0101 Capture rising edges only on PT0&1
46 void perDecoderReset(){} // Nothing special to reset for this code
49 void PrimaryRPMISR(){
50 /* Clear the interrupt flag for this input compare channel */
51 TFLG = 0x01;
52 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT0, PORTB);
54 /* Save all relevant available data here */
55 unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */
56 unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
58 // Prevent main from clearing values before sync is obtained!
59 Clocks.timeoutADCreadingClock = 0;
61 KeyUserDebugs.primaryTeethSeen++;
63 LongTime timeStamp;
64 /* Install the low word */
65 timeStamp.timeShorts[1] = edgeTimeStamp;
66 /* Find out what our timer value means and put it in the high word */
67 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
68 timeStamp.timeShorts[0] = timerExtensionClock + 1;
69 }else{
70 timeStamp.timeShorts[0] = timerExtensionClock;
72 unsigned long thisEventTimeStamp = timeStamp.timeLong;
74 unsigned long thisInterEventPeriod = 0;
75 unsigned short thisTicksPerDegree = 0;
76 if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){
77 thisInterEventPeriod = thisEventTimeStamp - lastPrimaryEventTimeStamp;
78 thisTicksPerDegree = (unsigned short)((ticks_per_degree_multiplier * thisInterEventPeriod) / eventAngles[1]); // with current scale range for 60/12000rpm is largest ticks per degree = 3472, smallest = 17 with largish error
81 if(KeyUserDebugs.decoderFlags & CONFIGURED_SYNC){
82 KeyUserDebugs.currentEvent++;
83 if(KeyUserDebugs.currentEvent == numberOfRealEvents){
84 resetToNonRunningState(COUNT_OF_EVENTS_IMPOSSIBLY_HIGH_NOISE);
85 return;
86 }// Can never be greater than without a code error or genuine noise issue, so give it a miss as we can not guarantee where we are now.
88 if(KeyUserDebugs.decoderFlags & LAST_PERIOD_VALID){
89 unsigned short ratioBetweenThisAndLast = (unsigned short)(((unsigned long)lastPrimaryTicksPerDegree * 1000) / thisTicksPerDegree);
90 KeyUserDebugs.inputEventTimeTolerance = ratioBetweenThisAndLast;
91 if(ratioBetweenThisAndLast > fixedConfigs2.decoderSettings.decelerationInputEventTimeTolerance){
92 resetToNonRunningState(PRIMARY_EVENT_ARRIVED_TOO_LATE);
93 return;
94 }else if(ratioBetweenThisAndLast < fixedConfigs2.decoderSettings.accelerationInputEventTimeTolerance){
95 resetToNonRunningState(PRIMARY_EVENT_ARRIVED_TOO_EARLY);
96 return;
97 }else{
98 if(PTITCurrentState & 0x01){
99 // TODO Calculate RPM from last primaryLeadingEdgeTimeStamp
100 }else{
101 // TODO Calculate RPM from last primaryTrailingEdgeTimeStamp
104 }/*else*/ if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){ // TODO temp for testing just do rpm this way, fill above out later.
105 *ticksPerDegreeRecord = thisTicksPerDegree;
106 sampleEachADC(ADCBuffers);
107 Counters.syncedADCreadings++;
109 // Set flag to say calc required
110 coreStatusA |= CALC_FUEL_IGN;
112 // Reset the clock for reading timeout
113 Clocks.timeoutADCreadingClock = 0;
116 // for now, sample always and see what we get result wise...
117 // if((currentEvent % 6) == 0){
118 // sampleEachADC(ADCBuffers);
119 // Counters.syncedADCreadings++;
121 // // Set flag to say calc required
122 // coreStatusA |= CALC_FUEL_IGN;
124 // // Reset the clock for reading timeout
125 // Clocks.timeoutADCreadingClock = 0;
126 // }
128 SCHEDULE_ECT_OUTPUTS();
131 OUTPUT_COARSE_BBS();
133 // do these always at first, and use them with a single 30 degree angle for the first cut
134 if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){
135 lastPrimaryTicksPerDegree = thisTicksPerDegree;
136 KeyUserDebugs.decoderFlags |= LAST_PERIOD_VALID;
138 // Always
139 lastPrimaryEventTimeStamp = thisEventTimeStamp;
140 KeyUserDebugs.decoderFlags |= LAST_TIMESTAMP_VALID;
142 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT0, PORTB);
146 void SecondaryRPMISR(){
147 /* Clear the interrupt flag for this input compare channel */
148 TFLG = 0x02;
149 DEBUG_TURN_PIN_ON(DECODER_BENCHMARKS, BIT1, PORTB);
151 /* Save all relevant available data here */
152 unsigned short edgeTimeStamp = TC1; /* Save the timestamp */
153 // unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
155 KeyUserDebugs.secondaryTeethSeen++;
157 LongTime timeStamp;
158 /* Install the low word */
159 timeStamp.timeShorts[1] = edgeTimeStamp;
160 /* Find out what our timer value means and put it in the high word */
161 if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
162 timeStamp.timeShorts[0] = timerExtensionClock + 1;
163 }else{
164 timeStamp.timeShorts[0] = timerExtensionClock;
166 unsigned long thisEventTimeStamp = timeStamp.timeLong;
168 unsigned long thisInterEventPeriod = 0;
169 if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){
170 thisInterEventPeriod = thisEventTimeStamp - lastSecondaryEventTimeStamp;
173 // This sets currentEvent to 255 such that when the primary ISR runs it is rolled over to zero!
174 if(KeyUserDebugs.decoderFlags & CONFIGURED_SYNC){
175 // If sync not confirmed, register sync point. Must be before the count checks, otherwise loss of sync would result in sync being redeclared.
176 if(!(KeyUserDebugs.decoderFlags & OK_TO_SCHEDULE)){
177 SET_SYNC_LEVEL_TO(CONFIGURED_SYNC);
180 /* If the count is less than 23, then we know that the electrical pulse that triggered
181 * this ISR execution was almost certainly in error and it is NOT valid to stay in sync.
183 * If the count is greater than 24, then we know that an electrical noise pulse triggered
184 * the other interrupt in between and was missed by the time period checks (unlikely, but
185 * possible) and that, therefore, there could have been a noise pulse on this input too,
186 * and therefore we don't really know where we are.
188 * In the case where the count is exactly 24 we can only rely on the time period checks in
189 * the other ISR, which should be sufficient unless poorly setup by a user with too wide
190 * of a tolerance level.
192 * There is zero point adding relative timing checks to this ISR because by nature, the
193 * other N teeth have already checked out good timing wise and therefore the average also
194 * does. Thus if we did check, for it to ever fail it would need to be tighter, and in
195 * reality it must be more loose due to the larger possible variation over the much much
196 * larger time frame.
198 if(KeyUserDebugs.currentEvent < (numberOfRealEvents - 1)){
199 resetToNonRunningState(COUNT_OF_EVENTS_IMPOSSIBLY_LOW_NOISE);
200 }else if(KeyUserDebugs.currentEvent > (numberOfRealEvents -1)){
201 resetToNonRunningState(COUNT_OF_EVENTS_IMPOSSIBLY_HIGH_NOISE);
202 } // ELSE do nothing, and be happy :-)
203 }else{ // If sync not found, register first sync point, as this is our reference point.
204 SET_SYNC_LEVEL_TO(CONFIGURED_SYNC);
207 KeyUserDebugs.currentEvent = 0xFF; // TODO reset always, and catch noise induced errors below, this behaviour (now some lines above) may be bad/not fussy enough, or could be good, depending upon determinate nature of the inter event timing between primary and secondary, or not, perhaps move "lose sync or correct sync" as a configuration variable
209 DEBUG_TURN_PIN_OFF(DECODER_BENCHMARKS, NBIT1, PORTB);