Subversion Repositories chibiosIgnition

Rev

Rev 23 | 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"
23 mjames 12
#define  MICROSECS_PULSE 4
6 mjames 13
 
14
// with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000
15
// freq = 5000/60 * 2 = 166Hz. Because the breaker might bounce , we accept the
16
// first pulse longer than 1/300 of a second as being a proper closure .
20 mjames 17
// the TIM2 counter counts in 1uS increments,
6 mjames 18
#define BREAKER_COUNT_MIN (1E6/(MICROSECS_PULSE * 300))
19
 
13 mjames 20
#define COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
21
 
20 mjames 22
int16_t nominal = 0;
6 mjames 23
uint16_t halfRot;
20 mjames 24
int16_t phase10 = 100; // 10 degrees
19 mjames 25
volatile uint16_t sampleVar;
13 mjames 26
volatile uint16_t sampleRef;
6 mjames 27
 
19 mjames 28
volatile uint16_t lastSampleRef = 0;
17 mjames 29
 
19 mjames 30
volatile uint8_t refCount = 0;
31
volatile uint8_t varCount = 0;
17 mjames 32
 
23 mjames 33
volatile uint16_t samplePeriod = 0;
14 mjames 34
 
19 mjames 35
static signed phaseSamp = 0;
36
static uint8_t validPhaseSamp = 0;
6 mjames 37
 
24 mjames 38
static uint8_t locked = 0; // in lock if true
23 mjames 39
int gainControl = 1000;
6 mjames 40
 
19 mjames 41
uint16_t rpm;
42
signed count;
43
signed delta;
6 mjames 44
 
23 mjames 45
void
46
recalcPhase ()
6 mjames 47
{
23 mjames 48
  nominal = halfRot * (long) (phase10) / 3600;
6 mjames 49
}
50
 
23 mjames 51
void
52
adjustRPM (void)
6 mjames 53
{
24 mjames 54
  if (rpm < 500)
55
    rpm = 500;
56
  if (rpm > 10000)
57
    rpm = 10000;
6 mjames 58
 
59
}
60
 
23 mjames 61
uint16_t
62
setRPM (uint16_t rpm_)
6 mjames 63
{
24 mjames 64
  if (rpm_ >= 500 && rpm_ < 10000)
23 mjames 65
    {
66
      rpm = rpm_;
67
      adjustRPM ();
68
    }
69
  return halfRot;
6 mjames 70
}
71
 
23 mjames 72
uint16_t
73
getRPM (void)
6 mjames 74
{
23 mjames 75
  return rpm;
6 mjames 76
}
77
 
23 mjames 78
signed
79
getDelta (void)
11 mjames 80
{
23 mjames 81
  return delta;
11 mjames 82
}
83
 
23 mjames 84
signed
85
getCount (void)
6 mjames 86
{
23 mjames 87
  return count;
6 mjames 88
}
89
 
23 mjames 90
void
91
setGain (int gain)
17 mjames 92
{
23 mjames 93
  gainControl = gain;
17 mjames 94
}
6 mjames 95
 
