Subversion Repositories chibiosIgnition

Rev

Rev 14 | Rev 18 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 mjames 1
/*
2
 * timer2.c
3
 *
4
 *  Created on: 2 Apr 2018
5
 *      Author: Mike
6
 */
7
 
8
#include "ch.h"  // needs for all ChibiOS programs
9
#include "hal.h" // hardware abstraction layer header
10
 
11
#include "timer2.h"
12
#define  MICROSECS_PULSE 10
13
 
14
 
15
// 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
17
// first pulse longer than 1/300 of a second as being a proper closure .
18
// the TIM2 counter counts in 10uS increments,
19
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
20
 
13 mjames 21
#define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
22
 
23
 
14 mjames 24
 
25
 
26
#define SAMPLE_BUFF_SIZE 16
13 mjames 27
uint16_t nominal = 0;
6 mjames 28
uint16_t halfRot;
29
uint16_t phase10 = 100; // 10 degrees
13 mjames 30
volatile uint16_t sampleRefCount = 0;
31
uint16_t outSampleRefCount = 0;
32
volatile uint16_t  sampleVar;
33
volatile uint16_t sampleRef;
34
volatile uint16_t  sampleDiffBuff[SAMPLE_BUFF_SIZE];
14 mjames 35
volatile uint16_t samplePeriodBuff[SAMPLE_BUFF_SIZE];
36
volatile uint8_t   refCountBuff[SAMPLE_BUFF_SIZE];
37
volatile uint8_t  varCountBuff[SAMPLE_BUFF_SIZE];
6 mjames 38
 
17 mjames 39
 
40
int gainControl = 1000 ;
41
 
14 mjames 42
volatile uint8_t haveSlowPulse = 0;
43
 
6 mjames 44
uint16_t rpm;
17 mjames 45
signed count;
46
signed delta;
6 mjames 47
 
48
void initTimer2()
49
{
50
        rccEnableTIM2(FALSE);
51
        rccResetTIM2();
52
 
53
        TIM2->PSC = 72*MICROSECS_PULSE;
54
        TIM2->ARR = 60000;
55
        TIM2->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN |
56
                        TIM_CR1_ARPE );
57
 
7 mjames 58
        /// pulse width 200 uS
59
        TIM2->CCR1 = 200/MICROSECS_PULSE;
6 mjames 60
 
11 mjames 61
    TIM2->CCER =  TIM_CCER_CC1E | TIM_CCER_CC1P  ; //enabled and active high
6 mjames 62
 
11 mjames 63
    TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
6 mjames 64
                           TIM_CCMR1_OC1PE ;
65
 
66
 
67
    TIM2->CR2 = TIM_CR2_MMS_1 ; // trigger out is 010 = update
68
 
69
 
70
    // change the TIM2 CC2 to TIM3 CC1
71
        rccEnableTIM3(FALSE);
72
        rccResetTIM3();
73
        // TIM3 on the PA6 ... pins : remap code 00
74
        AFIO->MAPR &= ~ AFIO_MAPR_TIM3_REMAP;
75
 
76
        TIM3->PSC = 72*MICROSECS_PULSE;
77
        TIM3->ARR = 0xFFFF;
78
 
79
 
80
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
81
 
82
 
13 mjames 83
    // link TIM3 ITR2 to TIM2 reload
84
    // use TS = 001 to make TRC from Tim2 TRIGGER
85
        TIM3->SMCR  &= ~(TIM_SMCR_TS_Msk );
86
        TIM3->SMCR  |=  TIM_SMCR_TS_0; // select ITR2 as trigger source TRC
6 mjames 87
 
13 mjames 88
    TIM3->CCMR1 |=  TIM_CCMR1_CC2S_1 |  TIM_CCMR1_CC2S_0 ; //  The CC2S bits are 11, use TRC
6 mjames 89
 
13 mjames 90
        TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
91
 
6 mjames 92
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
93
 
94
 
95
    nvicEnableVector(TIM3_IRQn,
7 mjames 96
                          4);
6 mjames 97
 
98
 
99
 
