drv_hwtimer.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-03-04 stevetong459 first version
  9. */
  10. #include <board.h>
  11. #define LOG_TAG "drv.hwtimer"
  12. #define DBG_LVL DBG_INFO
  13. #include <rtdbg.h>
  14. #ifdef RT_USING_HWTIMER
  15. static const struct rt_hwtimer_info _info =
  16. {
  17. .maxfreq = 1000000,
  18. .minfreq = 2000,
  19. .maxcnt = 0xFFFF,
  20. .cntmode = HWTIMER_CNTMODE_UP,
  21. };
  22. /* apm32 config class */
  23. struct apm32_timer
  24. {
  25. char *name;
  26. TMR_T *tmr;
  27. IRQn_Type irqn;
  28. rt_hwtimer_t device;
  29. };
  30. enum
  31. {
  32. #ifdef BSP_USING_TMR1
  33. TMR1_INDEX,
  34. #endif
  35. #ifdef BSP_USING_TMR2
  36. TMR2_INDEX,
  37. #endif
  38. #ifdef BSP_USING_TMR3
  39. TMR3_INDEX,
  40. #endif
  41. #ifdef BSP_USING_TMR4
  42. TMR4_INDEX,
  43. #endif
  44. #ifdef BSP_USING_TMR5
  45. TMR5_INDEX,
  46. #endif
  47. #ifdef BSP_USING_TMR6
  48. TMR6_INDEX,
  49. #endif
  50. #ifdef BSP_USING_TMR7
  51. TMR7_INDEX,
  52. #endif
  53. #ifdef BSP_USING_TMR8
  54. TMR8_INDEX,
  55. #endif
  56. };
  57. static struct apm32_timer tmr_config[] =
  58. {
  59. #ifdef BSP_USING_TMR1
  60. {
  61. "timer1",
  62. TMR1,
  63. TMR1_UP_IRQn,
  64. },
  65. #endif
  66. #ifdef BSP_USING_TMR2
  67. {
  68. "timer2",
  69. TMR2,
  70. TMR2_IRQn,
  71. },
  72. #endif
  73. #ifdef BSP_USING_TMR3
  74. {
  75. "timer3",
  76. TMR3,
  77. TMR3_IRQn,
  78. },
  79. #endif
  80. #ifdef BSP_USING_TMR4
  81. {
  82. "timer4",
  83. TMR4,
  84. TMR4_IRQn,
  85. },
  86. #endif
  87. #ifdef BSP_USING_TMR5
  88. {
  89. "timer5",
  90. TMR5,
  91. TMR5_IRQn,
  92. },
  93. #endif
  94. #ifdef BSP_USING_TMR6
  95. {
  96. "timer6",
  97. TMR6,
  98. TMR6_IRQn,
  99. },
  100. #endif
  101. #ifdef BSP_USING_TMR7
  102. {
  103. "timer7",
  104. TMR7,
  105. TMR7_IRQn,
  106. },
  107. #endif
  108. #ifdef BSP_USING_TMR8
  109. {
  110. "timer8",
  111. TMR8,
  112. TMR8_UP_IRQn,
  113. },
  114. #endif
  115. };
  116. static rt_uint32_t _hwtimer_clock_get(TMR_T *tmr)
  117. {
  118. uint32_t pclk1;
  119. RCM_ReadPCLKFreq(&pclk1, NULL);
  120. return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != RCM_APB_DIV_1) ? 2 : 1));
  121. }
  122. static void _hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
  123. {
  124. TMR_BaseConfig_T base_config;
  125. uint32_t prescaler = 0;
  126. struct apm32_timer *timer_config;
  127. RT_ASSERT(timer != RT_NULL);
  128. if (state)
  129. {
  130. timer_config = (struct apm32_timer *)timer->parent.user_data;
  131. if (timer_config->tmr == TMR1)
  132. {
  133. RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
  134. }
  135. else if (timer_config->tmr == TMR8)
  136. {
  137. RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
  138. }
  139. else if (timer_config->tmr == TMR2)
  140. {
  141. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);
  142. }
  143. else if (timer_config->tmr == TMR3)
  144. {
  145. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
  146. }
  147. else if (timer_config->tmr == TMR4)
  148. {
  149. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
  150. }
  151. else if (timer_config->tmr == TMR5)
  152. {
  153. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR5);
  154. }
  155. else if (timer_config->tmr == TMR6)
  156. {
  157. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);
  158. }
  159. else if (timer_config->tmr == TMR7)
  160. {
  161. RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR7);
  162. }
  163. prescaler = (uint32_t)(_hwtimer_clock_get(timer_config->tmr) / 10000) - 1;
  164. base_config.period = 10000 - 1;
  165. base_config.division = prescaler;
  166. base_config.clockDivision = TMR_CLOCK_DIV_1;
  167. if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
  168. {
  169. base_config.countMode = TMR_COUNTER_MODE_UP;
  170. }
  171. else
  172. {
  173. base_config.countMode = TMR_COUNTER_MODE_DOWN;
  174. }
  175. base_config.repetitionCounter = 0;
  176. TMR_ConfigTimeBase(timer_config->tmr, &base_config);
  177. /* set the TIMx priority */
  178. NVIC_EnableIRQRequest(timer_config->irqn, 3, 0);
  179. /* clear update flag */
  180. TMR_ClearStatusFlag(timer_config->tmr, TMR_FLAG_UPDATE);
  181. /* enable update request source */
  182. TMR_ConfigUpdateRequest(timer_config->tmr, TMR_UPDATE_SOURCE_REGULAR);
  183. LOG_D("%s init success", timer_config->name);
  184. }
  185. }
  186. static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  187. {
  188. rt_err_t result = RT_EOK;
  189. struct apm32_timer *timer_config = RT_NULL;
  190. RT_ASSERT(timer != RT_NULL);
  191. timer_config = (struct apm32_timer *)timer->parent.user_data;
  192. /* set timer_config counter */
  193. TMR_ConfigCounter(timer_config->tmr, 0);
  194. /* set timer_config autoReload */
  195. TMR_ConfigAutoreload(timer_config->tmr, t - 1);
  196. if (opmode == HWTIMER_MODE_ONESHOT)
  197. {
  198. /* set timer to single mode */
  199. TMR_ConfigSinglePulseMode(timer_config->tmr, TMR_SPM_SINGLE);
  200. }
  201. else
  202. {
  203. TMR_ConfigSinglePulseMode(timer_config->tmr, TMR_SPM_REPETITIVE);
  204. }
  205. TMR_EnableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
  206. if (timer_config->tmr == TMR1 || timer_config->tmr == TMR8 || timer_config->tmr == TMR2 ||
  207. timer_config->tmr == TMR3 || timer_config->tmr == TMR4 || timer_config->tmr == TMR5)
  208. {
  209. if (timer_config->tmr->SMCTRL_B.SMFSEL != TMR_SLAVE_MODE_TRIGGER)
  210. {
  211. TMR_Enable(timer_config->tmr);
  212. result = -RT_EOK;
  213. }
  214. }
  215. else
  216. {
  217. TMR_Enable(timer_config->tmr);
  218. result = -RT_EOK;
  219. }
  220. return result;
  221. }
  222. static void _hwtimer_stop(rt_hwtimer_t *timer)
  223. {
  224. struct apm32_timer *timer_config = RT_NULL;
  225. RT_ASSERT(timer != RT_NULL);
  226. timer_config = (struct apm32_timer *)timer->parent.user_data;
  227. TMR_DisableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
  228. TMR_Enable(timer_config->tmr);
  229. TMR_ConfigCounter(timer_config->tmr, 0);
  230. }
  231. static rt_err_t _hwtimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  232. {
  233. struct apm32_timer *timer_config = RT_NULL;
  234. rt_err_t result = RT_EOK;
  235. rt_uint32_t freq;
  236. rt_uint16_t val;
  237. RT_ASSERT(timer != RT_NULL);
  238. RT_ASSERT(arg != RT_NULL);
  239. timer_config = (struct apm32_timer *)timer->parent.user_data;
  240. switch (cmd)
  241. {
  242. case HWTIMER_CTRL_FREQ_SET:
  243. /* set timer frequence */
  244. freq = *((rt_uint32_t *)arg);
  245. val = _hwtimer_clock_get(timer_config->tmr) / freq;
  246. TMR_ConfigPrescaler(timer_config->tmr, val - 1, TMR_PSC_RELOAD_IMMEDIATE);
  247. break;
  248. default:
  249. result = -RT_ENOSYS;
  250. break;
  251. }
  252. return result;
  253. }
  254. static rt_uint32_t _hwtimer_counter_get(rt_hwtimer_t *timer)
  255. {
  256. struct apm32_timer *timer_config = RT_NULL;
  257. RT_ASSERT(timer != RT_NULL);
  258. timer_config = (struct apm32_timer *)timer->parent.user_data;
  259. return timer_config->tmr->CNT;
  260. }
  261. static const struct rt_hwtimer_ops _hwtimer_ops =
  262. {
  263. .init = _hwtimer_init,
  264. .start = _hwtimer_start,
  265. .stop = _hwtimer_stop,
  266. .count_get = _hwtimer_counter_get,
  267. .control = _hwtimer_ctrl,
  268. };
  269. #ifdef BSP_USING_TMR1
  270. void TMR1_UP_IRQHandler(void)
  271. {
  272. rt_interrupt_enter();
  273. rt_device_hwtimer_isr(&tmr_config[TMR1_INDEX].device);
  274. TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
  275. rt_interrupt_leave();
  276. }
  277. #endif
  278. #ifdef BSP_USING_TMR2
  279. void TMR2_IRQHandler(void)
  280. {
  281. rt_interrupt_enter();
  282. rt_device_hwtimer_isr(&tmr_config[TMR2_INDEX].device);
  283. TMR_ClearIntFlag(TMR2, TMR_INT_UPDATE);
  284. rt_interrupt_leave();
  285. }
  286. #endif
  287. #ifdef BSP_USING_TMR3
  288. void TMR3_IRQHandler(void)
  289. {
  290. rt_interrupt_enter();
  291. rt_device_hwtimer_isr(&tmr_config[TMR3_INDEX].device);
  292. TMR_ClearIntFlag(TMR3, TMR_INT_UPDATE);
  293. rt_interrupt_leave();
  294. }
  295. #endif
  296. #ifdef BSP_USING_TMR4
  297. void TMR4_IRQHandler(void)
  298. {
  299. rt_interrupt_enter();
  300. rt_device_hwtimer_isr(&tmr_config[TMR4_INDEX].device);
  301. TMR_ClearIntFlag(TMR4, TMR_INT_UPDATE);
  302. rt_interrupt_leave();
  303. }
  304. #endif
  305. #ifdef BSP_USING_TMR5
  306. void TMR5_IRQHandler(void)
  307. {
  308. rt_interrupt_enter();
  309. rt_device_hwtimer_isr(&tmr_config[TMR5_INDEX].device);
  310. TMR_ClearIntFlag(TMR5, TMR_INT_UPDATE);
  311. rt_interrupt_leave();
  312. }
  313. #endif
  314. #ifdef BSP_USING_TMR6
  315. void TMR6_IRQHandler(void)
  316. {
  317. rt_interrupt_enter();
  318. rt_device_hwtimer_isr(&tmr_config[TMR6_INDEX].device);
  319. TMR_ClearIntFlag(TMR6, TMR_INT_UPDATE);
  320. rt_interrupt_leave();
  321. }
  322. #endif
  323. #ifdef BSP_USING_TMR7
  324. void TMR7_IRQHandler(void)
  325. {
  326. rt_interrupt_enter();
  327. rt_device_hwtimer_isr(&tmr_config[TMR7_INDEX].device);
  328. TMR_ClearIntFlag(TMR7, TMR_INT_UPDATE);
  329. rt_interrupt_leave();
  330. }
  331. #endif
  332. #ifdef BSP_USING_TMR8
  333. void TMR8_UP_IRQHandler(void)
  334. {
  335. rt_interrupt_enter();
  336. rt_device_hwtimer_isr(&tmr_config[TMR8_INDEX].device);
  337. TMR_ClearIntFlag(TMR8, TMR_INT_UPDATE);
  338. rt_interrupt_leave();
  339. }
  340. #endif
  341. static int rt_hw_hwtimer_init(void)
  342. {
  343. int i = 0;
  344. int result = RT_EOK;
  345. for (i = 0; i < sizeof(tmr_config) / sizeof(tmr_config[0]); i++)
  346. {
  347. tmr_config[i].device.info = &_info;
  348. tmr_config[i].device.ops = &_hwtimer_ops;
  349. if (rt_device_hwtimer_register(&tmr_config[i].device, tmr_config[i].name, &tmr_config[i]) == RT_EOK)
  350. {
  351. LOG_D("%s register success", tmr_config[i].name);
  352. }
  353. else
  354. {
  355. LOG_E("%s register failed", tmr_config[i].name);
  356. result = -RT_ERROR;
  357. }
  358. }
  359. return result;
  360. }
  361. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  362. #endif /* RT_USING_HWTIMER */