drv_hwtimer.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /*
  2. * Copyright (C) 2020, Huada Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-30 CDT first version
  9. */
  10. #include <rtdevice.h>
  11. #include <rtdbg.h>
  12. #ifdef RT_USING_HWTIMER
  13. #if !defined(BSP_USING_TIMER1) && !defined(BSP_USING_TIMER2) && !defined(BSP_USING_TIMER3) && \
  14. !defined(BSP_USING_TIMER4) && !defined(BSP_USING_TIMER5) && !defined(BSP_USING_TIMER6) && \
  15. !defined(BSP_USING_TIMER7) && !defined(BSP_USING_TIMER8) && !defined(BSP_USING_TIMER9) && \
  16. !defined(BSP_USING_TIMER10) && !defined(BSP_USING_TIMER11) && !defined(BSP_USING_TIMER12)
  17. #error "Please define at least one BSP_USING_TIMERx"
  18. /* this driver can be disabled at menuconfig -> Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable TIMER */
  19. #endif
  20. #include "drv_hwtimer.h"
  21. #include "drv_irq.h"
  22. enum
  23. {
  24. #ifdef BSP_USING_TIMER1
  25. TIMER1_INDEX,
  26. #endif
  27. #ifdef BSP_USING_TIMER2
  28. TIMER2_INDEX,
  29. #endif
  30. #ifdef BSP_USING_TIMER3
  31. TIMER3_INDEX,
  32. #endif
  33. #ifdef BSP_USING_TIMER4
  34. TIMER4_INDEX,
  35. #endif
  36. #ifdef BSP_USING_TIMER5
  37. TIMER5_INDEX,
  38. #endif
  39. #ifdef BSP_USING_TIMER6
  40. TIMER6_INDEX,
  41. #endif
  42. #ifdef BSP_USING_TIMER7
  43. TIMER7_INDEX,
  44. #endif
  45. #ifdef BSP_USING_TIMER8
  46. TIMER8_INDEX,
  47. #endif
  48. #ifdef BSP_USING_TIMER9
  49. TIMER9_INDEX,
  50. #endif
  51. #ifdef BSP_USING_TIMER10
  52. TIMER10_INDEX,
  53. #endif
  54. #ifdef BSP_USING_TIMER11
  55. TIMER11_INDEX,
  56. #endif
  57. #ifdef BSP_USING_TIMER12
  58. TIMER12_INDEX,
  59. #endif
  60. };
  61. #ifdef BSP_USING_TIMER1
  62. static void timer1_irq_handler(void);
  63. #endif
  64. #ifdef BSP_USING_TIMER2
  65. static void timer2_irq_handler(void);
  66. #endif
  67. #ifdef BSP_USING_TIMER3
  68. static void timer3_irq_handler(void);
  69. #endif
  70. #ifdef BSP_USING_TIMER4
  71. static void timer4_irq_handler(void);
  72. #endif
  73. #ifdef BSP_USING_TIMER5
  74. static void timer5_irq_handler(void);
  75. #endif
  76. #ifdef BSP_USING_TIMER6
  77. static void timer6_irq_handler(void);
  78. #endif
  79. #ifdef BSP_USING_TIMER7
  80. static void timer7_irq_handler(void);
  81. #endif
  82. #ifdef BSP_USING_TIMER8
  83. static void timer8_irq_handler(void);
  84. #endif
  85. #ifdef BSP_USING_TIMER9
  86. static void timer9_irq_handler(void);
  87. #endif
  88. #ifdef BSP_USING_TIMER10
  89. static void timer10_irq_handler(void);
  90. #endif
  91. #ifdef BSP_USING_TIMER11
  92. static void timer11_irq_handler(void);
  93. #endif
  94. #ifdef BSP_USING_TIMER12
  95. static void timer12_irq_handler(void);
  96. #endif
  97. struct hc32_hwtimer_config
  98. {
  99. rt_hwtimer_t time_device;
  100. M4_TMRA_TypeDef *timer_periph;
  101. struct hc32_irq_config irq_config;
  102. func_ptr_t irq_callback;
  103. uint32_t extend_div;
  104. uint32_t extend_cnt;
  105. char *name;
  106. };
  107. #ifndef HC32_TIMER_CONFIG
  108. #define HC32_TIMER_CONFIG(periph, irq, label, src, irq_info) \
  109. { \
  110. .timer_periph = periph, \
  111. .irq_callback = irq, \
  112. .name = label, \
  113. .irq_config = irq_info, \
  114. .irq_config.int_src = src, \
  115. }
  116. #endif /* HC32_TIMER_CONFIG */
  117. static struct hc32_hwtimer_config hwtimer_obj[] =
  118. {
  119. #ifdef BSP_USING_TIMER1
  120. HC32_TIMER_CONFIG(M4_TMRA_1, timer1_irq_handler, "timer1", INT_TMRA_1_OVF, TIMER1_IRQ_CONFIG),
  121. #endif
  122. #ifdef BSP_USING_TIMER2
  123. HC32_TIMER_CONFIG(M4_TMRA_2, timer2_irq_handler, "timer2", INT_TMRA_2_OVF, TIMER2_IRQ_CONFIG),
  124. #endif
  125. #ifdef BSP_USING_TIMER3
  126. HC32_TIMER_CONFIG(M4_TMRA_3, timer3_irq_handler, "timer3", INT_TMRA_3_OVF, TIMER3_IRQ_CONFIG),
  127. #endif
  128. #ifdef BSP_USING_TIMER4
  129. HC32_TIMER_CONFIG(M4_TMRA_4, timer4_irq_handler, "timer4", INT_TMRA_4_OVF, TIMER4_IRQ_CONFIG),
  130. #endif
  131. #ifdef BSP_USING_TIMER5
  132. HC32_TIMER_CONFIG(M4_TMRA_5, timer5_irq_handler, "timer5", INT_TMRA_5_OVF, TIMER5_IRQ_CONFIG),
  133. #endif
  134. #ifdef BSP_USING_TIMER6
  135. HC32_TIMER_CONFIG(M4_TMRA_6, timer6_irq_handler, "timer6", INT_TMRA_6_OVF, TIMER6_IRQ_CONFIG),
  136. #endif
  137. #ifdef BSP_USING_TIMER7
  138. HC32_TIMER_CONFIG(M4_TMRA_7, timer7_irq_handler, "timer7", INT_TMRA_7_OVF, TIMER7_IRQ_CONFIG),
  139. #endif
  140. #ifdef BSP_USING_TIMER8
  141. HC32_TIMER_CONFIG(M4_TMRA_8, timer8_irq_handler, "timer8", INT_TMRA_8_OVF, TIMER8_IRQ_CONFIG),
  142. #endif
  143. #ifdef BSP_USING_TIMER9
  144. HC32_TIMER_CONFIG(M4_TMRA_9, timer9_irq_handler, "timer9", INT_TMRA_9_OVF, TIMER9_IRQ_CONFIG),
  145. #endif
  146. #ifdef BSP_USING_TIMER10
  147. HC32_TIMER_CONFIG(M4_TMRA_10, timer10_irq_handler, "timer10", INT_TMRA_10_OVF, TIMER10_IRQ_CONFIG),
  148. #endif
  149. #ifdef BSP_USING_TIMER11
  150. HC32_TIMER_CONFIG(M4_TMRA_11, timer11_irq_handler, "timer11", INT_TMRA_11_OVF, TIMER11_IRQ_CONFIG),
  151. #endif
  152. #ifdef BSP_USING_TIMER12
  153. HC32_TIMER_CONFIG(M4_TMRA_12, timer12_irq_handler, "timer12", INT_TMRA_12_OVF, TIMER12_IRQ_CONFIG),
  154. #endif
  155. };
  156. static void hc32_timer_irq_handler(struct hc32_hwtimer_config *timer_config)
  157. {
  158. if ((++timer_config->extend_cnt) >= timer_config->extend_div)
  159. {
  160. timer_config->extend_cnt = 0;
  161. rt_device_hwtimer_isr(&timer_config->time_device);
  162. }
  163. TMRA_ClrStatus(timer_config->timer_periph, (TMRA_FLAG_OVF | TMRA_FLAG_UNF));
  164. }
  165. #ifdef BSP_USING_TIMER1
  166. static void timer1_irq_handler(void)
  167. {
  168. /* enter interrupt */
  169. rt_interrupt_enter();
  170. hc32_timer_irq_handler(&hwtimer_obj[TIMER1_INDEX]);
  171. /* leave interrupt */
  172. rt_interrupt_leave();
  173. }
  174. #endif
  175. #ifdef BSP_USING_TIMER2
  176. static void timer2_irq_handler(void)
  177. {
  178. /* enter interrupt */
  179. rt_interrupt_enter();
  180. hc32_timer_irq_handler(&hwtimer_obj[TIMER2_INDEX]);
  181. /* leave interrupt */
  182. rt_interrupt_leave();
  183. }
  184. #endif
  185. #ifdef BSP_USING_TIMER3
  186. static void timer3_irq_handler(void)
  187. {
  188. /* enter interrupt */
  189. rt_interrupt_enter();
  190. hc32_timer_irq_handler(&hwtimer_obj[TIMER3_INDEX]);
  191. /* leave interrupt */
  192. rt_interrupt_leave();
  193. }
  194. #endif
  195. #ifdef BSP_USING_TIMER4
  196. static void timer4_irq_handler(void)
  197. {
  198. /* enter interrupt */
  199. rt_interrupt_enter();
  200. hc32_timer_irq_handler(&hwtimer_obj[TIMER4_INDEX]);
  201. /* leave interrupt */
  202. rt_interrupt_leave();
  203. }
  204. #endif
  205. #ifdef BSP_USING_TIMER5
  206. static void timer5_irq_handler(void)
  207. {
  208. /* enter interrupt */
  209. rt_interrupt_enter();
  210. hc32_timer_irq_handler(&hwtimer_obj[TIMER5_INDEX]);
  211. /* leave interrupt */
  212. rt_interrupt_leave();
  213. }
  214. #endif
  215. #ifdef BSP_USING_TIMER6
  216. static void timer6_irq_handler(void)
  217. {
  218. /* enter interrupt */
  219. rt_interrupt_enter();
  220. hc32_timer_irq_handler(&hwtimer_obj[TIMER6_INDEX]);
  221. /* leave interrupt */
  222. rt_interrupt_leave();
  223. }
  224. #endif
  225. #ifdef BSP_USING_TIMER7
  226. static void timer7_irq_handler(void)
  227. {
  228. /* enter interrupt */
  229. rt_interrupt_enter();
  230. hc32_timer_irq_handler(&hwtimer_obj[TIMER7_INDEX]);
  231. /* leave interrupt */
  232. rt_interrupt_leave();
  233. }
  234. #endif
  235. #ifdef BSP_USING_TIMER8
  236. static void timer8_irq_handler(void)
  237. {
  238. /* enter interrupt */
  239. rt_interrupt_enter();
  240. hc32_timer_irq_handler(&hwtimer_obj[TIMER8_INDEX]);
  241. /* leave interrupt */
  242. rt_interrupt_leave();
  243. }
  244. #endif
  245. #ifdef BSP_USING_TIMER9
  246. static void timer9_irq_handler(void)
  247. {
  248. /* enter interrupt */
  249. rt_interrupt_enter();
  250. hc32_timer_irq_handler(&hwtimer_obj[TIMER9_INDEX]);
  251. /* leave interrupt */
  252. rt_interrupt_leave();
  253. }
  254. #endif
  255. #ifdef BSP_USING_TIMER10
  256. static void timer10_irq_handler(void)
  257. {
  258. /* enter interrupt */
  259. rt_interrupt_enter();
  260. hc32_timer_irq_handler(&hwtimer_obj[TIMER10_INDEX]);
  261. /* leave interrupt */
  262. rt_interrupt_leave();
  263. }
  264. #endif
  265. #ifdef BSP_USING_TIMER11
  266. static void timer11_irq_handler(void)
  267. {
  268. /* enter interrupt */
  269. rt_interrupt_enter();
  270. hc32_timer_irq_handler(&hwtimer_obj[TIMER11_INDEX]);
  271. /* leave interrupt */
  272. rt_interrupt_leave();
  273. }
  274. #endif
  275. #ifdef BSP_USING_TIMER12
  276. static void timer12_irq_handler(void)
  277. {
  278. /* enter interrupt */
  279. rt_interrupt_enter();
  280. hc32_timer_irq_handler(&hwtimer_obj[TIMER12_INDEX]);
  281. /* leave interrupt */
  282. rt_interrupt_leave();
  283. }
  284. #endif
  285. static rt_uint16_t hc32_timer_get_unit_number(M4_TMRA_TypeDef *TMRAx)
  286. {
  287. rt_uint16_t unit_num;
  288. const rt_uint32_t unit_step = 0x400U;
  289. if (((rt_uint32_t)TMRAx) >= ((rt_uint32_t)M4_TMRA_1))
  290. {
  291. unit_num = (((rt_uint32_t)TMRAx) - ((rt_uint32_t)M4_TMRA_1)) / unit_step;
  292. }
  293. else
  294. {
  295. unit_num = (((rt_uint32_t)TMRAx) - ((rt_uint32_t)M4_TMRA_5)) / unit_step + 4;
  296. }
  297. return unit_num;
  298. }
  299. static void hc32_timer_clock_config(M4_TMRA_TypeDef *TMRAx, en_functional_state_t enNewState)
  300. {
  301. rt_uint32_t timer_periph;
  302. rt_uint16_t unit_num;
  303. unit_num = hc32_timer_get_unit_number(TMRAx);
  304. timer_periph = PWC_FCG2_TMRA_1 << unit_num;
  305. PWC_Fcg2PeriphClockCmd(timer_periph, enNewState);
  306. }
  307. static void hc32_timer_get_div_value(M4_TMRA_TypeDef *TMRAx, uint32_t freq, uint16_t *div, uint32_t *extend_div)
  308. {
  309. stc_clk_freq_t stcClkFreq;
  310. rt_uint32_t divisor, remainder;
  311. rt_uint16_t div_val;
  312. rt_uint32_t clk_freq;
  313. rt_uint16_t unit_num;
  314. CLK_GetClockFreq(&stcClkFreq);
  315. unit_num = hc32_timer_get_unit_number(TMRAx);
  316. if (unit_num >= 4)
  317. {
  318. clk_freq = stcClkFreq.pclk1Freq;
  319. }
  320. else
  321. {
  322. clk_freq = stcClkFreq.pclk0Freq;
  323. }
  324. divisor = clk_freq / freq;
  325. remainder = clk_freq % freq;
  326. for (div_val=1; div_val<=1024; div_val<<=1)
  327. {
  328. if (((divisor % 2) == 0) && (remainder == 0))
  329. {
  330. remainder = divisor % 2;
  331. divisor = divisor / 2;
  332. }
  333. else
  334. {
  335. break;
  336. }
  337. }
  338. *extend_div = divisor;
  339. *div = (__CLZ(__RBIT(div_val))) << TMRA_BCSTR_CKDIV_POS;
  340. }
  341. static void hc32_timer_interrupt_config(struct rt_hwtimer_device *timer, en_functional_state_t enNewState)
  342. {
  343. struct hc32_hwtimer_config *timer_config = RT_NULL;
  344. timer_config = (struct hc32_hwtimer_config *)timer;
  345. if (INT_MAX == timer_config->irq_config.int_src)
  346. {
  347. LOG_D("%s interrupt init failed", timer_config->name);
  348. return;
  349. }
  350. if (Enable == enNewState)
  351. {
  352. /* Enable the specified interrupts of Timer */
  353. hc32_install_irq_handler(&timer_config->irq_config, timer_config->irq_callback, RT_FALSE);
  354. NVIC_EnableIRQ(timer_config->irq_config.irq);
  355. TMRA_IntCmd(timer_config->timer_periph, TMRA_INT_OVF, Enable);
  356. }
  357. else
  358. {
  359. /* Disable the specified interrupts of Timer */
  360. TMRA_IntCmd(timer_config->timer_periph, TMRA_INT_OVF, Disable);
  361. NVIC_DisableIRQ(timer_config->irq_config.irq);
  362. }
  363. }
  364. static void hc32_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  365. {
  366. stc_tmra_init_t stcTmraInit;
  367. struct hc32_hwtimer_config *timer_config = RT_NULL;
  368. RT_ASSERT(timer != RT_NULL);
  369. timer_config = (struct hc32_hwtimer_config *)timer;
  370. if (state)
  371. {
  372. /* Enable Timer peripheral clock. */
  373. hc32_timer_clock_config(timer_config->timer_periph, Enable);
  374. TMRA_DeInit(timer_config->timer_periph);
  375. TMRA_StructInit(&stcTmraInit);
  376. stcTmraInit.u32CntDir = TMRA_DIR_UP;
  377. TMRA_Init(timer_config->timer_periph, &stcTmraInit);
  378. LOG_D("%s init success", timer_config->name);
  379. }
  380. else
  381. {
  382. TMRA_DeInit(timer_config->timer_periph);
  383. hc32_timer_interrupt_config(timer, Disable);
  384. /* Disable Timer peripheral clock. */
  385. hc32_timer_clock_config(timer_config->timer_periph, Disable);
  386. }
  387. }
  388. static rt_err_t hc32_timer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  389. {
  390. rt_err_t result = RT_EOK;
  391. struct hc32_hwtimer_config *timer_config = RT_NULL;
  392. RT_ASSERT(timer != RT_NULL);
  393. timer_config = (struct hc32_hwtimer_config *)timer;
  394. if (mode == HWTIMER_MODE_ONESHOT)
  395. {
  396. TMRA_SetOvfOperation(timer_config->timer_periph, TMRA_OVF_CNT_STOP);
  397. }
  398. else
  399. {
  400. TMRA_SetOvfOperation(timer_config->timer_periph, TMRA_OVF_CNT_CONTINUE);
  401. }
  402. timer_config->extend_cnt = 0;
  403. TMRA_SetCntVal(timer_config->timer_periph, 0);
  404. TMRA_SetPeriodVal(timer_config->timer_periph, cnt - 1);
  405. hc32_timer_interrupt_config(timer, Enable);
  406. TMRA_Start(timer_config->timer_periph);
  407. return result;
  408. }
  409. static void hc32_timer_stop(struct rt_hwtimer_device *timer)
  410. {
  411. struct hc32_hwtimer_config *timer_config = RT_NULL;
  412. RT_ASSERT(timer != RT_NULL);
  413. timer_config = (struct hc32_hwtimer_config *)timer;
  414. /* stop timer */
  415. TMRA_Stop(timer_config->timer_periph);
  416. hc32_timer_interrupt_config(timer, Disable);
  417. TMRA_SetCntVal(timer_config->timer_periph, 0);
  418. }
  419. static rt_uint32_t hc32_timer_get_counter(struct rt_hwtimer_device *timer)
  420. {
  421. rt_uint32_t count_val;
  422. rt_uint32_t period_val;
  423. float temp;
  424. struct hc32_hwtimer_config *timer_config = RT_NULL;
  425. RT_ASSERT(timer != RT_NULL);
  426. timer_config = (struct hc32_hwtimer_config *)timer;
  427. period_val = TMRA_GetPeriodVal(timer_config->timer_periph);
  428. count_val = TMRA_GetCntVal(timer_config->timer_periph);
  429. temp = (timer_config->extend_cnt * period_val + count_val);
  430. temp = temp / (timer_config->extend_div * period_val) * period_val;
  431. count_val = (rt_uint32_t)temp;
  432. return count_val;
  433. }
  434. static rt_err_t hc32_timer_ctrl(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
  435. {
  436. struct hc32_hwtimer_config *timer_config = RT_NULL;
  437. rt_err_t result = RT_EOK;
  438. RT_ASSERT(timer != RT_NULL);
  439. RT_ASSERT(args != RT_NULL);
  440. timer_config = (struct hc32_hwtimer_config *)timer;
  441. switch (cmd)
  442. {
  443. case HWTIMER_CTRL_FREQ_SET:
  444. {
  445. rt_uint32_t freq;
  446. rt_uint16_t div_val;
  447. rt_uint32_t extend_div_val;
  448. /* set timer frequency */
  449. freq = *((rt_uint32_t *)args);
  450. hc32_timer_get_div_value(timer_config->timer_periph, freq, &div_val, &extend_div_val);
  451. TMRA_SetPCLKDiv(timer_config->timer_periph, div_val);
  452. timer_config->extend_div = extend_div_val;
  453. }
  454. break;
  455. default:
  456. {
  457. result = -RT_ENOSYS;
  458. }
  459. break;
  460. }
  461. return result;
  462. }
  463. static const struct rt_hwtimer_ops hwtimer_ops =
  464. {
  465. .init = hc32_timer_init,
  466. .start = hc32_timer_start,
  467. .stop = hc32_timer_stop,
  468. .count_get = hc32_timer_get_counter,
  469. .control = hc32_timer_ctrl,
  470. };
  471. static const struct rt_hwtimer_info hwtimer_info =
  472. {
  473. .maxfreq = 30000000,
  474. .minfreq = 1000,
  475. .maxcnt = 0xFFFF,
  476. .cntmode = HWTIMER_CNTMODE_UP,
  477. };
  478. static int rt_hwtimer_init(void)
  479. {
  480. int i = 0;
  481. int result = RT_EOK;
  482. for (i = 0; i < sizeof(hwtimer_obj) / sizeof(hwtimer_obj[0]); i++)
  483. {
  484. hwtimer_obj[i].time_device.info = &hwtimer_info;
  485. hwtimer_obj[i].time_device.ops = &hwtimer_ops;
  486. if (rt_device_hwtimer_register(&hwtimer_obj[i].time_device, hwtimer_obj[i].name, hwtimer_obj[i].timer_periph) == RT_EOK)
  487. {
  488. LOG_D("%s register success", hwtimer_obj[i].name);
  489. }
  490. else
  491. {
  492. LOG_E("%s register failed", hwtimer_obj[i].name);
  493. result = -RT_ERROR;
  494. }
  495. }
  496. return result;
  497. }
  498. INIT_BOARD_EXPORT(rt_hwtimer_init);
  499. #endif /* RT_USING_HWTIMER */