Subversion Repositories chibiosIgnition

Rev

Rev 20 | Rev 23 | 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
 
146
 
147
 
20 mjames 148
       int deltaPd= pd/ phaseScale;
6 mjames 149
 
18 mjames 150
 
21 mjames 151
       if(deltaPd == 0)
19 mjames 152
       {
21 mjames 153
       if(pd > 0)
154
           deltaPd =1;
155
 
156
       if(pd<  0)
157
           deltaPd =-1;
19 mjames 158
       }
18 mjames 159
 
21 mjames 160
           arr =  intSample + deltaPd;
6 mjames 161
 
14 mjames 162
 
21 mjames 163
// clamp values
14 mjames 164
 
165
 
19 mjames 166
    if(arr > 65535)
167
        arr = 65535;
168
    if(arr < 1000)
169
        arr = 1000;
14 mjames 170
 
13 mjames 171
     count = arr;
12 mjames 172
 
19 mjames 173
    TIM2->ARR = arr -1;
12 mjames 174
 
21 mjames 175
    nominal = intSample * (long) (phase10)/ 3600;
12 mjames 176
 
18 mjames 177
    float nomRPM = 30E6 / (MICROSECS_PULSE * arr);
12 mjames 178
 
179
        rpm =  nomRPM ;
180
 
6 mjames 181
        adjustRPM();
11 mjames 182
    }
6 mjames 183
 
184
 
185
 
11 mjames 186
 
20 mjames 187
// set the timing advance from reference in 0.1 degrees units
6 mjames 188
void setAdvance(int16_t deg10)
189
{
190
    phase10 = deg10;
191
 
192
}
193
 
19 mjames 194
 
195
 
196
// specialist timer setup :
21 mjames 197
// 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,
199
// 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.
201
// 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.
203
//
204
void initTimers()
19 mjames 205
{
206
        rccEnableTIM2(FALSE);
207
        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
 
225
 
21 mjames 226
    rccEnableTIM3(FALSE);
19 mjames 227
        rccResetTIM3();
228
        // TIM3 on the PA6 ... pins : remap code 00
229
        AFIO->MAPR &= ~ AFIO_MAPR_TIM3_REMAP;
230
 
231
        TIM3->PSC = 72*MICROSECS_PULSE;
232
        TIM3->ARR = 0xFFFF;
233
 
234
 
235
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
236
 
237
 
238
    // link TIM3 ITR2 to TIM2 reload
239
    // use TS = 001 to make TRC from Tim2 TRIGGER
240
        TIM3->SMCR  &= ~(TIM_SMCR_TS_Msk );
241
        TIM3->SMCR  |=  TIM_SMCR_TS_0; // select ITR2 as trigger source TRC
242
 
243
    TIM3->CCMR1 |=  TIM_CCMR1_CC2S_1 |  TIM_CCMR1_CC2S_0 ; //  The CC2S bits are 11, use TRC
244
 
245
        TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
246
 
247
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
248
 
249
 
250
    nvicEnableVector(TIM3_IRQn,
251
                          4);
252
 
253
 
254
 
255
    TIM3->DIER |= TIM_DIER_CC1IE  | TIM_DIER_CC2IE;
256
}
257
 
258
 
6 mjames 259
// timer 3 interrupt
260
void VectorB4(void)
261
{
13 mjames 262
 
19 mjames 263
        if(TIM3->SR & TIM_SR_CC1IF)
6 mjames 264
        {
13 mjames 265
                uint16_t sample = TIM3->CCR1;
19 mjames 266
//              if(sample-lastSampleRef >  1000 /*BREAKER_COUNT_MIN */)
13 mjames 267
                {
14 mjames 268
 
19 mjames 269
                samplePeriod = sample-sampleRef;
270
 
271
                sampleRef = sample;
272
 
13 mjames 273
                        ++refCount;
274
                }
19 mjames 275
                lastSampleRef= sample;
14 mjames 276
 
6 mjames 277
        }
19 mjames 278
        if(TIM3->SR & TIM_SR_CC2IF)
13 mjames 279
        {
280
                 sampleVar  = TIM3->CCR2;
281
                 ++varCount;
282
        }
283
 
19 mjames 284
    if(refCount == 1 && varCount == 1)
285
    {
286
        if(sampleRef == sampleVar)
287
                phaseSamp = 0;
288
        else
289
        {
13 mjames 290
 
19 mjames 291
        uint16_t refToVar = sampleRef - sampleVar;
292
        uint16_t varToRef = sampleVar - sampleRef;
13 mjames 293
 
20 mjames 294
        if(refToVar < varToRef)
19 mjames 295
                phaseSamp = refToVar;
20 mjames 296
        else if(varToRef <= refToVar)
19 mjames 297
                phaseSamp = -varToRef;
13 mjames 298
 
19 mjames 299
        }
13 mjames 300
 
301
 
19 mjames 302
        validPhaseSamp = 1;
303
        refCount=0;
304
        varCount=0;
13 mjames 305
 
19 mjames 306
    }
13 mjames 307
 
19 mjames 308
    // frequency error, should deal with by direct period measurement
309
    if(refCount > 1 || varCount > 1  )
310
    {
311
        refCount = 0;
312
        varCount = 0;
313
 
314
    }
315
 
6 mjames 316
}
317
 
318
 
319