drv_timer_capture.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  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-8-20 Philo First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_TIMER_CAPTURE)
  14. #if defined(BSP_USING_TIMER0_CAPTURE)|| \
  15. defined(BSP_USING_TIMER1_CAPTURE)|| \
  16. defined(BSP_USING_TIMER2_CAPTURE)|| \
  17. defined(BSP_USING_TIMER3_CAPTURE)|| \
  18. defined(BSP_USING_TIMER4_CAPTURE)|| \
  19. defined(BSP_USING_TIMER5_CAPTURE)
  20. #include <rtdevice.h>
  21. #include "NuMicro.h"
  22. /* Private typedef --------------------------------------------------------------*/
  23. typedef struct _timer
  24. {
  25. struct rt_inputcapture_device parent;
  26. TIMER_T *timer;
  27. uint8_t u8Channel;
  28. IRQn_Type irq;
  29. uint32_t u32CurrentCnt;
  30. rt_bool_t input_data_level;
  31. rt_bool_t first_edge;
  32. } nu_capture_t;
  33. /* Private functions ------------------------------------------------------------*/
  34. static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture);
  35. static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture);
  36. static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture);
  37. static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
  38. /* Private define ---------------------------------------------------------------*/
  39. #define TIMER_CHANNEL_NUM (6)
  40. #define TIMER0_POS (0)
  41. #define TIMER1_POS (1)
  42. #define TIMER2_POS (2)
  43. #define TIMER3_POS (3)
  44. #define TIMER4_POS (4)
  45. #define TIMER5_POS (5)
  46. /* Timer prescale setting. Since it will affect the pulse width of measure, it is recommended to set to 2. */
  47. #define PSC_DIV (2)
  48. /* Public functions -------------------------------------------------------------*/
  49. /* Private variables ------------------------------------------------------------*/
  50. static const char *nu_timer_device_name[TIMER_CHANNEL_NUM] = { "timer0i0", "timer1i0", "timer2i0", "timer3i0", "timer4i0", "timer5i0"};
  51. static const IRQn_Type nu_timer_irq[TIMER_CHANNEL_NUM] = { TMR0_IRQn, TMR1_IRQn, TMR2_IRQn, TMR3_IRQn, TMR4_IRQn, TMR5_IRQn};
  52. static TIMER_T *nu_timer_base[TIMER_CHANNEL_NUM] = { TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5};
  53. static nu_capture_t *nu_timer_capture[TIMER_CHANNEL_NUM] = {0};
  54. static struct rt_inputcapture_ops nu_capture_ops =
  55. {
  56. .init = nu_capture_init,
  57. .open = nu_capture_open,
  58. .close = nu_capture_close,
  59. .get_pulsewidth = nu_capture_get_pulsewidth,
  60. };
  61. /* Functions define ------------------------------------------------------------*/
  62. void timer_interrupt_handler(nu_capture_t *nu_timer_capture)
  63. {
  64. TIMER_ClearCaptureIntFlag(nu_timer_capture->timer);
  65. /* First event is rising edge */
  66. if (nu_timer_capture->first_edge == RT_TRUE)
  67. {
  68. nu_timer_capture->first_edge = RT_FALSE;
  69. nu_timer_capture->input_data_level = RT_FALSE;
  70. }
  71. else
  72. {
  73. nu_timer_capture->input_data_level = !nu_timer_capture->input_data_level;
  74. nu_timer_capture->u32CurrentCnt = TIMER_GetCaptureData(nu_timer_capture->timer);
  75. rt_hw_inputcapture_isr(&nu_timer_capture->parent, nu_timer_capture->input_data_level);
  76. }
  77. }
  78. #if defined(BSP_USING_TIMER0_CAPTURE)
  79. void TMR0_IRQHandler(void)
  80. {
  81. /* enter interrupt */
  82. rt_interrupt_enter();
  83. timer_interrupt_handler(nu_timer_capture[0]);
  84. /* leave interrupt */
  85. rt_interrupt_leave();
  86. }
  87. #endif //defined(BSP_USING_TIMER0_CAPTURE)
  88. #if defined(BSP_USING_TIMER1_CAPTURE)
  89. void TMR1_IRQHandler(void)
  90. {
  91. /* enter interrupt */
  92. rt_interrupt_enter();
  93. timer_interrupt_handler(nu_timer_capture[1]);
  94. /* leave interrupt */
  95. rt_interrupt_leave();
  96. }
  97. #endif //defined(BSP_USING_TIMER1_CAPTURE)
  98. #if defined(BSP_USING_TIMER2_CAPTURE)
  99. void TMR2_IRQHandler(void)
  100. {
  101. /* enter interrupt */
  102. rt_interrupt_enter();
  103. timer_interrupt_handler(nu_timer_capture[2]);
  104. /* leave interrupt */
  105. rt_interrupt_leave();
  106. }
  107. #endif //defined(BSP_USING_TIMER2_CAPTURE)
  108. #if defined(BSP_USING_TIMER3_CAPTURE)
  109. void TMR3_IRQHandler(void)
  110. {
  111. /* enter interrupt */
  112. rt_interrupt_enter();
  113. timer_interrupt_handler(nu_timer_capture[3]);
  114. /* leave interrupt */
  115. rt_interrupt_leave();
  116. }
  117. #endif //defined(BSP_USING_TIMER3_CAPTURE)
  118. #if defined(BSP_USING_TIMER4_CAPTURE)
  119. void TMR4_IRQHandler(void)
  120. {
  121. /* enter interrupt */
  122. rt_interrupt_enter();
  123. timer_interrupt_handler(nu_timer_capture[4]);
  124. /* leave interrupt */
  125. rt_interrupt_leave();
  126. }
  127. #endif //defined(BSP_USING_TIMER4_CAPTURE)
  128. #if defined(BSP_USING_TIMER5_CAPTURE)
  129. void TMR5_IRQHandler(void)
  130. {
  131. /* enter interrupt */
  132. rt_interrupt_enter();
  133. timer_interrupt_handler(nu_timer_capture[5]);
  134. /* leave interrupt */
  135. rt_interrupt_leave();
  136. }
  137. #endif //defined(BSP_USING_TIMER5_CAPTURE)
  138. static rt_err_t nu_capture_get_pulsewidth(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us)
  139. {
  140. rt_err_t ret = RT_EOK;
  141. nu_capture_t *nu_capture;
  142. nu_capture = (nu_capture_t *)inputcapture;
  143. *pulsewidth_us = nu_capture->u32CurrentCnt / PSC_DIV;
  144. return -(ret);
  145. }
  146. static rt_err_t nu_timer_init(nu_capture_t *nu_capture)
  147. {
  148. SYS_UnlockReg();
  149. #if defined(BSP_USING_TIMER0_CAPTURE)
  150. if (nu_capture->timer == TIMER0)
  151. {
  152. /* Enable TIMER0 clock */
  153. CLK_EnableModuleClock(TMR0_MODULE);
  154. CLK_SetModuleClock(TMR0_MODULE, CLK_CLKSEL1_TMR0SEL_PCLK0, 0);
  155. goto exit_nu_timer_init;
  156. }
  157. #endif
  158. #if defined(BSP_USING_TIMER1_CAPTURE)
  159. if (nu_capture->timer == TIMER1)
  160. {
  161. /* Enable TIMER1 clock */
  162. CLK_EnableModuleClock(TMR1_MODULE);
  163. CLK_SetModuleClock(TMR1_MODULE, CLK_CLKSEL1_TMR1SEL_PCLK0, 0);
  164. goto exit_nu_timer_init;
  165. }
  166. #endif
  167. #if defined(BSP_USING_TIMER2_CAPTURE)
  168. if (nu_capture->timer == TIMER2)
  169. {
  170. /* Enable TIMER2 clock */
  171. CLK_EnableModuleClock(TMR2_MODULE);
  172. CLK_SetModuleClock(TMR2_MODULE, CLK_CLKSEL1_TMR2SEL_PCLK1, 0);
  173. goto exit_nu_timer_init;
  174. }
  175. #endif
  176. #if defined(BSP_USING_TIMER3_CAPTURE)
  177. if (nu_capture->timer == TIMER3)
  178. {
  179. /* Enable TIMER3 clock */
  180. CLK_EnableModuleClock(TMR3_MODULE);
  181. CLK_SetModuleClock(TMR3_MODULE, CLK_CLKSEL1_TMR3SEL_PCLK1, 0);
  182. goto exit_nu_timer_init;
  183. }
  184. #endif
  185. #if defined(BSP_USING_TIMER4_CAPTURE)
  186. if (nu_capture->timer == TIMER4)
  187. {
  188. /* Enable TIMER4 clock */
  189. CLK_EnableModuleClock(TMR4_MODULE);
  190. CLK_SetModuleClock(TMR4_MODULE, CLK_CLKSEL3_TMR4SEL_PCLK0, 0);
  191. goto exit_nu_timer_init;
  192. }
  193. #endif
  194. #if defined(BSP_USING_TIMER5_CAPTURE)
  195. if (nu_capture->timer == TIMER5)
  196. {
  197. /* Enable TIMER3 clock */
  198. CLK_EnableModuleClock(TMR5_MODULE);
  199. CLK_SetModuleClock(TMR5_MODULE, CLK_CLKSEL3_TMR5SEL_PCLK0, 0);
  200. goto exit_nu_timer_init;
  201. }
  202. #endif
  203. SYS_LockReg();
  204. return -(RT_ERROR);
  205. exit_nu_timer_init:
  206. SYS_LockReg();
  207. return RT_EOK;
  208. }
  209. static rt_err_t nu_capture_init(struct rt_inputcapture_device *inputcapture)
  210. {
  211. rt_err_t ret = RT_EOK;
  212. nu_capture_t *nu_capture;
  213. RT_ASSERT(inputcapture != RT_NULL);
  214. nu_capture = (nu_capture_t *) inputcapture;
  215. if (nu_timer_init(nu_capture) != RT_EOK)
  216. {
  217. rt_kprintf("Failed to initialize TIMER.\n");
  218. ret = RT_ERROR;
  219. }
  220. return -(ret);
  221. }
  222. static uint8_t cal_time_prescale(nu_capture_t *nu_capture)
  223. {
  224. uint32_t u32Clk = TIMER_GetModuleClock(nu_capture->timer);
  225. /* 1 tick = 1/PSC_DIV us */
  226. return (u32Clk / 1000000 / PSC_DIV) - 1;
  227. }
  228. static rt_err_t nu_capture_open(struct rt_inputcapture_device *inputcapture)
  229. {
  230. rt_err_t ret = RT_EOK;
  231. nu_capture_t *nu_capture;
  232. RT_ASSERT(inputcapture != RT_NULL);
  233. nu_capture = (nu_capture_t *) inputcapture;
  234. nu_capture->first_edge = RT_TRUE;
  235. /* Enable Timer NVIC */
  236. NVIC_EnableIRQ(nu_capture->irq);
  237. /* Reset counter before openning. */
  238. TIMER_ResetCounter(nu_capture->timer);
  239. TIMER_Open(nu_capture->timer, TIMER_CONTINUOUS_MODE, 1);
  240. TIMER_SET_PRESCALE_VALUE(nu_capture->timer, cal_time_prescale(nu_capture));
  241. TIMER_SET_CMP_VALUE(nu_capture->timer, 0xFFFFFF);
  242. TIMER_EnableCapture(nu_capture->timer, TIMER_CAPTURE_COUNTER_RESET_MODE, TIMER_CAPTURE_EVENT_RISING_FALLING);
  243. TIMER_EnableInt(nu_capture->timer);
  244. TIMER_EnableCaptureInt(nu_capture->timer);
  245. TIMER_Start(nu_capture->timer);
  246. return ret;
  247. }
  248. static rt_err_t nu_capture_close(struct rt_inputcapture_device *inputcapture)
  249. {
  250. rt_err_t ret = RT_EOK;
  251. nu_capture_t *nu_capture;
  252. RT_ASSERT(inputcapture != RT_NULL);
  253. nu_capture = (nu_capture_t *) inputcapture;
  254. TIMER_Stop(nu_capture->timer);
  255. TIMER_DisableCaptureInt(nu_capture->timer);
  256. TIMER_DisableInt(nu_capture->timer);
  257. TIMER_Close(nu_capture->timer);
  258. NVIC_DisableIRQ(nu_capture->irq);
  259. return ret;
  260. }
  261. /* Init and register timer capture */
  262. static int nu_timer_capture_device_init(void)
  263. {
  264. uint8_t TIMER_MSK = 0;
  265. #if defined(BSP_USING_TIMER0_CAPTURE)
  266. TIMER_MSK |= (0x1 << 0);
  267. #endif
  268. #if defined(BSP_USING_TIMER1_CAPTURE)
  269. TIMER_MSK |= (0x1 << 1);
  270. #endif
  271. #if defined(BSP_USING_TIMER2_CAPTURE)
  272. TIMER_MSK |= (0x1 << 2);
  273. #endif
  274. #if defined(BSP_USING_TIMER3_CAPTURE)
  275. TIMER_MSK |= (0x1 << 3);
  276. #endif
  277. #if defined(BSP_USING_TIMER4_CAPTURE)
  278. TIMER_MSK |= (0x1 << 4);
  279. #endif
  280. #if defined(BSP_USING_TIMER5_CAPTURE)
  281. TIMER_MSK |= (0x1 << 5);
  282. #endif
  283. for (int i = 0; i < TIMER_CHANNEL_NUM; i++)
  284. {
  285. if (TIMER_MSK & (0x1 << i))
  286. {
  287. nu_timer_capture[i] = (nu_capture_t *)rt_malloc(sizeof(nu_capture_t));
  288. nu_timer_capture[i]->timer = nu_timer_base[i];
  289. nu_timer_capture[i]->u8Channel = i;
  290. nu_timer_capture[i]->irq = nu_timer_irq[i];
  291. nu_timer_capture[i]->u32CurrentCnt = 0;
  292. nu_timer_capture[i]->parent.ops = &nu_capture_ops;
  293. nu_timer_capture[i]->first_edge = RT_TRUE;
  294. /* register inputcapture device */
  295. rt_device_inputcapture_register(&nu_timer_capture[i]->parent, nu_timer_device_name[i], &nu_timer_capture[i]);
  296. }
  297. }
  298. return 0;
  299. }
  300. INIT_DEVICE_EXPORT(nu_timer_capture_device_init);
  301. #endif //#if defined(BSP_USING_TIMER*_CAPTURE)
  302. #endif //#if defined(BSP_USING_TIMER_CAPTURE)