drv_hwtimer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-02-25 iysheng first version
  9. */
  10. #include <board.h>
  11. #include <rtdevice.h>
  12. #include <drivers/hwtimer.h>
  13. #ifdef BSP_USING_HWTIMER
  14. typedef struct {
  15. uint32_t reg_base;
  16. IRQn_Type irqn;
  17. rcu_periph_enum rcu;
  18. } gd32_hwtimer_data;
  19. typedef struct {
  20. char dev_name[RT_NAME_MAX];
  21. const gd32_hwtimer_data hw_data;
  22. rt_hwtimer_t hwtimer_dev;
  23. const struct rt_hwtimer_info hwtimer_info;
  24. } gd32_hwtimer_device;
  25. enum timer_index_E {
  26. #ifdef BSP_USING_HWTIMER0
  27. TIM0_INDEX,
  28. #endif
  29. #ifdef BSP_USING_HWTIMER1
  30. TIM1_INDEX,
  31. #endif
  32. #ifdef BSP_USING_HWTIMER2
  33. TIM2_INDEX,
  34. #endif
  35. #ifdef BSP_USING_HWTIMER3
  36. TIM3_INDEX,
  37. #endif
  38. #ifdef BSP_USING_HWTIMER4
  39. TIM4_INDEX,
  40. #endif
  41. #ifdef BSP_USING_HWTIMER5
  42. TIM5_INDEX,
  43. #endif
  44. #ifdef BSP_USING_HWTIMER6
  45. TIM6_INDEX,
  46. #endif
  47. #ifdef BSP_USING_HWTIMER7
  48. TIM7_INDEX,
  49. #endif
  50. #ifdef BSP_USING_HWTIMER8
  51. TIM8_INDEX,
  52. #endif
  53. #ifdef BSP_USING_HWTIMER9
  54. TIM9_INDEX,
  55. #endif
  56. #ifdef BSP_USING_HWTIMER10
  57. TIM10_INDEX,
  58. #endif
  59. #ifdef BSP_USING_HWTIMER11
  60. TIM11_INDEX,
  61. #endif
  62. #ifdef BSP_USING_HWTIMER12
  63. TIM12_INDEX,
  64. #endif
  65. #ifdef BSP_USING_HWTIMER13
  66. TIM13_INDEX,
  67. #endif
  68. };
  69. /*
  70. * static void __set_timerx_freq
  71. * Set freq with timerx
  72. *
  73. * @param timerx the pointer of TIMER_TypeDef
  74. * @param freq of the timer clock
  75. * @retval None
  76. */
  77. static void __set_timerx_freq(uint32_t timerx, uint32_t freq)
  78. {
  79. uint32_t ap1freq, ap2freq;
  80. uint16_t prescaler;
  81. uint32_t temp;
  82. if (timerx == TIMER0 || timerx == TIMER7 || timerx == TIMER8 \
  83. || timerx == TIMER9 || timerx == TIMER10)
  84. {
  85. ap2freq = rcu_clock_freq_get(CK_APB2);
  86. temp = RCU_CFG0 & RCU_CFG0_APB2PSC;
  87. temp >>= 11;
  88. /* whether should frequency doubling */
  89. temp = (temp < 4) ? 0 : 1;
  90. prescaler = (ap2freq << temp) / freq - 1;
  91. }
  92. else
  93. {
  94. ap1freq = rcu_clock_freq_get(CK_APB1);
  95. temp = RCU_CFG0 & RCU_CFG0_APB1PSC;
  96. temp >>= 8;
  97. /* whether should frequency doubling */
  98. temp = (temp < 4) ? 0 : 1;
  99. prescaler = (ap1freq << temp) / freq - 1;
  100. }
  101. timer_prescaler_config(timerx, prescaler, TIMER_PSC_RELOAD_NOW);
  102. }
  103. static void gd32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  104. {
  105. uint32_t timer_base = (uint32_t)timer->parent.user_data;
  106. timer_parameter_struct initpara;
  107. if (state)
  108. {
  109. timer_internal_clock_config(timer_base);
  110. timer_struct_para_init(&initpara);
  111. initpara.period = timer->info->maxcnt;
  112. timer_init(timer_base, &initpara);
  113. __set_timerx_freq(timer_base, timer->info->maxfreq);
  114. }
  115. }
  116. static rt_err_t gd32_hwtimer_start(struct rt_hwtimer_device *timer, \
  117. rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  118. {
  119. uint32_t timer_base = (uint32_t)timer->parent.user_data;
  120. if (mode == HWTIMER_MODE_ONESHOT)
  121. {
  122. timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_SINGLE);
  123. }
  124. else if (mode == HWTIMER_MODE_PERIOD)
  125. {
  126. timer_single_pulse_mode_config(timer_base, TIMER_SP_MODE_REPETITIVE);
  127. }
  128. timer_counter_value_config(timer_base, 0);
  129. timer_autoreload_value_config(timer_base, cnt - 1);
  130. timer_enable(timer_base);
  131. return 0;
  132. }
  133. static void gd32_hwtimer_stop(struct rt_hwtimer_device *timer)
  134. {
  135. uint32_t timer_base = (uint32_t)timer->parent.user_data;
  136. timer_disable(timer_base);
  137. }
  138. static rt_uint32_t gd32_hwtimer_count_get(struct rt_hwtimer_device *timer)
  139. {
  140. uint32_t timer_base = (uint32_t)timer->parent.user_data;
  141. rt_uint32_t count;
  142. count = timer_counter_read(timer_base);
  143. return count;
  144. }
  145. static rt_err_t gd32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, \
  146. void *args)
  147. {
  148. int ret = RT_EOK;
  149. rt_int32_t freq;
  150. rt_hwtimer_mode_t mode;
  151. switch (cmd)
  152. {
  153. case HWTIMER_CTRL_FREQ_SET:
  154. freq = *(rt_uint32_t *)args;
  155. __set_timerx_freq((uint32_t)timer->parent.user_data, freq);
  156. break;
  157. default:
  158. rt_kprintf("invalid cmd:%x\n", cmd);
  159. ret = -RT_EINVAL;
  160. break;
  161. }
  162. return ret;
  163. }
  164. static const struct rt_hwtimer_ops g_gd32_hwtimer_ops = {
  165. gd32_hwtimer_init,
  166. gd32_hwtimer_start,
  167. gd32_hwtimer_stop,
  168. gd32_hwtimer_count_get,
  169. gd32_hwtimer_control,
  170. };
  171. static gd32_hwtimer_device g_gd32_hwtimer[] = {
  172. #ifdef BSP_USING_HWTIMER0
  173. {
  174. "timer0",
  175. {
  176. TIMER0,
  177. TIMER0_UP_IRQn,
  178. RCU_TIMER0,
  179. },
  180. {0},
  181. {
  182. 1000000,
  183. 1000,
  184. 0xffff,
  185. 0, /* count up mode */
  186. }
  187. },
  188. #endif
  189. #ifdef BSP_USING_HWTIMER1
  190. {
  191. "timer1",
  192. {
  193. TIMER1,
  194. TIMER1_IRQn,
  195. RCU_TIMER1,
  196. },
  197. {0},
  198. {
  199. 1000000,
  200. 1000,
  201. 0xffff,
  202. 0, /* count up mode */
  203. }
  204. },
  205. #endif
  206. #ifdef BSP_USING_HWTIMER2
  207. {
  208. "timer2",
  209. {
  210. TIMER2,
  211. TIMER2_IRQn,
  212. RCU_TIMER2,
  213. },
  214. {0},
  215. {
  216. 1000000,
  217. 1000,
  218. 0xffff,
  219. 0, /* count up mode */
  220. }
  221. },
  222. #endif
  223. #ifdef BSP_USING_HWTIMER3
  224. {
  225. "timer3",
  226. {
  227. TIMER3,
  228. TIMER3_IRQn,
  229. RCU_TIMER3,
  230. },
  231. {0},
  232. {
  233. 1000000,
  234. 1000,
  235. 0xffff,
  236. 0, /* count up mode */
  237. }
  238. },
  239. #endif
  240. #ifdef BSP_USING_HWTIMER4
  241. {
  242. "timer4",
  243. {
  244. TIMER4,
  245. TIMER4_IRQn,
  246. RCU_TIMER4,
  247. },
  248. {0},
  249. {
  250. 1000000,
  251. 1000,
  252. 0xffff,
  253. 0, /* count up mode */
  254. }
  255. },
  256. #endif
  257. #ifdef BSP_USING_HWTIMER5
  258. {
  259. "timer5",
  260. {
  261. TIMER5,
  262. TIMER5_IRQn,
  263. RCU_TIMER5,
  264. },
  265. {0},
  266. {
  267. 1000000,
  268. 1000,
  269. 0xffff,
  270. 0, /* count up mode */
  271. }
  272. },
  273. #endif
  274. #ifdef BSP_USING_HWTIMER6
  275. {
  276. "timer6",
  277. {
  278. TIMER6,
  279. TIMER6_IRQn,
  280. RCU_TIMER6,
  281. },
  282. {0},
  283. {
  284. 1000000,
  285. 1000,
  286. 0xffff,
  287. 0, /* count up mode */
  288. }
  289. },
  290. #endif
  291. #ifdef BSP_USING_HWTIMER7
  292. {
  293. "timer7",
  294. {
  295. TIMER7,
  296. TIMER7_UP_IRQn,
  297. RCU_TIMER7,
  298. },
  299. {0},
  300. {
  301. 1000000,
  302. 1000,
  303. 0xffff,
  304. 0, /* count up mode */
  305. }
  306. },
  307. #endif
  308. #ifdef BSP_USING_HWTIMER8
  309. {
  310. "timer8",
  311. {
  312. TIMER8,
  313. TIMER8_IRQn,
  314. RCU_TIMER8,
  315. },
  316. {0},
  317. {
  318. 1000000,
  319. 1000,
  320. 0xffff,
  321. 0, /* count up mode */
  322. }
  323. },
  324. #endif
  325. #ifdef BSP_USING_HWTIMER9
  326. {
  327. "timer9",
  328. {
  329. TIMER9,
  330. TIMER9_IRQn,
  331. RCU_TIMER9,
  332. },
  333. {0},
  334. {
  335. 1000000,
  336. 1000,
  337. 0xffff,
  338. 0, /* count up mode */
  339. }
  340. },
  341. #endif
  342. #ifdef BSP_USING_HWTIMER10
  343. {
  344. "timer10",
  345. {
  346. TIMER10,
  347. TIMER10_IRQn,
  348. RCU_TIMER10,
  349. },
  350. {0},
  351. {
  352. 1000000,
  353. 1000,
  354. 0xffff,
  355. 0, /* count up mode */
  356. }
  357. },
  358. #endif
  359. #ifdef BSP_USING_HWTIMER11
  360. {
  361. "timer11",
  362. {
  363. TIMER11,
  364. TIMER11_IRQn,
  365. RCU_TIMER11,
  366. },
  367. {0},
  368. {
  369. 1000000,
  370. 1000,
  371. 0xffff,
  372. 0, /* count up mode */
  373. }
  374. },
  375. #endif
  376. #ifdef BSP_USING_HWTIMER12
  377. {
  378. "timer12",
  379. {
  380. TIMER12,
  381. TIMER12_IRQn,
  382. RCU_TIMER12,
  383. },
  384. {0},
  385. {
  386. 1000000,
  387. 1000,
  388. 0xffff,
  389. 0, /* count up mode */
  390. }
  391. },
  392. #endif
  393. #ifdef BSP_USING_HWTIMER13
  394. {
  395. "timer13",
  396. {
  397. TIMER13,
  398. TIMER13_IRQn,
  399. RCU_TIMER13,
  400. },
  401. {0},
  402. {
  403. 1000000,
  404. 1000,
  405. 0xffff,
  406. 0, /* count up mode */
  407. }
  408. },
  409. #endif
  410. };
  411. #ifdef BSP_USING_HWTIMER0
  412. void TIMER0_UP_IRQHandler(void)
  413. {
  414. rt_interrupt_enter();
  415. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev);
  416. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM0_INDEX].hwtimer_dev.parent.user_data, \
  417. TIMER_INT_UP);
  418. rt_interrupt_leave();
  419. }
  420. #endif
  421. #ifdef BSP_USING_HWTIMER1
  422. void TIMER1_IRQHandler(void)
  423. {
  424. rt_interrupt_enter();
  425. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev);
  426. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM1_INDEX].hwtimer_dev.parent.user_data, \
  427. TIMER_INT_UP);
  428. rt_interrupt_leave();
  429. }
  430. #endif
  431. #ifdef BSP_USING_HWTIMER2
  432. void TIMER2_IRQHandler(void)
  433. {
  434. rt_interrupt_enter();
  435. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev);
  436. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM2_INDEX].hwtimer_dev.parent.user_data, \
  437. TIMER_INT_UP);
  438. rt_interrupt_leave();
  439. }
  440. #endif
  441. #ifdef BSP_USING_HWTIMER3
  442. void TIMER3_IRQHandler(void)
  443. {
  444. rt_interrupt_enter();
  445. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev);
  446. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM3_INDEX].hwtimer_dev.parent.user_data, \
  447. TIMER_INT_UP);
  448. rt_interrupt_leave();
  449. }
  450. #endif
  451. #ifdef BSP_USING_HWTIMER4
  452. void TIMER4_IRQHandler(void)
  453. {
  454. rt_interrupt_enter();
  455. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev);
  456. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM4_INDEX].hwtimer_dev.parent.user_data, \
  457. TIMER_INT_UP);
  458. rt_interrupt_leave();
  459. }
  460. #endif
  461. #ifdef BSP_USING_HWTIMER5
  462. void TIMER5_IRQHandler(void)
  463. {
  464. rt_interrupt_enter();
  465. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev);
  466. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM5_INDEX].hwtimer_dev.parent.user_data, \
  467. TIMER_INT_UP);
  468. rt_interrupt_leave();
  469. }
  470. #endif
  471. #ifdef BSP_USING_HWTIMER6
  472. void TIMER6_IRQHandler(void)
  473. {
  474. rt_interrupt_enter();
  475. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev);
  476. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM6_INDEX].hwtimer_dev.parent.user_data, \
  477. TIMER_INT_UP);
  478. rt_interrupt_leave();
  479. }
  480. #endif
  481. #ifdef BSP_USING_HWTIMER7
  482. void TIMER7_UP_IRQHandler(void)
  483. {
  484. rt_interrupt_enter();
  485. rt_device_hwtimer_isr(&g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev);
  486. timer_flag_clear((uint32_t)g_gd32_hwtimer[TIM7_INDEX].hwtimer_dev.parent.user_data, \
  487. TIMER_INT_UP);
  488. rt_interrupt_leave();
  489. }
  490. #endif
  491. static int rt_hwtimer_init(void)
  492. {
  493. int ret = 0, i = 0;
  494. for (; i < sizeof(g_gd32_hwtimer) / sizeof(g_gd32_hwtimer[0]); i++)
  495. {
  496. g_gd32_hwtimer[i].hwtimer_dev.ops = &g_gd32_hwtimer_ops;
  497. g_gd32_hwtimer[i].hwtimer_dev.info = &g_gd32_hwtimer[i].hwtimer_info;
  498. rcu_periph_clock_enable(g_gd32_hwtimer[i].hw_data.rcu);
  499. NVIC_SetPriority(g_gd32_hwtimer[i].hw_data.irqn, 0);
  500. NVIC_EnableIRQ(g_gd32_hwtimer[i].hw_data.irqn);
  501. timer_interrupt_enable(g_gd32_hwtimer[i].hw_data.reg_base, TIMER_INT_UP);
  502. ret = rt_device_hwtimer_register(&g_gd32_hwtimer[i].hwtimer_dev, \
  503. g_gd32_hwtimer[i].dev_name, (void *)g_gd32_hwtimer[i].hw_data.reg_base);
  504. if (RT_EOK != ret)
  505. {
  506. rt_kprintf("failed register %s, err=%d\n", g_gd32_hwtimer[i].dev_name, \
  507. ret);
  508. break;
  509. }
  510. }
  511. return ret;
  512. }
  513. INIT_BOARD_EXPORT(rt_hwtimer_init);
  514. #endif