drv_hwtimer.c 8.4 KB

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