Subversion Repositories chibiosIgnition

Rev

Rev 8 | Rev 12 | 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 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];
  28. typedef enum { WAIT_GAP, SKIP_BOUNCE, HAVE_SAMPLE } sampleState_t ;
  29. sampleState_t  sampleState = WAIT_GAP;
  30. // difference between samples
  31. volatile uint16_t deltaTime;
  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.  
  46.         /// pulse width 200 uS
  47.         TIM2->CCR1 = 200/MICROSECS_PULSE;
  48.  
  49.     TIM2->CCER =  TIM_CCER_CC1E | TIM_CCER_CC1P  ; //enabled and active high
  50.  
  51.     TIM2->CCMR1 = TIM_CCMR1_OC1M_0 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 |
  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,
  81.                           4);
  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.  
  125. uint16_t getDelta(void)
  126. {
  127.         return deltaTime;
  128. }
  129.  
  130. uint16_t wrapIndex(uint16_t index)
  131. {
  132.         if (index >= SAMPLE_BUFF_SIZE)
  133.                 index -= SAMPLE_BUFF_SIZE;
  134.     return index;
  135. }
  136.  
  137.  
  138. // allows for wrapping
  139. uint16_t getSampleBuff(uint16_t index)
  140. {
  141.         chSysLock();
  142.         return sampleBuff[wrapIndex(index)];
  143.         chSysUnlock();
  144. }
  145.  
  146.  
  147. // waits for ignition pulse , debounces readings,
  148. // returns the pulse time, skips debounce time
  149. uint16_t getNextPulse(void)
  150. {
  151.         static uint16_t lastSampleIndex = 0;
  152.         while(1)
  153.         {
  154.                         while (outSampleCount == sampleCount)
  155.                                 chThdSleep(10);
  156.  
  157.                         uint16_t thisTime  = getSampleBuff(outSampleCount);
  158.  
  159.                         outSampleCount = wrapIndex(outSampleCount + 1);
  160.                         while (outSampleCount == sampleCount)
  161.                                 chThdSleep(10);
  162.  
  163.                         uint16_t nextTime = getSampleBuff(outSampleCount);
  164.  
  165.                         // calculate wrapped time delta : should be > than bounce time to allow
  166.                         uint16_t diffTime = nextTime - thisTime;
  167.  
  168.                         if(diffTime > BREAKER_COUNT_MIN)
  169.                         {
  170.                                 lastSampleIndex = outSampleCount;
  171.                                 return nextTime;
  172.                         }
  173.  
  174.         }
  175.   return 0;
  176. }
  177.  
  178.  
  179. void processNextPulse(uint16_t retVal)
  180. {
  181.  
  182.         static uint16_t lastVal = 0;
  183.         // at this point we should try to phase lock
  184.     deltaTime = retVal - lastVal;
  185.  
  186.  
  187.  
  188.     if(deltaTime > 10000)
  189.     {
  190.         __asm(" BKPT #0");
  191.     }
  192.  
  193.     lastVal = retVal;
  194.  
  195.  
  196.  
  197.  
  198.  
  199.     float nomRPM = 30E6 / (MICROSECS_PULSE * deltaTime) ;
  200.  
  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();
  218.     }
  219.  
  220.  
  221.  
  222.  
  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;
  240.             if (sampleCount >= SAMPLE_BUFF_SIZE)
  241.                 sampleCount = 0;
  242.         }
  243. }
  244.  
  245.  
  246.  
  247.