drv_hwtimer.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018-12-10 Zohar_Lee first version
  9. * 2020-07-10 lik format file
  10. */
  11. #include "drv_hwtimer.h"
  12. #ifdef RT_USING_HWTIMER
  13. #ifdef BSP_USING_TIM
  14. //#define DRV_DEBUG
  15. #define LOG_TAG "drv.hwtimer"
  16. #include <drv_log.h>
  17. #if !defined(BSP_USING_TIM0) && !defined(BSP_USING_TIM1) && !defined(BSP_USING_TIM2) && !defined(BSP_USING_TIM3) \
  18. && !defined(BSP_USING_TIM4) && !defined(BSP_USING_TIM5)
  19. #error "Please define at least one BSP_USING_TIMx"
  20. /* this driver can be disabled at menuconfig ? RT-Thread Components ? Device Drivers */
  21. #endif
  22. #ifndef TIM_DEV_INFO_CONFIG
  23. #define TIM_DEV_INFO_CONFIG \
  24. { \
  25. .maxfreq = 120000000, \
  26. .minfreq = 120000000, \
  27. .maxcnt = 0xFFFFFFFF, \
  28. .cntmode = HWTIMER_CNTMODE_DW, \
  29. }
  30. #endif /* TIM_DEV_INFO_CONFIG */
  31. #ifdef BSP_USING_TIM0
  32. #ifndef TIM0_CFG
  33. #define TIM0_CFG \
  34. { \
  35. .name = "timer0", \
  36. .TIMRx = TIMR0, \
  37. }
  38. #endif /* TIM0_CFG */
  39. #endif /* BSP_USING_TIM0 */
  40. #ifdef BSP_USING_TIM1
  41. #ifndef TIM1_CFG
  42. #define TIM1_CFG \
  43. { \
  44. .name = "timer1", \
  45. .TIMRx = TIMR1, \
  46. }
  47. #endif /* TIM1_CFG */
  48. #endif /* BSP_USING_TIM1 */
  49. #ifdef BSP_USING_TIM2
  50. #ifndef TIM2_CFG
  51. #define TIM2_CFG \
  52. { \
  53. .name = "timer2", \
  54. .TIMRx = TIMR2, \
  55. }
  56. #endif /* TIM2_CFG */
  57. #endif /* BSP_USING_TIM2 */
  58. #ifdef BSP_USING_TIM3
  59. #ifndef TIM3_CFG
  60. #define TIM3_CFG \
  61. { \
  62. .name = "timer3", \
  63. .TIMRx = TIMR3, \
  64. }
  65. #endif /* TIM3_CFG */
  66. #endif /* BSP_USING_TIM3 */
  67. #ifdef BSP_USING_TIM4
  68. #ifndef TIM4_CFG
  69. #define TIM4_CFG \
  70. { \
  71. .name = "timer4", \
  72. .TIMRx = TIMR4, \
  73. }
  74. #endif /* TIM4_CFG */
  75. #endif /* BSP_USING_TIM4 */
  76. #ifdef BSP_USING_TIM5
  77. #ifndef TIM5_CFG
  78. #define TIM5_CFG \
  79. { \
  80. .name = "timer5", \
  81. .TIMRx = TIMR5, \
  82. }
  83. #endif /* TIM5_CFG */
  84. #endif /* BSP_USING_TIM5 */
  85. struct swm_hwtimer_cfg
  86. {
  87. char *name;
  88. TIMR_TypeDef *TIMRx;
  89. };
  90. struct swm_hwtimer_device
  91. {
  92. struct swm_hwtimer_cfg *hwtimer_cfg;
  93. rt_hwtimer_t time_device;
  94. };
  95. enum
  96. {
  97. #ifdef BSP_USING_TIM0
  98. TIM0_INDEX,
  99. #endif
  100. #ifdef BSP_USING_TIM1
  101. TIM1_INDEX,
  102. #endif
  103. #ifdef BSP_USING_TIM2
  104. TIM2_INDEX,
  105. #endif
  106. #ifdef BSP_USING_TIM3
  107. TIM3_INDEX,
  108. #endif
  109. #ifdef BSP_USING_TIM4
  110. TIM4_INDEX,
  111. #endif
  112. #ifdef BSP_USING_TIM5
  113. TIM5_INDEX,
  114. #endif
  115. };
  116. static struct swm_hwtimer_cfg swm_hwtimer_cfg[] =
  117. {
  118. #ifdef BSP_USING_TIM0
  119. TIM0_CFG,
  120. #endif
  121. #ifdef BSP_USING_TIM1
  122. TIM1_CFG,
  123. #endif
  124. #ifdef BSP_USING_TIM2
  125. TIM2_CFG,
  126. #endif
  127. #ifdef BSP_USING_TIM3
  128. TIM3_CFG,
  129. #endif
  130. #ifdef BSP_USING_TIM4
  131. TIM4_CFG,
  132. #endif
  133. #ifdef BSP_USING_TIM5
  134. TIM5_CFG,
  135. #endif
  136. };
  137. static struct swm_hwtimer_device hwtimer_obj[sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0])] = {0};
  138. static void swm_timer_configure(struct rt_hwtimer_device *timer_device, rt_uint32_t state)
  139. {
  140. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  141. RT_ASSERT(timer_device != RT_NULL);
  142. if (state)
  143. {
  144. hwtimer_cfg = timer_device->parent.user_data;
  145. TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, SystemCoreClock, 1);
  146. timer_device->freq = SystemCoreClock;
  147. }
  148. }
  149. static rt_err_t swm_timer_start(rt_hwtimer_t *timer_device, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
  150. {
  151. rt_err_t result = RT_EOK;
  152. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  153. RT_ASSERT(timer_device != RT_NULL);
  154. hwtimer_cfg = timer_device->parent.user_data;
  155. if (opmode == HWTIMER_MODE_ONESHOT)
  156. {
  157. /* set timer to single mode */
  158. timer_device->mode = HWTIMER_MODE_ONESHOT;
  159. }
  160. else
  161. {
  162. timer_device->mode = HWTIMER_MODE_PERIOD;
  163. }
  164. TIMR_SetPeriod(hwtimer_cfg->TIMRx, cnt);
  165. TIMR_Stop(hwtimer_cfg->TIMRx);
  166. TIMR_Start(hwtimer_cfg->TIMRx);
  167. return result;
  168. }
  169. static void swm_timer_stop(rt_hwtimer_t *timer_device)
  170. {
  171. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  172. RT_ASSERT(timer_device != RT_NULL);
  173. hwtimer_cfg = timer_device->parent.user_data;
  174. /* stop timer */
  175. TIMR_Stop(hwtimer_cfg->TIMRx);
  176. }
  177. static rt_uint32_t swm_timer_count_get(rt_hwtimer_t *timer_device)
  178. {
  179. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  180. RT_ASSERT(timer_device != RT_NULL);
  181. hwtimer_cfg = timer_device->parent.user_data;
  182. return TIMR_GetCurValue(hwtimer_cfg->TIMRx);
  183. }
  184. static rt_err_t swm_timer_control(rt_hwtimer_t *timer_device, rt_uint32_t cmd, void *args)
  185. {
  186. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  187. rt_err_t result = RT_EOK;
  188. RT_ASSERT(timer_device != RT_NULL);
  189. RT_ASSERT(args != RT_NULL);
  190. hwtimer_cfg = timer_device->parent.user_data;
  191. switch (cmd)
  192. {
  193. case HWTIMER_CTRL_FREQ_SET:
  194. {
  195. rt_uint32_t freq;
  196. freq = *(rt_uint32_t *)args;
  197. TIMR_Init(hwtimer_cfg->TIMRx, TIMR_MODE_TIMER, SystemCoreClock / freq, 1);
  198. }
  199. break;
  200. default:
  201. {
  202. result = -RT_ENOSYS;
  203. }
  204. break;
  205. }
  206. return result;
  207. }
  208. static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
  209. static const struct rt_hwtimer_ops swm_timer_ops =
  210. {
  211. .init = swm_timer_configure,
  212. .start = swm_timer_start,
  213. .stop = swm_timer_stop,
  214. .count_get = swm_timer_count_get,
  215. .control = swm_timer_control};
  216. void swm_timer_isr(rt_hwtimer_t *timer_device)
  217. {
  218. struct swm_hwtimer_cfg *hwtimer_cfg = RT_NULL;
  219. RT_ASSERT(timer_device != RT_NULL);
  220. hwtimer_cfg = timer_device->parent.user_data;
  221. TIMR_INTClr(hwtimer_cfg->TIMRx);
  222. rt_device_hwtimer_isr(timer_device);
  223. }
  224. #ifdef BSP_USING_TIM0
  225. void TIMR0_Handler(void)
  226. {
  227. /* enter interrupt */
  228. rt_interrupt_enter();
  229. swm_timer_isr(&(hwtimer_obj[TIM0_INDEX].time_device));
  230. /* leave interrupt */
  231. rt_interrupt_leave();
  232. }
  233. #endif //BSP_USING_TIM0
  234. #ifdef BSP_USING_TIM1
  235. void TIMR1_Handler(void)
  236. {
  237. /* enter interrupt */
  238. rt_interrupt_enter();
  239. swm_timer_isr(&(hwtimer_obj[TIM1_INDEX].time_device));
  240. /* leave interrupt */
  241. rt_interrupt_leave();
  242. }
  243. #endif //BSP_USING_TIM1
  244. #ifdef BSP_USING_TIM2
  245. void TIMR2_Handler(void)
  246. {
  247. /* enter interrupt */
  248. rt_interrupt_enter();
  249. swm_timer_isr(&(hwtimer_obj[TIM2_INDEX].time_device));
  250. /* leave interrupt */
  251. rt_interrupt_leave();
  252. }
  253. #endif //BSP_USING_TIM2
  254. #ifdef BSP_USING_TIM3
  255. void TIMR3_Handler(void)
  256. {
  257. /* enter interrupt */
  258. rt_interrupt_enter();
  259. swm_timer_isr(&(hwtimer_obj[TIM3_INDEX].time_device));
  260. /* leave interrupt */
  261. rt_interrupt_leave();
  262. }
  263. #endif //BSP_USING_TIM3
  264. #ifdef BSP_USING_TIM4
  265. void TIMR4_Handler(void)
  266. {
  267. /* enter interrupt */
  268. rt_interrupt_enter();
  269. swm_timer_isr(&(hwtimer_obj[TIM4_INDEX].time_device));
  270. /* leave interrupt */
  271. rt_interrupt_leave();
  272. }
  273. #endif //BSP_USING_TIM4
  274. #ifdef BSP_USING_TIM5
  275. void TIMR5_Handler(void)
  276. {
  277. /* enter interrupt */
  278. rt_interrupt_enter();
  279. swm_timer_isr(&(hwtimer_obj[TIM5_INDEX].time_device));
  280. /* leave interrupt */
  281. rt_interrupt_leave();
  282. }
  283. #endif //BSP_USING_TIM5
  284. static int swm_timer_init(void)
  285. {
  286. int i = 0;
  287. int result = RT_EOK;
  288. for (i = 0; i < sizeof(swm_hwtimer_cfg) / sizeof(swm_hwtimer_cfg[0]); i++)
  289. {
  290. hwtimer_obj[i].hwtimer_cfg = &swm_hwtimer_cfg[i];
  291. hwtimer_obj[i].time_device.info = &_info;
  292. hwtimer_obj[i].time_device.ops = &swm_timer_ops;
  293. result = rt_device_hwtimer_register(&hwtimer_obj[i].time_device, hwtimer_obj[i].hwtimer_cfg->name, hwtimer_obj[i].hwtimer_cfg);
  294. if (result != RT_EOK)
  295. {
  296. LOG_E("%s register fail.", hwtimer_obj[i].hwtimer_cfg->name);
  297. }
  298. else
  299. {
  300. LOG_D("%s register success.", hwtimer_obj[i].hwtimer_cfg->name);
  301. }
  302. }
  303. return result;
  304. }
  305. INIT_BOARD_EXPORT(swm_timer_init);
  306. #endif /* BSP_USING_TIM */
  307. #endif /* RT_USING_HWTIMER */