Subversion Repositories chibiosIgnition

Rev

Rev 21 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 21 Rev 23
Line 7... Line 7...
7
 
7
 
8
#include "ch.h"  // needs for all ChibiOS programs
8
#include "ch.h"  // needs for all ChibiOS programs
9
#include "hal.h" // hardware abstraction layer header
9
#include "hal.h" // hardware abstraction layer header
10
 
10
 
11
#include "timer2.h"
11
#include "timer2.h"
12
#define  MICROSECS_PULSE 1
12
#define  MICROSECS_PULSE 4
13
 
-
 
14
 
13
 
15
// with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000
14
// with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000
16
// freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the
15
// freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the
17
// first pulse longer than 1/300 of a second as being a proper closure .
16
// first pulse longer than 1/300 of a second as being a proper closure .
18
// the TIM2 counter counts in 1uS increments,
17
// the TIM2 counter counts in 1uS increments,
19
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
18
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
20
 
19
 
21
#define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
20
#define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
22
 
21
 
23
 
-
 
24
int16_t nominal = 0;
22
int16_t nominal = 0;
25
uint16_t halfRot;
23
uint16_t halfRot;
26
int16_t phase10 = 100; // 10 degrees
24
int16_t phase10 = 100; // 10 degrees
27
volatile uint16_t sampleVar;
25
volatile uint16_t sampleVar;
28
volatile uint16_t sampleRef;
26
volatile uint16_t sampleRef;
Line 30... Line 28...
30
volatile uint16_t lastSampleRef = 0;
28
volatile uint16_t lastSampleRef = 0;
31
 
29
 
32
volatile uint8_t refCount = 0;
30
volatile uint8_t refCount = 0;
33
volatile uint8_t varCount = 0;
31
volatile uint8_t varCount = 0;
34
 
32
 
35
 
-
 
36
 
-
 
37
 
-
 
38
volatile uint16_t samplePeriod = 0 ;
33
volatile uint16_t samplePeriod = 0;
39
 
34
 
40
static signed phaseSamp = 0;
35
static signed phaseSamp = 0;
41
static uint8_t validPhaseSamp = 0;
36
static uint8_t validPhaseSamp = 0;
42
 
37
 
43
int gainControl = 1000 ;
38
int gainControl = 1000;
44
 
-
 
45
 
39
 
46
uint16_t rpm;
40
uint16_t rpm;
47
signed count;
41
signed count;
48
signed delta;
42
signed delta;
49
 
43
 
50
 
-
 
51
 
44
void
52
void recalcPhase()
45
recalcPhase ()
53
{
46
{
54
        nominal = halfRot * (long) (phase10)/ 3600;
47
  nominal = halfRot * (long) (phase10) / 3600;
55
}
48
}
56
 
49
 
-
 
50
void
57
void adjustRPM(void)
51
adjustRPM (void)
58
{
52
{
59
        if(rpm < 600)
53
  if (rpm < 600)
60
                rpm = 600;
54
    rpm = 600;
61
        if(rpm >  5000)
55
  if (rpm > 5000)
62
                rpm = 5000;
56
    rpm = 5000;
63
 
-
 
64
 
57
 
65
}
58
}
66
 
59
 
-
 
60
uint16_t
67
uint16_t setRPM(uint16_t rpm_ )
61
setRPM (uint16_t rpm_)
68
{
62
{
69
        if(rpm_ >= 600 && rpm_ < 6000)
63
  if (rpm_ >= 600 && rpm_ < 6000)
70
        {
64
    {
71
          rpm = rpm_;
65
      rpm = rpm_;
72
          adjustRPM();
66
      adjustRPM ();
73
        }
67
    }
74
          return halfRot;
68
  return halfRot;
75
}
69
}
76
 
70
 
-
 
71
uint16_t
77
uint16_t getRPM(void)
72
getRPM (void)
78
{
73
{
79
        return rpm;
74
  return rpm;
80
}
75
}
81
 
76
 
-
 
77
signed
82
signed getDelta(void)
78
getDelta (void)
83
{
79
{
84
        return delta;
80
  return delta;
85
}
81
}
86
 
82
 
-
 
83
signed
87
signed getCount(void)
84
getCount (void)
88
{
85
{
89
        return  count;
86
  return count;
90
}
87
}
91
 
88
 
-
 
89
void
92
void setGain(int gain)
90
setGain (int gain)
93
{
91
{
94
        gainControl = gain;
92
  gainControl = gain;
95
}
93
}
96
 
94
 
97
 
-
 
98
 
-
 
99
 