13 mjames 100
    TIM3->DIER |= TIM_DIER_CC1IE  | TIM_DIER_CC2IE;
6 mjames 101
}
102
 
103
 
104
void recalcPhase(void)
105
{
106
        nominal = halfRot * (long) (phase10)/ 1800;
107
}
108
 
109
void adjustRPM(void)
110
{
111
        if(rpm < 600)
112
                rpm = 600;
113
        if(rpm >  5000)
114
                rpm = 5000;
115
 
116
 
117
}
118
 
119
uint16_t setRPM(uint16_t rpm_ )
120
{
12 mjames 121
        if(rpm_ >= 600 && rpm_ < 6000)
6 mjames 122
        {
123
          rpm = rpm_;
124
          adjustRPM();
125
        }
126
          return halfRot;
127
}
128
 
129
uint16_t getRPM(void)
130
{
131
        return rpm;
132
}
133
 
17 mjames 134
signed getDelta(void)
11 mjames 135
{
13 mjames 136
        return delta;
11 mjames 137
}
138
 
17 mjames 139
signed getCount(void)
6 mjames 140
{
13 mjames 141
        return  count;
6 mjames 142
}
143
 
17 mjames 144
void setGain(int gain)
145
{
146
        gainControl = gain;
147
}
6 mjames 148
 
17 mjames 149
 
14 mjames 150
uint8_t slowPulse(void)
151
{
152
        return haveSlowPulse;
153
}
154
 
155
// waits for ignition pulse reading in the buffer, returns
156
// the sample index of the next sample.
157
 
13 mjames 158
uint16_t getNextRefPulseIndex(void)
6 mjames 159
{
13 mjames 160
        while (outSampleRefCount == sampleRefCount)
161
                chThdSleep(10);
6 mjames 162
 
13 mjames 163
        uint16_t sampleIndex = outSampleRefCount;
6 mjames 164
 
13 mjames 165
    if(++outSampleRefCount == SAMPLE_BUFF_SIZE)
166
        outSampleRefCount = 0;
167
    return sampleIndex;
168
}
6 mjames 169
 
170
 
13 mjames 171
void processNextPulse(uint16_t index)
11 mjames 172
{
173
 
12 mjames 174
    // scale it up by 32
13 mjames 175
        static int32_t periodEstimate = 2000 * 256 ;
6 mjames 176
        // at this point we should try to phase lock
14 mjames 177
 
13 mjames 178
        uint16_t sampleDiff = sampleDiffBuff[index];
6 mjames 179
 
14 mjames 180
        signed pd = 0;
181
        bool lock = false;
182
// basically locked
183
        if(refCountBuff[index]==1 && varCountBuff[index]==1 )
184
        {
185
                lock = true;
186
       pd = (sampleDiff <  32768 ? sampleDiff : sampleDiff - 65536L) ;
187
        }
188
        else if (refCountBuff[index] > 1)
189
        {
190
                pd = (refCountBuff [index]*32768L);
191
        }
192
        else if (varCountBuff[index] > 1)
193
        {
194
                pd = (-varCountBuff[index] * 32768L);
195
        }
17 mjames 196
    float delta_phi = pd/ (gainControl * 1.0);
11 mjames 197
 
198
 
17 mjames 199
    delta = delta_phi;
11 mjames 200
 
6 mjames 201
 
17 mjames 202
 
14 mjames 203
    // phase detector returns +/
204
 
205
 
206
 
17 mjames 207
    float const wn = 0.03f;
13 mjames 208
    float const zeta = 0.707f;
14 mjames 209
    float const K = 1;
6 mjames 210
 
13 mjames 211
    float const t1 = K/(wn*wn);
212
    float const t2 = 2 * zeta/wn;
213
    float const  b0 = (4*K/t1)*(1.+t2/2.0f);
214
    float const b1 = (8*K / t1);
215
    float const b2 = (4*K/t1)*(1.-t2/2.0f);
11 mjames 216
 
13 mjames 217
    float const a1 = -2.0f;
218
    float const a2 = 1.0f;
14 mjames 219
    static float v0=0, v1 = 0, v2 = 0 ;
11 mjames 220
 
221
 
13 mjames 222
    static float phi_hat = 0.0f;
6 mjames 223
 
224
 
13 mjames 225
    v2=v1; v1=v0;
226
    v0 = delta_phi -v1 *a1 -v2 *a2;
6 mjames 227
 
228
 
14 mjames 229
    phi_hat = v0 * b0 + v1 * b1 + v2 * b2 ;
6 mjames 230
 
14 mjames 231
    // 6.283 = 1.0 Hz
6 mjames 232
 
14 mjames 233
    // 62.2 = 10Hz
234
    // decide on whether to go for forcing loop or to track
235
 
236
    int32_t arr;
237
 
238
   //   if(lock)
239
 
240
 
241
       arr = (6283000L/MICROSECS_PULSE)/ phi_hat;
242
 
243
    if(arr > 5000)
244
        arr = 5000;
245
    if(arr < 500)
246
        arr = 500;
247
 
248
    // compute period error]
13 mjames 249
      // periodErr +=   periodEstimate - (arr * 256);
6 mjames 250
 
12 mjames 251
 
13 mjames 252
     count = arr;
12 mjames 253
 
13 mjames 254
    TIM2->ARR = arr ;
12 mjames 255
    recalcPhase();
256
 
257
 
258
 
259
// calculate RPM
260
    float nomRPM = 30E6 / (MICROSECS_PULSE * (periodEstimate/256));
261
 
262
        rpm =  nomRPM ;
263
 
264
 
265
 
6 mjames 266
//      rpm += delta / 256;
267
 
268
        adjustRPM();
11 mjames 269
    }
