Subversion Repositories chibiosIgnition

Rev

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