drv_hwtimer.c 12 KB

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