PageRenderTime 94ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/source/firmware/src/comm_tim.c

https://github.com/esden/open-bldc
C | 243 lines | 113 code | 44 blank | 86 comment | 4 complexity | e16ed649428cd06ba50a20adeb32667d MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * Open-BLDC - Open BrushLess DC Motor Controller
  3. * Copyright (C) 2009-2010 by Piotr Esden-Tempski <piotr@esden.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * @file comm_tim.c
  20. * @author Piotr Esden-Tempski <piotr@esden.net>
  21. * @date Tue Aug 17 02:05:17 2010
  22. *
  23. * @brief Commutation timer hardware implementation.
  24. *
  25. * Implements the timer that is directly triggering the commutation event of
  26. * the PWM generation subsystem.
  27. *
  28. * @todo The comm timer should use a timer driver and not combine timer
  29. * peripheral handling code together with the commutation handling part.
  30. */
  31. #include <libopencm3/stm32/f1/nvic.h>
  32. #include <libopencm3/stm32/f1/rcc.h>
  33. #include <libopencm3/stm32/timer.h>
  34. #include <libopencm3/stm32/f1/gpio.h>
  35. #include "types.h"
  36. #include <lg/gpdef.h>
  37. #include <lg/gprotc.h>
  38. #include "comm_tim.h"
  39. #include "gprot.h"
  40. #include "driver/led.h"
  41. #include "driver/adc.h"
  42. #include "driver/debug_pins.h"
  43. #include "pwm/pwm.h"
  44. /**
  45. * Commutation timer internal state
  46. */
  47. struct comm_tim_state {
  48. volatile u32 update_count; /**< update count since curr_time, needed for data.update_count calculation */
  49. volatile u16 next_prev_time;
  50. };
  51. struct comm_tim_data comm_tim_data; /**< Commutation timer data instance */
  52. static struct comm_tim_state comm_tim_state; /**< Commutation timer internal state instance */
  53. bool comm_tim_trigger_comm = false; /**< Commutation timer trigger commutations flag */
  54. bool comm_tim_trigger_comm_once = false; /**< Commutation timer trigger one commutation flag */
  55. bool comm_tim_trigger = false; /**< Commutation timer trigger (it's an output not input) */
  56. /**
  57. * Commutation timer hardware initialization.
  58. */
  59. void comm_tim_init(void)
  60. {
  61. comm_tim_data.freq = 65535;
  62. (void)gpc_setup_reg(GPROT_COMM_TIM_FREQ_REG_ADDR, &(comm_tim_data.freq));
  63. /* TIM2 clock enable */
  64. rcc_peripheral_enable_clock(&RCC_APB1ENR, RCC_APB1ENR_TIM2EN);
  65. /* Enable the TIM2 gloabal interrupt. */
  66. nvic_enable_irq(NVIC_TIM2_IRQ);
  67. /* Reset TIM2 peripheral. */
  68. timer_reset(TIM2);
  69. /* TIM2 time base configuration */
  70. timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
  71. TIM_CR1_CMS_EDGE,
  72. TIM_CR1_DIR_UP);
  73. /* Set prescaler value */
  74. timer_set_prescaler(TIM2, 4);
  75. /* Disable preload. */
  76. timer_disable_preload(TIM2);
  77. /* Set continous mode. */
  78. timer_continuous_mode(TIM2);
  79. /* Set period to maximum */
  80. timer_set_period(TIM2, 65535);
  81. /* Disable outputs. */
  82. timer_disable_oc_output(TIM2, TIM_OC1);
  83. timer_disable_oc_output(TIM2, TIM_OC2);
  84. timer_disable_oc_output(TIM2, TIM_OC3);
  85. timer_disable_oc_output(TIM2, TIM_OC4);
  86. /* TIM2 Output Compare Timing Mode configuration: Channel1 */
  87. timer_disable_oc_clear(TIM2, TIM_OC1);
  88. timer_disable_oc_preload(TIM2, TIM_OC1);
  89. timer_set_oc_slow_mode(TIM2, TIM_OC1);
  90. timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_FROZEN);
  91. //timer_set_oc_polarity_high(TIM2, TIM_OC1);
  92. /* Set initial capture compare value for OC1 */
  93. timer_set_oc_value(TIM2, TIM_OC1, comm_tim_data.freq);
  94. /* ARR reload enable */
  95. timer_disable_preload(TIM2);
  96. /* Counter enable */
  97. timer_enable_counter(TIM2);
  98. /* TIM2 Capture Compare 1 IT enable */
  99. timer_enable_irq(TIM2, TIM_DIER_CC1IE);
  100. /* TIM2 Update IT enable */
  101. timer_enable_irq(TIM2, TIM_DIER_UIE);
  102. comm_tim_reset();
  103. }
  104. /**
  105. * Reset the commutation timer internal state.
  106. */
  107. void comm_tim_reset(void)
  108. {
  109. comm_tim_trigger_comm = false;
  110. comm_tim_trigger_comm_once = false;
  111. comm_tim_data.freq = 65535;
  112. }
  113. /**
  114. * Record the time of the last commutation
  115. */
  116. void comm_tim_capture_time(void)
  117. {
  118. u16 new_time = timer_get_counter(TIM2);
  119. comm_tim_data.prev_time = comm_tim_state.next_prev_time;
  120. comm_tim_data.curr_time = new_time;
  121. comm_tim_state.next_prev_time = new_time;
  122. comm_tim_data.update_count = comm_tim_state.update_count;
  123. comm_tim_state.update_count = 0;
  124. }
  125. /**
  126. * Update the commutation timer frequency using the value stored in
  127. * @ref comm_tim_data.freq
  128. */
  129. void comm_tim_update_freq(void)
  130. {
  131. timer_set_oc_value(TIM2, TIM_OC1,
  132. comm_tim_data.last_capture_time + comm_tim_data.freq);
  133. }
  134. /**
  135. * Update our last capture time
  136. *
  137. */
  138. void comm_tim_update_capture(void)
  139. {
  140. comm_tim_data.last_capture_time = timer_get_counter(TIM2);
  141. timer_set_oc_value(TIM2, TIM_OC1,
  142. comm_tim_data.last_capture_time + comm_tim_data.freq);
  143. OFF(DP_EXT_SCL);
  144. }
  145. /**
  146. * Update the next prev time to the current time
  147. */
  148. void comm_tim_update_next_prev(void)
  149. {
  150. comm_tim_state.next_prev_time = timer_get_counter(TIM2);
  151. }
  152. /**
  153. * Update our last capture time and curr time
  154. *
  155. */
  156. void comm_tim_update_capture_and_time(void)
  157. {
  158. comm_tim_data.last_capture_time = timer_get_counter(TIM2);
  159. timer_set_oc_value(TIM2, TIM_OC1,
  160. comm_tim_data.last_capture_time + comm_tim_data.freq);
  161. comm_tim_data.prev_time = comm_tim_state.next_prev_time;
  162. comm_tim_data.curr_time = comm_tim_data.last_capture_time;
  163. comm_tim_state.next_prev_time = comm_tim_data.last_capture_time;
  164. comm_tim_data.update_count = comm_tim_state.update_count;
  165. comm_tim_state.update_count = 0;
  166. }
  167. /**
  168. * Timer 2 interrupt handler
  169. */
  170. void tim2_isr(void)
  171. {
  172. if (timer_get_flag(TIM2, TIM_SR_CC1IF)) {
  173. timer_clear_flag(TIM2, TIM_SR_CC1IF);
  174. /* prepare for next comm */
  175. comm_tim_data.last_capture_time = timer_get_counter(TIM2);
  176. //comm_tim_data.last_capture_time = timer_get_ic_value(TIM2, TIM_OC1);
  177. //comm_tim_data.last_capture_time = TIM2_CCR1;
  178. /* triggering commutation event */
  179. if (comm_tim_trigger_comm || comm_tim_trigger_comm_once) {
  180. timer_generate_event(TIM1, TIM_EGR_COMG);
  181. //timer_generate_event(TIM1, TIM_EGR_COMG | TIM_EGR_UG);
  182. }
  183. /* (re)setting "semaphors" */
  184. comm_tim_trigger_comm_once = false;
  185. comm_tim_trigger = true;
  186. /* Set next comm time */
  187. timer_set_oc_value(TIM2, TIM_OC1,
  188. comm_tim_data.last_capture_time +
  189. (comm_tim_data.freq * 2));
  190. //timer_set_oc_value(TIM2, TIM_OC1,
  191. // comm_tim_data.last_capture_time +
  192. // 65535);
  193. TOGGLE(DP_EXT_SCL);
  194. }
  195. if (timer_get_flag(TIM2, TIM_SR_UIF)) {
  196. timer_clear_flag(TIM2, TIM_SR_UIF);
  197. comm_tim_state.update_count++;
  198. }
  199. }