FreeEMS  0.2.0-SNAPSHOT-285-g028e24c
BenchTest.c
Go to the documentation of this file.
1 /* FreeEMS - the open source engine management system
2  *
3  * Copyright 2011-2012 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  * To facilitate testing of output circuits and physical hardware such as
32  * injectors and coils on the bench or in the car.
33  *
34  * This "decoder" is intended to generate an output pattern that allows various
35  * testing to occur without any external stimulus. This is useful for scheduler
36  * testing, injector testing, output hardware testing, coil testing, etc. This
37  * will be the only decoder that will be usable with just a cpu and comms interface.
38  *
39  * @todo TODO setup the timer registers as required.
40  */
41 
42 
43 #define DECODER_IMPLEMENTATION_C
44 #define DECODER_MAX_CODE_TIME 66 // TODO measure reality
45 #define NUMBER_OF_REAL_EVENTS 1 // no events really...
46 #define NUMBER_OF_VIRTUAL_EVENTS 1 // no events really...
47 
48 
49 #include "../inc/freeEMS.h"
50 #include "../inc/interrupts.h"
51 #include "../inc/decoderInterface.h"
52 #include "inc/BenchTest.h"
53 
54 
55 // Setup the timer interrupts as internal timers only triggered by a serial call that returns if this isn't the decoder.
57  // Configure 0 and 1 as outputs, but decouple them from the interrupts
58  TIOS = 0xFF; // All outputs
59 
60  // Disable capture when in IC mode.
61  TCTL4 = 0x00; // TODO Unrequired, remove.
62 
63  // Leave configured to not toggle the pin at all (0,0)
64  // Std behaviour, no change required
65 
66  // Disable interrupts, to be enabled by a serial trigger
67  TIE = 0x00;
68 }
69 
70 
71 void perDecoderReset(){} // Nothing special to reset for this code
72 
73 
74 const unsigned short eventAngles[] = {0}; // no events really...
75 const unsigned char eventValidForCrankSync[] = {0}; // no events really...
76 
77 
78 /* Fire from serial, then repeat X revolutions or seconds or whatever and trigger Z outputs of various types etc
79  *
80  * Possible modes of repetition:
81  * - Iterations
82  * - Revolutions
83  * - Time units
84  */
86  TFLG = 0x01;
88 
89  unsigned short edgeTimeStamp = TC0;
90 
91  /* Reset the clock for reading timeout */
93 
94  // call sched output with args
96  /* Install the low word */
97  timeStamp.timeShorts[1] = edgeTimeStamp;
98  /* Find out what our timer value means and put it in the high word */
99  if(TFLGOF && !(edgeTimeStamp & 0x8000)){ /* see 10.3.5 paragraph 4 of 68hc11 ref manual for details */
100  timeStamp.timeShorts[0] = timerExtensionClock + 1;
101  }else{
102  timeStamp.timeShorts[0] = timerExtensionClock;
103  }
104 
105  unsigned char shouldFire = 1;
106 // unsigned long localPeriod = 0; // mutlifire or busy wait, if doing this, check last period for some min, and if too small, shrink second to last and increase last
107 // unsigned short localPeriod = 0; // normal mode
113  if(testNumberOfCycles == 0){
114  // Disable the interrupt again, to be enabled by a serial trigger
115  TIE &= NBIT0;
117  return;
118  }
119  }
120 
121  // TODO make this more sophisticated
128  if(testNumberOfCycles == 0){
129  // Disable the interrupt again, to be enabled by a serial trigger
130  TIE &= NBIT0;
132  return;
133  }
134  }
135 
136  // Grab updated time period
138 
139  // Output the sync pulse only once per "engine cycle"
140  if(KeyUserDebugs.currentEvent == 0){
141  // Schedule the cam pulse
145  }else{
147  }
148 
149  // Generate crank strength signal
150  unsigned char fakeCurrentEvent = 0;
152  fakeCurrentEvent = KeyUserDebugs.currentEvent - (testEventsPerCycle/2);
153  }else{
154  fakeCurrentEvent = KeyUserDebugs.currentEvent;
155  }
156 
157  // Schedule the main teeth, or not
158  if(fakeCurrentEvent < testNumberOfMissing){
160  }else{
163 
164  unsigned short singleWidth = testTicksPerEvent/2;
165  // See if this is the last one before the gap
167  // Migrate this to a safeMultiply() inline function
168  unsigned long wideWideWidth = (unsigned long)singleWidth * (testNumberOfMissing + 1);
169  if(wideWideWidth < SHORTMAX){
170  outputEventPulseWidthsMath[0] = (unsigned short)wideWideWidth;
171  }else{
173  }
174  }else{
175  outputEventPulseWidthsMath[0] = singleWidth;
176  }
177  }
178 
180  }else if(testMode == TEST_MODE_REVOLUTIONS){
181  // sub modes of different patterns, use scheduler for this by setting the ADC array up and probing/triggering/touching/poking/starting/
182  // switch statement for selecting different const arrays of angles, use busy wait, or multiple interrupt to do larger gaps for lower rpms/coarse events
183  // perhaps accept the pattern in the input packet and busy wait on some "run completed" flag before returning and freeing the buffer.
184  // TEMP de-configure timers and leave shouldFire zeroed.
185  TIE &= NBIT0;
187  // reset all timer modes for first time around, then check for timer >= requested value, check appropriate units of time, obviously...
188  // TEMP de-configure timers and leave shouldFire zeroed.
189  TIE &= NBIT0;
191  // ditto
192  // TEMP de-configure timers and leave shouldFire zeroed.
193  TIE &= NBIT0;
195  // ditto again
196  // TEMP de-configure timers and leave shouldFire zeroed.
197  TIE &= NBIT0;
198  }else{
199  // de-configure timers and leave shouldFire zeroed.
200  TIE &= NBIT0;
201  }
202 
203  if(shouldFire){
204  // configuration for multiple periods setup here?
205 
206  // fire outputs here
207  unsigned char channel;
208  for(channel = 0;channel < 6;channel++){
210  schedulePortTPin(channel, timeStamp);
211  }
212  }
213  }
215 }
216 
217