23 mjames 96
void
97
processPhase (void)
6 mjames 98
{
23 mjames 99
  // lpcl
24 mjames 100
  const signed pdClip = 1000;
23 mjames 101
  static signed pd;
102
  if (validPhaseSamp)
103
    {
104
      chSysLock ();
6 mjames 105
 
23 mjames 106
      pd = phaseSamp - nominal;
14 mjames 107
 
23 mjames 108
      validPhaseSamp = 0;
109
      chSysUnlock ();
6 mjames 110
 
23 mjames 111
      if (pd > pdClip)
112
        pd = pdClip;
113
      if (pd < -pdClip)
114
        pd = -pdClip;
11 mjames 115
 
23 mjames 116
    }
117
  else
118
    return;
20 mjames 119
 
23 mjames 120
  delta = pd;
20 mjames 121
 
23 mjames 122
  static int sampleAverage = 0;
11 mjames 123
 
23 mjames 124
  static int phaseAverage = 0;
24 mjames 125
  const int freqScale = 1024;  // scale up calculations
11 mjames 126
 
24 mjames 127
  const int periodScale = 8; // 1/periodScale  of difference between period measured and average is added to period.
128
  const int phaseScale = 500;
129
  const int phaseLim = 1; // total contribution of phase accumulator
23 mjames 130
  // measure sample period devi
24 mjames 131
  sampleAverage = sampleAverage
132
      + (samplePeriod * freqScale - sampleAverage) / periodScale;
20 mjames 133
 
23 mjames 134
  int32_t arr;
6 mjames 135
 
23 mjames 136
  //    if(lock)
17 mjames 137
 
24 mjames 138
  int intSample = sampleAverage;
14 mjames 139
 
24 mjames 140
  // dont phase lock until r and v in lock
141
  if (locked == 1)
23 mjames 142
    {
24 mjames 143
      phaseAverage += pd;
23 mjames 144
    }
24 mjames 145
  else
146
    {
147
      phaseAverage = 0;
148
    }
6 mjames 149
 
24 mjames 150
  if(phaseAverage > phaseScale * phaseLim)
151
    phaseAverage = phaseScale * phaseLim;
152
  if (phaseAverage < -phaseScale * phaseLim)
153
    phaseAverage = -phaseScale *phaseLim;
11 mjames 154
 
24 mjames 155
  arr = sampleAverage / freqScale + phaseAverage / phaseScale;
156
 
21 mjames 157
// clamp values
14 mjames 158
 
23 mjames 159
  if (arr > 65535)
160
    arr = 65535;
161
  if (arr < 1000)
162
    arr = 1000;
14 mjames 163
 
23 mjames 164
  count = arr;
14 mjames 165
 
23 mjames 166
  TIM2->ARR = arr - 1;
12 mjames 167
 
24 mjames 168
  nominal = count * (long) (phase10) / 3600;
12 mjames 169
 
23 mjames 170
  float nomRPM = 30E6 / (MICROSECS_PULSE * arr);
12 mjames 171
 
23 mjames 172
  rpm = nomRPM;
12 mjames 173
 
23 mjames 174
  adjustRPM ();
175
}
12 mjames 176
 
20 mjames 177
// set the timing advance from reference in 0.1 degrees units
23 mjames 178
void
179
setAdvance (int16_t deg10)
6 mjames 180
{
23 mjames 181
  phase10 = deg10;
6 mjames 182
 
183
}
184
 
