Subversion Repositories chibiosIgnition

Rev

Rev 12 | Rev 14 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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 COUNT_FROM_RPM(RPM) ((1E6/(MICROSECS_PULSE * 30 / (RPM ) )))
  22.  
  23.  
  24. #define SAMPLE_BUFF_SIZE 256
  25. uint16_t nominal = 0;
  26. uint16_t halfRot;
  27. uint16_t phase10 = 100; // 10 degrees
  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];
  34.  
  35. uint16_t rpm;
  36. uint16_t count;
  37. uint16_t delta;
  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.  
  49.         /// pulse width 200 uS
  50.         TIM2->CCR1 = 200/MICROSECS_PULSE;
  51.  
  52.     TIM2->CCER =  TIM_CCER_CC1E | TIM_CCER_CC1P  ; //enabled and active high
  53.  
  54.     TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
  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.  
  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
  78.  
  79.     TIM3->CCMR1 |=  TIM_CCMR1_CC2S_1 |  TIM_CCMR1_CC2S_0 ; //  The CC2S bits are 11, use TRC
  80.  
  81.         TIM3->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E;
  82.  
  83.         TIM3->CR1 = ~TIM_CR1_CKD  & (TIM_CR1_CEN | TIM_CR1_ARPE );
  84.  
  85.  
  86.     nvicEnableVector(TIM3_IRQn,
  87.                           4);
  88.  
  89.  
  90.  
  91.     TIM3->DIER |= TIM_DIER_CC1IE  | TIM_DIER_CC2IE;
  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. {
  112.         if(rpm_ >= 600 && rpm_ < 6000)
  113.         {
  114.           rpm = rpm_;
  115.           adjustRPM();
  116.         }
  117.           return halfRot;
  118. }
  119.  
  120. uint16_t getRPM(void)
  121. {
  122.         return rpm;
  123. }
  124.  
  125. unsigned getDelta(void)
  126. {
  127.         return delta;
  128. }
  129.  
  130. unsigned getCount(void)
  131. {
  132.         return  count;
  133. }
  134.  
  135.  
  136. // waits for ignition pulse , debounces readings,
  137. // returns the pulse time, skips debounce time
  138. uint16_t getNextRefPulseIndex(void)
  139. {
  140.         while (outSampleRefCount == sampleRefCount)
  141.                 chThdSleep(10);
  142.  
  143.         uint16_t sampleIndex = outSampleRefCount;
  144.  
  145.     if(++outSampleRefCount == SAMPLE_BUFF_SIZE)
  146.         outSampleRefCount = 0;
  147.     return sampleIndex;
  148. }
  149.  
  150.  
  151.  
  152. void processNextPulse(uint16_t index)
  153. {
  154.  
  155.     // scale it up by 32
  156.         static int32_t periodEstimate = 2000 * 256 ;
  157.         // at this point we should try to phase lock
  158.      static signed pdLast = 0;
  159.         uint16_t sampleDiff = sampleDiffBuff[index];
  160.  
  161.  
  162.     signed pd = (sampleDiff <  32768 ? sampleDiff : sampleDiff - 65536L) ;
  163.  
  164.  
  165.  
  166.     static float phase_offset = 0;
  167.     float const wn = 0.01f;
  168.     float const zeta = 0.707f;
  169.     float const K = 100;
  170.  
  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);
  176.  
  177.     float const a1 = -2.0f;
  178.     float const a2 = 1.0f;
  179.  
  180.     static float v0=0.0f, v1 = 0.0f, v2 = 0.0f;
  181.  
  182.  
  183.     static float phi_hat = 0.0f;
  184.  
  185.     float delta_phi = pd/ 32768.0;
  186.  
  187.     v2=v1; v1=v0;
  188.     v0 = delta_phi -v1 *a1 -v2 *a2;
  189.  
  190.     phi_hat = v0 * b0 + v1 * b1 + v2 * b2;
  191.  
  192.  
  193.  
  194.     uint16_t arr = phi_hat < 100 ? 100 : phi_hat;
  195.     // compute period error
  196.       // periodErr +=   periodEstimate - (arr * 256);
  197.  
  198.  
  199.      count = arr;
  200.      delta = pd;
  201.  
  202.     TIM2->ARR = arr ;
  203.     recalcPhase();
  204.  
  205.  
  206.  
  207. // calculate RPM
  208.     float nomRPM = 30E6 / (MICROSECS_PULSE * (periodEstimate/256));
  209.  
  210.         rpm =  nomRPM ;
  211.  
  212.  
  213.  
  214. //      rpm += delta / 256;
  215.  
  216.         adjustRPM();
  217.     }
  218.  
  219.  
  220.  
  221.  
  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. {
  233.     static uint16_t lastSampleRef = 0;
  234.  
  235.     static uint8_t refCount = 0;
  236.         static uint8_t varCount = 0;
  237.  
  238.         uint16_t stat = TIM3->SR;
  239.         if(stat & TIM_SR_CC1IF)
  240.         {
  241.                 TIM3->SR &= ~TIM_SR_CC1IF;
  242.                 uint16_t sample = TIM3->CCR1;
  243.                 if(sample-lastSampleRef >  100 /*BREAKER_COUNT_MIN */)
  244.                 {
  245.                         sampleRef = sample;
  246.                         ++refCount;
  247.                 }
  248.                 lastSampleRef = sample;
  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.  
  284. }
  285.  
  286.  
  287.  
  288.