drv_hwtimer.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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. rt_section(".irq.timer")
  61. static void _rt_device_hwtimer_isr(rt_hwtimer_t *timer)
  62. {
  63. RT_ASSERT(timer != RT_NULL);
  64. timer->overflow ++;
  65. if (timer->cycles != 0)
  66. {
  67. timer->cycles --;
  68. }
  69. if (timer->cycles == 0)
  70. {
  71. timer->cycles = timer->reload;
  72. if (timer->mode == HWTIMER_MODE_ONESHOT)
  73. {
  74. if (timer->ops->stop != RT_NULL)
  75. {
  76. timer->ops->stop(timer);
  77. }
  78. }
  79. if (timer->parent.rx_indicate != RT_NULL)
  80. {
  81. timer->parent.rx_indicate(&timer->parent, sizeof(struct rt_hwtimerval));
  82. }
  83. }
  84. }
  85. static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  86. {
  87. rt_uint32_t prescaler_value = 0;
  88. hal_sfr_t tim = RT_NULL;
  89. struct ab32_hwtimer *tim_device = RT_NULL;
  90. RT_ASSERT(timer != RT_NULL);
  91. tim = (hal_sfr_t)timer->parent.user_data;
  92. if (state)
  93. {
  94. tim_device = (struct ab32_hwtimer *)timer;
  95. if (timer->info->cntmode != HWTIMER_CNTMODE_UP)
  96. {
  97. LOG_E("Only support HWTIMER_CNTMODE_UP!");
  98. }
  99. /* set tim int */
  100. tim[TMRxCON] = BIT(7);
  101. LOG_D("%s init success", tim_device->name);
  102. } else {
  103. /* stop timer */
  104. tim[TMRxCON] = 0;
  105. }
  106. }
  107. static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  108. {
  109. rt_err_t result = RT_EOK;
  110. hal_sfr_t tim = RT_NULL;
  111. RT_ASSERT(timer != RT_NULL);
  112. tim = (hal_sfr_t)timer->parent.user_data;
  113. /* set tim cnt */
  114. tim[TMRxCNT] = 0;
  115. tim[TMRxPR] = t * (get_sysclk_nhz() / timer->freq) - 1;
  116. if (opmode != HWTIMER_MODE_PERIOD)
  117. {
  118. LOG_E("Opmode only support HWTIMER_MODE_PERIOD!");
  119. return -RT_EINVAL;
  120. }
  121. /* start timer */
  122. tim[TMRxCON] |= BIT(0);
  123. return result;
  124. }
  125. static void timer_stop(rt_hwtimer_t *timer)
  126. {
  127. hal_sfr_t tim = RT_NULL;
  128. RT_ASSERT(timer != RT_NULL);
  129. tim = (hal_sfr_t)timer->parent.user_data;
  130. /* stop timer */
  131. tim[TMRxCON] &= ~BIT(0);
  132. /* set tim cnt */
  133. tim[TMRxCNT] = 0;
  134. }
  135. static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  136. {
  137. hal_sfr_t tim = RT_NULL;
  138. rt_err_t result = RT_EOK;
  139. RT_ASSERT(timer != RT_NULL);
  140. RT_ASSERT(arg != RT_NULL);
  141. tim = (hal_sfr_t)timer->parent.user_data;
  142. switch (cmd)
  143. {
  144. case HWTIMER_CTRL_FREQ_SET:
  145. {
  146. }
  147. break;
  148. default:
  149. {
  150. result = -RT_ENOSYS;
  151. }
  152. break;
  153. }
  154. return result;
  155. }
  156. static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
  157. {
  158. hal_sfr_t tim = RT_NULL;
  159. RT_ASSERT(timer != RT_NULL);
  160. tim = (hal_sfr_t)timer->parent.user_data;
  161. return tim[TMRxCNT] / (get_sysclk_nhz() / timer->freq);
  162. }
  163. static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
  164. static const struct rt_hwtimer_ops _ops =
  165. {
  166. .init = timer_init,
  167. .start = timer_start,
  168. .stop = timer_stop,
  169. .count_get = timer_counter_get,
  170. .control = timer_ctrl,
  171. };
  172. #if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
  173. rt_section(".irq.timer")
  174. void timer2_4_5_isr(int vector, void *param)
  175. {
  176. rt_interrupt_enter();
  177. #ifdef BSP_USING_TIM2
  178. if (ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCON] != 0) {
  179. ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCPND] = BIT(9);
  180. _rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM2_INDEX].time_device);
  181. }
  182. #endif
  183. #ifdef BSP_USING_TIM4
  184. if (ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCON] != 0) {
  185. ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCPND] = BIT(9);
  186. _rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM4_INDEX].time_device);
  187. }
  188. #endif
  189. #ifdef BSP_USING_TIM5
  190. if (ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCON] != 0) {
  191. ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCPND] = BIT(9);
  192. _rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM5_INDEX].time_device);
  193. }
  194. #endif
  195. rt_interrupt_leave();
  196. }
  197. #endif
  198. #ifdef BSP_USING_TIM3
  199. rt_section(".irq.timer")
  200. void timer3_isr(int vector, void *param)
  201. {
  202. rt_interrupt_enter();
  203. ab32_hwtimer_obj[TIM3_INDEX].tim_handle[TMRxCPND] = BIT(9);
  204. _rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM3_INDEX].time_device);
  205. rt_interrupt_leave();
  206. }
  207. #endif
  208. #ifdef BSP_USING_TIM1
  209. rt_section(".irq.timer")
  210. void timer1_isr(int vector, void *param)
  211. {
  212. rt_interrupt_enter();
  213. ab32_hwtimer_obj[TIM1_INDEX].tim_handle[TMRxCPND] = BIT(9);
  214. _rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM1_INDEX].time_device);
  215. rt_interrupt_leave();
  216. }
  217. #endif
  218. static int ab32_hwtimer_init(void)
  219. {
  220. int i = 0;
  221. int result = RT_EOK;
  222. for (i = 0; i < sizeof(ab32_hwtimer_obj) / sizeof(ab32_hwtimer_obj[0]); i++)
  223. {
  224. ab32_hwtimer_obj[i].time_device.info = &_info;
  225. ab32_hwtimer_obj[i].time_device.ops = &_ops;
  226. 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)
  227. {
  228. LOG_D("%s register success", ab32_hwtimer_obj[i].name);
  229. }
  230. else
  231. {
  232. LOG_E("%s register failed", ab32_hwtimer_obj[i].name);
  233. result = -RT_ERROR;
  234. }
  235. }
  236. #ifdef BSP_USING_TIM1
  237. rt_hw_interrupt_install(IRQ_TMR1_VECTOR, timer1_isr, RT_NULL, "t1_isr");
  238. #endif
  239. #if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
  240. rt_hw_interrupt_install(IRQ_TMR2_4_5_VECTOR, timer2_4_5_isr, RT_NULL, "t245_isr");
  241. #endif
  242. #ifdef BSP_USING_TIM3
  243. rt_hw_interrupt_install(IRQ_IRRX_VECTOR, timer3_isr, RT_NULL, "t3_isr");
  244. #endif
  245. return result;
  246. }
  247. INIT_BOARD_EXPORT(ab32_hwtimer_init);
  248. #endif /* RT_USING_HWTIMER */
  249. #endif /* BSP_USING_TIM */