Subversion Repositories chibiosIgnition

Rev

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