Rev 13 | Rev 17 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 13 | Rev 14 | ||
|---|---|---|---|
| Line 19... | Line 19... | ||
| 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 ) ))) |
21 | #define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) ))) |
| 22 | 22 | ||
| 23 | 23 | ||
| - | 24 | ||
| - | 25 | ||
| 24 | #define SAMPLE_BUFF_SIZE 256 |
26 | #define SAMPLE_BUFF_SIZE 16 |
| 25 | uint16_t nominal = 0; |
27 | uint16_t nominal = 0; |
| 26 | uint16_t halfRot; |
28 | uint16_t halfRot; |
| 27 | uint16_t phase10 = 100; // 10 degrees |
29 | uint16_t phase10 = 100; // 10 degrees |
| 28 | volatile uint16_t sampleRefCount = 0; |
30 | volatile uint16_t sampleRefCount = 0; |
| 29 | uint16_t outSampleRefCount = 0; |
31 | uint16_t outSampleRefCount = 0; |
| 30 | volatile uint16_t sampleRefBuff[SAMPLE_BUFF_SIZE]; |
- | |
| 31 | volatile uint16_t sampleVar; |
32 | volatile uint16_t sampleVar; |
| 32 | volatile uint16_t sampleRef; |
33 | volatile uint16_t sampleRef; |
| 33 | volatile uint16_t sampleDiffBuff[SAMPLE_BUFF_SIZE]; |
34 | volatile uint16_t sampleDiffBuff[SAMPLE_BUFF_SIZE]; |
| - | 35 | volatile uint16_t samplePeriodBuff[SAMPLE_BUFF_SIZE]; |
|
| - | 36 | volatile uint8_t refCountBuff[SAMPLE_BUFF_SIZE]; |
|
| - | 37 | volatile uint8_t varCountBuff[SAMPLE_BUFF_SIZE]; |
|
| - | 38 | ||
| - | 39 | volatile uint8_t haveSlowPulse = 0; |
|
| 34 | 40 | ||
| 35 | uint16_t rpm; |
41 | uint16_t rpm; |
| 36 | uint16_t count; |
42 | uint16_t count; |
| 37 | uint16_t delta; |
43 | uint16_t delta; |
| 38 | 44 | ||
| Line 131... | Line 137... | ||
| 131 | { |
137 | { |
| 132 | return count; |
138 | return count; |
| 133 | } |
139 | } |
| 134 | 140 | ||
| 135 | 141 | ||
| - | 142 | uint8_t slowPulse(void) |
|
| - | 143 | { |
|
| - | 144 | return haveSlowPulse; |
|
| - | 145 | } |
|
| - | 146 | ||
| 136 | // waits for ignition pulse , debounces readings, |
147 | // waits for ignition pulse reading in the buffer, returns |
| 137 | // returns the pulse time, skips debounce time |
148 | // the sample index of the next sample. |
| - | 149 | ||
| 138 | uint16_t getNextRefPulseIndex(void) |
150 | uint16_t getNextRefPulseIndex(void) |
| 139 | { |
151 | { |
| 140 | while (outSampleRefCount == sampleRefCount) |
152 | while (outSampleRefCount == sampleRefCount) |
| 141 | chThdSleep(10); |
153 | chThdSleep(10); |
| 142 | 154 | ||
| Line 146... | Line 158... | ||
| 146 | outSampleRefCount = 0; |
158 | outSampleRefCount = 0; |
| 147 | return sampleIndex; |
159 | return sampleIndex; |
| 148 | } |
160 | } |
| 149 | 161 | ||
| 150 | 162 | ||
| 151 | - | ||
| 152 | void processNextPulse(uint16_t index) |
163 | void processNextPulse(uint16_t index) |
| 153 | { |
164 | { |
| 154 | 165 | ||
| 155 | // scale it up by 32 |
166 | // scale it up by 32 |
| 156 | static int32_t periodEstimate = 2000 * 256 ; |
167 | static int32_t periodEstimate = 2000 * 256 ; |
| 157 | // at this point we should try to phase lock |
168 | // at this point we should try to phase lock |
| 158 | static signed pdLast = 0; |
- | |
| - | 169 | ||
| 159 | uint16_t sampleDiff = sampleDiffBuff[index]; |
170 | uint16_t sampleDiff = sampleDiffBuff[index]; |
| 160 | 171 | ||
| - | 172 | signed pd = 0; |
|
| - | 173 | bool lock = false; |
|
| - | 174 | // basically locked |
|
| - | 175 | if(refCountBuff[index]==1 && varCountBuff[index]==1 ) |
|
| - | 176 | { |
|
| - | 177 | lock = true; |
|
| - | 178 | pd = (sampleDiff < 32768 ? sampleDiff : sampleDiff - 65536L) ; |
|
| - | 179 | } |
|
| - | 180 | else if (refCountBuff[index] > 1) |
|
| - | 181 | { |
|
| - | 182 | pd = (refCountBuff [index]*32768L); |
|
| - | 183 | } |
|
| - | 184 | else if (varCountBuff[index] > 1) |
|
| - | 185 | { |
|
| - | 186 | pd = (-varCountBuff[index] * 32768L); |
|
| - | 187 | } |
|
| - | 188 | float delta_phi = pd/ 2000; |
|
| - | 189 | ||
| - | 190 | ||
| 161 | 191 | ||
| - | 192 | ||
| 162 | signed pd = (sampleDiff < 32768 ? sampleDiff : sampleDiff - 65536L) ; |
193 | // phase detector returns +/ |
| 163 | 194 | ||
| 164 | 195 | ||
| 165 | 196 | ||
| 166 | static float phase_offset = 0; |
- | |
| 167 | float const wn = 0.01f; |
197 | float const wn = 0.01f; |
| 168 | float const zeta = 0.707f; |
198 | float const zeta = 0.707f; |
| 169 | float const K = 100; |
199 | float const K = 1; |
| 170 | 200 | ||
| 171 | float const t1 = K/(wn*wn); |
201 | float const t1 = K/(wn*wn); |
| 172 | float const t2 = 2 * zeta/wn; |
202 | float const t2 = 2 * zeta/wn; |
| 173 | float const b0 = (4*K/t1)*(1.+t2/2.0f); |
203 | float const b0 = (4*K/t1)*(1.+t2/2.0f); |
| 174 | float const b1 = (8*K / t1); |
204 | float const b1 = (8*K / t1); |
| 175 | float const b2 = (4*K/t1)*(1.-t2/2.0f); |
205 | float const b2 = (4*K/t1)*(1.-t2/2.0f); |
| 176 | 206 | ||
| 177 | float const a1 = -2.0f; |
207 | float const a1 = -2.0f; |
| 178 | float const a2 = 1.0f; |
208 | float const a2 = 1.0f; |
| 179 | - | ||
| 180 | static float v0=0.0f, v1 = 0.0f, v2 = 0.0f; |
209 | static float v0=0, v1 = 0, v2 = 0 ; |
| 181 | 210 | ||
| 182 | 211 | ||
| 183 | static float phi_hat = 0.0f; |
212 | static float phi_hat = 0.0f; |
| 184 | 213 | ||
| 185 | float delta_phi = pd/ 32768.0; |
- | |
| 186 | 214 | ||
| 187 | v2=v1; v1=v0; |
215 | v2=v1; v1=v0; |
| 188 | v0 = delta_phi -v1 *a1 -v2 *a2; |
216 | v0 = delta_phi -v1 *a1 -v2 *a2; |
| 189 | 217 | ||
| 190 | phi_hat = v0 * b0 + v1 * b1 + v2 * b2; |
- | |
| 191 | 218 | ||
| - | 219 | phi_hat = v0 * b0 + v1 * b1 + v2 * b2 ; |
|
| - | 220 | delta = phi_hat; |
|
| - | 221 | ||
| - | 222 | // 6.283 = 1.0 Hz |
|
| - | 223 | ||
| - | 224 | // 62.2 = 10Hz |
|
| - | 225 | // decide on whether to go for forcing loop or to track |
|
| - | 226 | ||
| - | 227 | int32_t arr; |
|
| 192 | 228 | ||
| - | 229 | // if(lock) |
|
| 193 | 230 | ||
| - | 231 | ||
| 194 | uint16_t arr = phi_hat < 100 ? 100 : phi_hat; |
232 | arr = (6283000L/MICROSECS_PULSE)/ phi_hat; |
| - | 233 | ||
| - | 234 | if(arr > 5000) |
|
| - | 235 | arr = 5000; |
|
| - | 236 | if(arr < 500) |
|
| - | 237 | arr = 500; |
|
| - | 238 | ||
| 195 | // compute period error |
239 | // compute period error] |
| 196 | // periodErr += periodEstimate - (arr * 256); |
240 | // periodErr += periodEstimate - (arr * 256); |
| 197 | 241 | ||
| 198 | 242 | ||
| 199 | count = arr; |
243 | count = arr; |
| 200 | delta = pd; |
- | |
| 201 | 244 | ||
| 202 | TIM2->ARR = arr ; |
245 | TIM2->ARR = arr ; |
| 203 | recalcPhase(); |
246 | recalcPhase(); |
| 204 | 247 | ||
| 205 | 248 | ||
| Line 229... | Line 272... | ||
| 229 | 272 | ||
| 230 | // timer 3 interrupt |
273 | // timer 3 interrupt |
| 231 | void VectorB4(void) |
274 | void VectorB4(void) |
| 232 | { |
275 | { |
| 233 | static uint16_t lastSampleRef = 0; |
276 | static uint16_t lastSampleRef = 0; |
| 234 | - | ||
| 235 | static uint8_t refCount = 0; |
277 | static uint8_t refCount = 0; |
| 236 | static uint8_t varCount = 0; |
278 | static uint8_t varCount = 0; |
| - | 279 | uint16_t samplePeriod; |
|
| 237 | 280 | ||
| 238 | uint16_t stat = TIM3->SR; |
281 | uint16_t stat = TIM3->SR; |
| 239 | if(stat & TIM_SR_CC1IF) |
282 | if(stat & TIM_SR_CC1IF) |
| 240 | { |
283 | { |
| 241 | TIM3->SR &= ~TIM_SR_CC1IF; |
284 | TIM3->SR &= ~TIM_SR_CC1IF; |
| 242 | uint16_t sample = TIM3->CCR1; |
285 | uint16_t sample = TIM3->CCR1; |
| 243 | if(sample-lastSampleRef > 100 /*BREAKER_COUNT_MIN */) |
286 | if(sample-lastSampleRef > 100 /*BREAKER_COUNT_MIN */) |
| 244 | { |
287 | { |
| 245 | sampleRef = sample; |
288 | sampleRef = sample; |
| - | 289 | ||
| 246 | ++refCount; |
290 | ++refCount; |
| 247 | } |
291 | } |
| - | 292 | samplePeriod = sample-lastSampleRef; |
|
| - | 293 | ||
| - | 294 | chDbgCheck(samplePeriod != 65535); |
|
| 248 | lastSampleRef = sample; |
295 | lastSampleRef = sample; |
| 249 | } |
296 | } |
| 250 | if(stat & TIM_SR_CC2IF) |
297 | if(stat & TIM_SR_CC2IF) |
| 251 | { |
298 | { |
| 252 | TIM3->SR &= ~TIM_SR_CC2IF; |
299 | TIM3->SR &= ~TIM_SR_CC2IF; |
| 253 | sampleVar = TIM3->CCR2; |
300 | sampleVar = TIM3->CCR2; |
| Line 258... | Line 305... | ||
| 258 | 305 | ||
| 259 | 306 | ||
| 260 | if(refCount != 0 && varCount != 0 ) /*we have an R,V pair */ |
307 | if(refCount != 0 && varCount != 0 ) /*we have an R,V pair */ |
| 261 | { |
308 | { |
| 262 | 309 | ||
| - | 310 | // |
|
| - | 311 | ||
| - | 312 | refCountBuff[sampleRefCount] = refCount; |
|
| - | 313 | varCountBuff[sampleRefCount] = varCount; |
|
| - | 314 | ||
| - | 315 | ||
| - | 316 | haveSlowPulse = (varCount > 20); |
|
| - | 317 | ||
| - | 318 | ||
| - | 319 | ||
| - | 320 | sampleDiffBuff[sampleRefCount] = sampleRef - sampleVar; |
|
| 263 | 321 | ||
| 264 | if(refCount < varCount) |
- | |
| 265 | sampleDiffBuff[sampleRefCount] = 32767; // indicate +ve max phase |
322 | samplePeriodBuff[sampleRefCount] = samplePeriod; |
| 266 | 323 | ||
| 267 | if(refCount > varCount ) |
- | |
| 268 | sampleDiffBuff[sampleRefCount] = 65536-32767 ; // indicate -ve max phase |
- | |
| 269 | 324 | ||
| 270 | if(varCount == refCount) |
- | |
| 271 | sampleDiffBuff[sampleRefCount] = sampleRef - sampleVar; |
- | |
| 272 | 325 | ||
| 273 | if(sampleRef) |
- | |
| 274 | sampleRefBuff[sampleRefCount] = sampleRef; |
- | |
| 275 | if(++sampleRefCount == SAMPLE_BUFF_SIZE) |
326 | if(++sampleRefCount == SAMPLE_BUFF_SIZE) |
| 276 | sampleRefCount = 0; |
327 | sampleRefCount = 0; |
| 277 | 328 | ||
| 278 | refCount = 0; |
329 | refCount = 0; |
| 279 | varCount = 0; |
330 | varCount = 0; |