drv_timer.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. * 2021-9-17 Wayne 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. #include <drv_sys.h>
  17. /* Private define ---------------------------------------------------------------*/
  18. #define NU_TIMER_DEVICE(timer) (nu_timer_t)(timer)
  19. enum
  20. {
  21. TIMER_START = -1,
  22. #if defined(BSP_USING_TIMER0)
  23. TIMER0_IDX,
  24. #endif
  25. #if defined(BSP_USING_TIMER1)
  26. TIMER1_IDX,
  27. #endif
  28. #if defined(BSP_USING_TIMER2)
  29. TIMER2_IDX,
  30. #endif
  31. #if defined(BSP_USING_TIMER3)
  32. TIMER3_IDX,
  33. #endif
  34. #if defined(BSP_USING_TIMER4)
  35. TIMER4_IDX,
  36. #endif
  37. #if defined(BSP_USING_TIMER5)
  38. TIMER5_IDX,
  39. #endif
  40. #if defined(BSP_USING_TIMER6)
  41. TIMER6_IDX,
  42. #endif
  43. #if defined(BSP_USING_TIMER7)
  44. TIMER7_IDX,
  45. #endif
  46. #if defined(BSP_USING_TIMER8)
  47. TIMER8_IDX,
  48. #endif
  49. #if defined(BSP_USING_TIMER9)
  50. TIMER9_IDX,
  51. #endif
  52. #if defined(BSP_USING_TIMER10)
  53. TIMER10_IDX,
  54. #endif
  55. #if defined(BSP_USING_TIMER11)
  56. TIMER11_IDX,
  57. #endif
  58. TIMER_CNT
  59. };
  60. /* Private typedef --------------------------------------------------------------*/
  61. struct nu_timer
  62. {
  63. rt_hwtimer_t parent;
  64. char *name;
  65. TIMER_T *base;
  66. IRQn_Type irqn;
  67. uint32_t rstidx;
  68. uint32_t modid;
  69. };
  70. typedef struct nu_timer *nu_timer_t;
  71. /* Private functions ------------------------------------------------------------*/
  72. static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state);
  73. static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode);
  74. static void nu_timer_stop(rt_hwtimer_t *timer);
  75. static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer);
  76. static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
  77. /* Public functions -------------------------------------------------------------*/
  78. /* Private variables ------------------------------------------------------------*/
  79. static struct nu_timer nu_timer_arr [] =
  80. {
  81. #if defined(BSP_USING_TIMER0)
  82. { .name = "timer0", .base = TIMER0, .irqn = TMR0_IRQn, .rstidx = TMR0_RST, .modid = TMR0_MODULE },
  83. #endif
  84. #if defined(BSP_USING_TIMER1)
  85. { .name = "timer1", .base = TIMER1, .irqn = TMR1_IRQn, .rstidx = TMR1_RST, .modid = TMR1_MODULE },
  86. #endif
  87. #if defined(BSP_USING_TIMER2)
  88. { .name = "timer2", .base = TIMER2, .irqn = TMR2_IRQn, .rstidx = TMR2_RST, .modid = TMR2_MODULE },
  89. #endif
  90. #if defined(BSP_USING_TIMER3)
  91. { .name = "timer3", .base = TIMER3, .irqn = TMR3_IRQn, .rstidx = TMR3_RST, .modid = TMR3_MODULE },
  92. #endif
  93. #if defined(BSP_USING_TIMER4)
  94. { .name = "timer4", .base = TIMER4, .irqn = TMR4_IRQn, .rstidx = TMR4_RST, .modid = TMR4_MODULE },
  95. #endif
  96. #if defined(BSP_USING_TIMER5)
  97. { .name = "timer5", .base = TIMER5, .irqn = TMR5_IRQn, .rstidx = TMR5_RST, .modid = TMR5_MODULE },
  98. #endif
  99. #if defined(BSP_USING_TIMER6)
  100. { .name = "timer6", .base = TIMER6, .irqn = TMR6_IRQn, .rstidx = TMR6_RST, .modid = TMR6_MODULE },
  101. #endif
  102. #if defined(BSP_USING_TIMER7)
  103. { .name = "timer7", .base = TIMER7, .irqn = TMR7_IRQn, .rstidx = TMR7_RST, .modid = TMR7_MODULE },
  104. #endif
  105. #if defined(BSP_USING_TIMER8)
  106. { .name = "timer8", .base = TIMER8, .irqn = TMR8_IRQn, .rstidx = TMR8_RST, .modid = TMR8_MODULE },
  107. #endif
  108. #if defined(BSP_USING_TIMER9)
  109. { .name = "timer9", .base = TIMER9, .irqn = TMR9_IRQn, .rstidx = TMR9_RST, .modid = TMR9_MODULE },
  110. #endif
  111. #if defined(BSP_USING_TIMER10)
  112. { .name = "timer10", .base = TIMER10, .irqn = TMR10_IRQn, .rstidx = TMR10_RST, .modid = TMR10_MODULE },
  113. #endif
  114. #if defined(BSP_USING_TIMER11)
  115. { .name = "timer11", .base = TIMER11, .irqn = TMR11_IRQn, .rstidx = TMR11_RST, .modid = TMR11_MODULE },
  116. #endif
  117. };
  118. static struct rt_hwtimer_info nu_timer_info =
  119. {
  120. __HXT, /* maximum count frequency */
  121. (__HXT / 256), /* minimum count frequency */
  122. 0xFFFFFF, /* the maximum counter value */
  123. HWTIMER_CNTMODE_UP, /* Increment or Decreasing count mode */
  124. };
  125. static struct rt_hwtimer_ops nu_timer_ops =
  126. {
  127. nu_timer_init,
  128. nu_timer_start,
  129. nu_timer_stop,
  130. nu_timer_count_get,
  131. nu_timer_control
  132. };
  133. /* Functions define ------------------------------------------------------------*/
  134. static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  135. {
  136. nu_timer_t psNuTmr = NU_TIMER_DEVICE(timer);
  137. RT_ASSERT(psNuTmr != RT_NULL);
  138. if (1 == state)
  139. {
  140. uint32_t timer_clk;
  141. struct rt_hwtimer_info *info = &nu_timer_info;
  142. timer_clk = TIMER_GetModuleClock(psNuTmr->base);
  143. info->maxfreq = timer_clk;
  144. info->minfreq = timer_clk / 256;
  145. TIMER_Open(psNuTmr->base, TIMER_ONESHOT_MODE, 1);
  146. TIMER_EnableInt(psNuTmr->base);
  147. rt_hw_interrupt_umask(psNuTmr->irqn);
  148. }
  149. else
  150. {
  151. rt_hw_interrupt_mask(psNuTmr->irqn);
  152. TIMER_DisableInt(psNuTmr->base);
  153. TIMER_Close(psNuTmr->base);
  154. }
  155. }
  156. static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
  157. {
  158. rt_err_t ret = -RT_EINVAL;
  159. rt_uint32_t u32OpMode;
  160. nu_timer_t psNuTmr = NU_TIMER_DEVICE(timer);
  161. RT_ASSERT(psNuTmr != RT_NULL);
  162. if (cnt <= 1 || cnt > 0xFFFFFF)
  163. {
  164. goto exit_nu_timer_start;
  165. }
  166. switch (opmode)
  167. {
  168. case HWTIMER_MODE_PERIOD:
  169. u32OpMode = TIMER_PERIODIC_MODE;
  170. break;
  171. case HWTIMER_MODE_ONESHOT:
  172. u32OpMode = TIMER_ONESHOT_MODE;
  173. break;
  174. default:
  175. goto exit_nu_timer_start;
  176. }
  177. TIMER_SET_CMP_VALUE(psNuTmr->base, cnt);
  178. TIMER_SET_OPMODE(psNuTmr->base, u32OpMode);
  179. TIMER_EnableInt(psNuTmr->base);
  180. rt_hw_interrupt_umask(psNuTmr->irqn);
  181. TIMER_Start(psNuTmr->base);
  182. ret = RT_EOK;
  183. exit_nu_timer_start:
  184. return -(ret);
  185. }
  186. static void nu_timer_stop(rt_hwtimer_t *timer)
  187. {
  188. nu_timer_t psNuTmr = NU_TIMER_DEVICE(timer);
  189. RT_ASSERT(psNuTmr != RT_NULL);
  190. rt_hw_interrupt_mask(psNuTmr->irqn);
  191. TIMER_DisableInt(psNuTmr->base);
  192. TIMER_Stop(psNuTmr->base);
  193. TIMER_ResetCounter(psNuTmr->base);
  194. }
  195. static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer)
  196. {
  197. nu_timer_t psNuTmr = NU_TIMER_DEVICE(timer);
  198. RT_ASSERT(psNuTmr != RT_NULL);
  199. return TIMER_GetCounter(psNuTmr->base);
  200. }
  201. static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  202. {
  203. rt_err_t ret = RT_EOK;
  204. nu_timer_t psNuTmr = NU_TIMER_DEVICE(timer);
  205. RT_ASSERT(psNuTmr != RT_NULL);
  206. switch (cmd)
  207. {
  208. case HWTIMER_CTRL_FREQ_SET:
  209. {
  210. uint32_t clk;
  211. uint32_t pre;
  212. clk = TIMER_GetModuleClock(psNuTmr->base);
  213. pre = clk / *((uint32_t *)args) - 1;
  214. TIMER_SET_PRESCALE_VALUE(psNuTmr->base, pre);
  215. *((uint32_t *)args) = clk / (pre + 1) ;
  216. }
  217. break;
  218. case HWTIMER_CTRL_STOP:
  219. TIMER_Stop(psNuTmr->base);
  220. break;
  221. default:
  222. ret = -RT_EINVAL;
  223. break;
  224. }
  225. return -(ret);
  226. }
  227. /**
  228. * All UART interrupt service routine
  229. */
  230. static void nu_timer_isr(int vector, void *param)
  231. {
  232. nu_timer_t psNuTmr = NU_TIMER_DEVICE(param);
  233. RT_ASSERT(psNuTmr != RT_NULL);
  234. if (TIMER_GetIntFlag(psNuTmr->base))
  235. {
  236. TIMER_ClearIntFlag(psNuTmr->base);
  237. rt_device_hwtimer_isr(&psNuTmr->parent);
  238. }
  239. }
  240. int rt_hw_timer_init(void)
  241. {
  242. int i;
  243. rt_err_t ret = RT_EOK;
  244. for (i = (TIMER_START + 1); i < TIMER_CNT; i++)
  245. {
  246. CLK_EnableModuleClock(nu_timer_arr[i].modid);
  247. SYS_ResetModule(nu_timer_arr[i].rstidx);
  248. /* Register Timer information. */
  249. nu_timer_arr[i].parent.info = &nu_timer_info;
  250. /* Register Timer operation. */
  251. nu_timer_arr[i].parent.ops = &nu_timer_ops;
  252. /* Register Timer interrupt service routine. */
  253. rt_hw_interrupt_install(nu_timer_arr[i].irqn, nu_timer_isr, &nu_timer_arr[i], nu_timer_arr[i].name);
  254. /* Register RT hwtimer device. */
  255. ret = rt_device_hwtimer_register(&nu_timer_arr[i].parent, nu_timer_arr[i].name, &nu_timer_arr[i]);
  256. RT_ASSERT(ret == RT_EOK);
  257. }
  258. return 0;
  259. }
  260. INIT_BOARD_EXPORT(rt_hw_timer_init);
  261. #endif //#if defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER)