Subversion Repositories chibiosIgnition

Rev

Rev 8 | Rev 12 | 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
 
21
#define SAMPLE_BUFF_SIZE 256
22
uint16_t halfRot;
23
uint16_t nominal  = 0;
24
uint16_t phase10 = 100; // 10 degrees
25
volatile uint16_t sampleCount = 0;
26
uint16_t outSampleCount = 0;
27
volatile uint16_t sampleBuff[SAMPLE_BUFF_SIZE];
11 mjames 28
typedef enum { WAIT_GAP, SKIP_BOUNCE, HAVE_SAMPLE } sampleState_t ;
6 mjames 29
sampleState_t  sampleState = WAIT_GAP;
11 mjames 30
// difference between samples
31
volatile uint16_t deltaTime;
6 mjames 32
 
33
 
34
uint16_t rpm;
35
 
36
void initTimer2()
37
{
38
        rccEnableTIM2(FALSE);
39
        rccResetTIM2();
40
 
41
        TIM2->PSC = 72*MICROSECS_PULSE;
42
        TIM2->ARR = 60000;
43
        TIM2->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN |
44
                        TIM_CR1_ARPE );
45
 
7 mjames 46
        /// pulse width 200 uS
47
        TIM2->CCR1 = 200/MICROSECS_PULSE;
6 mjames 48
 
11 mjames 49
    TIM2->CCER =  TIM_CCER_CC1E | TIM_CCER_CC1P  ; //enabled and active high
6 mjames 50
 
11 mjames 51
    TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
6 mjames 52
                           TIM_CCMR1_OC1PE ;
53
 
54
 
55
    TIM2->CR2 = TIM_CR2_MMS_1 ; // trigger out is 010 = update
56
 
57
 
58
    // change the TIM2 CC2 to TIM3 CC1
59
        rccEnableTIM3(FALSE);
60
        rccResetTIM3();
61
        // TIM3 on the PA6 ... pins : remap code 00
62
        AFIO->MAPR &= ~ AFIO_MAPR_TIM3_REMAP;
63
 
64
        TIM3->PSC = 72*MICROSECS_PULSE;
65
        TIM3->ARR = 0xFFFF;
66
 
67
 
68
        TIM3->CCMR1 = TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */ ;  // filter 16, input
69
 
70
        TIM3->CCER = TIM_CCER_CC1E;
71
 
72
    // link TIM3 ITR1 to TIM2 reload
73
    // use CCR3
74
    TIM3->CCMR2 = TIM_CCMR2_CC3S_1 | TIM_CCMR2_CC3S_0 ; //  The
75
 
76
 
77
        TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
78
 
79
 
80
    nvicEnableVector(TIM3_IRQn,
7 mjames 81
                          4);
6 mjames 82
 
83
 
84
 
85
    TIM3->DIER |= TIM_DIER_CC1IE ;
86
}
87
 
88
 
89
void recalcPhase(void)
90
{
91
        nominal = halfRot * (long) (phase10)/ 1800;
92
}
93
 
94
void adjustRPM(void)
95
{
96
        if(rpm < 600)
97
                rpm = 600;
98
        if(rpm >  5000)
99
                rpm = 5000;
100
 
101
 
102
        float pulseSec = rpm /30;
103
 
104
halfRot = 1e6 / (pulseSec * MICROSECS_PULSE) ;
105
 
106
  TIM2->ARR = halfRot;
107
recalcPhase();
108
}
109
 
110
uint16_t setRPM(uint16_t rpm_ )
111
{
112
        if(rpm_ >= 600 && rpm_ < 5000)
113
        {
114
          rpm = rpm_;
115
          adjustRPM();
116
        }
117
          return halfRot;
118
}
119
 
120
uint16_t getRPM(void)
121
{
122
        return rpm;
123
}
124
 
11 mjames 125
uint16_t getDelta(void)
126
{
127
        return deltaTime;
128
}
129
 
