drv_hwtimer.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /*
  2. * Copyright (c) 2020-2021, Bluetrum Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-01-22 greedyhao first version
  9. */
  10. #include "board.h"
  11. #ifdef BSP_USING_TIM
  12. #include "tim_config.h"
  13. //#define DRV_DEBUG
  14. #define LOG_TAG "drv.hwtimer"
  15. #include <drv_log.h>
  16. #ifdef RT_USING_HWTIMER
  17. enum
  18. {
  19. #ifdef BSP_USING_TIM1
  20. TIM1_INDEX,
  21. #endif
  22. #ifdef BSP_USING_TIM2
  23. TIM2_INDEX,
  24. #endif
  25. #ifdef BSP_USING_TIM3
  26. TIM3_INDEX,
  27. #endif
  28. #ifdef BSP_USING_TIM4
  29. TIM4_INDEX,
  30. #endif
  31. #ifdef BSP_USING_TIM5
  32. TIM5_INDEX,
  33. #endif
  34. };
  35. struct ab32_hwtimer
  36. {
  37. rt_hwtimer_t time_device;
  38. hal_sfr_t tim_handle;
  39. char *name;
  40. irq_type tim_irqn;
  41. };
  42. static struct ab32_hwtimer ab32_hwtimer_obj[] =
  43. {
  44. #ifdef BSP_USING_TIM1
  45. TIM1_CONFIG,
  46. #endif
  47. #ifdef BSP_USING_TIM2
  48. TIM2_CONFIG,
  49. #endif
  50. #ifdef BSP_USING_TIM3
  51. TIM3_CONFIG,
  52. #endif
  53. #ifdef BSP_USING_TIM4
  54. TIM4_CONFIG,
  55. #endif
  56. #ifdef BSP_USING_TIM5
  57. TIM5_CONFIG,
  58. #endif
  59. };
  60. static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  61. {
  62. uint32_t prescaler_value = 0;
  63. hal_sfr_t tim = RT_NULL;
  64. struct ab32_hwtimer *tim_device = RT_NULL;
  65. RT_ASSERT(timer != RT_NULL);
  66. tim = (hal_sfr_t)timer->parent.user_data;
  67. if (state)
  68. {
  69. tim_device = (struct ab32_hwtimer *)timer;
  70. if (timer->info->cntmode != HWTIMER_CNTMODE_UP)
  71. {
  72. LOG_E("Only support HWTIMER_CNTMODE_UP!");
  73. }
  74. /* set tim int */
  75. tim[TMRxCON] = BIT(7);
  76. LOG_D("%s init success", tim_device->name);
  77. } else {
  78. /* stop timer */
  79. tim[TMRxCON] = 0;
  80. }
  81. }
  82. static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  83. {
  84. rt_err_t result = RT_EOK;
  85. hal_sfr_t tim = RT_NULL;
  86. RT_ASSERT(timer != RT_NULL);
  87. tim = (hal_sfr_t)timer->parent.user_data;
  88. /* set tim cnt */
  89. tim[TMRxCNT] = 0;
  90. tim[TMRxPR] = t * (get_sysclk_nhz() / timer->freq) - 1;
  91. if (opmode != HWTIMER_MODE_PERIOD)
  92. {
  93. LOG_E("Opmode only support HWTIMER_MODE_PERIOD!");
  94. return -RT_EINVAL;
  95. }
  96. /* start timer */
  97. tim[TMRxCON] |= BIT(0);
  98. return result;
  99. }
  100. static void timer_stop(rt_hwtimer_t *timer)
  101. {
  102. hal_sfr_t tim = RT_NULL;
  103. RT_ASSERT(timer != RT_NULL);
  104. tim = (hal_sfr_t)timer->parent.user_data;
  105. /* stop timer */
  106. tim[TMRxCON] &= ~BIT(0);
  107. /* set tim cnt */
  108. tim[TMRxCNT] = 0;
  109. }
  110. static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  111. {
  112. hal_sfr_t tim = RT_NULL;
  113. rt_err_t result = RT_EOK;
  114. RT_ASSERT(timer != RT_NULL);
  115. RT_ASSERT(arg != RT_NULL);
  116. tim = (hal_sfr_t)timer->parent.user_data;
  117. switch (cmd)
  118. {
  119. case HWTIMER_CTRL_FREQ_SET:
  120. {
  121. }
  122. break;
  123. default:
  124. {
  125. result = -RT_ENOSYS;
  126. }
  127. break;
  128. }
  129. return result;
  130. }
  131. static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
  132. {
  133. hal_sfr_t tim = RT_NULL;
  134. RT_ASSERT(timer != RT_NULL);
  135. tim = (hal_sfr_t)timer->parent.user_data;
  136. return tim[TMRxCNT] / (get_sysclk_nhz() / timer->freq);
  137. }
  138. static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
  139. static const struct rt_hwtimer_ops _ops =
  140. {
  141. .init = timer_init,
  142. .start = timer_start,
  143. .stop = timer_stop,
  144. .count_get = timer_counter_get,
  145. .control = timer_ctrl,
  146. };
  147. #if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
  148. void timer2_4_5_isr(int vector, void *param)
  149. {
  150. rt_interrupt_enter();
  151. #ifdef BSP_USING_TIM2
  152. if (ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCON] != 0) {
  153. ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCPND] = BIT(9);
  154. rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM2_INDEX].time_device);
  155. }
  156. #endif
  157. #ifdef BSP_USING_TIM4
  158. if (ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCON] != 0) {
  159. ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCPND] = BIT(9);
  160. rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM4_INDEX].time_device);
  161. }
  162. #endif
  163. #ifdef BSP_USING_TIM5
  164. if (ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCON] != 0) {
  165. ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCPND] = BIT(9);
  166. rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM5_INDEX].time_device);
  167. }
  168. #endif
  169. rt_interrupt_leave();
  170. }
  171. #endif
  172. #ifdef BSP_USING_TIM3
  173. void timer3_isr(int vector, void *param)
  174. {
  175. rt_interrupt_enter();
  176. ab32_hwtimer_obj[TIM3_INDEX].tim_handle[TMRxCPND] = BIT(9);
  177. rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM3_INDEX].time_device);
  178. rt_interrupt_leave();
  179. }
  180. #endif
  181. #ifdef BSP_USING_TIM1
  182. void timer1_isr(int vector, void *param)
  183. {
  184. rt_interrupt_enter();
  185. ab32_hwtimer_obj[TIM1_INDEX].tim_handle[TMRxCPND] = BIT(9);
  186. rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM1_INDEX].time_device);
  187. rt_interrupt_leave();
  188. }
  189. #endif
  190. static int ab32_hwtimer_init(void)
  191. {
  192. int i = 0;
  193. int result = RT_EOK;
  194. for (i = 0; i < sizeof(ab32_hwtimer_obj) / sizeof(ab32_hwtimer_obj[0]); i++)
  195. {
  196. ab32_hwtimer_obj[i].time_device.info = &_info;
  197. ab32_hwtimer_obj[i].time_device.ops = &_ops;
  198. if (rt_device_hwtimer_register(&ab32_hwtimer_obj[i].time_device, ab32_hwtimer_obj[i].name, (void *)ab32_hwtimer_obj[i].tim_handle) == RT_EOK)
  199. {
  200. LOG_D("%s register success", ab32_hwtimer_obj[i].name);
  201. }
  202. else
  203. {
  204. LOG_E("%s register failed", ab32_hwtimer_obj[i].name);
  205. result = -RT_ERROR;
  206. }
  207. }
  208. #ifdef BSP_USING_TIM1
  209. rt_hw_interrupt_install(IRQ_TMR1_VECTOR, timer1_isr, RT_NULL, "t1_isr");
  210. #endif
  211. #if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
  212. rt_hw_interrupt_install(IRQ_TMR2_4_5_VECTOR, timer2_4_5_isr, RT_NULL, "t245_isr");
  213. #endif
  214. #ifdef BSP_USING_TIM3
  215. rt_hw_interrupt_install(IRQ_IRRX_VECTOR, timer3_isr, RT_NULL, "t3_isr");
  216. #endif
  217. return result;
  218. }
  219. INIT_BOARD_EXPORT(ab32_hwtimer_init);
  220. #endif /* RT_USING_HWTIMER */
  221. #endif /* BSP_USING_TIM */