FreeEMS  0.2.0-SNAPSHOT-282-g9efc524
JSeries-12CrankWith6-2Cam.c
Go to the documentation of this file.
1 /* FreeEMS - the open source engine management system
2  *
3  * Copyright 2012-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 interruptHandlers
30  * @ingroup enginePositionRPMDecoders
31  *
32  * Decoder for the Honda J Series V6 engine, using one cam wheel and the crank wheel.
33  *
34  * @author Peter Johnson
35  */
36 
37 
38 #define DECODER_MAX_CODE_TIME 150
39 #define NUMBER_OF_REAL_EVENTS 24 // 12 Even Crank teeth
40 #define NUMBER_OF_VIRTUAL_EVENTS 24 // 24 Crank teeth in 720degrees
41 #define DECODER_IMPLEMENTATION_C
42 
43 #include "../inc/freeEMS.h"
44 #include "../inc/utils.h"
45 #include "../inc/interrupts.h"
46 #include "../inc/decoderInterface.h"
47 
48 unsigned char camTeethSeen = 0;
49 unsigned char previousCrankTeethSeen = 0;
50 unsigned char crankTeethSinceLastCamTooth = 0;
51 
52 const unsigned short eventAngles[] = {ANGLE( 0), ANGLE( 30), ANGLE( 60), ANGLE( 90),
53  ANGLE(120), ANGLE(150), ANGLE(180), ANGLE(210),
54  ANGLE(240), ANGLE(270), ANGLE(300), ANGLE(330),
55  ANGLE(360), ANGLE(390), ANGLE(420), ANGLE(450),
56  ANGLE(480), ANGLE(510), ANGLE(540), ANGLE(570),
57  ANGLE(600), ANGLE(630), ANGLE(660), ANGLE(690)};
58 const unsigned char eventValidForCrankSync[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
59 
61  // Set PT0 and PT1 to only capture on rising edges
62  TCTL4 = 0x05;
63 }
64 
66  camTeethSeen = 0;
69 }
70 
71 // Just count and check time stamps, sync is handled by the secondary ISR
73  /* Clear the interrupt flag for this input compare channel */
74  TFLG = 0x01;
76 
77  /* Save all relevant available data here */
78  unsigned short edgeTimeStamp = TC0; /* Save the edge time stamp */
79  unsigned char PTITCurrentState = PTIT; /* Save the values on port T regardless of the state of DDRT */
80 
81  // Prevent main from clearing values before sync is obtained!
83 
85 
87  /* Install the low word */
88  timeStamp.timeShorts[1] = edgeTimeStamp;
89  /* Find out what our timer value means and put it in the high word */
90  if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
91  timeStamp.timeShorts[0] = timerExtensionClock + 1;
92  }else{
93  timeStamp.timeShorts[0] = timerExtensionClock;
94  }
95  unsigned long thisEventTimeStamp = timeStamp.timeLong;
96 
97  unsigned short thisTicksPerDegree = 0;
99  unsigned long thisInterEventPeriod = thisEventTimeStamp - lastPrimaryEventTimeStamp;
100  thisTicksPerDegree = (unsigned short)((ticks_per_degree_multiplier * thisInterEventPeriod) / eventAngles[1]);
101  }
102 
104  if(KeyUserDebugs.currentEvent == 23){
106  }else{
108  }
111  return;
112  }// 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.
113 
115  unsigned short ratioBetweenThisAndLast = (unsigned short)(((unsigned long)lastPrimaryTicksPerDegree * 1000) / thisTicksPerDegree);
116  KeyUserDebugs.inputEventTimeTolerance = ratioBetweenThisAndLast;
119  return;
120  }else if(ratioBetweenThisAndLast < fixedConfigs2.decoderSettings.accelerationInputEventTimeTolerance){
122  return;
123  }else{
124  if(PTITCurrentState & 0x02){
125  // TODO Calculate RPM from last primaryLeadingEdgeTimeStamp
126  }else{
127  // TODO Calculate RPM from last primaryTrailingEdgeTimeStamp
128  }
129  }
130  }/*else*/ if(KeyUserDebugs.decoderFlags & LAST_TIMESTAMP_VALID){ // TODO temp for testing just do rpm this way, fill above out later.
131  *ticksPerDegreeRecord = thisTicksPerDegree;
134 
135  // Set flag to say calc required
137 
138  // Reset the clock for reading timeout
140  }
141 
142  SCHEDULE_ECT_OUTPUTS();
143  }
144 
145  OUTPUT_COARSE_BBS();
146 
147  // do these always at first, and use them with a single 30 degree angle for the first cut
149  lastPrimaryTicksPerDegree = thisTicksPerDegree;
151  }
152  // Always
153  lastPrimaryEventTimeStamp = thisEventTimeStamp;
155 
157 }
158 
159 // CAM sensor doesn't use time stamps due to timing belt tension vibration, plus the crank has 6 times more events, so any discrepancy would be caught that way
161  /* Clear the interrupt flag for this input compare channel */
162  TFLG = 0x02;
166  // check crankTeethSinceLastCamTooth to see if it's 4 or 12 and if not either of those, lose sync.
172  return;
173  }else{
175  return;
176  }
177  }
178  }
179 
181  if(camTeethSeen == 0){
182  camTeethSeen = 1;
184  }else if(camTeethSeen == 1){
185  camTeethSeen = 2;
188  if(crankTeethSinceLastCamTooth == 12){ // 12 Crank teeth in the 2 missing Cam teeth
191  }else if(crankTeethSinceLastCamTooth != 4){ // 4 Crank teeth in 1 Cam tooth
194  }else{
196  }
197  } // Else fall through and wait for a 12
198  }else if(camTeethSeen == 2){
199  camTeethSeen = 3;
202  if(crankTeethSinceLastCamTooth == 12){
205  }else if(crankTeethSinceLastCamTooth != 4){
208  }else{
210  }
211  } // Else fall through and wait for a 12
212  }else if(camTeethSeen == 3){
213  camTeethSeen = 4;
216  if(crankTeethSinceLastCamTooth == 12){
219  }else if(crankTeethSinceLastCamTooth != 4){
222  }else{
224  }
225  }else{
226  SET_SYNC_LEVEL_TO(CAM_SYNC); // Set the sync on the eventAngle[12] 360 degrees
228  }
229  }else if(camTeethSeen == 4){ // Guaranteed to have already synced
230  // If this crank teeth seen wasn't a valid number, it would have never made it here, having returned in the block near the top of the ISR
231  SET_SYNC_LEVEL_TO(CAM_SYNC); // Add sync confirmation point
232  }else{
234  }
235  }
237 }