95
void
100
void processPhase ( void )
96
processPhase (void)
101
{
97
{
102
    // lpcl
98
  // lpcl
103
        chSysLock();
-
 
104
 
-
 
105
        const signed pdClip = 10000;
99
  const signed pdClip = 10000;
106
        static signed pd;
100
  static signed pd;
107
        if(validPhaseSamp)
101
  if (validPhaseSamp)
108
        {
-
 
109
         pd =   phaseSamp - nominal;
-
 
110
     validPhaseSamp = 0;
-
 
111
        if(pd > pdClip)
-
 
112
        pd = pdClip;
-
 
113
        if(pd < -pdClip)
-
 
114
                pd = -pdClip;
-
 
115
 
-
 
116
 
-
 
117
   }
102
    {
118
 
-
 
119
 
-
 
120
 
-
 
121
     chSysUnlock();
103
      chSysLock ();
122
 
-
 
123
 
-
 
124
     delta = pd;
-
 
125
 
-
 
126
 
-
 
127
     static int sampleAverage = 0;
-
 
128
 
-
 
129
     static int phaseAverage  = 0;
-
 
130
     const int freqScale = 6;
-
 
131
 
-
 
132
     const int phaseScale = 50;
-
 
133
 
104
 
134
     sampleAverage = sampleAverage + (samplePeriod - sampleAverage/freqScale);
105
      pd = phaseSamp - nominal;
135
 
106
 
-
 
107
      validPhaseSamp = 0;
-
 
108
      chSysUnlock ();
136
 
109
 
-
 
110
      if (pd > pdClip)
-
 
111
        pd = pdClip;
-
 
112
      if (pd < -pdClip)
-
 
113
        pd = -pdClip;
137
 
114
 
-
 
115
    }
-
 
116
  else
-
 
117
    return;
138
 
118
 
-
 
119
  delta = pd;
139
 
120
 
140
     int32_t arr;
121
  static int sampleAverage = 0;
141
 
122
 
-
 
123
  static int phaseAverage = 0;
142
   //   if(lock)
124
  const int freqScale =  16;
143
 
125
 
-
 
126
  const int periodScale= 4;  // 1/periodScale  of difference between period measured and average is added to period.
144
       int intSample = sampleAverage / freqScale;
127
  const int phaseScale = 50;
145
 
128
 
-
 
129
  // measure sample period devi
-
 
130
  sampleAverage = sampleAverage + (samplePeriod *freqScale  - sampleAverage) / periodScale;
146
 
131
 
-
 
132
  int32_t arr;
147
 
133
 
148
       int deltaPd= pd/ phaseScale;
134
  //    if(lock)
149
 
135
 
-
 
136
  int intSample = sampleAverage / freqScale;
150
 
137
 
151
       if(deltaPd == 0)
-
 
152
       {
-
 
153
       if(pd > 0)
-
 
154
           deltaPd =1;
138
  int deltaPd = pd / phaseScale;
155
 
139
 
156
       if(pd<  0)
140
  if (deltaPd == 0)
-
 
141
    {
157
           deltaPd =-1;
142
      if (pd > 0)
158
       }
143
        deltaPd = 1;
159
 
144
 
160
           arr =  intSample + deltaPd;
145
      if (pd < 0)
-
 
146
        deltaPd = -1;
-
 
147
    }
161
 
148
 
-
 
149
  arr = intSample + deltaPd;
162
 
150
 
163
// clamp values
151
// clamp values
164
 
152
 
-
 
153
  if (arr > 65535)
-
 
154
    arr = 65535;
-
 
155
  if (arr < 1000)
-
 
156
    arr = 1000;
165
 
157
 
166
    if(arr > 65535)
-
 
167
        arr = 65535;
-
 
168
    if(arr < 1000)
-
 
169
        arr = 1000;
-
 
170
 
-
 
171
     count = arr;
158
  count = arr;
172
 
-
 
173
    TIM2->ARR = arr -1;
-
 
174
 
159
 
175
    nominal = intSample * (long) (phase10)/ 3600;
160
  TIM2->ARR = arr - 1;
176
 
161
 
177
    float nomRPM = 30E6 / (MICROSECS_PULSE * arr);
162
  nominal = intSample * (long) (phase10) / 3600;
178
 
-
 
179
        rpm =  nomRPM ;
-
 
180
 
-
 
181
        adjustRPM();
-
 
182
    }
-
 
183
 
163
 
-
 
164
  float nomRPM = 30E6 / (MICROSECS_PULSE * arr);
184
 
165
 
-
 
166
  rpm = nomRPM;
185
 
167
 
-
 
168
  adjustRPM ();
-
 
169
}
186
 
170
 
187
// set the timing advance from reference in 0.1 degrees units
171
// set the timing advance from reference in 0.1 degrees units
-
 
