Subversion Repositories chibiosIgnition

Rev

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