drv_hwtimer.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. * Copyright (c) 2022-2023 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <rtthread.h>
  8. #include <rtdevice.h>
  9. #include <rtdbg.h>
  10. #ifdef RT_USING_HWTIMER
  11. #include "drv_hwtimer.h"
  12. #include "board.h"
  13. #include "hpm_gptmr_drv.h"
  14. typedef struct _hpm_gptimer
  15. {
  16. GPTMR_Type *base;
  17. const char *name;
  18. rt_hwtimer_t timer;
  19. uint32_t channel;
  20. clock_name_t clock_name;
  21. int32_t irq_num;
  22. } hpm_gptimer_t;
  23. static void hpm_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state);
  24. static rt_err_t hpm_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
  25. static void hpm_hwtimer_stop(rt_hwtimer_t *timer);
  26. static rt_uint32_t hpm_hwtimer_count_get(rt_hwtimer_t *timer);
  27. static rt_err_t hpm_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
  28. static void hpm_hwtmr_isr(hpm_gptimer_t *gptmr);
  29. static const struct rt_hwtimer_ops hpm_hwtimer_ops = {
  30. .init = hpm_hwtimer_init,
  31. .start = hpm_hwtimer_start,
  32. .stop = hpm_hwtimer_stop,
  33. .count_get = hpm_hwtimer_count_get,
  34. .control = hpm_hwtimer_control
  35. };
  36. static const struct rt_hwtimer_info hpm_hwtimer_info = {
  37. .maxfreq = 100000000UL,
  38. .minfreq = 93750UL,
  39. .maxcnt = 0xFFFFFFFFUL,
  40. .cntmode = HWTIMER_CNTMODE_UP
  41. };
  42. #ifdef BSP_USING_GPTMR0
  43. static hpm_gptimer_t timer0 = {.name = "GPT0", .base = HPM_GPTMR0, .clock_name = clock_gptmr0, .irq_num = IRQn_GPTMR0 };
  44. #endif
  45. #ifdef BSP_USING_GPTMR1
  46. static hpm_gptimer_t timer1 = {.name = "GPT1", .base = HPM_GPTMR1, .clock_name = clock_gptmr1, .irq_num = IRQn_GPTMR1 };
  47. #endif
  48. #ifdef BSP_USING_GPTMR2
  49. static hpm_gptimer_t timer2 = {.name = "GPT2", .base = HPM_GPTMR2, .clock_name = clock_gptmr2, .irq_num = IRQn_GPTMR2 };
  50. #endif
  51. #ifdef BSP_USING_GPTMR3
  52. static hpm_gptimer_t timer3 = {.name = "GPT3", .base = HPM_GPTMR3, .clock_name = clock_gptmr3, .irq_num = IRQn_GPTMR3 };
  53. #endif
  54. #ifdef BSP_USING_GPTMR4
  55. static hpm_gptimer_t timer4 = {.name = "GPT4", .base = HPM_GPTMR4, .clock_name = clock_gptmr4, .irq_num = IRQn_GPTMR4 };
  56. #endif
  57. #ifdef BSP_USING_GPTMR5
  58. static hpm_gptimer_t timer5 = {.name = "GPT5", .base = HPM_GPTMR5, .clock_name = clock_gptmr5, .irq_num = IRQn_GPTMR5 };
  59. #endif
  60. #ifdef BSP_USING_GPTMR6
  61. static hpm_gptimer_t timer6 = {.name = "GPT6", .base = HPM_GPTMR6, .clock_name = clock_gptmr6, .irq_num = IRQn_GPTMR6 };
  62. #endif
  63. #ifdef BSP_USING_GPTMR7
  64. static hpm_gptimer_t timer7 = {.name = "GPT7", .base = HPM_GPTMR7, .clock_name = clock_gptmr7, .irq_num = IRQn_GPTMR7 };
  65. #endif
  66. static hpm_gptimer_t *s_gptimers[] = {
  67. #ifdef BSP_USING_GPTMR0
  68. &timer0,
  69. #endif
  70. #ifdef BSP_USING_GPTMR1
  71. &timer1,
  72. #endif
  73. #ifdef BSP_USING_GPTMR2
  74. &timer2,
  75. #endif
  76. #ifdef BSP_USING_GPTMR3
  77. &timer3,
  78. #endif
  79. #ifdef BSP_USING_GPTMR4
  80. &timer4,
  81. #endif
  82. #ifdef BSP_USING_GPTMR5
  83. &timer5,
  84. #endif
  85. #ifdef BSP_USING_GPTMR6
  86. &timer6,
  87. #endif
  88. #ifdef BSP_USING_GPTMR7
  89. &timer7,
  90. #endif
  91. };
  92. #ifdef BSP_USING_GPTMR0
  93. void gptmr0_isr(void)
  94. {
  95. hpm_hwtmr_isr(&timer0);
  96. }
  97. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR0, gptmr0_isr);
  98. #endif
  99. #ifdef BSP_USING_GPTMR1
  100. void gptmr1_isr(void)
  101. {
  102. hpm_hwtmr_isr(&timer1);
  103. }
  104. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR1, gptmr1_isr);
  105. #endif
  106. #ifdef BSP_USING_GPTMR2
  107. void gptmr2_isr(void)
  108. {
  109. hpm_hwtmr_isr(&timer2);
  110. }
  111. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR2, gptmr2_isr);
  112. #endif
  113. #ifdef BSP_USING_GPTMR3
  114. void gptmr3_isr(void)
  115. {
  116. hpm_hwtmr_isr(&timer3);
  117. }
  118. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR3, gptmr3_isr);
  119. #endif
  120. #ifdef BSP_USING_GPTMR4
  121. void gptmr4_isr(void)
  122. {
  123. hpm_hwtmr_isr(&timer4);
  124. }
  125. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR4, gptmr4_isr);
  126. #endif
  127. #ifdef BSP_USING_GPTMR5
  128. void gptmr5_isr(void)
  129. {
  130. hpm_hwtmr_isr(&timer5);
  131. }
  132. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR5, gptmr5_isr);
  133. #endif
  134. #ifdef BSP_USING_GPTMR6
  135. void gptmr6_isr(void)
  136. {
  137. hpm_hwtmr_isr(&timer6);
  138. }
  139. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR6, gptmr6_isr);
  140. #endif
  141. #ifdef BSP_USING_GPTMR7
  142. void gptmr7_isr(void)
  143. {
  144. hpm_hwtmr_isr(&timer7);
  145. }
  146. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR7, gptmr7_isr);
  147. #endif
  148. static void hpm_hwtmr_isr(hpm_gptimer_t *timer)
  149. {
  150. uint32_t hwtmr_stat = gptmr_get_status(timer->base);
  151. if ((hwtmr_stat & GPTMR_CH_RLD_STAT_MASK(timer->channel)) != 0U)
  152. {
  153. rt_device_hwtimer_isr(&timer->timer);
  154. gptmr_clear_status(timer->base, GPTMR_CH_RLD_STAT_MASK(timer->channel));
  155. }
  156. }
  157. static void hpm_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  158. {
  159. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  160. GPTMR_Type *base = hpm_gptmr->base;
  161. gptmr_channel_config_t config;
  162. if (state == 1)
  163. {
  164. hpm_gptmr->timer.freq = board_init_gptmr_clock(base);
  165. gptmr_channel_get_default_config(base, &config);
  166. gptmr_channel_config(base, hpm_gptmr->channel, &config, false);
  167. }
  168. }
  169. static rt_err_t hpm_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  170. {
  171. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*) timer->parent.user_data;
  172. GPTMR_Type *base = hpm_gptmr->base;
  173. gptmr_channel_config_t config;
  174. gptmr_channel_get_default_config(base, &config);
  175. config.cmp[0] = 0;
  176. config.reload = cnt;
  177. timer->mode = mode;
  178. gptmr_channel_config(base, hpm_gptmr->channel, &config, true);
  179. gptmr_clear_status(base, 0xFU);
  180. gptmr_enable_irq(base, GPTMR_CH_RLD_IRQ_MASK(hpm_gptmr->channel));
  181. gptmr_channel_update_count(base, hpm_gptmr->channel, 0);
  182. gptmr_start_counter(base, hpm_gptmr->channel);
  183. intc_m_enable_irq_with_priority(hpm_gptmr->irq_num, 1);
  184. return RT_EOK;
  185. }
  186. static void hpm_hwtimer_stop(rt_hwtimer_t *timer)
  187. {
  188. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  189. GPTMR_Type *base = hpm_gptmr->base;
  190. gptmr_stop_counter(base, hpm_gptmr->channel);
  191. }
  192. static rt_uint32_t hpm_hwtimer_count_get(rt_hwtimer_t *timer)
  193. {
  194. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  195. GPTMR_Type *base = hpm_gptmr->base;
  196. rt_uint32_t current_cnt = gptmr_channel_get_counter(base, hpm_gptmr->channel, gptmr_counter_type_normal);
  197. return current_cnt;
  198. }
  199. static rt_err_t hpm_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  200. {
  201. rt_err_t err = RT_EOK;
  202. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*) timer->parent.user_data;
  203. GPTMR_Type *base = hpm_gptmr->base;
  204. switch (cmd)
  205. {
  206. case HWTIMER_CTRL_FREQ_SET:
  207. err = -RT_ERROR;
  208. break;
  209. case HWTIMER_CTRL_INFO_GET:
  210. *(rt_hwtimer_t*)args = hpm_gptmr->timer;
  211. break;
  212. case HWTIMER_CTRL_MODE_SET:
  213. hpm_gptmr->timer.mode = *(rt_uint32_t*)args;
  214. break;
  215. case HWTIMER_CTRL_STOP:
  216. gptmr_stop_counter(base, hpm_gptmr->channel);
  217. break;
  218. }
  219. return err;
  220. }
  221. int rt_hw_hwtimer_init(void)
  222. {
  223. int ret = RT_EOK;
  224. for (uint32_t i = 0; i < ARRAY_SIZE(s_gptimers); i++)
  225. {
  226. s_gptimers[i]->timer.info = &hpm_hwtimer_info;
  227. s_gptimers[i]->timer.ops = &hpm_hwtimer_ops;
  228. ret = rt_device_hwtimer_register(&s_gptimers[i]->timer, s_gptimers[i]->name, s_gptimers[i]);
  229. if (ret != RT_EOK)
  230. {
  231. LOG_E("%s register failed\n", s_gptimers[i]->name);
  232. }
  233. }
  234. return ret;
  235. }
  236. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  237. #endif /* BSP_USING_GPTMR */