6 mjames 130
uint16_t wrapIndex(uint16_t index)
131
{
11 mjames 132
        if (index >= SAMPLE_BUFF_SIZE)
6 mjames 133
                index -= SAMPLE_BUFF_SIZE;
134
    return index;
135
}
136
 
137
 
138
// allows for wrapping
139
uint16_t getSampleBuff(uint16_t index)
140
{
11 mjames 141
        chSysLock();
6 mjames 142
        return sampleBuff[wrapIndex(index)];
11 mjames 143
        chSysUnlock();
6 mjames 144
}
145
 
11 mjames 146
 
147
// waits for ignition pulse , debounces readings,
148
// returns the pulse time, skips debounce time
6 mjames 149
uint16_t getNextPulse(void)
150
{
11 mjames 151
        static uint16_t lastSampleIndex = 0;
152
        while(1)
6 mjames 153
        {
11 mjames 154
                        while (outSampleCount == sampleCount)
155
                                chThdSleep(10);
6 mjames 156
 
11 mjames 157
                        uint16_t thisTime  = getSampleBuff(outSampleCount);
6 mjames 158
 
11 mjames 159
                        outSampleCount = wrapIndex(outSampleCount + 1);
160
                        while (outSampleCount == sampleCount)
161
                                chThdSleep(10);
6 mjames 162
 
163
                        uint16_t nextTime = getSampleBuff(outSampleCount);
164
 
165
                        // calculate wrapped time delta : should be > than bounce time to allow
11 mjames 166
                        uint16_t diffTime = nextTime - thisTime;
6 mjames 167
 
11 mjames 168
                        if(diffTime > BREAKER_COUNT_MIN)
6 mjames 169
                        {
11 mjames 170
                                lastSampleIndex = outSampleCount;
171
                                return nextTime;
6 mjames 172
                        }
173
 
174
        }
11 mjames 175
  return 0;
176
}
6 mjames 177
 
11 mjames 178
 
179
void processNextPulse(uint16_t retVal)
180
{
181
 
182
        static uint16_t lastVal = 0;
6 mjames 183
        // at this point we should try to phase lock
11 mjames 184
    deltaTime = retVal - lastVal;
6 mjames 185
 
11 mjames 186
 
187
 
188
    if(deltaTime > 10000)
189
    {
190
        __asm(" BKPT #0");
191
    }
192
 
6 mjames 193
    lastVal = retVal;
194
 
195
 
11 mjames 196
 
197
 
198
 
199
    float nomRPM = 30E6 / (MICROSECS_PULSE * deltaTime) ;
200
 
6 mjames 201
        rpm = rpm + (nomRPM -rpm)/10;
202
 
203
 
204
 
205
 
206
        uint16_t skew = 32768 - nominal;
207
 
208
        long delta = (retVal+skew) - (nominal+skew);
209
 
210
        if(delta > 10)
211
                rpm = rpm - 1;
212
        if(delta -10)
213
                rpm = rpm + 1;
214
 
215
//      rpm += delta / 256;
216
 
217
        adjustRPM();
11 mjames 218
    }
6 mjames 219
 
220
 
221
 
11 mjames 222
 
6 mjames 223
// set the timing advance from reference to
224
void setAdvance(int16_t deg10)
225
{
226
    phase10 = deg10;
227
    recalcPhase();
228
 
229
}
230
 
231
// timer 3 interrupt
232
void VectorB4(void)
233
{
234
        uint16_t stat = TIM3->SR;
235
        if(stat & TIM_SR_CC1IF)
236
        {
237
                TIM3->SR &= ~TIM_SR_CC1IF;
238
            uint16_t sample = TIM3->CCR1;
239
            sampleBuff[sampleCount++] = sample;
11 mjames 240
            if (sampleCount >= SAMPLE_BUFF_SIZE)
6 mjames 241
                sampleCount = 0;
242
        }
243
}
244
 
245
 
246