172
void
188
void setAdvance(int16_t deg10)
173
setAdvance (int16_t deg10)
189
{
174
{
190
    phase10 = deg10;
175
  phase10 = deg10;
191
 
176
 
192
}
177
}
193
 
178
 
194
 
-
 
195
 
-
 
196
// specialist timer setup :
179
// specialist timer setup :
197
// timer 2 is a reloading counter with a cycle period controlled by its ARR register.
180
// timer 2 is a reloading counter with a cycle period controlled by its ARR register.
198
// Just before terminal count it produces a pulse of 200 microseconds using its CCR1 count compare register,
181
// Just before terminal count it produces a pulse of 200 microseconds using its CCR1 count compare register,
199
// used to drive the strobe LED.
182
// used to drive the strobe LED.
200
// Timer 3 is then used to count the time of the reload of Timer 2 via its Trigger Out being selected as reload.
183
// Timer 3 is then used to count the time of the reload of Timer 2 via its Trigger Out being selected as reload.
201
// The time is latched in TIM3  CCR2
184
// The time is latched in TIM3  CCR2
202
// and ignition pulses are latched on TIM3 CCR1, to allow it to be used in a PLL.
185
// and ignition pulses are latched on TIM3 CCR1, to allow it to be used in a PLL.
203
//
186
//
-
 
187
void
204
void initTimers()
188
initTimers ()
205
{
189
{
206
        rccEnableTIM2(FALSE);
190
  rccEnableTIM2 (FALSE);
207
        rccResetTIM2();
191
  rccResetTIM2 ();
208
 
-
 
209
        TIM2->PSC = 72*MICROSECS_PULSE;
-
 
210
        TIM2->ARR = 60000;
-
 
211
        TIM2->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN |
-
 
212
                        TIM_CR1_ARPE );
-
 
213
 
-
 
214
        /// pulse width 200 uS
-
 
215
        TIM2->CCR1 = 200/MICROSECS_PULSE;
-
 
216
 
-
 
217
    TIM2->CCER =  TIM_CCER_CC1E | TIM_CCER_CC1P  ; //enabled and active high
-
 
218
 
-
 
219
    TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
-
 
220
                           TIM_CCMR1_OC1PE ;
-
 
221
 
-
 
222
 
-
 
223
    TIM2->CR2 = TIM_CR2_MMS_1 ; // trigger out is 010 = update
-
 
224
 
192
 
-
 
193
  TIM2->PSC = 72 * MICROSECS_PULSE;
-
 
194
  TIM2->ARR = 60000;
-
 
195
  TIM2->CR1 = ~TIM_CR1_CKD & (TIM_CR1_CEN | TIM_CR1_ARPE);
225
 
196
 
226
    rccEnableTIM3(FALSE);
197
  /// pulse width 200 uS
227
        rccResetTIM3();
-
 
228
        // TIM3 on the PA6 ... pins : remap code 00
-
 
229
        AFIO->MAPR &= ~ AFIO_MAPR_TIM3_REMAP;
198
  TIM2->CCR1 = 200 / MICROSECS_PULSE;
230
 
199
 
231
        TIM3->PSC = 72*MICROSECS_PULSE;
200
  TIM2->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; //enabled and active high
232
        TIM3->ARR = 0xFFFF;
-
 
233
 
201
 
-
 
202
  TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2
-
 
203
      | TIM_CCMR1_OC1PE;
234
 
204
 
235
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
205
  TIM2->CR2 = TIM_CR2_MMS_1; // trigger out is 010 = update
236
 
206
 
-
 
207
  rccEnableTIM3 (FALSE);
-
 
208
  rccResetTIM3 ();
-
 
209
  // TIM3 on the PA6 ... pins : remap code 00
-
 
210
  AFIO->MAPR &= ~AFIO_MAPR_TIM3_REMAP;
237
 
211
 
238
    // link TIM3 ITR2 to TIM2 reload
212
  TIM3->PSC = 72 * MICROSECS_PULSE;
239
    // use TS = 001 to make TRC from Tim2 TRIGGER
-
 
240
        TIM3->SMCR  &= ~(TIM_SMCR_TS_Msk );
213
  TIM3->ARR = 0xFFFF;
241
        TIM3->SMCR  |=  TIM_SMCR_TS_0; // select ITR2 as trigger source TRC
-
 
242
 
214
 
-
 
215
  TIM3->CCMR1 =
243
    TIM3->CCMR1 |=  TIM_CCMR1_CC2S_1 |  TIM_CCMR1_CC2S_0 ; //  The CC2S bits are 11, use TRC
216
      TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */; // filter 16, input
244
 
217
 
-
 
218
  // link TIM3 ITR2 to TIM2 reload
-
 
219
  // use TS = 001 to make TRC from Tim2 TRIGGER
245
        TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
220
  TIM3->SMCR &= ~(TIM_SMCR_TS_Msk);
-
 
221
  TIM3->SMCR |= TIM_SMCR_TS_0; // select ITR2 as trigger source TRC
246
 
222
 
247
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
223
  TIM3->CCMR1 |= TIM_CCMR1_CC2S_1 | TIM_CCMR1_CC2S_0; //  The CC2S bits are 11, use TRC
248
 
224
 
-
 
225
  TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
249
 
226
 
250
    nvicEnableVector(TIM3_IRQn,
227
  TIM3->CR1 = ~TIM_CR1_CKD & (TIM_CR1_CEN | TIM_CR1_ARPE);
251
                          4);
-
 
252
 
228
 
-
 
229
  nvicEnableVector (TIM3_IRQn, 4);
253
 
230
 
254
 
-
 
255
    TIM3->DIER |= TIM_DIER_CC1IE  | TIM_DIER_CC2IE;
231
  TIM3->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE;
256
}
232
}
257
 
