Projet voilier 4IRA1 Arnaud Vergnet Marino Benassai Bastien Picco Yohan Simard
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Timer.c 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #include "Timer.h"
  2. #include "stm32f1xx_ll_bus.h" // Pour l'activation des horloges
  3. #include "stm32f1xx_ll_tim.h" // Pour les timers
  4. /****************************************************************************
  5. * INTERRUPTIONS
  6. ***************************************************************************/
  7. // variable pointeur de fonction permettant de m�moriser le callback � appeler depuis
  8. // le handler d'IT
  9. void (*it_callback_TIM1)(void);
  10. void (*it_callback_TIM2)(void);
  11. void (*it_callback_TIM3)(void);
  12. void (*it_callback_TIM4)(void);
  13. void TIM1_UP_IRQHandler(void)
  14. {
  15. // rabaisser le flag d'IT
  16. LL_TIM_ClearFlag_UPDATE(TIM1);
  17. (*it_callback_TIM1)();
  18. }
  19. void TIM2_IRQHandler(void)
  20. {
  21. // rabaisser le flag d'IT
  22. LL_TIM_ClearFlag_UPDATE(TIM2);
  23. (*it_callback_TIM2)();
  24. }
  25. void TIM3_IRQHandler(void)
  26. {
  27. // rabaisser le flag d'IT
  28. LL_TIM_ClearFlag_UPDATE(TIM3);
  29. (*it_callback_TIM3)();
  30. }
  31. void TIM4_IRQHandler(void)
  32. {
  33. // rabaisser le flag d'IT
  34. LL_TIM_ClearFlag_UPDATE(TIM4);
  35. (*it_callback_TIM4)();
  36. }
  37. /**
  38. * @brief Autorise les interruptions
  39. * @note
  40. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  41. * @retval None
  42. */
  43. void Timer_IT_enable(TIM_TypeDef * timer)
  44. {
  45. LL_TIM_EnableIT_UPDATE(timer);
  46. }
  47. /**
  48. * @brief Interdit les interruptions
  49. * @note
  50. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  51. * @retval None
  52. */
  53. void Timer_IT_disable(TIM_TypeDef * timer)
  54. {
  55. LL_TIM_DisableIT_UPDATE(timer);
  56. }
  57. /**
  58. * @brief Configure le Timer consid�r� en interruption sur d�bordement.
  59. * @note A ce stade, les interruptions ne sont pas valid�s (voir MyTimer_IT_Enable )
  60. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  61. * void (*IT_function) (void) : nom (adresse) de la fonction � lancer sur interruption
  62. * int Prio : priorit� associ�e � l'interruption
  63. * @retval None
  64. */
  65. void Timer_IT_conf(TIM_TypeDef * timer, void (*it_callback) (void), int prio)
  66. {
  67. // affectation de la fonction
  68. if (timer == TIM1) it_callback_TIM1 = it_callback;
  69. else if (timer == TIM2) it_callback_TIM2 = it_callback;
  70. else if (timer == TIM3) it_callback_TIM3 = it_callback;
  71. else it_callback_TIM4 = it_callback;
  72. // Blocage IT (il faudra la d�bloquer voir fct suivante)
  73. LL_TIM_DisableIT_UPDATE(timer);
  74. // validation du canal NVIC
  75. IRQn_Type TIM_irq;
  76. if (timer == TIM1) TIM_irq = TIM1_UP_IRQn;
  77. else if (timer == TIM2) TIM_irq = TIM2_IRQn;
  78. else if (timer == TIM3) TIM_irq = TIM3_IRQn;
  79. else TIM_irq = TIM4_IRQn;
  80. NVIC_SetPriority(TIM_irq, prio);
  81. NVIC_EnableIRQ(TIM_irq);
  82. }
  83. /****************************************************************************
  84. * TIMER
  85. ***************************************************************************/
  86. /**
  87. * @brief D�marre le timer consid�r� et active les interruptions
  88. * @note
  89. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  90. * @retval None
  91. */
  92. void Timer_start(TIM_TypeDef * timer)
  93. {
  94. LL_TIM_EnableCounter(timer);
  95. }
  96. /**
  97. * @brief Arr�t le timer consid�r� et d�sactive les interruptions
  98. * @note
  99. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  100. * @retval None
  101. */
  102. void Timer_stop(TIM_TypeDef * timer)
  103. {
  104. LL_TIM_DisableCounter(timer);
  105. }
  106. /**
  107. * @brief Active l'horloge et r�gle l'ARR et le PSC du timer vis�.
  108. * @note Fonction � lancer avant toute autre. Le timer n'est pas encore lanc� (voir Timer_start)
  109. * @param TIM_TypeDef Timer : indique le timer � utiliser par le chronom�tre, TIM1, TIM2, TIM3 ou TIM4
  110. * int Arr : valeur � placer dans ARR
  111. * int Psc : valeur � placer dans PSC
  112. * @retval None
  113. */
  114. void Timer_conf(TIM_TypeDef * timer, int arr, int psc)
  115. {
  116. LL_TIM_InitTypeDef init_struct;
  117. // Validation horloge locale
  118. if (timer == TIM1) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
  119. else if (timer == TIM2) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
  120. else if (timer == TIM3) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
  121. else LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
  122. // chargement structure Arr, Psc, Up Count
  123. init_struct.Autoreload = arr;
  124. init_struct.Prescaler = psc;
  125. init_struct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  126. init_struct.CounterMode = LL_TIM_COUNTERMODE_UP;
  127. init_struct.RepetitionCounter = 0;
  128. LL_TIM_Init(timer,&init_struct);
  129. // Blocage interruptions
  130. Timer_IT_disable(timer);
  131. // Blocage Timer
  132. Timer_stop(timer);
  133. }
  134. /****************************************************************************
  135. * PWM INPUT
  136. ***************************************************************************/
  137. void PWMi_conf(TIM_TypeDef * TIMx, int channel){
  138. //Periode à recuperer dans TIMx_CCR1, duty cycle dans TIMx_CCR2. Seul les 2 premiers channels peuvent être utilisés (cf 315).
  139. // Validation horloge locale
  140. if (TIMx == TIM1) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
  141. else if (TIMx == TIM2) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
  142. else if (TIMx == TIM3) LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM3);
  143. else LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM4);
  144. if (channel == 1) {
  145. //
  146. TIMx -> CCMR1 |= TIM_CCMR1_CC1S_0;
  147. TIMx -> CCMR1 |= TIM_CCMR1_CC2S_1;
  148. //TIM_CCMR1_IC1F_0; Potentiellement utile, à voir plus tard
  149. //On met le channel principal en rising edge, le secondaire en falling edge
  150. TIMx -> CCER &= ~TIM_CCER_CC1P;
  151. TIMx -> CCER |= TIM_CCER_CC2P;
  152. TIMx -> SMCR |= TIM_SMCR_TS_0 | TIM_SMCR_TS_2; //101
  153. TIMx -> SMCR |= TIM_SMCR_SMS_2; //100
  154. }
  155. else {
  156. TIMx -> CCMR1 |= TIM_CCMR1_CC1S_1;
  157. TIMx -> CCMR1 |= TIM_CCMR1_CC2S_0;
  158. TIMx -> CCER |= TIM_CCER_CC1P;
  159. TIMx -> CCER &= ~TIM_CCER_CC2P;
  160. TIMx -> SMCR |= TIM_SMCR_TS_1 | TIM_SMCR_TS_2; //110
  161. TIMx -> SMCR |= TIM_SMCR_SMS_2; //100
  162. }
  163. //On met les prescalers à 0, on veut compter chaque transition
  164. TIMx -> CCMR1 &= ~TIM_CCMR1_IC1PSC;
  165. TIMx -> CCMR1 &= ~TIM_CCMR1_IC2PSC;
  166. TIMx -> CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E;
  167. //TIMx -> DIER |= TIM_DIER_CC1IE; gestion des interrupts, probablement pas utile
  168. //TIM_DIER_CC1DE_Pos; Probablement pas utile
  169. }
  170. int PWMi_getPeriod(TIM_TypeDef * TIMx) {
  171. return TIMx->CCR1;
  172. }
  173. float PWMi_getDutyCycle(TIM_TypeDef * TIMx) {
  174. const int arr = LL_TIM_GetAutoReload(TIMx);
  175. float duty_cycle = (float)TIMx->CCR2 / (float)arr;
  176. return duty_cycle;
  177. }
  178. /****************************************************************************
  179. * PWM OUTPUT
  180. ***************************************************************************/
  181. int getArrFromFreq(float freq)
  182. {
  183. return (72000 / freq) - 1;
  184. }
  185. void Timer_pwmo_conf(TIM_TypeDef * timer, int channel, float freq, float dutyCycle)
  186. {
  187. const int arr = getArrFromFreq(freq);
  188. Timer_conf(timer, arr, 1000);
  189. LL_TIM_OC_InitTypeDef init_struct;
  190. LL_TIM_OC_StructInit(&init_struct);
  191. init_struct.OCMode = LL_TIM_OCMODE_PWM1;
  192. init_struct.OCState = LL_TIM_OCSTATE_ENABLE;
  193. init_struct.CompareValue= dutyCycle * arr;
  194. LL_TIM_OC_Init(timer, channel, &init_struct);
  195. }
  196. void Timer_pwmo_setFreq(TIM_TypeDef * timer, float freq)
  197. {
  198. const int arr = getArrFromFreq(freq);
  199. LL_TIM_SetAutoReload(timer, arr);
  200. }
  201. void Timer_pwmo_setDutyCycle(TIM_TypeDef * timer, int channel, float dutyCycle)
  202. {
  203. const int arr = LL_TIM_GetAutoReload(timer);
  204. int compare = dutyCycle * arr;
  205. if (channel == LL_TIM_CHANNEL_CH1) LL_TIM_OC_SetCompareCH1(timer, compare);
  206. else if (channel == LL_TIM_CHANNEL_CH2) LL_TIM_OC_SetCompareCH2(timer, compare);
  207. else if (channel == LL_TIM_CHANNEL_CH3) LL_TIM_OC_SetCompareCH3(timer, compare);
  208. else LL_TIM_OC_SetCompareCH4(timer, compare);
  209. }
  210. float Timer_pwmo_getDutyCycle(TIM_TypeDef * timer, int channel)
  211. {
  212. int compare = 0;
  213. const int arr = LL_TIM_GetAutoReload(timer);
  214. if (channel == LL_TIM_CHANNEL_CH1) compare = LL_TIM_OC_GetCompareCH1(timer);
  215. else if (channel == LL_TIM_CHANNEL_CH2) compare = LL_TIM_OC_GetCompareCH2(timer);
  216. else if (channel == LL_TIM_CHANNEL_CH3) compare = LL_TIM_OC_GetCompareCH3(timer);
  217. else compare = LL_TIM_OC_GetCompareCH4(timer);
  218. return ((float) compare) / ((float) arr);
  219. }
  220. /****************************************************************************
  221. * ENCODER
  222. ***************************************************************************/
  223. void Timer_encoder_conf(TIM_TypeDef * timer)
  224. {
  225. Timer_conf(timer, 719, 0);
  226. LL_TIM_ENCODER_InitTypeDef init_struct;
  227. LL_TIM_ENCODER_StructInit(&init_struct);
  228. init_struct.EncoderMode = LL_TIM_ENCODERMODE_X2_TI1;
  229. LL_TIM_ENCODER_Init(timer, &init_struct);
  230. }
  231. int Timer_encoder_getAngle(TIM_TypeDef * timer)
  232. {
  233. return LL_TIM_GetCounter(timer)/2;
  234. }
  235. enum CounterDirection Timer_encoder_getDirection(TIM_TypeDef * timer)
  236. {
  237. const int dir = LL_TIM_GetDirection(timer);
  238. if (dir == LL_TIM_COUNTERDIRECTION_UP)
  239. return CLOCKWISE;
  240. else
  241. return COUNTER_CLOCKWISE;
  242. }