drv_hwtimer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-09-10 MXH the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #ifdef BSP_USING_HWTIMER
  13. #define DBG_TAG "TIM"
  14. #define DBG_LVL DBG_LOG
  15. #include <rtdbg.h>
  16. #include "drv_hwtimer.h"
  17. #include "board.h"
  18. #ifdef RT_USING_HWTIMER
  19. enum
  20. {
  21. #ifdef BSP_USING_TIM1
  22. TIM1_INDEX,
  23. #endif
  24. #ifdef BSP_USING_TIM2
  25. TIM2_INDEX,
  26. #endif
  27. #ifdef BSP_USING_TIM3
  28. TIM3_INDEX,
  29. #endif
  30. #ifdef BSP_USING_TIM4
  31. TIM4_INDEX,
  32. #endif
  33. #ifdef BSP_USING_TIM5
  34. TIM5_INDEX,
  35. #endif
  36. #ifdef BSP_USING_TIM6
  37. TIM6_INDEX,
  38. #endif
  39. #ifdef BSP_USING_TIM7
  40. TIM7_INDEX,
  41. #endif
  42. #ifdef BSP_USING_TIM8
  43. TIM8_INDEX,
  44. #endif
  45. #ifdef BSP_USING_TIM9
  46. TIM9_INDEX,
  47. #endif
  48. #ifdef BSP_USING_TIM10
  49. TIM10_INDEX,
  50. #endif
  51. };
  52. static struct ch32_hwtimer ch32_hwtimer_obj[] =
  53. {
  54. #ifdef BSP_USING_TIM1
  55. TIM1_CONFIG,
  56. #endif
  57. #ifdef BSP_USING_TIM2
  58. TIM2_CONFIG,
  59. #endif
  60. #ifdef BSP_USING_TIM3
  61. TIM3_CONFIG,
  62. #endif
  63. #ifdef BSP_USING_TIM4
  64. TIM4_CONFIG,
  65. #endif
  66. #ifdef BSP_USING_TIM5
  67. TIM5_CONFIG,
  68. #endif
  69. #ifdef BSP_USING_TIM6
  70. TIM6_CONFIG,
  71. #endif
  72. #ifdef BSP_USING_TIM7
  73. TIM7_CONFIG,
  74. #endif
  75. #ifdef BSP_USING_TIM8
  76. TIM8_CONFIG,
  77. #endif
  78. #ifdef BSP_USING_TIM9
  79. TIM9_CONFIG,
  80. #endif
  81. #ifdef BSP_USING_TIM10
  82. TIM10_CONFIG,
  83. #endif
  84. };
  85. /* APBx timer clocks frequency doubler state related to APB1CLKDivider value */
  86. void ch32_get_pclk_doubler(rt_uint32_t *pclk1_doubler, rt_uint32_t *pclk2_doubler)
  87. {
  88. RT_ASSERT(pclk1_doubler != RT_NULL);
  89. RT_ASSERT(pclk2_doubler != RT_NULL);
  90. *pclk1_doubler = 1;
  91. *pclk2_doubler = 1;
  92. if((RCC->CFGR0 & RCC_PPRE1) == RCC_PPRE1_DIV1)
  93. {
  94. *pclk1_doubler = 1;
  95. }
  96. else
  97. {
  98. *pclk1_doubler = 2;
  99. }
  100. if((RCC->CFGR0 & RCC_PPRE2) == RCC_PPRE2_DIV1)
  101. {
  102. *pclk2_doubler = 1;
  103. }
  104. else
  105. {
  106. *pclk2_doubler = 2;
  107. }
  108. }
  109. static void ch32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  110. {
  111. RT_ASSERT(timer != RT_NULL);
  112. TIM_HandleTypeDef *tim = RT_NULL;
  113. RCC_ClocksTypeDef RCC_ClockStruct;
  114. NVIC_InitTypeDef NVIC_InitStruct;
  115. struct ch32_hwtimer *tim_device = RT_NULL;
  116. rt_uint32_t prescaler_value = 0;
  117. rt_uint32_t pclk1_doubler, pclk2_doubler;
  118. RCC_GetClocksFreq(&RCC_ClockStruct);
  119. ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
  120. if(state)
  121. {
  122. tim = (TIM_HandleTypeDef *)timer->parent.user_data;
  123. tim_device = (struct ch32_hwtimer *)timer;
  124. #if defined (SOC_RISCV_SERIES_CH32V2)
  125. if(tim->instance == TIM1)
  126. #elif defined(SOC_RISCV_SERIES_CH32V3)
  127. if(tim->instance == TIM1 || tim->instance == TIM8 ||
  128. tim->instance == TIM9 || tim->instance == TIM10)
  129. #else
  130. #error " unsupported CH32 series! "
  131. if(RT_NULL)
  132. #endif
  133. {
  134. RCC_APB2PeriphClockCmd(tim->rcc, ENABLE);
  135. prescaler_value = (RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / 10000) - 1;
  136. }
  137. else
  138. {
  139. RCC_APB1PeriphClockCmd(tim->rcc, ENABLE);
  140. prescaler_value = (RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / 10000) - 1;
  141. }
  142. tim->init.TIM_Prescaler = prescaler_value;
  143. tim->init.TIM_ClockDivision = TIM_CKD_DIV1;
  144. tim->init.TIM_Period = 10000 - 1;
  145. tim->init.TIM_RepetitionCounter = 0;
  146. if(timer->info->cntmode == HWTIMER_CNTMODE_UP)
  147. {
  148. tim->init.TIM_CounterMode = TIM_CounterMode_Up;
  149. }
  150. else
  151. {
  152. tim->init.TIM_CounterMode = TIM_CounterMode_Down;
  153. }
  154. #if defined (SOC_RISCV_SERIES_CH32V3)
  155. /* TIM6 and TIM7 only support counter up mode */
  156. if(tim->instance == TIM6 || tim->instance == TIM7)
  157. {
  158. tim->init.TIM_CounterMode = TIM_CounterMode_Up;
  159. }
  160. #endif
  161. TIM_TimeBaseInit(tim->instance, &tim->init);
  162. NVIC_InitStruct.NVIC_IRQChannel = tim_device->irqn;
  163. NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
  164. NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
  165. NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  166. NVIC_Init(&NVIC_InitStruct);
  167. TIM_ClearITPendingBit(tim->instance, TIM_IT_Update);
  168. TIM_ITConfig(tim->instance, TIM_IT_Update, ENABLE);
  169. }
  170. }
  171. static rt_err_t ch32_hwtimer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  172. {
  173. RT_ASSERT(timer != RT_NULL);
  174. TIM_HandleTypeDef *tim = RT_NULL;
  175. tim = (TIM_HandleTypeDef *)timer->parent.user_data;
  176. /* set tim cnt */
  177. tim->instance->CNT = 0;
  178. /* set tim arr */
  179. tim->instance->ATRLR = cnt - 1;
  180. tim->init.TIM_Period = cnt - 1;
  181. if (mode == HWTIMER_MODE_ONESHOT)
  182. {
  183. /* set timer to single mode */
  184. tim->instance->CTLR1 &= (rt_uint16_t) ~((rt_uint16_t)TIM_OPM);
  185. tim->instance->CTLR1 |= TIM_OPMode_Single;
  186. }
  187. else
  188. {
  189. tim->instance->CTLR1 &= (rt_uint16_t) ~((rt_uint16_t)TIM_OPM);
  190. tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
  191. }
  192. /* start timer */
  193. TIM_Cmd(tim->instance, ENABLE);
  194. return RT_EOK;
  195. }
  196. static void ch32_hwtimer_stop(struct rt_hwtimer_device *timer)
  197. {
  198. RT_ASSERT(timer != RT_NULL);
  199. TIM_HandleTypeDef *tim = RT_NULL;
  200. tim = (TIM_HandleTypeDef *)timer->parent.user_data;
  201. /* stop timer */
  202. TIM_Cmd(tim->instance, DISABLE);
  203. /* set tim cnt */
  204. tim->instance->CNT = 0;
  205. }
  206. static rt_uint32_t ch32_hwtimer_count_get(struct rt_hwtimer_device *timer)
  207. {
  208. RT_ASSERT(timer != RT_NULL);
  209. TIM_HandleTypeDef *tim = RT_NULL;
  210. tim = (TIM_HandleTypeDef *)timer->parent.user_data;
  211. return tim->instance->CNT;
  212. }
  213. static rt_err_t ch32_hwtimer_control(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
  214. {
  215. RT_ASSERT(timer != RT_NULL);
  216. RT_ASSERT(args != RT_NULL);
  217. TIM_HandleTypeDef *tim = RT_NULL;
  218. rt_err_t result = RT_EOK;
  219. rt_uint32_t pclk1_doubler, pclk2_doubler;
  220. tim = (TIM_HandleTypeDef *)timer->parent.user_data;
  221. switch (cmd)
  222. {
  223. case HWTIMER_CTRL_FREQ_SET:
  224. {
  225. rt_uint32_t freq;
  226. rt_uint16_t val;
  227. RCC_ClocksTypeDef RCC_ClockStruct;
  228. /* set timer frequence */
  229. freq = *((rt_uint32_t *)args);
  230. ch32_get_pclk_doubler(&pclk1_doubler, &pclk2_doubler);
  231. RCC_GetClocksFreq(&RCC_ClockStruct);
  232. #if defined (SOC_RISCV_SERIES_CH32V2)
  233. if(tim->instance == TIM1)
  234. #elif defined(SOC_RISCV_SERIES_CH32V3)
  235. if(tim->instance == TIM1 || tim->instance == TIM8 ||
  236. tim->instance == TIM9 || tim->instance == TIM10)
  237. #else
  238. #error " unsupported CH32 series! "
  239. if(RT_NULL)
  240. #endif
  241. {
  242. val = RCC_ClockStruct.PCLK2_Frequency * pclk2_doubler / freq;
  243. }
  244. else
  245. {
  246. val = RCC_ClockStruct.PCLK1_Frequency * pclk1_doubler / freq;
  247. }
  248. /* Update frequency value */
  249. TIM_PrescalerConfig(tim->instance, val - 1, TIM_PSCReloadMode_Immediate);
  250. result = RT_EOK;
  251. break;
  252. }
  253. case HWTIMER_CTRL_MODE_SET:
  254. {
  255. if (*(rt_hwtimer_mode_t *)args == HWTIMER_MODE_ONESHOT)
  256. {
  257. /* set timer to single mode */
  258. tim->instance->CTLR1 &= (rt_uint16_t) ~((rt_uint16_t)TIM_OPM);
  259. tim->instance->CTLR1 |= TIM_OPMode_Single;
  260. }
  261. else
  262. {
  263. tim->instance->CTLR1 &= (rt_uint16_t) ~((rt_uint16_t)TIM_OPM);
  264. tim->instance->CTLR1 |= TIM_OPMode_Repetitive;
  265. }
  266. break;
  267. }
  268. case HWTIMER_CTRL_INFO_GET:
  269. {
  270. *(rt_hwtimer_mode_t *)args = tim->instance->CNT;
  271. break;
  272. }
  273. case HWTIMER_CTRL_STOP:
  274. {
  275. ch32_hwtimer_stop(timer);
  276. break;
  277. }
  278. default:
  279. {
  280. result = -RT_EINVAL;
  281. break;
  282. }
  283. }
  284. return result;
  285. }
  286. static const struct rt_hwtimer_info ch32_hwtimer_info = TIM_DEV_INFO_CONFIG;
  287. static const struct rt_hwtimer_ops ch32_hwtimer_ops =
  288. {
  289. ch32_hwtimer_init,
  290. ch32_hwtimer_start,
  291. ch32_hwtimer_stop,
  292. ch32_hwtimer_count_get,
  293. ch32_hwtimer_control
  294. };
  295. static void ch32_hwtimer_isr(struct rt_hwtimer_device *device)
  296. {
  297. RT_ASSERT(device != RT_NULL);
  298. struct ch32_hwtimer *hwtimer = RT_NULL;
  299. hwtimer = rt_container_of(device, struct ch32_hwtimer, device);
  300. if(TIM_GetITStatus(hwtimer->handle.instance, TIM_IT_Update) != RESET)
  301. {
  302. rt_device_hwtimer_isr(device);
  303. TIM_ClearITPendingBit(hwtimer->handle.instance, TIM_IT_Update);
  304. }
  305. }
  306. #ifdef BSP_USING_TIM1
  307. void TIM1_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  308. void TIM1_UP_IRQHandler(void)
  309. {
  310. GET_INT_SP();
  311. rt_interrupt_enter();
  312. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM1_INDEX].device));
  313. rt_interrupt_leave();
  314. FREE_INT_SP();
  315. }
  316. #endif /* BSP_USING_TIM1 */
  317. #ifdef BSP_USING_TIM2
  318. void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  319. void TIM2_IRQHandler(void)
  320. {
  321. GET_INT_SP();
  322. rt_interrupt_enter();
  323. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM2_INDEX].device));
  324. rt_interrupt_leave();
  325. FREE_INT_SP();
  326. }
  327. #endif /* BSP_USING_TIM2 */
  328. #ifdef BSP_USING_TIM3
  329. void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  330. void TIM3_IRQHandler(void)
  331. {
  332. GET_INT_SP();
  333. rt_interrupt_enter();
  334. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM3_INDEX].device));
  335. rt_interrupt_leave();
  336. FREE_INT_SP();
  337. }
  338. #endif /* BSP_USING_TIM3 */
  339. #ifdef BSP_USING_TIM4
  340. void TIM4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  341. void TIM4_IRQHandler(void)
  342. {
  343. GET_INT_SP();
  344. rt_interrupt_enter();
  345. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM4_INDEX].device));
  346. rt_interrupt_leave();
  347. FREE_INT_SP();
  348. }
  349. #endif /* BSP_USING_TIM4 */
  350. #ifdef BSP_USING_TIM5
  351. void TIM5_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  352. void TIM5_IRQHandler(void)
  353. {
  354. GET_INT_SP();
  355. rt_interrupt_enter();
  356. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM5_INDEX].device));
  357. rt_interrupt_leave();
  358. FREE_INT_SP();
  359. }
  360. #endif /* BSP_USING_TIM5 */
  361. #ifdef BSP_USING_TIM6
  362. void TIM6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  363. void TIM6_IRQHandler(void)
  364. {
  365. GET_INT_SP();
  366. rt_interrupt_enter();
  367. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM6_INDEX].device));
  368. rt_interrupt_leave();
  369. FREE_INT_SP();
  370. }
  371. #endif /* BSP_USING_TIM6 */
  372. #ifdef BSP_USING_TIM7
  373. void TIM7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  374. void TIM7_IRQHandler(void)
  375. {
  376. GET_INT_SP();
  377. rt_interrupt_enter();
  378. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM7_INDEX].device));
  379. rt_interrupt_leave();
  380. FREE_INT_SP();
  381. }
  382. #endif /* BSP_USING_TIM7 */
  383. #ifdef BSP_USING_TIM8
  384. void TIM8_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  385. void TIM8_UP_IRQHandler(void)
  386. {
  387. GET_INT_SP();
  388. rt_interrupt_enter();
  389. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM8_INDEX].device));
  390. rt_interrupt_leave();
  391. FREE_INT_SP();
  392. }
  393. #endif /* BSP_USING_TIM8 */
  394. #ifdef BSP_USING_TIM9
  395. void TIM9_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  396. void TIM9_UP_IRQHandler(void)
  397. {
  398. GET_INT_SP();
  399. rt_interrupt_enter();
  400. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM9_INDEX].device));
  401. rt_interrupt_leave();
  402. FREE_INT_SP();
  403. }
  404. #endif /* BSP_USING_TIM9 */
  405. #ifdef BSP_USING_TIM10
  406. void TIM10_UP_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
  407. void TIM10_UP_IRQHandler(void)
  408. {
  409. GET_INT_SP();
  410. rt_interrupt_enter();
  411. ch32_hwtimer_isr(&(ch32_hwtimer_obj[TIM10_INDEX].device));
  412. rt_interrupt_leave();
  413. FREE_INT_SP();
  414. }
  415. #endif /* BSP_USING_TIM10 */
  416. static int rt_hw_timer_init(void)
  417. {
  418. int i = 0;
  419. int result = RT_EOK;
  420. for (i = 0; i < sizeof(ch32_hwtimer_obj) / sizeof(ch32_hwtimer_obj[0]); i++)
  421. {
  422. ch32_hwtimer_obj[i].device.info = &ch32_hwtimer_info;
  423. ch32_hwtimer_obj[i].device.ops = &ch32_hwtimer_ops;
  424. result = rt_device_hwtimer_register(&ch32_hwtimer_obj[i].device,
  425. ch32_hwtimer_obj[i].name, (void *)&ch32_hwtimer_obj[i].handle);
  426. RT_ASSERT(result == RT_EOK);
  427. }
  428. return result;
  429. }
  430. INIT_BOARD_EXPORT(rt_hw_timer_init);
  431. #endif /* RT_USING_HWTIMER */
  432. #endif /* BSP_USING_HWTIMER */