Subversion Repositories chibiosIgnition

Rev

Rev 12 | Rev 14 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 12 Rev 13
Line 16... Line 16...
16
// freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the
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 .
17
// first pulse longer than 1/300 of a second as being a proper closure .
18
// the TIM2 counter counts in 10uS increments,
18
// the TIM2 counter counts in 10uS increments,
19
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
19
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
20
 
20
 
-
 
21
#define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
-
 
22
 
-
 
23
 
21
#define SAMPLE_BUFF_SIZE 256
24
#define SAMPLE_BUFF_SIZE 256
-
 
25
uint16_t nominal = 0;
22
uint16_t halfRot;
26
uint16_t halfRot;
23
uint16_t nominal  = 0;
-
 
24
uint16_t phase10 = 100; // 10 degrees
27
uint16_t phase10 = 100; // 10 degrees
25
volatile uint16_t sampleCount = 0;
28
volatile uint16_t sampleRefCount = 0;
26
uint16_t outSampleCount = 0;
29
uint16_t outSampleRefCount = 0;
27
volatile uint16_t sampleBuff[SAMPLE_BUFF_SIZE];
30
volatile uint16_t sampleRefBuff[SAMPLE_BUFF_SIZE];
28
typedef enum { WAIT_GAP, SKIP_BOUNCE, HAVE_SAMPLE } sampleState_t ;
-
 
29
sampleState_t  sampleState = WAIT_GAP;
31
volatile uint16_t  sampleVar;
30
// difference between samples
-
 
31
volatile uint16_t deltaTime;
32
volatile uint16_t sampleRef;
32
 
-
 
33
static signed pdI = 0;
33
volatile uint16_t  sampleDiffBuff[SAMPLE_BUFF_SIZE];
34
 
-
 
35
 
34
 
36
uint16_t rpm;
35
uint16_t rpm;
-
 
36
uint16_t count;
-
 
37
uint16_t delta;
37
 
38
 
38
void initTimer2()
39
void initTimer2()
39
{
40
{
40
        rccEnableTIM2(FALSE);
41
        rccEnableTIM2(FALSE);
41
        rccResetTIM2();
42
        rccResetTIM2();
Line 67... Line 68...
67
        TIM3->ARR = 0xFFFF;
68
        TIM3->ARR = 0xFFFF;
68
 
69
 
69
 
70
 
70
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
71
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
71
 
72
 
72
        TIM3->CCER = TIM_CCER_CC1E;
-
 
73
 
73
 
74
    // link TIM3 ITR1 to TIM2 reload
74
    // link TIM3 ITR2 to TIM2 reload
75
    // use CCR3
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
-
 
78
 
76
    TIM3->CCMR2 = TIM_CCMR2_CC3S_1 | TIM_CCMR2_CC3S_0 ; //  The
79
    TIM3->CCMR1 |=  TIM_CCMR1_CC2S_1 |  TIM_CCMR1_CC2S_0 ; //  The CC2S bits are 11, use TRC
77
 
80
 
-
 
81
        TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
78
 
82
 
79
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
83
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
80
 
84
 
81
 
85
 
82
    nvicEnableVector(TIM3_IRQn,
86
    nvicEnableVector(TIM3_IRQn,
83
                          4);
87
                          4);
84
 
88
 
85
 
89
 
86
 
90
 
87
    TIM3->DIER |= TIM_DIER_CC1IE ;
91
    TIM3->DIER |= TIM_DIER_CC1IE  | TIM_DIER_CC2IE;
88
}
92
}
89
 
93
 
90
 
94
 
