drv_timer.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-6-17 YCHuang12 First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))
  14. #include <rtdevice.h>
  15. #include "NuMicro.h"
  16. /* Private define ---------------------------------------------------------------*/
  17. #define NU_TIMER_DEVICE(timer) (nu_timer_t *)(timer)
  18. /* Private typedef --------------------------------------------------------------*/
  19. typedef struct nu_timer
  20. {
  21. rt_hwtimer_t parent;
  22. TIMER_T *timer_periph;
  23. IRQn_Type IRQn;
  24. } nu_timer_t;
  25. /* Private functions ------------------------------------------------------------*/
  26. static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state);
  27. static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode);
  28. static void nu_timer_stop(rt_hwtimer_t *timer);
  29. static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer);
  30. static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
  31. /* Public functions -------------------------------------------------------------*/
  32. /* Private variables ------------------------------------------------------------*/
  33. #ifdef BSP_USING_TIMER0
  34. static nu_timer_t nu_timer0;
  35. #endif
  36. #ifdef BSP_USING_TIMER1
  37. static nu_timer_t nu_timer1;
  38. #endif
  39. #ifdef BSP_USING_TIMER2
  40. static nu_timer_t nu_timer2;
  41. #endif
  42. #ifdef BSP_USING_TIMER3
  43. static nu_timer_t nu_timer3;
  44. #endif
  45. #ifdef BSP_USING_TIMER4
  46. static nu_timer_t nu_timer4;
  47. #endif
  48. #ifdef BSP_USING_TIMER5
  49. static nu_timer_t nu_timer5;
  50. #endif
  51. static struct rt_hwtimer_info nu_timer_info =
  52. {
  53. 12000000, /* maximum count frequency */
  54. 46875, /* minimum count frequency */
  55. 0xFFFFFF, /* the maximum counter value */
  56. HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
  57. };
  58. static struct rt_hwtimer_ops nu_timer_ops =
  59. {
  60. nu_timer_init,
  61. nu_timer_start,
  62. nu_timer_stop,
  63. nu_timer_count_get,
  64. nu_timer_control
  65. };
  66. /* Functions define ------------------------------------------------------------*/
  67. static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  68. {
  69. RT_ASSERT(timer != RT_NULL);
  70. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  71. RT_ASSERT(nu_timer != RT_NULL);
  72. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  73. if (1 == state)
  74. {
  75. uint32_t timer_clk;
  76. struct rt_hwtimer_info *info = &nu_timer_info;
  77. timer_clk = TIMER_GetModuleClock(nu_timer->timer_periph);
  78. info->maxfreq = timer_clk;
  79. info->minfreq = timer_clk / 256;
  80. TIMER_Open(nu_timer->timer_periph, TIMER_ONESHOT_MODE, 1);
  81. TIMER_EnableInt(nu_timer->timer_periph);
  82. NVIC_EnableIRQ(nu_timer->IRQn);
  83. }
  84. else
  85. {
  86. NVIC_DisableIRQ(nu_timer->IRQn);
  87. TIMER_DisableInt(nu_timer->timer_periph);
  88. TIMER_Close(nu_timer->timer_periph);
  89. }
  90. }
  91. static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
  92. {
  93. rt_err_t err = RT_EOK;
  94. RT_ASSERT(timer != RT_NULL);
  95. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  96. RT_ASSERT(nu_timer != RT_NULL);
  97. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  98. if (cnt > 1 && cnt <= 0xFFFFFF)
  99. {
  100. TIMER_SET_CMP_VALUE(nu_timer->timer_periph, cnt);
  101. }
  102. else
  103. {
  104. rt_kprintf("nu_timer_start set compared value failed\n");
  105. err = RT_ERROR;
  106. }
  107. if (HWTIMER_MODE_PERIOD == opmode)
  108. {
  109. TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_PERIODIC_MODE);
  110. }
  111. else if (HWTIMER_MODE_ONESHOT == opmode)
  112. {
  113. TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_ONESHOT_MODE);
  114. }
  115. else
  116. {
  117. rt_kprintf("nu_timer_start set operation mode failed\n");
  118. err = RT_ERROR;
  119. }
  120. TIMER_Start(nu_timer->timer_periph);
  121. return err;
  122. }
  123. static void nu_timer_stop(rt_hwtimer_t *timer)
  124. {
  125. RT_ASSERT(timer != RT_NULL);
  126. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  127. RT_ASSERT(nu_timer != RT_NULL);
  128. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  129. TIMER_Stop(nu_timer->timer_periph);
  130. }
  131. static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer)
  132. {
  133. RT_ASSERT(timer != RT_NULL);
  134. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  135. RT_ASSERT(nu_timer != RT_NULL);
  136. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  137. return TIMER_GetCounter(nu_timer->timer_periph);
  138. }
  139. static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  140. {
  141. rt_err_t ret = RT_EOK;
  142. RT_ASSERT(timer != RT_NULL);
  143. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  144. RT_ASSERT(nu_timer != RT_NULL);
  145. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  146. switch (cmd)
  147. {
  148. case HWTIMER_CTRL_FREQ_SET:
  149. {
  150. uint32_t clk;
  151. uint32_t pre;
  152. clk = TIMER_GetModuleClock(nu_timer->timer_periph);
  153. pre = clk / *((uint32_t *)args) - 1;
  154. TIMER_SET_PRESCALE_VALUE(nu_timer->timer_periph, pre);
  155. *((uint32_t *)args) = clk / (pre + 1) ;
  156. }
  157. break;
  158. case HWTIMER_CTRL_STOP:
  159. TIMER_Stop(nu_timer->timer_periph);
  160. break;
  161. default:
  162. ret = RT_EINVAL;
  163. break;
  164. }
  165. return ret;
  166. }
  167. int rt_hw_timer_init(void)
  168. {
  169. rt_err_t ret = RT_EOK;
  170. #ifdef BSP_USING_TIMER0
  171. nu_timer0.timer_periph = TIMER0;
  172. nu_timer0.parent.info = &nu_timer_info;
  173. nu_timer0.parent.ops = &nu_timer_ops;
  174. nu_timer0.IRQn = TMR0_IRQn;
  175. ret = rt_device_hwtimer_register(&nu_timer0.parent, "timer0", &nu_timer0);
  176. if (ret != RT_EOK)
  177. {
  178. rt_kprintf("timer0 register failed\n");
  179. }
  180. SYS_ResetModule(TMR0_RST);
  181. CLK_EnableModuleClock(TMR0_MODULE);
  182. #endif
  183. #ifdef BSP_USING_TIMER1
  184. nu_timer1.timer_periph = TIMER1;
  185. nu_timer1.parent.info = &nu_timer_info;
  186. nu_timer1.parent.ops = &nu_timer_ops;
  187. nu_timer1.IRQn = TMR1_IRQn;
  188. ret = rt_device_hwtimer_register(&nu_timer1.parent, "timer1", &nu_timer1);
  189. if (ret != RT_EOK)
  190. {
  191. rt_kprintf("timer1 register failed\n");
  192. }
  193. SYS_ResetModule(TMR1_RST);
  194. CLK_EnableModuleClock(TMR1_MODULE);
  195. #endif
  196. #ifdef BSP_USING_TIMER2
  197. nu_timer2.timer_periph = TIMER2;
  198. nu_timer2.parent.info = &nu_timer_info;
  199. nu_timer2.parent.ops = &nu_timer_ops;
  200. nu_timer2.IRQn = TMR2_IRQn;
  201. ret = rt_device_hwtimer_register(&nu_timer2.parent, "timer2", &nu_timer2);
  202. if (ret != RT_EOK)
  203. {
  204. rt_kprintf("timer2 register failed\n");
  205. }
  206. SYS_ResetModule(TMR2_RST);
  207. CLK_EnableModuleClock(TMR2_MODULE);
  208. #endif
  209. #ifdef BSP_USING_TIMER3
  210. nu_timer3.timer_periph = TIMER3;
  211. nu_timer3.parent.info = &nu_timer_info;
  212. nu_timer3.parent.ops = &nu_timer_ops;
  213. nu_timer3.IRQn = TMR3_IRQn;
  214. ret = rt_device_hwtimer_register(&nu_timer3.parent, "timer3", &nu_timer3);
  215. if (ret != RT_EOK)
  216. {
  217. rt_kprintf("timer3 register failed\n");
  218. }
  219. SYS_ResetModule(TMR3_RST);
  220. CLK_EnableModuleClock(TMR3_MODULE);
  221. #endif
  222. #ifdef BSP_USING_TIMER4
  223. nu_timer4.timer_periph = TIMER4;
  224. nu_timer4.parent.info = &nu_timer_info;
  225. nu_timer4.parent.ops = &nu_timer_ops;
  226. nu_timer4.IRQn = TMR4_IRQn;
  227. ret = rt_device_hwtimer_register(&nu_timer4.parent, "timer4", &nu_timer4);
  228. if (ret != RT_EOK)
  229. {
  230. rt_kprintf("timer4 register failed\n");
  231. }
  232. SYS_ResetModule(TMR4_RST);
  233. CLK_EnableModuleClock(TMR4_MODULE);
  234. #endif
  235. #ifdef BSP_USING_TIMER5
  236. nu_timer5.timer_periph = TIMER5;
  237. nu_timer5.parent.info = &nu_timer_info;
  238. nu_timer5.parent.ops = &nu_timer_ops;
  239. nu_timer5.IRQn = TMR5_IRQn;
  240. ret = rt_device_hwtimer_register(&nu_timer5.parent, "timer5", &nu_timer5);
  241. if (ret != RT_EOK)
  242. {
  243. rt_kprintf("timer5 register failed\n");
  244. }
  245. SYS_ResetModule(TMR5_RST);
  246. CLK_EnableModuleClock(TMR5_MODULE);
  247. #endif
  248. return ret;
  249. }
  250. INIT_BOARD_EXPORT(rt_hw_timer_init);
  251. #ifdef BSP_USING_TIMER0
  252. void TMR0_IRQHandler(void)
  253. {
  254. rt_interrupt_enter();
  255. if (TIMER_GetIntFlag(TIMER0))
  256. {
  257. TIMER_ClearIntFlag(TIMER0);
  258. rt_device_hwtimer_isr(&nu_timer0.parent);
  259. }
  260. rt_interrupt_leave();
  261. }
  262. #endif
  263. #ifdef BSP_USING_TIMER1
  264. void TMR1_IRQHandler(void)
  265. {
  266. rt_interrupt_enter();
  267. if (TIMER_GetIntFlag(TIMER1))
  268. {
  269. TIMER_ClearIntFlag(TIMER1);
  270. rt_device_hwtimer_isr(&nu_timer1.parent);
  271. }
  272. rt_interrupt_leave();
  273. }
  274. #endif
  275. #ifdef BSP_USING_TIMER2
  276. void TMR2_IRQHandler(void)
  277. {
  278. rt_interrupt_enter();
  279. if (TIMER_GetIntFlag(TIMER2))
  280. {
  281. TIMER_ClearIntFlag(TIMER2);
  282. rt_device_hwtimer_isr(&nu_timer2.parent);
  283. }
  284. rt_interrupt_leave();
  285. }
  286. #endif
  287. #ifdef BSP_USING_TIMER3
  288. void TMR3_IRQHandler(void)
  289. {
  290. rt_interrupt_enter();
  291. if (TIMER_GetIntFlag(TIMER3))
  292. {
  293. TIMER_ClearIntFlag(TIMER3);
  294. rt_device_hwtimer_isr(&nu_timer3.parent);
  295. }
  296. rt_interrupt_leave();
  297. }
  298. #endif
  299. #ifdef BSP_USING_TIMER4
  300. void TMR4_IRQHandler(void)
  301. {
  302. rt_interrupt_enter();
  303. if (TIMER_GetIntFlag(TIMER4))
  304. {
  305. TIMER_ClearIntFlag(TIMER4);
  306. rt_device_hwtimer_isr(&nu_timer4.parent);
  307. }
  308. rt_interrupt_leave();
  309. }
  310. #endif
  311. #ifdef BSP_USING_TIMER5
  312. void TMR5_IRQHandler(void)
  313. {
  314. rt_interrupt_enter();
  315. if (TIMER_GetIntFlag(TIMER5))
  316. {
  317. TIMER_ClearIntFlag(TIMER5);
  318. rt_device_hwtimer_isr(&nu_timer5.parent);
  319. }
  320. rt_interrupt_leave();
  321. }
  322. #endif
  323. #endif //#if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))