1 /* FreeEMS - the open source engine management system
3 * Copyright 2011-2012 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!
30 * @ingroup interruptHandlers
31 * @ingroup enginePositionRPMDecoders
33 * @brief Missing teeth, M-N, with or without cam sync, configured externally
35 * This sets up the required arrays and defines such that the generic missing
36 * teeth decoder base can function in a specific way for the configured values.
38 * Choose one of these three options:
41 * - CRANK_WITH_CAM_SYNC
43 * @note The above setting will affect the init routine. CRANK_WITH_CAM_SYNC is
44 * not currently supported.
46 * Define both of these values appropriately:
50 * @note Please see the docs directory MissingTeethValidCombos.ods file first.
61 unsigned char pattern
;
65 #define DECODER_MAX_CODE_TIME 250 // From Spudmn's measurements in NZ. 171us runtime was max = 214 ticks.
67 #include "../../inc/freeEMS.h"
68 #include "../../inc/utils.h"
69 #include "../../inc/interrupts.h"
70 // See approximately 72 lines below for decoderInterface.h include
74 #error "Total number of teeth not defined!"
78 #error "Total number of teeth must be greater than 4!"
82 #error "Number of missing teeth not defined!"
85 #if (MISSING_TEETH < 1)
86 #error "Missing teeth must be greater than 0!"
89 #if ((MISSING_TEETH * 3) > TOTAL_TEETH)
90 #error "Too many missing teeth! (or not enough total teeth!)"
94 #define NUMBER_OF_WHEEL_EVENTS (TOTAL_TEETH - MISSING_TEETH)
97 #if (NUMBER_OF_WHEEL_EVENTS > 64)
98 #error "Real events over 64 are currently not supported by this decoder style!"
102 #if ((defined(CRANK_ONLY) && defined(CAM_ONLY)) || (defined(CRANK_ONLY) && defined(CRANK_WITH_CAM_SYNC)) || (defined(CRANK_WITH_CAM_SYNC) && defined(CAM_ONLY)))
103 #error "Can not be cam and crank, choose one!"
107 #if defined(CRANK_ONLY)
108 #define NUMBER_OF_REAL_EVENTS NUMBER_OF_WHEEL_EVENTS
109 #define NUMBER_OF_VIRTUAL_EVENTS (2 * NUMBER_OF_REAL_EVENTS)
110 #define ANGLE_BETWEEN_EVENTS ((ANGLE_FACTOR * 360.0) / TOTAL_TEETH)
111 #define angleOfSingleIteration (360 * ANGLE_FACTOR)
112 #elif defined(CAM_ONLY)
113 #define NUMBER_OF_REAL_EVENTS NUMBER_OF_WHEEL_EVENTS
114 #define NUMBER_OF_VIRTUAL_EVENTS NUMBER_OF_REAL_EVENTS
115 #define ANGLE_BETWEEN_EVENTS ((ANGLE_FACTOR * 720.0) / TOTAL_TEETH)
116 #define angleOfSingleIteration (720 * ANGLE_FACTOR)
117 #elif defined(CRANK_WITH_CAM_SYNC)
118 #define NUMBER_OF_REAL_EVENTS (2 * NUMBER_OF_WHEEL_EVENTS)
119 #define NUMBER_OF_VIRTUAL_EVENTS NUMBER_OF_REAL_EVENTS
120 #define ANGLE_BETWEEN_EVENTS ((ANGLE_FACTOR * 360.0) / TOTAL_TEETH)
121 #define angleOfSingleIteration (720 * ANGLE_FACTOR)
122 #error "Not yet supported!" // And maybe done a different way, we'll see...
124 #error "You MUST configure the style of this decoder!"
128 #include "../../inc/decoderInterface.h"
131 // For cam events, this is all that is used, for crank, this is the first half.
133 #define E1 ANGLE_BETWEEN_EVENTS
134 #define E2 ( E1 + ANGLE_BETWEEN_EVENTS)
135 #define E3 ( E2 + ANGLE_BETWEEN_EVENTS)
136 #define E4 ( E3 + ANGLE_BETWEEN_EVENTS)
137 #define E5 ( E4 + ANGLE_BETWEEN_EVENTS)
138 #define E6 ( E5 + ANGLE_BETWEEN_EVENTS)
139 #define E7 ( E6 + ANGLE_BETWEEN_EVENTS)
140 #define E8 ( E7 + ANGLE_BETWEEN_EVENTS)
141 #define E9 ( E8 + ANGLE_BETWEEN_EVENTS)
142 #define E10 ( E9 + ANGLE_BETWEEN_EVENTS)
143 #define E11 ( E10 + ANGLE_BETWEEN_EVENTS)
144 #define E12 ( E11 + ANGLE_BETWEEN_EVENTS)
145 #define E13 ( E12 + ANGLE_BETWEEN_EVENTS)
146 #define E14 ( E13 + ANGLE_BETWEEN_EVENTS)
147 #define E15 ( E14 + ANGLE_BETWEEN_EVENTS)
148 #define E16 ( E15 + ANGLE_BETWEEN_EVENTS)
149 #define E17 ( E16 + ANGLE_BETWEEN_EVENTS)
150 #define E18 ( E17 + ANGLE_BETWEEN_EVENTS)
151 #define E19 ( E18 + ANGLE_BETWEEN_EVENTS)
152 #define E20 ( E19 + ANGLE_BETWEEN_EVENTS)
153 #define E21 ( E20 + ANGLE_BETWEEN_EVENTS)
154 #define E22 ( E21 + ANGLE_BETWEEN_EVENTS)
155 #define E23 ( E22 + ANGLE_BETWEEN_EVENTS)
156 #define E24 ( E23 + ANGLE_BETWEEN_EVENTS)
157 #define E25 ( E24 + ANGLE_BETWEEN_EVENTS)
158 #define E26 ( E25 + ANGLE_BETWEEN_EVENTS)
159 #define E27 ( E26 + ANGLE_BETWEEN_EVENTS)
160 #define E28 ( E27 + ANGLE_BETWEEN_EVENTS)
161 #define E29 ( E28 + ANGLE_BETWEEN_EVENTS)
162 #define E30 ( E29 + ANGLE_BETWEEN_EVENTS)
163 #define E31 ( E30 + ANGLE_BETWEEN_EVENTS)
164 #define E32 ( E31 + ANGLE_BETWEEN_EVENTS)
165 #define E33 ( E32 + ANGLE_BETWEEN_EVENTS)
166 #define E34 ( E33 + ANGLE_BETWEEN_EVENTS)
167 #define E35 ( E34 + ANGLE_BETWEEN_EVENTS)
168 #define E36 ( E35 + ANGLE_BETWEEN_EVENTS)
169 #define E37 ( E36 + ANGLE_BETWEEN_EVENTS)
170 #define E38 ( E37 + ANGLE_BETWEEN_EVENTS)
171 #define E39 ( E38 + ANGLE_BETWEEN_EVENTS)
172 #define E40 ( E39 + ANGLE_BETWEEN_EVENTS)
173 #define E41 ( E40 + ANGLE_BETWEEN_EVENTS)
174 #define E42 ( E41 + ANGLE_BETWEEN_EVENTS)
175 #define E43 ( E42 + ANGLE_BETWEEN_EVENTS)
176 #define E44 ( E43 + ANGLE_BETWEEN_EVENTS)
177 #define E45 ( E44 + ANGLE_BETWEEN_EVENTS)
178 #define E46 ( E45 + ANGLE_BETWEEN_EVENTS)
179 #define E47 ( E46 + ANGLE_BETWEEN_EVENTS)
180 #define E48 ( E47 + ANGLE_BETWEEN_EVENTS)
181 #define E49 ( E48 + ANGLE_BETWEEN_EVENTS)
182 #define E50 ( E49 + ANGLE_BETWEEN_EVENTS)
183 #define E51 ( E50 + ANGLE_BETWEEN_EVENTS)
184 #define E52 ( E51 + ANGLE_BETWEEN_EVENTS)
185 #define E53 ( E52 + ANGLE_BETWEEN_EVENTS)
186 #define E54 ( E53 + ANGLE_BETWEEN_EVENTS)
187 #define E55 ( E54 + ANGLE_BETWEEN_EVENTS)
188 #define E56 ( E55 + ANGLE_BETWEEN_EVENTS)
189 #define E57 ( E56 + ANGLE_BETWEEN_EVENTS)
190 #define E58 ( E57 + ANGLE_BETWEEN_EVENTS)
191 #define E59 ( E58 + ANGLE_BETWEEN_EVENTS)
192 #define E60 ( E59 + ANGLE_BETWEEN_EVENTS)
193 #define E61 ( E60 + ANGLE_BETWEEN_EVENTS)
194 #define E62 ( E61 + ANGLE_BETWEEN_EVENTS)
195 #define E63 ( E62 + ANGLE_BETWEEN_EVENTS)
198 // For crank speed wheels we need a second set of events offset 360 degrees from the first set. With a cam sync, they are real, without, only virtual.
199 #define E0_2 ((ANGLE_FACTOR * 360.0) + E0)
200 #define E1_2 ((ANGLE_FACTOR * 360.0) + E1)
201 #define E2_2 ((ANGLE_FACTOR * 360.0) + E2)
202 #define E3_2 ((ANGLE_FACTOR * 360.0) + E3)
203 #define E4_2 ((ANGLE_FACTOR * 360.0) + E4)
204 #define E5_2 ((ANGLE_FACTOR * 360.0) + E5)
205 #define E6_2 ((ANGLE_FACTOR * 360.0) + E6)
206 #define E7_2 ((ANGLE_FACTOR * 360.0) + E7)
207 #define E8_2 ((ANGLE_FACTOR * 360.0) + E8)
208 #define E9_2 ((ANGLE_FACTOR * 360.0) + E9)
209 #define E10_2 ((ANGLE_FACTOR * 360.0) + E10)
210 #define E11_2 ((ANGLE_FACTOR * 360.0) + E11)
211 #define E12_2 ((ANGLE_FACTOR * 360.0) + E12)
212 #define E13_2 ((ANGLE_FACTOR * 360.0) + E13)
213 #define E14_2 ((ANGLE_FACTOR * 360.0) + E14)
214 #define E15_2 ((ANGLE_FACTOR * 360.0) + E15)
215 #define E16_2 ((ANGLE_FACTOR * 360.0) + E16)
216 #define E17_2 ((ANGLE_FACTOR * 360.0) + E17)
217 #define E18_2 ((ANGLE_FACTOR * 360.0) + E18)
218 #define E19_2 ((ANGLE_FACTOR * 360.0) + E19)
219 #define E20_2 ((ANGLE_FACTOR * 360.0) + E20)
220 #define E21_2 ((ANGLE_FACTOR * 360.0) + E21)
221 #define E22_2 ((ANGLE_FACTOR * 360.0) + E22)
222 #define E23_2 ((ANGLE_FACTOR * 360.0) + E23)
223 #define E24_2 ((ANGLE_FACTOR * 360.0) + E24)
224 #define E25_2 ((ANGLE_FACTOR * 360.0) + E25)
225 #define E26_2 ((ANGLE_FACTOR * 360.0) + E26)
226 #define E27_2 ((ANGLE_FACTOR * 360.0) + E27)
227 #define E28_2 ((ANGLE_FACTOR * 360.0) + E28)
228 #define E29_2 ((ANGLE_FACTOR * 360.0) + E29)
229 #define E30_2 ((ANGLE_FACTOR * 360.0) + E30)
230 #define E31_2 ((ANGLE_FACTOR * 360.0) + E31)
231 #define E32_2 ((ANGLE_FACTOR * 360.0) + E32)
232 #define E33_2 ((ANGLE_FACTOR * 360.0) + E33)
233 #define E34_2 ((ANGLE_FACTOR * 360.0) + E34)
234 #define E35_2 ((ANGLE_FACTOR * 360.0) + E35)
235 #define E36_2 ((ANGLE_FACTOR * 360.0) + E36)
236 #define E37_2 ((ANGLE_FACTOR * 360.0) + E37)
237 #define E38_2 ((ANGLE_FACTOR * 360.0) + E38)
238 #define E39_2 ((ANGLE_FACTOR * 360.0) + E39)
239 #define E40_2 ((ANGLE_FACTOR * 360.0) + E40)
240 #define E41_2 ((ANGLE_FACTOR * 360.0) + E41)
241 #define E42_2 ((ANGLE_FACTOR * 360.0) + E42)
242 #define E43_2 ((ANGLE_FACTOR * 360.0) + E43)
243 #define E44_2 ((ANGLE_FACTOR * 360.0) + E44)
244 #define E45_2 ((ANGLE_FACTOR * 360.0) + E45)
245 #define E46_2 ((ANGLE_FACTOR * 360.0) + E46)
246 #define E47_2 ((ANGLE_FACTOR * 360.0) + E47)
247 #define E48_2 ((ANGLE_FACTOR * 360.0) + E48)
248 #define E49_2 ((ANGLE_FACTOR * 360.0) + E49)
249 #define E50_2 ((ANGLE_FACTOR * 360.0) + E50)
250 #define E51_2 ((ANGLE_FACTOR * 360.0) + E51)
251 #define E52_2 ((ANGLE_FACTOR * 360.0) + E52)
252 #define E53_2 ((ANGLE_FACTOR * 360.0) + E53)
253 #define E54_2 ((ANGLE_FACTOR * 360.0) + E54)
254 #define E55_2 ((ANGLE_FACTOR * 360.0) + E55)
255 #define E56_2 ((ANGLE_FACTOR * 360.0) + E56)
256 #define E57_2 ((ANGLE_FACTOR * 360.0) + E57)
257 #define E58_2 ((ANGLE_FACTOR * 360.0) + E58)
258 #define E59_2 ((ANGLE_FACTOR * 360.0) + E59)
259 #define E60_2 ((ANGLE_FACTOR * 360.0) + E60)
260 #define E61_2 ((ANGLE_FACTOR * 360.0) + E61)
261 #define E62_2 ((ANGLE_FACTOR * 360.0) + E62)
262 #define E63_2 ((ANGLE_FACTOR * 360.0) + E63)
265 const unsigned short eventAngles
[] = {
266 E0
// Always this event...
268 #if (NUMBER_OF_WHEEL_EVENTS > 1)
270 #if (NUMBER_OF_WHEEL_EVENTS > 2)
272 #if (NUMBER_OF_WHEEL_EVENTS > 3)
274 #if (NUMBER_OF_WHEEL_EVENTS > 4)
276 #if (NUMBER_OF_WHEEL_EVENTS > 5)
278 #if (NUMBER_OF_WHEEL_EVENTS > 6)
280 #if (NUMBER_OF_WHEEL_EVENTS > 7)
282 #if (NUMBER_OF_WHEEL_EVENTS > 8)
284 #if (NUMBER_OF_WHEEL_EVENTS > 9)
286 #if (NUMBER_OF_WHEEL_EVENTS > 10)
288 #if (NUMBER_OF_WHEEL_EVENTS > 11)
290 #if (NUMBER_OF_WHEEL_EVENTS > 12)
292 #if (NUMBER_OF_WHEEL_EVENTS > 13)
294 #if (NUMBER_OF_WHEEL_EVENTS > 14)
296 #if (NUMBER_OF_WHEEL_EVENTS > 15)
298 #if (NUMBER_OF_WHEEL_EVENTS > 16)
300 #if (NUMBER_OF_WHEEL_EVENTS > 17)
302 #if (NUMBER_OF_WHEEL_EVENTS > 18)
304 #if (NUMBER_OF_WHEEL_EVENTS > 19)
306 #if (NUMBER_OF_WHEEL_EVENTS > 20)
308 #if (NUMBER_OF_WHEEL_EVENTS > 21)
310 #if (NUMBER_OF_WHEEL_EVENTS > 22)
312 #if (NUMBER_OF_WHEEL_EVENTS > 23)
314 #if (NUMBER_OF_WHEEL_EVENTS > 24)
316 #if (NUMBER_OF_WHEEL_EVENTS > 25)
318 #if (NUMBER_OF_WHEEL_EVENTS > 26)
320 #if (NUMBER_OF_WHEEL_EVENTS > 27)
322 #if (NUMBER_OF_WHEEL_EVENTS > 28)
324 #if (NUMBER_OF_WHEEL_EVENTS > 29)
326 #if (NUMBER_OF_WHEEL_EVENTS > 30)
328 #if (NUMBER_OF_WHEEL_EVENTS > 31)
330 #if (NUMBER_OF_WHEEL_EVENTS > 32)
332 #if (NUMBER_OF_WHEEL_EVENTS > 33)
334 #if (NUMBER_OF_WHEEL_EVENTS > 34)
336 #if (NUMBER_OF_WHEEL_EVENTS > 35)
338 #if (NUMBER_OF_WHEEL_EVENTS > 36)
340 #if (NUMBER_OF_WHEEL_EVENTS > 37)
342 #if (NUMBER_OF_WHEEL_EVENTS > 38)
344 #if (NUMBER_OF_WHEEL_EVENTS > 39)
346 #if (NUMBER_OF_WHEEL_EVENTS > 40)
348 #if (NUMBER_OF_WHEEL_EVENTS > 41)
350 #if (NUMBER_OF_WHEEL_EVENTS > 42)
352 #if (NUMBER_OF_WHEEL_EVENTS > 43)
354 #if (NUMBER_OF_WHEEL_EVENTS > 44)
356 #if (NUMBER_OF_WHEEL_EVENTS > 45)
358 #if (NUMBER_OF_WHEEL_EVENTS > 46)
360 #if (NUMBER_OF_WHEEL_EVENTS > 47)
362 #if (NUMBER_OF_WHEEL_EVENTS > 48)
364 #if (NUMBER_OF_WHEEL_EVENTS > 49)
366 #if (NUMBER_OF_WHEEL_EVENTS > 50)
368 #if (NUMBER_OF_WHEEL_EVENTS > 51)
370 #if (NUMBER_OF_WHEEL_EVENTS > 52)
372 #if (NUMBER_OF_WHEEL_EVENTS > 53)
374 #if (NUMBER_OF_WHEEL_EVENTS > 54)
376 #if (NUMBER_OF_WHEEL_EVENTS > 55)
378 #if (NUMBER_OF_WHEEL_EVENTS > 56)
380 #if (NUMBER_OF_WHEEL_EVENTS > 57)
382 #if (NUMBER_OF_WHEEL_EVENTS > 58)
384 #if (NUMBER_OF_WHEEL_EVENTS > 59)
386 #if (NUMBER_OF_WHEEL_EVENTS > 60)
388 #if (NUMBER_OF_WHEEL_EVENTS > 61)
390 #if (NUMBER_OF_WHEEL_EVENTS > 62)
392 #if (NUMBER_OF_WHEEL_EVENTS > 63)
459 // If the missing tooth wheel is on the camshaft, it represents a full 720
460 // degree cycle and duplicating the events with 360 offset is not necessary.
463 // The following ifs are not strictly necessary as the array is only read up to
464 // where it should be read, and the balance, which would otherwise be random
465 // values in flash, are ignored. However it is consistent.
466 #if (NUMBER_OF_WHEEL_EVENTS > 1)
468 #if (NUMBER_OF_WHEEL_EVENTS > 2)
470 #if (NUMBER_OF_WHEEL_EVENTS > 3)
472 #if (NUMBER_OF_WHEEL_EVENTS > 4)
474 #if (NUMBER_OF_WHEEL_EVENTS > 5)
476 #if (NUMBER_OF_WHEEL_EVENTS > 6)
478 #if (NUMBER_OF_WHEEL_EVENTS > 7)
480 #if (NUMBER_OF_WHEEL_EVENTS > 8)
482 #if (NUMBER_OF_WHEEL_EVENTS > 9)
484 #if (NUMBER_OF_WHEEL_EVENTS > 10)
486 #if (NUMBER_OF_WHEEL_EVENTS > 11)
488 #if (NUMBER_OF_WHEEL_EVENTS > 12)
490 #if (NUMBER_OF_WHEEL_EVENTS > 13)
492 #if (NUMBER_OF_WHEEL_EVENTS > 14)
494 #if (NUMBER_OF_WHEEL_EVENTS > 15)
496 #if (NUMBER_OF_WHEEL_EVENTS > 16)
498 #if (NUMBER_OF_WHEEL_EVENTS > 17)
500 #if (NUMBER_OF_WHEEL_EVENTS > 18)
502 #if (NUMBER_OF_WHEEL_EVENTS > 19)
504 #if (NUMBER_OF_WHEEL_EVENTS > 20)
506 #if (NUMBER_OF_WHEEL_EVENTS > 21)
508 #if (NUMBER_OF_WHEEL_EVENTS > 22)
510 #if (NUMBER_OF_WHEEL_EVENTS > 23)
512 #if (NUMBER_OF_WHEEL_EVENTS > 24)
514 #if (NUMBER_OF_WHEEL_EVENTS > 25)
516 #if (NUMBER_OF_WHEEL_EVENTS > 26)
518 #if (NUMBER_OF_WHEEL_EVENTS > 27)
520 #if (NUMBER_OF_WHEEL_EVENTS > 28)
522 #if (NUMBER_OF_WHEEL_EVENTS > 29)
524 #if (NUMBER_OF_WHEEL_EVENTS > 30)
526 #if (NUMBER_OF_WHEEL_EVENTS > 31)
528 #if (NUMBER_OF_WHEEL_EVENTS > 32)
530 #if (NUMBER_OF_WHEEL_EVENTS > 33)
532 #if (NUMBER_OF_WHEEL_EVENTS > 34)
534 #if (NUMBER_OF_WHEEL_EVENTS > 35)
536 #if (NUMBER_OF_WHEEL_EVENTS > 36)
538 #if (NUMBER_OF_WHEEL_EVENTS > 37)
540 #if (NUMBER_OF_WHEEL_EVENTS > 38)
542 #if (NUMBER_OF_WHEEL_EVENTS > 39)
544 #if (NUMBER_OF_WHEEL_EVENTS > 40)
546 #if (NUMBER_OF_WHEEL_EVENTS > 41)
548 #if (NUMBER_OF_WHEEL_EVENTS > 42)
550 #if (NUMBER_OF_WHEEL_EVENTS > 43)
552 #if (NUMBER_OF_WHEEL_EVENTS > 44)
554 #if (NUMBER_OF_WHEEL_EVENTS > 45)
556 #if (NUMBER_OF_WHEEL_EVENTS > 46)
558 #if (NUMBER_OF_WHEEL_EVENTS > 47)
560 #if (NUMBER_OF_WHEEL_EVENTS > 48)
562 #if (NUMBER_OF_WHEEL_EVENTS > 49)
564 #if (NUMBER_OF_WHEEL_EVENTS > 50)
566 #if (NUMBER_OF_WHEEL_EVENTS > 51)
568 #if (NUMBER_OF_WHEEL_EVENTS > 52)
570 #if (NUMBER_OF_WHEEL_EVENTS > 53)
572 #if (NUMBER_OF_WHEEL_EVENTS > 54)
574 #if (NUMBER_OF_WHEEL_EVENTS > 55)
576 #if (NUMBER_OF_WHEEL_EVENTS > 56)
578 #if (NUMBER_OF_WHEEL_EVENTS > 57)
580 #if (NUMBER_OF_WHEEL_EVENTS > 58)
582 #if (NUMBER_OF_WHEEL_EVENTS > 59)
584 #if (NUMBER_OF_WHEEL_EVENTS > 60)
586 #if (NUMBER_OF_WHEEL_EVENTS > 61)
588 #if (NUMBER_OF_WHEEL_EVENTS > 62)
590 #if (NUMBER_OF_WHEEL_EVENTS > 63)
660 /// @todo TODO build this with similar hash if logic: need to reconsider how to use this or whether to even have it. A "corresponding event" table might be good instead, kinda like the mapping above, but from real to real, only when the angles are exactly 360 out.
661 const unsigned char eventValidForCrankSync
[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; // this is only correct while doing pure crank sync, wrong once doing more, i think, TBC...