19 mjames 185
// specialist timer setup :
21 mjames 186
// timer 2 is a reloading counter with a cycle period controlled by its ARR register.
187
// Just before terminal count it produces a pulse of 200 microseconds using its CCR1 count compare register,
188
// used to drive the strobe LED.
189
// Timer 3 is then used to count the time of the reload of Timer 2 via its Trigger Out being selected as reload.
190
// The time is latched in TIM3  CCR2
191
// and ignition pulses are latched on TIM3 CCR1, to allow it to be used in a PLL.
192
//
23 mjames 193
void
194
initTimers ()
19 mjames 195
{
23 mjames 196
  rccEnableTIM2 (FALSE);
197
  rccResetTIM2 ();
19 mjames 198
 
23 mjames 199
  TIM2->PSC = 72 * MICROSECS_PULSE;
200
  TIM2->ARR = 60000;
201
  TIM2->CR1 = ~TIM_CR1_CKD & (TIM_CR1_CEN | TIM_CR1_ARPE);
19 mjames 202
 
23 mjames 203
  /// pulse width 200 uS
204
  TIM2->CCR1 = 200 / MICROSECS_PULSE;
19 mjames 205
 
23 mjames 206
  TIM2->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; //enabled and active high
19 mjames 207
 
23 mjames 208
  TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2
209
      | TIM_CCMR1_OC1PE;
19 mjames 210
 
23 mjames 211
  TIM2->CR2 = TIM_CR2_MMS_1; // trigger out is 010 = update
19 mjames 212
 
23 mjames 213
  rccEnableTIM3 (FALSE);
214
  rccResetTIM3 ();
215
  // TIM3 on the PA6 ... pins : remap code 00
216
  AFIO->MAPR &= ~AFIO_MAPR_TIM3_REMAP;
19 mjames 217
 
23 mjames 218
  TIM3->PSC = 72 * MICROSECS_PULSE;
219
  TIM3->ARR = 0xFFFF;
19 mjames 220
 
23 mjames 221
  TIM3->CCMR1 =
222
      TIM_CCMR1_CC1S_0 /* | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1 | TIM_CCMR1_IC1F_2 */; // filter 16, input
19 mjames 223
 
23 mjames 224
  // link TIM3 ITR2 to TIM2 reload
225
  // use TS = 001 to make TRC from Tim2 TRIGGER
226
  TIM3->SMCR &= ~(TIM_SMCR_TS_Msk);
227
  TIM3->SMCR |= TIM_SMCR_TS_0; // select ITR2 as trigger source TRC
19 mjames 228
 
23 mjames 229
  TIM3->CCMR1 |= TIM_CCMR1_CC2S_1 | TIM_CCMR1_CC2S_0; //  The CC2S bits are 11, use TRC
19 mjames 230
 
23 mjames 231
  TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
19 mjames 232
 
23 mjames 233
  TIM3->CR1 = ~TIM_CR1_CKD & (TIM_CR1_CEN | TIM_CR1_ARPE);
19 mjames 234
 
23 mjames 235
  nvicEnableVector (TIM3_IRQn, 4);
19 mjames 236
 
23 mjames 237
  TIM3->DIER |= TIM_DIER_CC1IE | TIM_DIER_CC2IE;
19 mjames 238
}
239
 
6 mjames 240
// timer 3 interrupt
23 mjames 241
void
242
VectorB4 (void)
6 mjames 243
{
13 mjames 244
 
23 mjames 245
  if (TIM3->SR & TIM_SR_CC1IF)
246
    {
247
      uint16_t sample = TIM3->CCR1;
248
//              if(sample-lastSampleRef >  1000 /*BREAKER_COUNT_MIN */)
6 mjames 249
        {
14 mjames 250
 
23 mjames 251
          samplePeriod = sample - sampleRef;
19 mjames 252
 
23 mjames 253
          sampleRef = sample;
19 mjames 254
 
23 mjames 255
          ++refCount;
6 mjames 256
        }
23 mjames 257
      lastSampleRef = sample;
13 mjames 258
 
23 mjames 259
    }
260
  if (TIM3->SR & TIM_SR_CC2IF)
19 mjames 261
    {
23 mjames 262
      sampleVar = TIM3->CCR2;
263
      ++varCount;
264
    }
13 mjames 265
 
23 mjames 266
  if (refCount == 1 && varCount == 1)
267
    {
268
      if (sampleRef == sampleVar)
269
        phaseSamp = 0;
270
      else
271
        {
13 mjames 272
 
23 mjames 273
          uint16_t refToVar = sampleRef - sampleVar;
274
          uint16_t varToRef = sampleVar - sampleRef;
13 mjames 275
 
23 mjames 276
          if (refToVar < varToRef)
277
            phaseSamp = refToVar;
278
          else if (varToRef <= refToVar)
279
            phaseSamp = -varToRef;
13 mjames 280
 
23 mjames 281
        }
13 mjames 282
 
23 mjames 283
      validPhaseSamp = 1;
284
      refCount = 0;
285
      varCount = 0;
24 mjames 286
      locked = 1;
19 mjames 287
    }
13 mjames 288
 
24 mjames 289
 
23 mjames 290
  if (refCount > 1 || varCount > 1)
19 mjames 291
    {
23 mjames 292
      refCount = 0;
293
      varCount = 0;
24 mjames 294
      locked = 0;
19 mjames 295
    }
296
 
6 mjames 297
}
298