drv_timer.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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-2-7 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. static struct rt_hwtimer_info nu_timer_info =
  46. {
  47. 12000000, /* maximum count frequency */
  48. 46875, /* minimum count frequency */
  49. 0xFFFFFF, /* the maximum counter value */
  50. HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
  51. };
  52. static struct rt_hwtimer_ops nu_timer_ops =
  53. {
  54. nu_timer_init,
  55. nu_timer_start,
  56. nu_timer_stop,
  57. nu_timer_count_get,
  58. nu_timer_control
  59. };
  60. /* Functions define ------------------------------------------------------------*/
  61. static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  62. {
  63. RT_ASSERT(timer != RT_NULL);
  64. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  65. RT_ASSERT(nu_timer != RT_NULL);
  66. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  67. if (1 == state)
  68. {
  69. uint32_t timer_clk;
  70. struct rt_hwtimer_info *info = &nu_timer_info;
  71. timer_clk = TIMER_GetModuleClock(nu_timer->timer_periph);
  72. info->maxfreq = timer_clk;
  73. info->minfreq = timer_clk / 256;
  74. TIMER_Open(nu_timer->timer_periph, TIMER_ONESHOT_MODE, 1);
  75. TIMER_EnableInt(nu_timer->timer_periph);
  76. NVIC_EnableIRQ(nu_timer->IRQn);
  77. }
  78. else
  79. {
  80. NVIC_DisableIRQ(nu_timer->IRQn);
  81. TIMER_DisableInt(nu_timer->timer_periph);
  82. TIMER_Close(nu_timer->timer_periph);
  83. }
  84. }
  85. static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
  86. {
  87. rt_err_t err = RT_EOK;
  88. RT_ASSERT(timer != RT_NULL);
  89. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  90. RT_ASSERT(nu_timer != RT_NULL);
  91. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  92. if (cnt > 1 && cnt <= 0xFFFFFF)
  93. {
  94. TIMER_SET_CMP_VALUE(nu_timer->timer_periph, cnt);
  95. }
  96. else
  97. {
  98. rt_kprintf("nu_timer_start set compared value failed\n");
  99. err = RT_ERROR;
  100. }
  101. if (HWTIMER_MODE_PERIOD == opmode)
  102. {
  103. TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_PERIODIC_MODE);
  104. }
  105. else if (HWTIMER_MODE_ONESHOT == opmode)
  106. {
  107. TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_ONESHOT_MODE);
  108. }
  109. else
  110. {
  111. rt_kprintf("nu_timer_start set operation mode failed\n");
  112. err = RT_ERROR;
  113. }
  114. TIMER_Start(nu_timer->timer_periph);
  115. return err;
  116. }
  117. static void nu_timer_stop(rt_hwtimer_t *timer)
  118. {
  119. RT_ASSERT(timer != RT_NULL);
  120. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  121. RT_ASSERT(nu_timer != RT_NULL);
  122. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  123. TIMER_Stop(nu_timer->timer_periph);
  124. }
  125. static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer)
  126. {
  127. RT_ASSERT(timer != RT_NULL);
  128. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  129. RT_ASSERT(nu_timer != RT_NULL);
  130. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  131. return TIMER_GetCounter(nu_timer->timer_periph);
  132. }
  133. static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  134. {
  135. rt_err_t ret = RT_EOK;
  136. RT_ASSERT(timer != RT_NULL);
  137. nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
  138. RT_ASSERT(nu_timer != RT_NULL);
  139. RT_ASSERT(nu_timer->timer_periph != RT_NULL);
  140. switch (cmd)
  141. {
  142. case HWTIMER_CTRL_FREQ_SET:
  143. {
  144. uint32_t clk;
  145. uint32_t pre;
  146. clk = TIMER_GetModuleClock(nu_timer->timer_periph);
  147. pre = clk / *((uint32_t *)args) - 1;
  148. TIMER_SET_PRESCALE_VALUE(nu_timer->timer_periph, pre);
  149. *((uint32_t *)args) = clk / (pre + 1) ;
  150. }
  151. break;
  152. case HWTIMER_CTRL_STOP:
  153. TIMER_Stop(nu_timer->timer_periph);
  154. break;
  155. default:
  156. ret = RT_EINVAL;
  157. break;
  158. }
  159. return ret;
  160. }
  161. int rt_hw_timer_init(void)
  162. {
  163. rt_err_t ret = RT_EOK;
  164. #ifdef BSP_USING_TIMER0
  165. nu_timer0.timer_periph = TIMER0;
  166. nu_timer0.parent.info = &nu_timer_info;
  167. nu_timer0.parent.ops = &nu_timer_ops;
  168. nu_timer0.IRQn = TMR0_IRQn;
  169. ret = rt_device_hwtimer_register(&nu_timer0.parent, "timer0", &nu_timer0);
  170. if (ret != RT_EOK)
  171. {
  172. rt_kprintf("timer0 register failed\n");
  173. }
  174. SYS_ResetModule(TMR0_RST);
  175. CLK_EnableModuleClock(TMR0_MODULE);
  176. #endif
  177. #ifdef BSP_USING_TIMER1
  178. nu_timer1.timer_periph = TIMER1;
  179. nu_timer1.parent.info = &nu_timer_info;
  180. nu_timer1.parent.ops = &nu_timer_ops;
  181. nu_timer1.IRQn = TMR1_IRQn;
  182. ret = rt_device_hwtimer_register(&nu_timer1.parent, "timer1", &nu_timer1);
  183. if (ret != RT_EOK)
  184. {
  185. rt_kprintf("timer1 register failed\n");
  186. }
  187. SYS_ResetModule(TMR1_RST);
  188. CLK_EnableModuleClock(TMR1_MODULE);
  189. #endif
  190. #ifdef BSP_USING_TIMER2
  191. nu_timer2.timer_periph = TIMER2;
  192. nu_timer2.parent.info = &nu_timer_info;
  193. nu_timer2.parent.ops = &nu_timer_ops;
  194. nu_timer2.IRQn = TMR2_IRQn;
  195. ret = rt_device_hwtimer_register(&nu_timer2.parent, "timer2", &nu_timer2);
  196. if (ret != RT_EOK)
  197. {
  198. rt_kprintf("timer2 register failed\n");
  199. }
  200. SYS_ResetModule(TMR2_RST);
  201. CLK_EnableModuleClock(TMR2_MODULE);
  202. #endif
  203. #ifdef BSP_USING_TIMER3
  204. nu_timer3.timer_periph = TIMER3;
  205. nu_timer3.parent.info = &nu_timer_info;
  206. nu_timer3.parent.ops = &nu_timer_ops;
  207. nu_timer3.IRQn = TMR3_IRQn;
  208. ret = rt_device_hwtimer_register(&nu_timer3.parent, "timer3", &nu_timer3);
  209. if (ret != RT_EOK)
  210. {
  211. rt_kprintf("timer3 register failed\n");
  212. }
  213. SYS_ResetModule(TMR3_RST);
  214. CLK_EnableModuleClock(TMR3_MODULE);
  215. #endif
  216. return ret;
  217. }
  218. INIT_BOARD_EXPORT(rt_hw_timer_init);
  219. #ifdef BSP_USING_TIMER0
  220. void TMR0_IRQHandler(void)
  221. {
  222. rt_interrupt_enter();
  223. if (TIMER_GetIntFlag(TIMER0))
  224. {
  225. TIMER_ClearIntFlag(TIMER0);
  226. rt_device_hwtimer_isr(&nu_timer0.parent);
  227. }
  228. rt_interrupt_leave();
  229. }
  230. #endif
  231. #ifdef BSP_USING_TIMER1
  232. void TMR1_IRQHandler(void)
  233. {
  234. rt_interrupt_enter();
  235. if (TIMER_GetIntFlag(TIMER1))
  236. {
  237. TIMER_ClearIntFlag(TIMER1);
  238. rt_device_hwtimer_isr(&nu_timer1.parent);
  239. }
  240. rt_interrupt_leave();
  241. }
  242. #endif
  243. #ifdef BSP_USING_TIMER2
  244. void TMR2_IRQHandler(void)
  245. {
  246. rt_interrupt_enter();
  247. if (TIMER_GetIntFlag(TIMER2))
  248. {
  249. TIMER_ClearIntFlag(TIMER2);
  250. rt_device_hwtimer_isr(&nu_timer2.parent);
  251. }
  252. rt_interrupt_leave();
  253. }
  254. #endif
  255. #ifdef BSP_USING_TIMER3
  256. void TMR3_IRQHandler(void)
  257. {
  258. rt_interrupt_enter();
  259. if (TIMER_GetIntFlag(TIMER3))
  260. {
  261. TIMER_ClearIntFlag(TIMER3);
  262. rt_device_hwtimer_isr(&nu_timer3.parent);
  263. }
  264. rt_interrupt_leave();
  265. }
  266. #endif
  267. #endif //#if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))