drv_timer.c 8.2 KB

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