Subversion Repositories chibiosIgnition

Rev

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