233
 
258
 
-
 
259
// timer 3 interrupt
234
// timer 3 interrupt
-
 
235
void
260
void VectorB4(void)
236
VectorB4 (void)
261
{
237
{
262
 
238
 
263
        if(TIM3->SR & TIM_SR_CC1IF)
239
  if (TIM3->SR & TIM_SR_CC1IF)
264
        {
240
    {
265
                uint16_t sample = TIM3->CCR1;
241
      uint16_t sample = TIM3->CCR1;
266
//              if(sample-lastSampleRef >  1000 /*BREAKER_COUNT_MIN */)
242
//              if(sample-lastSampleRef >  1000 /*BREAKER_COUNT_MIN */)
267
                {
243
        {
268
 
-
 
269
                samplePeriod = sample-sampleRef;
-
 
270
 
244
 
271
                sampleRef = sample;
245
          samplePeriod = sample - sampleRef;
272
 
246
 
273
                        ++refCount;
-
 
274
                }
-
 
275
                lastSampleRef= sample;
247
          sampleRef = sample;
276
 
248
 
-
 
249
          ++refCount;
277
        }
250
        }
278
        if(TIM3->SR & TIM_SR_CC2IF)
-
 
279
        {
-
 
280
                 sampleVar  = TIM3->CCR2;
251
      lastSampleRef = sample;
281
                 ++varCount;
-
 
282
        }
-
 
283
 
252
 
-
 
253
    }
284
    if(refCount == 1 && varCount == 1)
254
  if (TIM3->SR & TIM_SR_CC2IF)
285
    {
255
    {
286
        if(sampleRef == sampleVar)
256
      sampleVar = TIM3->CCR2;
287
                phaseSamp = 0;
257
      ++varCount;
288
        else
-
 
289
        {
258
    }
290
 
259
 
291
        uint16_t refToVar = sampleRef - sampleVar;
260
  if (refCount == 1 && varCount == 1)
-
 
261
    {
292
        uint16_t varToRef = sampleVar - sampleRef;
262
      if (sampleRef == sampleVar)
-
 
263
        phaseSamp = 0;
-
 
264
      else
-
 
265
        {
293
 
266
 
294
        if(refToVar < varToRef)
267
          uint16_t refToVar = sampleRef - sampleVar;
295
                phaseSamp = refToVar;
-
 
296
        else if(varToRef <= refToVar)
268
          uint16_t varToRef = sampleVar - sampleRef;
297
                phaseSamp = -varToRef;
-
 
298
 
269
 
-
 
270
          if (refToVar < varToRef)
299
        }
271
            phaseSamp = refToVar;
-
 
272
          else if (varToRef <= refToVar)
-
 
273
            phaseSamp = -varToRef;
300
 
274
 
-
 
275
        }
301
 
276
 
302
        validPhaseSamp = 1;
277
      validPhaseSamp = 1;
303
        refCount=0;
278
      refCount = 0;
304
        varCount=0;
279
      varCount = 0;
305
 
280
 
306
    }
281
    }
307
 
282
 
308
    // frequency error, should deal with by direct period measurement
283
  // frequency error, should deal with by direct period measurement
309
    if(refCount > 1 || varCount > 1  )
284
  if (refCount > 1 || varCount > 1)
310
    {
285
    {
311
        refCount = 0;
286
      refCount = 0;
312
        varCount = 0;
287
      varCount = 0;
313
 
288
 
314
    }
289
    }
315
 
290
 
316
}
291
}
317
 
292
 
318
 
-
 
319
 
-