drv_hwtimer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. /*
  2. * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-06-21 CDT first version
  9. * 2024-02-20 CDT support HC32F448
  10. */
  11. #include <rtdevice.h>
  12. #include "drv_config.h"
  13. // #define DRV_DEBUG
  14. #define LOG_TAG "drv.hwtimer"
  15. #include <drv_log.h>
  16. #ifdef BSP_USING_HWTIMER
  17. #include "drv_irq.h"
  18. enum
  19. {
  20. #ifdef BSP_USING_TMRA_1
  21. TMRA_1_INDEX,
  22. #endif
  23. #ifdef BSP_USING_TMRA_2
  24. TMRA_2_INDEX,
  25. #endif
  26. #ifdef BSP_USING_TMRA_3
  27. TMRA_3_INDEX,
  28. #endif
  29. #ifdef BSP_USING_TMRA_4
  30. TMRA_4_INDEX,
  31. #endif
  32. #ifdef BSP_USING_TMRA_5
  33. TMRA_5_INDEX,
  34. #endif
  35. #ifdef BSP_USING_TMRA_6
  36. TMRA_6_INDEX,
  37. #endif
  38. #ifdef BSP_USING_TMRA_7
  39. TMRA_7_INDEX,
  40. #endif
  41. #ifdef BSP_USING_TMRA_8
  42. TMRA_8_INDEX,
  43. #endif
  44. #ifdef BSP_USING_TMRA_9
  45. TMRA_9_INDEX,
  46. #endif
  47. #ifdef BSP_USING_TMRA_10
  48. TMRA_10_INDEX,
  49. #endif
  50. #ifdef BSP_USING_TMRA_11
  51. TMRA_11_INDEX,
  52. #endif
  53. #ifdef BSP_USING_TMRA_12
  54. TMRA_12_INDEX,
  55. #endif
  56. };
  57. struct hc32_hwtimer
  58. {
  59. rt_hwtimer_t time_device;
  60. CM_TMRA_TypeDef *tmr_handle;
  61. rt_uint32_t clock_source;
  62. rt_uint32_t clock;
  63. rt_uint32_t flag;
  64. struct
  65. {
  66. en_int_src_t enIntSrc;
  67. IRQn_Type enIRQn;
  68. rt_uint8_t u8Int_Prio;
  69. func_ptr_t irq_callback;
  70. } isr;
  71. char *name;
  72. };
  73. static struct hc32_hwtimer hc32_hwtimer_obj[] =
  74. {
  75. #ifdef BSP_USING_TMRA_1
  76. TMRA_1_CONFIG,
  77. #endif
  78. #ifdef BSP_USING_TMRA_2
  79. TMRA_2_CONFIG,
  80. #endif
  81. #ifdef BSP_USING_TMRA_3
  82. TMRA_3_CONFIG,
  83. #endif
  84. #ifdef BSP_USING_TMRA_4
  85. TMRA_4_CONFIG,
  86. #endif
  87. #ifdef BSP_USING_TMRA_5
  88. TMRA_5_CONFIG,
  89. #endif
  90. #ifdef BSP_USING_TMRA_6
  91. TMRA_6_CONFIG,
  92. #endif
  93. #ifdef BSP_USING_TMRA_7
  94. TMRA_7_CONFIG,
  95. #endif
  96. #ifdef BSP_USING_TMRA_8
  97. TMRA_8_CONFIG,
  98. #endif
  99. #ifdef BSP_USING_TMRA_9
  100. TMRA_9_CONFIG,
  101. #endif
  102. #ifdef BSP_USING_TMRA_10
  103. TMRA_10_CONFIG,
  104. #endif
  105. #ifdef BSP_USING_TMRA_11
  106. TMRA_11_CONFIG,
  107. #endif
  108. #ifdef BSP_USING_TMRA_12
  109. TMRA_12_CONFIG,
  110. #endif
  111. };
  112. static void _timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  113. {
  114. stc_tmra_init_t stcTmraInit;
  115. struct hc32_irq_config irq_config;
  116. struct hc32_hwtimer *tmr_device = (struct hc32_hwtimer *)timer;
  117. RT_ASSERT(timer != RT_NULL);
  118. /* Interrupt configuration */
  119. irq_config.irq_num = tmr_device->isr.enIRQn;
  120. irq_config.int_src = tmr_device->isr.enIntSrc;
  121. irq_config.irq_prio = tmr_device->isr.u8Int_Prio;
  122. if (state) /* open */
  123. {
  124. /* Counter Frequency Fixed at maxfreq */
  125. timer->freq = timer->info->maxfreq;
  126. /* Enable TIMERA clock */
  127. FCG_Fcg2PeriphClockCmd(tmr_device->clock, ENABLE);
  128. /* TIMERA configuration */
  129. (void)TMRA_StructInit(&stcTmraInit);
  130. stcTmraInit.sw_count.u8ClockDiv = TMRA_CLK_DIV32;
  131. stcTmraInit.u32PeriodValue = timer->info->maxcnt;
  132. (void)TMRA_Init(tmr_device->tmr_handle, &stcTmraInit);
  133. TMRA_IntCmd(tmr_device->tmr_handle, TMRA_INT_OVF, ENABLE);
  134. #if defined (HC32F460) || defined (HC32F4A0)
  135. hc32_install_irq_handler(&irq_config, tmr_device->isr.irq_callback, RT_TRUE);
  136. #elif defined (HC32F448)
  137. hc32_install_independ_irq_handler(&irq_config, RT_TRUE);
  138. #endif
  139. }
  140. else /* close */
  141. {
  142. TMRA_DeInit(tmr_device->tmr_handle);
  143. #if defined (HC32F460) || defined (HC32F4A0)
  144. hc32_install_irq_handler(&irq_config, tmr_device->isr.irq_callback, RT_FALSE);
  145. #elif defined (HC32F448)
  146. hc32_install_independ_irq_handler(&irq_config, RT_FALSE);
  147. #endif
  148. FCG_Fcg2PeriphClockCmd(tmr_device->clock, DISABLE);
  149. }
  150. }
  151. static rt_err_t _timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  152. {
  153. rt_err_t result = RT_EOK;
  154. struct hc32_hwtimer *tmr_device = RT_NULL;
  155. RT_ASSERT(timer != RT_NULL);
  156. tmr_device = (struct hc32_hwtimer *)timer;
  157. /* set timer arr */
  158. TMRA_SetPeriodValue(tmr_device->tmr_handle, t - 1U);
  159. /* start timer */
  160. TMRA_Start(tmr_device->tmr_handle);
  161. return result;
  162. }
  163. static void _timer_stop(rt_hwtimer_t *timer)
  164. {
  165. struct hc32_hwtimer *tmr_device = RT_NULL;
  166. RT_ASSERT(timer != RT_NULL);
  167. tmr_device = (struct hc32_hwtimer *)timer;
  168. /* stop timer */
  169. TMRA_Stop(tmr_device->tmr_handle);
  170. /* reset timer cnt */
  171. TMRA_SetCountValue(tmr_device->tmr_handle, 0U);
  172. }
  173. static rt_err_t _timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  174. {
  175. rt_err_t result = -RT_ERROR;
  176. uint32_t freq = *(uint32_t *)arg;
  177. RT_ASSERT(timer != RT_NULL);
  178. RT_ASSERT(arg != RT_NULL);
  179. switch (cmd)
  180. {
  181. case HWTIMER_CTRL_FREQ_SET:
  182. {
  183. if (freq != timer->freq)
  184. {
  185. LOG_W("Not Support To Set The Counter Frequency! Default is %d Hz", timer->freq);
  186. result = -RT_EINVAL;
  187. }
  188. else
  189. {
  190. result = RT_EOK;
  191. }
  192. }
  193. break;
  194. default:
  195. {
  196. result = -RT_EINVAL;
  197. }
  198. break;
  199. }
  200. return result;
  201. }
  202. static rt_uint32_t _timer_counter_get(rt_hwtimer_t *timer)
  203. {
  204. struct hc32_hwtimer *tmr_device = RT_NULL;
  205. rt_uint32_t Counter;
  206. RT_ASSERT(timer != RT_NULL);
  207. tmr_device = (struct hc32_hwtimer *)timer;
  208. Counter = TMRA_GetCountValue(tmr_device->tmr_handle);
  209. return Counter;
  210. }
  211. #ifdef BSP_USING_TMRA_1
  212. static void TMRA_1_callback(void)
  213. {
  214. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_1_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_1_INDEX].flag);
  215. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_1_INDEX].time_device);
  216. }
  217. #if defined (HC32F448)
  218. void TMRA_1_Ovf_Udf_Handler(void)
  219. {
  220. TMRA_1_callback();
  221. }
  222. #endif /* HC32F448 */
  223. #endif /* BSP_USING_TMRA_1 */
  224. #ifdef BSP_USING_TMRA_2
  225. static void TMRA_2_callback(void)
  226. {
  227. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_2_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_2_INDEX].flag);
  228. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_2_INDEX].time_device);
  229. }
  230. #if defined (HC32F448)
  231. void TMRA_2_Ovf_Udf_Handler(void)
  232. {
  233. TMRA_2_callback();
  234. }
  235. #endif /* HC32F448 */
  236. #endif /* BSP_USING_TMRA_2 */
  237. #ifdef BSP_USING_TMRA_3
  238. static void TMRA_3_callback(void)
  239. {
  240. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_3_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_3_INDEX].flag);
  241. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_3_INDEX].time_device);
  242. }
  243. #if defined (HC32F448)
  244. void TMRA_3_Ovf_Udf_Handler(void)
  245. {
  246. TMRA_3_callback();
  247. }
  248. #endif /* HC32F448 */
  249. #endif /* BSP_USING_TMRA_3 */
  250. #ifdef BSP_USING_TMRA_4
  251. static void TMRA_4_callback(void)
  252. {
  253. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_4_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_4_INDEX].flag);
  254. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_4_INDEX].time_device);
  255. }
  256. #if defined (HC32F448)
  257. void TMRA_4_Ovf_Udf_Handler(void)
  258. {
  259. TMRA_4_callback();
  260. }
  261. #endif /* HC32F448 */
  262. #endif /* BSP_USING_TMRA_4 */
  263. #ifdef BSP_USING_TMRA_5
  264. static void TMRA_5_callback(void)
  265. {
  266. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_5_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_5_INDEX].flag);
  267. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_5_INDEX].time_device);
  268. }
  269. #if defined (HC32F448)
  270. void TMRA_5_Ovf_Udf_Handler(void)
  271. {
  272. TMRA_5_callback();
  273. }
  274. #endif /* HC32F448 */
  275. #endif /* BSP_USING_TMRA_5 */
  276. #ifdef BSP_USING_TMRA_6
  277. static void TMRA_6_callback(void)
  278. {
  279. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_6_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_6_INDEX].flag);
  280. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_6_INDEX].time_device);
  281. }
  282. #endif /* BSP_USING_TMRA_6 */
  283. #ifdef BSP_USING_TMRA_7
  284. static void TMRA_7_callback(void)
  285. {
  286. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_7_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_7_INDEX].flag);
  287. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_7_INDEX].time_device);
  288. }
  289. #endif /* BSP_USING_TMRA_7 */
  290. #ifdef BSP_USING_TMRA_8
  291. static void TMRA_8_callback(void)
  292. {
  293. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_8_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_8_INDEX].flag);
  294. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_8_INDEX].time_device);
  295. }
  296. #endif /* BSP_USING_TMRA_8 */
  297. #ifdef BSP_USING_TMRA_9
  298. static void TMRA_9_callback(void)
  299. {
  300. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_9_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_9_INDEX].flag);
  301. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_9_INDEX].time_device);
  302. }
  303. #endif /* BSP_USING_TMRA_9 */
  304. #ifdef BSP_USING_TMRA_10
  305. static void TMRA_10_callback(void)
  306. {
  307. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_10_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_10_INDEX].flag);
  308. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_10_INDEX].time_device);
  309. }
  310. #endif /* BSP_USING_TMRA_10 */
  311. #ifdef BSP_USING_TMRA_11
  312. static void TMRA_11_callback(void)
  313. {
  314. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_11_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_11_INDEX].flag);
  315. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_11_INDEX].time_device);
  316. }
  317. #endif /* BSP_USING_TMRA_11 */
  318. #ifdef BSP_USING_TMRA_12
  319. static void TMRA_12_callback(void)
  320. {
  321. TMRA_ClearStatus(hc32_hwtimer_obj[TMRA_12_INDEX].tmr_handle, hc32_hwtimer_obj[TMRA_12_INDEX].flag);
  322. rt_device_hwtimer_isr(&hc32_hwtimer_obj[TMRA_12_INDEX].time_device);
  323. }
  324. #endif /* BSP_USING_TMRA_12 */
  325. static struct rt_hwtimer_info _info[sizeof(hc32_hwtimer_obj) / sizeof(hc32_hwtimer_obj[0])];
  326. void tmra_get_info_callback(void)
  327. {
  328. /* Div = 32 */
  329. for (rt_uint8_t i = 0; i < sizeof(_info) / sizeof(_info[0]); i++)
  330. {
  331. _info[i].maxcnt = CLK_GetBusClockFreq(hc32_hwtimer_obj[i].clock_source) / 32U / 1000U; /* Period = 1ms */
  332. _info[i].maxfreq = CLK_GetBusClockFreq(hc32_hwtimer_obj[i].clock_source) / 32U;
  333. _info[i].minfreq = CLK_GetBusClockFreq(hc32_hwtimer_obj[i].clock_source) / 32U / _info[i].maxcnt;
  334. _info[i].cntmode = HWTIMER_CNTMODE_UP;
  335. }
  336. #ifdef BSP_USING_TMRA_1
  337. hc32_hwtimer_obj[TMRA_1_INDEX].isr.irq_callback = TMRA_1_callback;
  338. #endif
  339. #ifdef BSP_USING_TMRA_2
  340. hc32_hwtimer_obj[TMRA_2_INDEX].isr.irq_callback = TMRA_2_callback;
  341. #endif
  342. #ifdef BSP_USING_TMRA_3
  343. hc32_hwtimer_obj[TMRA_3_INDEX].isr.irq_callback = TMRA_3_callback;
  344. #endif
  345. #ifdef BSP_USING_TMRA_4
  346. hc32_hwtimer_obj[TMRA_4_INDEX].isr.irq_callback = TMRA_4_callback;
  347. #endif
  348. #ifdef BSP_USING_TMRA_5
  349. hc32_hwtimer_obj[TMRA_5_INDEX].isr.irq_callback = TMRA_5_callback;
  350. #endif
  351. #ifdef BSP_USING_TMRA_6
  352. hc32_hwtimer_obj[TMRA_6_INDEX].isr.irq_callback = TMRA_6_callback;
  353. #endif
  354. #ifdef BSP_USING_TMRA_7
  355. hc32_hwtimer_obj[TMRA_7_INDEX].isr.irq_callback = TMRA_7_callback;
  356. #endif
  357. #ifdef BSP_USING_TMRA_8
  358. hc32_hwtimer_obj[TMRA_8_INDEX].isr.irq_callback = TMRA_8_callback;
  359. #endif
  360. #ifdef BSP_USING_TMRA_9
  361. hc32_hwtimer_obj[TMRA_9_INDEX].isr.irq_callback = TMRA_9_callback;
  362. #endif
  363. #ifdef BSP_USING_TMRA_10
  364. hc32_hwtimer_obj[TMRA_10_INDEX].isr.irq_callback = TMRA_10_callback;
  365. #endif
  366. #ifdef BSP_USING_TMRA_11
  367. hc32_hwtimer_obj[TMRA_11_INDEX].isr.irq_callback = TMRA_11_callback;
  368. #endif
  369. #ifdef BSP_USING_TMRA_12
  370. hc32_hwtimer_obj[TMRA_12_INDEX].isr.irq_callback = TMRA_12_callback;
  371. #endif
  372. }
  373. static const struct rt_hwtimer_ops _ops =
  374. {
  375. .init = _timer_init,
  376. .start = _timer_start,
  377. .stop = _timer_stop,
  378. .count_get = _timer_counter_get,
  379. .control = _timer_ctrl,
  380. };
  381. static int rt_hw_hwtimer_init(void)
  382. {
  383. int i;
  384. int result = RT_EOK;
  385. tmra_get_info_callback();
  386. for (i = 0; i < sizeof(hc32_hwtimer_obj) / sizeof(hc32_hwtimer_obj[0]); i++)
  387. {
  388. hc32_hwtimer_obj[i].time_device.info = &_info[i];
  389. hc32_hwtimer_obj[i].time_device.ops = &_ops;
  390. if (rt_device_hwtimer_register(&hc32_hwtimer_obj[i].time_device,
  391. hc32_hwtimer_obj[i].name, &hc32_hwtimer_obj[i].tmr_handle) == RT_EOK)
  392. {
  393. LOG_D("%s register success", hc32_hwtimer_obj[i].name);
  394. }
  395. else
  396. {
  397. LOG_E("%s register failed", hc32_hwtimer_obj[i].name);
  398. result = -RT_ERROR;
  399. }
  400. }
  401. return result;
  402. }
  403. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  404. #endif /* BSP_USING_HWTIMER */