drv_hwtimer_ch32f10x.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  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-08-10 charlown first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <board.h>
  13. #ifdef BSP_USING_HWTIMER
  14. #define LOG_TAG "drv.hwtimer"
  15. #include <drv_log.h>
  16. struct hwtimer_device
  17. {
  18. struct rt_hwtimer_device parent;
  19. TIM_TypeDef *periph;
  20. IRQn_Type irqn;
  21. char *name;
  22. };
  23. #ifdef BSP_USING_TIM1_HWTIMER
  24. struct hwtimer_device hwtimer_device1 =
  25. {
  26. .periph = TIM1,
  27. .irqn = TIM1_UP_IRQn,
  28. .name = "timer1"};
  29. #endif
  30. #ifdef BSP_USING_TIM2_HWTIMER
  31. struct hwtimer_device hwtimer_device2 =
  32. {
  33. .periph = TIM2,
  34. .irqn = TIM2_IRQn,
  35. .name = "timer2"};
  36. #endif
  37. #ifdef BSP_USING_TIM3_HWTIMER
  38. struct hwtimer_device hwtimer_device3 =
  39. {
  40. .periph = TIM3,
  41. .irqn = TIM3_IRQn,
  42. .name = "timer3"};
  43. #endif
  44. #ifdef BSP_USING_TIM4_HWTIMER
  45. struct hwtimer_device hwtimer_device4 =
  46. {
  47. .periph = TIM4,
  48. .irqn = TIM4_IRQn,
  49. .name = "timer4"};
  50. #endif
  51. static void ch32f1_hwtimer_init(struct rt_hwtimer_device *device, rt_uint32_t state)
  52. {
  53. struct hwtimer_device *hwtimer_dev;
  54. struct rt_hwtimer_info *hwtimer_info;
  55. rt_uint32_t clk = 0;
  56. rt_uint16_t prescaler_value = 0;
  57. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitType;
  58. NVIC_InitTypeDef NVIC_InitStructure;
  59. RT_ASSERT(device != RT_NULL);
  60. hwtimer_dev = (struct hwtimer_device *)device;
  61. if (state)
  62. {
  63. ch32f1_tim_clock_init(hwtimer_dev->periph);
  64. hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_dev->periph);
  65. clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
  66. prescaler_value = (rt_uint16_t)(clk / hwtimer_info->minfreq) - 1;
  67. /*
  68. * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
  69. */
  70. TIM_TimeBaseInitType.TIM_Period = hwtimer_info->maxcnt - 1;
  71. TIM_TimeBaseInitType.TIM_Prescaler = prescaler_value;
  72. TIM_TimeBaseInitType.TIM_ClockDivision = TIM_CKD_DIV1;
  73. TIM_TimeBaseInitType.TIM_RepetitionCounter = 0;
  74. if (hwtimer_info == RT_NULL)
  75. {
  76. TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
  77. }
  78. else
  79. {
  80. if (hwtimer_info->cntmode == HWTIMER_CNTMODE_UP)
  81. {
  82. TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Up;
  83. }
  84. else
  85. {
  86. TIM_TimeBaseInitType.TIM_CounterMode = TIM_CounterMode_Down;
  87. }
  88. }
  89. TIM_TimeBaseInit(hwtimer_dev->periph, &TIM_TimeBaseInitType);
  90. NVIC_InitStructure.NVIC_IRQChannel = hwtimer_dev->irqn;
  91. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  92. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  93. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  94. NVIC_Init(&NVIC_InitStructure);
  95. TIM_ITConfig(hwtimer_dev->periph, TIM_IT_Update, ENABLE);
  96. TIM_ClearITPendingBit(hwtimer_dev->periph, TIM_IT_Update);
  97. LOG_D("%s init success", hwtimer_dev->name);
  98. }
  99. }
  100. static rt_err_t ch32f1_hwtimer_start(struct rt_hwtimer_device *device, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  101. {
  102. struct hwtimer_device *hwtimer_dev;
  103. RT_ASSERT(device != RT_NULL);
  104. hwtimer_dev = (struct hwtimer_device *)device;
  105. /*
  106. * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
  107. */
  108. TIM_SetCounter(hwtimer_dev->periph, 0);
  109. TIM_SetAutoreload(hwtimer_dev->periph, cnt - 1);
  110. if (mode == HWTIMER_MODE_ONESHOT)
  111. {
  112. TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Single);
  113. }
  114. else
  115. {
  116. TIM_SelectOnePulseMode(hwtimer_dev->periph, TIM_OPMode_Repetitive);
  117. }
  118. TIM_Cmd(hwtimer_dev->periph, ENABLE);
  119. LOG_D("%s start, cnt = %d", hwtimer_dev->name, cnt);
  120. return RT_EOK;
  121. }
  122. static void ch32f1_hwtimer_stop(struct rt_hwtimer_device *device)
  123. {
  124. struct hwtimer_device *hwtimer_dev;
  125. RT_ASSERT(device != RT_NULL);
  126. hwtimer_dev = (struct hwtimer_device *)device;
  127. TIM_Cmd(hwtimer_dev->periph, DISABLE);
  128. TIM_SetCounter(hwtimer_dev->periph, 0);
  129. }
  130. static rt_uint32_t ch32f1_hwtimer_counter_get(struct rt_hwtimer_device *device)
  131. {
  132. struct hwtimer_device *hwtimer_dev;
  133. RT_ASSERT(device != RT_NULL);
  134. hwtimer_dev = (struct hwtimer_device *)device;
  135. return hwtimer_dev->periph->CNT;
  136. }
  137. static rt_err_t ch32f1_hwtimer_control(struct rt_hwtimer_device *device, rt_uint32_t cmd, void *arg)
  138. {
  139. struct hwtimer_device *hwtimer_dev;
  140. rt_err_t result = RT_EOK;
  141. RT_ASSERT(device != RT_NULL);
  142. hwtimer_dev = (struct hwtimer_device *)device;
  143. switch (cmd)
  144. {
  145. case HWTIMER_CTRL_FREQ_SET:
  146. {
  147. rt_uint32_t freq = 0;
  148. rt_uint32_t clk = 0;
  149. rt_uint16_t prescaler_value = 0;
  150. /*
  151. * (1 / freq) = (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
  152. */
  153. if (arg != RT_NULL)
  154. {
  155. freq = *((rt_uint32_t *)arg);
  156. clk = ch32f1_tim_clock_get(hwtimer_dev->periph);
  157. prescaler_value = (rt_uint16_t)(clk / freq) - 1;
  158. TIM_PrescalerConfig(hwtimer_dev->periph, prescaler_value, TIM_PSCReloadMode_Immediate);
  159. }
  160. else
  161. {
  162. result = RT_EINVAL;
  163. }
  164. }
  165. break;
  166. default:
  167. result = RT_ENOSYS;
  168. break;
  169. }
  170. return result;
  171. }
  172. static const struct rt_hwtimer_ops hwtimer_ops =
  173. {
  174. .init = ch32f1_hwtimer_init,
  175. .start = ch32f1_hwtimer_start,
  176. .stop = ch32f1_hwtimer_stop,
  177. .count_get = ch32f1_hwtimer_counter_get,
  178. .control = ch32f1_hwtimer_control,
  179. };
  180. static int rt_hw_hwtimer_init(void)
  181. {
  182. rt_err_t ret;
  183. struct rt_hwtimer_info *hwtimer_info;
  184. #ifdef BSP_USING_TIM1_HWTIMER
  185. hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device1.periph);
  186. hwtimer_device1.parent.info = hwtimer_info;
  187. hwtimer_device1.parent.ops = &hwtimer_ops;
  188. ret = rt_device_hwtimer_register(&hwtimer_device1.parent, hwtimer_device1.name, RT_NULL);
  189. if (ret == RT_EOK)
  190. {
  191. LOG_D("hwtimer: %s register success.", hwtimer_device1.name);
  192. }
  193. else
  194. {
  195. LOG_D("hwtimer: %s register failed.", hwtimer_device1.name);
  196. }
  197. #endif
  198. #ifdef BSP_USING_TIM2_HWTIMER
  199. hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device2.periph);
  200. hwtimer_device2.parent.info = hwtimer_info;
  201. hwtimer_device2.parent.ops = &hwtimer_ops;
  202. ret = rt_device_hwtimer_register(&hwtimer_device2.parent, hwtimer_device2.name, RT_NULL);
  203. if (ret == RT_EOK)
  204. {
  205. LOG_D("hwtimer: %s register success.", hwtimer_device2.name);
  206. }
  207. else
  208. {
  209. LOG_D("hwtimer: %s register failed.", hwtimer_device2.name);
  210. }
  211. #endif
  212. #ifdef BSP_USING_TIM3_HWTIMER
  213. hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device3.periph);
  214. hwtimer_device3.parent.info = hwtimer_info;
  215. hwtimer_device3.parent.ops = &hwtimer_ops;
  216. ret = rt_device_hwtimer_register(&hwtimer_device3.parent, hwtimer_device3.name, RT_NULL);
  217. if (ret == RT_EOK)
  218. {
  219. LOG_D("hwtimer: %s register success.", hwtimer_device3.name);
  220. }
  221. else
  222. {
  223. LOG_D("hwtimer: %s register failed.", hwtimer_device3.name);
  224. }
  225. #endif
  226. #ifdef BSP_USING_TIM4_HWTIMER
  227. hwtimer_info = ch32f1_hwtimer_info_config_get(hwtimer_device4.periph);
  228. hwtimer_device4.parent.info = hwtimer_info;
  229. hwtimer_device4.parent.ops = &hwtimer_ops;
  230. ret = rt_device_hwtimer_register(&hwtimer_device4.parent, hwtimer_device4.name, RT_NULL);
  231. if (ret == RT_EOK)
  232. {
  233. LOG_D("hwtimer: %s register success.", hwtimer_device4.name);
  234. }
  235. else
  236. {
  237. LOG_D("hwtimer: %s register failed.", hwtimer_device4.name);
  238. }
  239. #endif
  240. return RT_EOK;
  241. }
  242. INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
  243. #ifdef BSP_USING_TIM1_HWTIMER
  244. void TIM1_UP_IRQHandler(void)
  245. {
  246. /* enter interrupt */
  247. rt_interrupt_enter();
  248. if (TIM_GetITStatus(hwtimer_device1.periph, TIM_IT_Update) == SET)
  249. {
  250. TIM_ClearITPendingBit(hwtimer_device1.periph, TIM_IT_Update);
  251. rt_device_hwtimer_isr(&hwtimer_device1.parent);
  252. }
  253. /* leave interrupt */
  254. rt_interrupt_leave();
  255. }
  256. #endif
  257. #ifdef BSP_USING_TIM2_HWTIMER
  258. void TIM2_IRQHandler(void)
  259. {
  260. /* enter interrupt */
  261. rt_interrupt_enter();
  262. if (TIM_GetITStatus(hwtimer_device2.periph, TIM_IT_Update) == SET)
  263. {
  264. TIM_ClearITPendingBit(hwtimer_device2.periph, TIM_IT_Update);
  265. rt_device_hwtimer_isr(&hwtimer_device2.parent);
  266. }
  267. /* leave interrupt */
  268. rt_interrupt_leave();
  269. }
  270. #endif
  271. #ifdef BSP_USING_TIM3_HWTIMER
  272. void TIM3_IRQHandler(void)
  273. {
  274. /* enter interrupt */
  275. rt_interrupt_enter();
  276. if (TIM_GetITStatus(hwtimer_device3.periph, TIM_IT_Update) == SET)
  277. {
  278. TIM_ClearITPendingBit(hwtimer_device3.periph, TIM_IT_Update);
  279. rt_device_hwtimer_isr(&hwtimer_device3.parent);
  280. }
  281. /* leave interrupt */
  282. rt_interrupt_leave();
  283. }
  284. #endif
  285. #ifdef BSP_USING_TIM4_HWTIMER
  286. void TIM4_IRQHandler(void)
  287. {
  288. /* enter interrupt */
  289. rt_interrupt_enter();
  290. if (TIM_GetITStatus(hwtimer_device4.periph, TIM_IT_Update) == SET)
  291. {
  292. TIM_ClearITPendingBit(hwtimer_device4.periph, TIM_IT_Update);
  293. rt_device_hwtimer_isr(&hwtimer_device4.parent);
  294. }
  295. /* leave interrupt */
  296. rt_interrupt_leave();
  297. }
  298. #endif
  299. #endif /* BSP_USING_HWTIMER */