6 mjames 270
 
271
 
272
 
11 mjames 273
 
6 mjames 274
// set the timing advance from reference to
275
void setAdvance(int16_t deg10)
276
{
277
    phase10 = deg10;
278
    recalcPhase();
279
 
280
}
281
 
282
// timer 3 interrupt
283
void VectorB4(void)
284
{
13 mjames 285
    static uint16_t lastSampleRef = 0;
286
    static uint8_t refCount = 0;
287
        static uint8_t varCount = 0;
14 mjames 288
        uint16_t samplePeriod;
13 mjames 289
 
6 mjames 290
        uint16_t stat = TIM3->SR;
291
        if(stat & TIM_SR_CC1IF)
292
        {
293
                TIM3->SR &= ~TIM_SR_CC1IF;
13 mjames 294
                uint16_t sample = TIM3->CCR1;
295
                if(sample-lastSampleRef >  100 /*BREAKER_COUNT_MIN */)
296
                {
297
                        sampleRef = sample;
14 mjames 298
 
13 mjames 299
                        ++refCount;
300
                }
14 mjames 301
        samplePeriod = sample-lastSampleRef;
302
 
303
        chDbgCheck(samplePeriod != 65535);
304
        lastSampleRef = sample;
6 mjames 305
        }
13 mjames 306
        if(stat & TIM_SR_CC2IF)
307
        {
308
                TIM3->SR &= ~TIM_SR_CC2IF;
309
                 sampleVar  = TIM3->CCR2;
310
                 ++varCount;
311
        }
312
 
313
 
314
 
315
 
316
    if(refCount != 0 && varCount != 0  ) /*we have an R,V pair  */
317
    {
318
 
14 mjames 319
//
13 mjames 320
 
14 mjames 321
    refCountBuff[sampleRefCount] = refCount;
322
    varCountBuff[sampleRefCount] = varCount;
13 mjames 323
 
17 mjames 324
    haveSlowPulse = (varCount > 20);
13 mjames 325
 
14 mjames 326
     sampleDiffBuff[sampleRefCount] = sampleRef - sampleVar;
327
 
328
     samplePeriodBuff[sampleRefCount] = samplePeriod;
329
 
330
 
331
 
13 mjames 332
            if(++sampleRefCount == SAMPLE_BUFF_SIZE)
333
                  sampleRefCount = 0;
334
 
335
   refCount = 0;
336
   varCount = 0;
337
   }
338
 
339
 
340
 
6 mjames 341
}
342
 
343
 
344