drv_hwtimer.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * Copyright (c) 2022-2025 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. #include "hpm_clock_drv.h"
  15. typedef struct _hpm_gptimer
  16. {
  17. GPTMR_Type *base;
  18. const char *name;
  19. rt_hwtimer_t timer;
  20. uint32_t channel;
  21. clock_name_t clock_name;
  22. int32_t irq_num;
  23. uint8_t irq_priority;
  24. } hpm_gptimer_t;
  25. static void hpm_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state);
  26. static rt_err_t hpm_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
  27. static void hpm_hwtimer_stop(rt_hwtimer_t *timer);
  28. static rt_uint32_t hpm_hwtimer_count_get(rt_hwtimer_t *timer);
  29. static rt_err_t hpm_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
  30. static void hpm_hwtmr_isr(hpm_gptimer_t *gptmr);
  31. static const struct rt_hwtimer_ops hpm_hwtimer_ops = {
  32. .init = hpm_hwtimer_init,
  33. .start = hpm_hwtimer_start,
  34. .stop = hpm_hwtimer_stop,
  35. .count_get = hpm_hwtimer_count_get,
  36. .control = hpm_hwtimer_control
  37. };
  38. static const struct rt_hwtimer_info hpm_hwtimer_info = {
  39. .maxfreq = 100000000UL,
  40. .minfreq = 93750UL,
  41. .maxcnt = 0xFFFFFFFFUL,
  42. .cntmode = HWTIMER_CNTMODE_UP
  43. };
  44. #ifdef BSP_USING_GPTMR0
  45. static hpm_gptimer_t timer0 =
  46. {
  47. .name = "GPT0",
  48. .base = HPM_GPTMR0,
  49. .clock_name = clock_gptmr0,
  50. .irq_num = IRQn_GPTMR0,
  51. #if defined(BSP_GPTMR0_IRQ_PRIORITY)
  52. .irq_priority = BSP_GPTMR0_IRQ_PRIORITY,
  53. #else
  54. .irq_priority = 1,
  55. #endif
  56. };
  57. #endif
  58. #ifdef BSP_USING_GPTMR1
  59. static hpm_gptimer_t timer1 =
  60. {
  61. .name = "GPT1",
  62. .base = HPM_GPTMR1,
  63. .clock_name = clock_gptmr1,
  64. .irq_num = IRQn_GPTMR1,
  65. #if defined(BSP_GPTMR1_IRQ_PRIORITY)
  66. .irq_priority = BSP_GPTMR1_IRQ_PRIORITY,
  67. #else
  68. .irq_priority = 1,
  69. #endif
  70. };
  71. #endif
  72. #ifdef BSP_USING_GPTMR2
  73. static hpm_gptimer_t timer2 =
  74. {
  75. .name = "GPT2",
  76. .base = HPM_GPTMR2,
  77. .clock_name = clock_gptmr2,
  78. .irq_num = IRQn_GPTMR2,
  79. #if defined(BSP_GPTMR2_IRQ_PRIORITY)
  80. .irq_priority = BSP_GPTMR2_IRQ_PRIORITY,
  81. #else
  82. .irq_priority = 1,
  83. #endif
  84. };
  85. #endif
  86. #ifdef BSP_USING_GPTMR3
  87. static hpm_gptimer_t timer3 =
  88. {
  89. .name = "GPT3",
  90. .base = HPM_GPTMR3,
  91. .clock_name = clock_gptmr3,
  92. .irq_num = IRQn_GPTMR3,
  93. #if defined(BSP_GPTMR3_IRQ_PRIORITY)
  94. .irq_priority = BSP_GPTMR3_IRQ_PRIORITY,
  95. #else
  96. .irq_priority = 1,
  97. #endif
  98. };
  99. #endif
  100. #ifdef BSP_USING_GPTMR4
  101. static hpm_gptimer_t timer4 =
  102. {
  103. .name = "GPT4",
  104. .base = HPM_GPTMR4,
  105. .clock_name = clock_gptmr4,
  106. .irq_num = IRQn_GPTMR4,
  107. #if defined(BSP_GPTMR4_IRQ_PRIORITY)
  108. .irq_priority = BSP_GPTMR4_IRQ_PRIORITY,
  109. #else
  110. .irq_priority = 1,
  111. #endif
  112. };
  113. #endif
  114. #ifdef BSP_USING_GPTMR5
  115. static hpm_gptimer_t timer5 =
  116. {
  117. .name = "GPT5",
  118. .base = HPM_GPTMR5,
  119. .clock_name = clock_gptmr5,
  120. .irq_num = IRQn_GPTMR5,
  121. #if defined(BSP_GPTMR5_IRQ_PRIORITY)
  122. .irq_priority = BSP_GPTMR5_IRQ_PRIORITY,
  123. #else
  124. .irq_priority = 1,
  125. #endif
  126. };
  127. #endif
  128. #ifdef BSP_USING_GPTMR6
  129. static hpm_gptimer_t timer6 =
  130. {
  131. .name = "GPT6",
  132. .base = HPM_GPTMR6,
  133. .clock_name = clock_gptmr6,
  134. .irq_num = IRQn_GPTMR6,
  135. #if defined(BSP_GPTMR6_IRQ_PRIORITY)
  136. .irq_priority = BSP_GPTMR6_IRQ_PRIORITY,
  137. #else
  138. .irq_priority = 1,
  139. #endif
  140. };
  141. #endif
  142. #ifdef BSP_USING_GPTMR7
  143. static hpm_gptimer_t timer7 =
  144. {
  145. .name = "GPT7",
  146. .base = HPM_GPTMR7,
  147. .clock_name = clock_gptmr7,
  148. .irq_num = IRQn_GPTMR7,
  149. #if defined(BSP_GPTMR7_IRQ_PRIORITY)
  150. .irq_priority = BSP_GPTMR7_IRQ_PRIORITY,
  151. #else
  152. .irq_priority = 1,
  153. #endif
  154. };
  155. #endif
  156. static hpm_gptimer_t *s_gptimers[] = {
  157. #ifdef BSP_USING_GPTMR0
  158. &timer0,
  159. #endif
  160. #ifdef BSP_USING_GPTMR1
  161. &timer1,
  162. #endif
  163. #ifdef BSP_USING_GPTMR2
  164. &timer2,
  165. #endif
  166. #ifdef BSP_USING_GPTMR3
  167. &timer3,
  168. #endif
  169. #ifdef BSP_USING_GPTMR4
  170. &timer4,
  171. #endif
  172. #ifdef BSP_USING_GPTMR5
  173. &timer5,
  174. #endif
  175. #ifdef BSP_USING_GPTMR6
  176. &timer6,
  177. #endif
  178. #ifdef BSP_USING_GPTMR7
  179. &timer7,
  180. #endif
  181. };
  182. #ifdef BSP_USING_GPTMR0
  183. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR0, gptmr0_isr);
  184. void gptmr0_isr(void)
  185. {
  186. hpm_hwtmr_isr(&timer0);
  187. }
  188. #endif
  189. #ifdef BSP_USING_GPTMR1
  190. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR1, gptmr1_isr);
  191. void gptmr1_isr(void)
  192. {
  193. hpm_hwtmr_isr(&timer1);
  194. }
  195. #endif
  196. #ifdef BSP_USING_GPTMR2
  197. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR2, gptmr2_isr);
  198. void gptmr2_isr(void)
  199. {
  200. hpm_hwtmr_isr(&timer2);
  201. }
  202. #endif
  203. #ifdef BSP_USING_GPTMR3
  204. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR3, gptmr3_isr);
  205. void gptmr3_isr(void)
  206. {
  207. hpm_hwtmr_isr(&timer3);
  208. }
  209. #endif
  210. #ifdef BSP_USING_GPTMR4
  211. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR4, gptmr4_isr);
  212. void gptmr4_isr(void)
  213. {
  214. hpm_hwtmr_isr(&timer4);
  215. }
  216. #endif
  217. #ifdef BSP_USING_GPTMR5
  218. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR5, gptmr5_isr);
  219. void gptmr5_isr(void)
  220. {
  221. hpm_hwtmr_isr(&timer5);
  222. }
  223. #endif
  224. #ifdef BSP_USING_GPTMR6
  225. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR6, gptmr6_isr);
  226. void gptmr6_isr(void)
  227. {
  228. hpm_hwtmr_isr(&timer6);
  229. }
  230. #endif
  231. #ifdef BSP_USING_GPTMR7
  232. SDK_DECLARE_EXT_ISR_M(IRQn_GPTMR7, gptmr7_isr);
  233. void gptmr7_isr(void)
  234. {
  235. hpm_hwtmr_isr(&timer7);
  236. }
  237. #endif
  238. static void hpm_hwtmr_isr(hpm_gptimer_t *timer)
  239. {
  240. uint32_t hwtmr_stat = gptmr_get_status(timer->base);
  241. if ((hwtmr_stat & GPTMR_CH_RLD_STAT_MASK(timer->channel)) != 0U)
  242. {
  243. rt_device_hwtimer_isr(&timer->timer);
  244. gptmr_clear_status(timer->base, GPTMR_CH_RLD_STAT_MASK(timer->channel));
  245. }
  246. }
  247. static void hpm_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  248. {
  249. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  250. GPTMR_Type *base = hpm_gptmr->base;
  251. gptmr_channel_config_t config;
  252. if (state == 1)
  253. {
  254. clock_add_to_group(hpm_gptmr->clock_name, BOARD_RUNNING_CORE & 0x1);
  255. hpm_gptmr->timer.freq = clock_get_frequency(hpm_gptmr->clock_name);
  256. gptmr_channel_get_default_config(base, &config);
  257. gptmr_channel_config(base, hpm_gptmr->channel, &config, false);
  258. }
  259. }
  260. static rt_err_t hpm_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  261. {
  262. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*) timer->parent.user_data;
  263. GPTMR_Type *base = hpm_gptmr->base;
  264. gptmr_channel_config_t config;
  265. gptmr_channel_get_default_config(base, &config);
  266. config.cmp[0] = 0;
  267. config.reload = cnt;
  268. timer->mode = mode;
  269. gptmr_channel_config(base, hpm_gptmr->channel, &config, true);
  270. gptmr_clear_status(base, 0xFU);
  271. gptmr_enable_irq(base, GPTMR_CH_RLD_IRQ_MASK(hpm_gptmr->channel));
  272. gptmr_channel_update_count(base, hpm_gptmr->channel, 0);
  273. gptmr_start_counter(base, hpm_gptmr->channel);
  274. intc_m_enable_irq_with_priority(hpm_gptmr->irq_num, hpm_gptmr->irq_priority);
  275. return RT_EOK;
  276. }
  277. static void hpm_hwtimer_stop(rt_hwtimer_t *timer)
  278. {
  279. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  280. GPTMR_Type *base = hpm_gptmr->base;
  281. gptmr_stop_counter(base, hpm_gptmr->channel);
  282. }
  283. static rt_uint32_t hpm_hwtimer_count_get(rt_hwtimer_t *timer)
  284. {
  285. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*)timer->parent.user_data;
  286. GPTMR_Type *base = hpm_gptmr->base;
  287. rt_uint32_t current_cnt = gptmr_channel_get_counter(base, hpm_gptmr->channel, gptmr_counter_type_normal);
  288. return current_cnt;
  289. }
  290. static rt_err_t hpm_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  291. {
  292. rt_err_t err = RT_EOK;
  293. hpm_gptimer_t *hpm_gptmr = (hpm_gptimer_t*) timer->parent.user_data;
  294. GPTMR_Type *base = hpm_gptmr->base;
  295. switch (cmd)
  296. {
  297. case HWTIMER_CTRL_FREQ_SET:
  298. err = -RT_ERROR;
  299. break;
  300. case HWTIMER_CTRL_INFO_GET:
  301. *(rt_hwtimer_t*)args = hpm_gptmr->timer;
  302. break;
  303. case HWTIMER_CTRL_MODE_SET:
  304. hpm_gptmr->timer.mode = *(rt_uint32_t*)args;
  305. break;
  306. case HWTIMER_CTRL_STOP:
  307. gptmr_stop_counter(base, hpm_gptmr->channel);
  308. break;
  309. }
  310. return err;
  311. }
  312. int rt_hw_hwtimer_init(void)
  313. {
  314. int ret = RT_EOK;
  315. for (uint32_t i = 0; i < ARRAY_SIZE(s_gptimers); i++)
  316. {
  317. s_gptimers[i]->timer.info = &hpm_hwtimer_info;
  318. s_gptimers[i]->timer.ops = &hpm_hwtimer_ops;
  319. ret = rt_device_hwtimer_register(&s_gptimers[i]->timer, s_gptimers[i]->name, s_gptimers[i]);
  320. if (ret != RT_EOK)
  321. {
  322. LOG_E("%s register failed\n", s_gptimers[i]->name);
  323. }
  324. }
  325. return ret;
  326. }
  327. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  328. #endif /* BSP_USING_GPTMR */