91
void recalcPhase(void)
95
void recalcPhase(void)
92
{
96
{
Line 116... Line 120...
116
uint16_t getRPM(void)
120
uint16_t getRPM(void)
117
{
121
{
118
        return rpm;
122
        return rpm;
119
}
123
}
120
 
124
 
121
uint16_t getDelta(void)
125
unsigned getDelta(void)
122
{
126
{
123
        return pdI&0xFFFF;
127
        return delta;
124
}
128
}
125
 
129
 
126
uint16_t wrapIndex(uint16_t index)
130
unsigned getCount(void)
127
{
131
{
128
        if (index >= SAMPLE_BUFF_SIZE)
-
 
129
                index -= SAMPLE_BUFF_SIZE;
-
 
130
    return index;
132
        return  count;
131
}
-
 
132
 
-
 
133
// allows for wrapping
-
 
134
uint16_t getSampleBuff(uint16_t index)
-
 
135
{
-
 
136
        chSysLock();
-
 
137
        return sampleBuff[wrapIndex(index)];
-
 
138
        chSysUnlock();
-
 
139
}
133
}
140
 
134
 
141
 
135
 
142
// waits for ignition pulse , debounces readings,
136
// waits for ignition pulse , debounces readings,
143
// returns the pulse time, skips debounce time
137
// returns the pulse time, skips debounce time
144
uint16_t getNextPulse(void)
138
uint16_t getNextRefPulseIndex(void)
145
{
139
{
146
        static uint16_t lastSampleIndex = 0;
-
 
147
        while(1)
-
 
148
        {
-
 
149
                        while (outSampleCount == sampleCount)
140
        while (outSampleRefCount == sampleRefCount)
150
                                chThdSleep(10);
141
                chThdSleep(10);
151
 
142
 
152
                        uint16_t thisTime  = getSampleBuff(outSampleCount);
143
        uint16_t sampleIndex = outSampleRefCount;
153
 
144
 
154
                        outSampleCount = wrapIndex(outSampleCount + 1);
-
 
155
                        while (outSampleCount == sampleCount)
145
    if(++outSampleRefCount == SAMPLE_BUFF_SIZE)
156
                                chThdSleep(10);
-
 
157
 
-
 
158
                        uint16_t nextTime = getSampleBuff(outSampleCount);
-
 
159
 
-
 
160
                        // calculate wrapped time delta : should be > than bounce time to allow
-
 
161
                        uint16_t diffTime = nextTime - thisTime;
-
 
162
 
-
 
163
                        if(diffTime > BREAKER_COUNT_MIN)
-
 
164
                        {
-
 
165
                                lastSampleIndex = outSampleCount;
146
        outSampleRefCount = 0;
166
                                return nextTime;
147
    return sampleIndex;
167
                        }
-
 
168
 
-
 
169
        }
-
 
170
  return 0;
-
 
171
}
148
}
172
 
149
 
173
 
150
 
-
 
151
 
174
void processNextPulse(uint16_t retVal)
152
void processNextPulse(uint16_t index)
175
{
153
{
176
 
154
 
177
        static uint32_t VperiodAccumulator = 0;
-
 
178
    // scale it up by 32
155
    // scale it up by 32
179
        static uint32_t periodEstimate = 2000 * 256 ;
156
        static int32_t periodEstimate = 2000 * 256 ;
180
        static uint16_t lastVal = 0;
-
 
181
        // at this point we should try to phase lock
157
        // at this point we should try to phase lock
182
    deltaTime = retVal - lastVal;
158
     static signed pdLast = 0;
-
 
159
        uint16_t sampleDiff = sampleDiffBuff[index];
183
 
160
 
184
 
161
 
-
 
162
    signed pd = (sampleDiff <  32768 ? sampleDiff : sampleDiff - 65536L) ;
185
 
163
 
186
    if(deltaTime > 10000)
-
 
187
    {
-
 
188
        __asm(" BKPT #0");
-
 
189
    }
-
 
190
 
164
 
191
    lastVal = retVal;
-
 
192
 
165
 
193
    // look at the values and try to pull them togwther
166
    static float phase_offset = 0;
-
 
167
    float const wn = 0.01f;
-
 
168
    float const zeta = 0.707f;
-
 
169
    float const K = 100;
194
 
170
 
195
    // accumulate phase
171
    float const t1 = K/(wn*wn);
196
    VperiodAccumulator += periodEstimate;
172
    float const t2 = 2 * zeta/wn;
-
 
173
    float const  b0 = (4*K/t1)*(1.+t2/2.0f);
197
    VperiodAccumulator &= 0xFFFFFFF;
174
    float const b1 = (8*K / t1);
-
 
175
    float const b2 = (4*K/t1)*(1.-t2/2.0f);
198
 
176
 
199
    uint16_t accum_low = (VperiodAccumulator) >> 8;
177
    float const a1 = -2.0f;
200
#define WINDOW 1000
178
    float const a2 = 1.0f;
201
 
179
 
202
#define LIMIT 2048
180
    static float v0=0.0f, v1 = 0.0f, v2 = 0.0f;
203
 
181
 
204
#define STEP 32
-
 
205
 
182
 
206
    uint16_t diff = accum_low - retVal;
-
 
207
    if(diff < WINDOW && diff != 0)
183
    static float phi_hat = 0.0f;
208
        pdI += diff/10;
-
 
209
    if(diff > 65536-WINDOW )
-
 
210
        pdI -= (65536-diff)/10;
-
 
211
 
184
 
212
    if(pdI > LIMIT)
-
 
213
        pdI = LIMIT;
-
 
214
    if(pdI < -(LIMIT))
-
 
215
        pdI = -(LIMIT);
185
    float delta_phi = pd/ 32768.0;
216
 
186
 
-
 
187
    v2=v1; v1=v0;
-
 
188
    v0 = delta_phi -v1 *a1 -v2 *a2;
217
 
189
 
-
 
190
    phi_hat = v0 * b0 + v1 * b1 + v2 * b2;
218
 
191
 
219
    signed pd = (signed)(periodEstimate)- (signed)(deltaTime*256) + pdI;
-
 
220
 
192
 
221
 
193
 
-
 
194
    uint16_t arr = phi_hat < 100 ? 100 : phi_hat;
-
 
195
    // compute period error
222
    periodEstimate -= pd / 100;
196
      // periodErr +=   periodEstimate - (arr * 256);
223
 
197
 
224
 
198
 
-
 
199
     count = arr;
-
 
200
     delta = pd;
225
 
201
 
226
    TIM2->ARR = (periodEstimate+128)/256 ;
202
    TIM2->ARR = arr ;
227
    recalcPhase();
203
    recalcPhase();
228
 
204
 
229
 
205
 
230
 
206
 
231
// calculate RPM
207
// calculate RPM
Line 252... Line 228...
252
}
228
}
253
 
229
 
254
// timer 3 interrupt
230
// timer 3 interrupt
255
void VectorB4(void)
231
void VectorB4(void)
256
{
232
{
-
 
233
    static uint16_t lastSampleRef = 0;
-
 
234
 
-
 
235
    static uint8_t refCount = 0;
-
 
236
        static uint8_t varCount = 0;
-
 
237
 
257
        uint16_t stat = TIM3->SR;
238
        uint16_t stat = TIM3->SR;
258
        if(stat & TIM_SR_CC1IF)
239
        if(stat & TIM_SR_CC1IF)
259
        {
240
        {
260
                TIM3->SR &= ~TIM_SR_CC1IF;
241
                TIM3->SR &= ~TIM_SR_CC1IF;
261
            uint16_t sample = TIM3->CCR1;
242
                uint16_t sample = TIM3->CCR1;
262
            sampleBuff[sampleCount++] = sample;
243
                if(sample-lastSampleRef >  100 /*BREAKER_COUNT_MIN */)
-
 
244
                {
263
            if (sampleCount >= SAMPLE_BUFF_SIZE)
245
                        sampleRef = sample;
-
 
246
                        ++refCount;
-
 
247
                }
264
                sampleCount = 0;
248
                lastSampleRef = sample;
265
        }
249
        }
-
 
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
 
266
}
284
}
267
 
285
 
268
 
286
 
269
 
287