drv_hwtimer.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Change Logs:
  19. * Date Author Notes
  20. * 2019-3-19 wangyq the first version
  21. * 2019-11-01 wangyq update libraries
  22. * 2021-04-20 liuhy the second version
  23. */
  24. #include <rthw.h>
  25. #include <rtthread.h>
  26. #include <rtdevice.h>
  27. #include <drv_hwtimer.h>
  28. #include <board.h>
  29. #ifdef RT_USING_HWTIMER
  30. struct es32f3_hwtimer_dev
  31. {
  32. rt_hwtimer_t parent;
  33. timer_handle_t *hwtimer_periph;
  34. IRQn_Type IRQn;
  35. };
  36. #ifdef BSP_USING_AD16C4T0_HWTIMER
  37. static struct es32f3_hwtimer_dev ad16c4t0_hwtimer;
  38. static struct rt_hwtimer_info ad16c4t0_info =
  39. {
  40. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  41. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  42. 0xFFFF, /* counter maximum value */
  43. ES_AD16C4T0_HWTIMER_MODE
  44. };
  45. void AD16C4T0_UP_Handler(void)
  46. {
  47. ald_timer_clear_flag_status(ad16c4t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  48. rt_device_hwtimer_isr(&ad16c4t0_hwtimer.parent);
  49. }
  50. #endif
  51. #ifdef BSP_USING_AD16C4T1_HWTIMER
  52. static struct es32f3_hwtimer_dev ad16c4t1_hwtimer;
  53. static struct rt_hwtimer_info ad16c4t1_info =
  54. {
  55. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  56. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  57. 0xFFFF, /* counter maximum value */
  58. ES_AD16C4T1_HWTIMER_MODE
  59. };
  60. void AD16C4T1_UP_Handler(void)
  61. {
  62. ald_timer_clear_flag_status(ad16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  63. rt_device_hwtimer_isr(&ad16c4t1_hwtimer.parent);
  64. }
  65. #endif
  66. #ifdef BSP_USING_GP32C4T0_HWTIMER
  67. static struct es32f3_hwtimer_dev gp32c4t0_hwtimer;
  68. static struct rt_hwtimer_info gp32c4t0_info =
  69. {
  70. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV , /* maximum count frequency */
  71. ( ES_SYS_CLK >> ES_CMU_PCLK_1_DIV )/(1U<<16), /* minimum count frequency */
  72. 0xFFFFFFFF, /* counter maximum value */
  73. ES_GP32C4T0_HWTIMER_MODE
  74. };
  75. void GP32C4T0_Handler(void)
  76. {
  77. ald_timer_clear_flag_status(gp32c4t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  78. rt_device_hwtimer_isr(&gp32c4t0_hwtimer.parent);
  79. }
  80. #endif
  81. #ifdef BSP_USING_GP32C4T1_HWTIMER
  82. static struct es32f3_hwtimer_dev gp32c4t1_hwtimer;
  83. static struct rt_hwtimer_info gp32c4t1_info =
  84. {
  85. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV ), /* maximum count frequency */
  86. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV )/(1U<<16), /* minimum count frequency */
  87. 0xFFFFFFFF, /* counter maximum value */
  88. ES_GP32C4T1_HWTIMER_MODE
  89. };
  90. void GP32C4T1_Handler(void)
  91. {
  92. ald_timer_clear_flag_status(gp32c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  93. rt_device_hwtimer_isr(&gp32c4t1_hwtimer.parent);
  94. }
  95. #endif
  96. #ifdef BSP_USING_GP16C4T0_HWTIMER
  97. static struct es32f3_hwtimer_dev gp16c4t0_hwtimer;
  98. static struct rt_hwtimer_info gp16c4t0_info =
  99. {
  100. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  101. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  102. 0xFFFF, /* counter maximum value */
  103. ES_GP16C4T0_HWTIMER_MODE
  104. };
  105. void GP16C4T0_Handler(void)
  106. {
  107. ald_timer_clear_flag_status(gp16c4t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  108. rt_device_hwtimer_isr(&gp16c4t0_hwtimer.parent);
  109. }
  110. #endif
  111. #ifdef BSP_USING_GP16C4T1_HWTIMER
  112. static struct es32f3_hwtimer_dev gp16c4t1_hwtimer;
  113. static struct rt_hwtimer_info gp16c4t1_info =
  114. {
  115. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  116. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  117. 0xFFFF, /* counter maximum value */
  118. ES_GP16C4T1_HWTIMER_MODE
  119. };
  120. void GP16C4T1_Handler(void)
  121. {
  122. ald_timer_clear_flag_status(gp16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  123. rt_device_hwtimer_isr(&gp16c4t1_hwtimer.parent);
  124. }
  125. #endif
  126. #ifdef BSP_USING_BS16T0_HWTIMER
  127. static struct es32f3_hwtimer_dev bs16t0_hwtimer;
  128. static struct rt_hwtimer_info bs16t0_info =
  129. {
  130. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  131. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  132. 0xFFFF, /* counter maximum value */
  133. ES_BS16T0_HWTIMER_MODE
  134. };
  135. void BS16T0_Handler(void)
  136. {
  137. ald_timer_clear_flag_status(bs16t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  138. rt_device_hwtimer_isr(&bs16t0_hwtimer.parent);
  139. }
  140. #endif
  141. #ifdef BSP_USING_BS16T1_HWTIMER
  142. static struct es32f3_hwtimer_dev bs16t1_hwtimer;
  143. static struct rt_hwtimer_info bs16t1_info =
  144. {
  145. ES_SYS_CLK >> ES_CMU_PCLK_1_DIV, /* maximum count frequency */
  146. (ES_SYS_CLK >> ES_CMU_PCLK_1_DIV)/(1U<<16), /* minimum count frequency */
  147. 0xFFFF, /* counter maximum value */
  148. ES_BS16T1_HWTIMER_MODE
  149. };
  150. void BS16T1_Handler(void)
  151. {
  152. ald_timer_clear_flag_status(bs16t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  153. rt_device_hwtimer_isr(&bs16t1_hwtimer.parent);
  154. }
  155. #endif
  156. static void es32f3_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  157. {
  158. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  159. struct rt_hwtimer_info *hwtimer_info = (struct rt_hwtimer_info *)timer->info;
  160. RT_ASSERT(hwtimer != RT_NULL);
  161. if (1 == state)
  162. {
  163. ald_timer_base_init(hwtimer->hwtimer_periph);
  164. ald_timer_interrupt_config(hwtimer->hwtimer_periph, TIMER_IT_UPDATE, ENABLE);
  165. NVIC_EnableIRQ(hwtimer->IRQn);
  166. }
  167. hwtimer->parent.freq = ald_cmu_get_pclk1_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
  168. hwtimer_info->maxfreq = hwtimer->parent.freq;
  169. hwtimer_info->minfreq = (hwtimer->parent.freq)/0xFFFF;
  170. }
  171. static rt_err_t es32f3_hwtimer_start(rt_hwtimer_t *timer,
  172. rt_uint32_t cnt,
  173. rt_hwtimer_mode_t mode)
  174. {
  175. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  176. RT_ASSERT(hwtimer != RT_NULL);
  177. WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
  178. ald_timer_base_start(hwtimer->hwtimer_periph);
  179. return RT_EOK;
  180. }
  181. static void es32f3_hwtimer_stop(rt_hwtimer_t *timer)
  182. {
  183. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  184. RT_ASSERT(hwtimer != RT_NULL);
  185. ald_timer_base_stop(hwtimer->hwtimer_periph);
  186. }
  187. static rt_uint32_t es32f3_hwtimer_count_get(rt_hwtimer_t *timer)
  188. {
  189. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  190. uint32_t hwtimer_count = 0;
  191. RT_ASSERT(hwtimer != RT_NULL);
  192. hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
  193. return hwtimer_count;
  194. }
  195. static rt_err_t es32f3_hwtimer_control(rt_hwtimer_t *timer,
  196. rt_uint32_t cmd,
  197. void *args)
  198. {
  199. rt_err_t ret = RT_EOK;
  200. rt_uint32_t freq = 0;
  201. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  202. RT_ASSERT(hwtimer != RT_NULL);
  203. switch (cmd)
  204. {
  205. case HWTIMER_CTRL_FREQ_SET:
  206. freq = *(rt_uint32_t *)args;
  207. ret = -RT_ERROR;
  208. if(freq)
  209. {
  210. double temp,target;
  211. temp = (double)ald_cmu_get_pclk1_clock();
  212. target = temp/freq;
  213. if(target < 0x10001) /*最大分频 = max(PRES)+1*/
  214. {
  215. temp = target - (int)(target);
  216. if((temp > 0.998)&&(target < 0x10000))
  217. {
  218. hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target;
  219. ret = RT_EOK;
  220. }
  221. if((temp < 0.002)&&(target >= 0x1))
  222. {
  223. hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target - 1;
  224. ret = RT_EOK;
  225. }
  226. }
  227. if(ret == RT_EOK) /*更新信息*/
  228. hwtimer->parent.freq = ald_cmu_get_pclk1_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
  229. }
  230. break;
  231. case HWTIMER_CTRL_STOP:
  232. ald_timer_base_stop(hwtimer->hwtimer_periph);
  233. break;
  234. default:
  235. ret = -RT_EINVAL;
  236. break;
  237. }
  238. return ret;
  239. }
  240. static struct rt_hwtimer_ops es32f3_hwtimer_ops =
  241. {
  242. es32f3_hwtimer_init,
  243. es32f3_hwtimer_start,
  244. es32f3_hwtimer_stop,
  245. es32f3_hwtimer_count_get,
  246. es32f3_hwtimer_control
  247. };
  248. int rt_hw_hwtimer_init(void)
  249. {
  250. rt_err_t ret = RT_EOK;
  251. #ifdef BSP_USING_AD16C4T0_HWTIMER
  252. static timer_handle_t ad16c4t0_hwtimer_periph;
  253. ad16c4t0_hwtimer_periph.perh = AD16C4T0;
  254. ad16c4t0_hwtimer.IRQn = AD16C4T0_UP_IRQn;
  255. ad16c4t0_hwtimer_periph.init.prescaler = ES_AD16C4T0_HWTIMER_PRES - 1;
  256. ad16c4t0_hwtimer_periph.init.mode = ( ES_AD16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  257. ad16c4t0_hwtimer.hwtimer_periph = &ad16c4t0_hwtimer_periph;
  258. ad16c4t0_hwtimer.parent.info = &ad16c4t0_info;
  259. ad16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  260. ret = rt_device_hwtimer_register(&ad16c4t0_hwtimer.parent, ES_DEVICE_NAME_AD16C4T0_HWTIMER, &ad16c4t0_hwtimer);
  261. #endif
  262. #ifdef BSP_USING_AD16C4T1_HWTIMER
  263. static timer_handle_t ad16c4t1_hwtimer_periph;
  264. ad16c4t1_hwtimer_periph.perh = AD16C4T1;
  265. ad16c4t1_hwtimer.IRQn = AD16C4T1_UP_IRQn;
  266. ad16c4t1_hwtimer_periph.init.prescaler = ES_AD16C4T1_HWTIMER_PRES - 1;
  267. ad16c4t1_hwtimer_periph.init.mode = ( ES_AD16C4T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  268. ad16c4t1_hwtimer.hwtimer_periph = &ad16c4t1_hwtimer_periph;
  269. ad16c4t1_hwtimer.parent.info = &ad16c4t1_info;
  270. ad16c4t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  271. ret = rt_device_hwtimer_register(&ad16c4t1_hwtimer.parent, ES_DEVICE_NAME_AD16C4T1_HWTIMER, &ad16c4t1_hwtimer);
  272. #endif
  273. #ifdef BSP_USING_GP32C4T0_HWTIMER
  274. static timer_handle_t gp32c4t0_hwtimer_periph;
  275. gp32c4t0_hwtimer_periph.perh = GP32C4T0;
  276. gp32c4t0_hwtimer.IRQn = GP32C4T0_IRQn;
  277. gp32c4t0_hwtimer_periph.init.prescaler = ES_GP32C4T0_HWTIMER_PRES - 1;
  278. gp32c4t0_hwtimer_periph.init.mode = ( ES_GP32C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  279. gp32c4t0_hwtimer.hwtimer_periph = &gp32c4t0_hwtimer_periph;
  280. gp32c4t0_hwtimer.parent.info = &gp32c4t0_info;
  281. gp32c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  282. ret = rt_device_hwtimer_register(&gp32c4t0_hwtimer.parent, ES_DEVICE_NAME_GP32C4T0_HWTIMER, &gp32c4t0_hwtimer);
  283. #endif
  284. #ifdef BSP_USING_GP32C4T1_HWTIMER
  285. static timer_handle_t gp32c4t1_hwtimer_periph;
  286. gp32c4t1_hwtimer_periph.perh = GP32C4T1;
  287. gp32c4t1_hwtimer.IRQn = GP32C4T1_IRQn;
  288. gp32c4t1_hwtimer_periph.init.prescaler = ES_GP32C4T1_HWTIMER_PRES - 1;
  289. gp32c4t1_hwtimer_periph.init.mode = ( ES_GP32C4T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  290. gp32c4t1_hwtimer.hwtimer_periph = &gp32c4t1_hwtimer_periph;
  291. gp32c4t1_hwtimer.parent.info = &gp32c4t1_info;
  292. gp32c4t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  293. ret = rt_device_hwtimer_register(&gp32c4t1_hwtimer.parent, ES_DEVICE_NAME_GP32C4T1_HWTIMER, &gp32c4t1_hwtimer);
  294. #endif
  295. #ifdef BSP_USING_GP16C4T0_HWTIMER
  296. static timer_handle_t gp16c4t0_hwtimer_periph;
  297. gp16c4t0_hwtimer_periph.perh = GP16C4T0;
  298. gp16c4t0_hwtimer.IRQn = GP16C4T0_IRQn;
  299. gp16c4t0_hwtimer_periph.init.prescaler = ES_GP16C4T0_HWTIMER_PRES - 1;
  300. gp16c4t0_hwtimer_periph.init.mode = ( ES_GP16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  301. gp16c4t0_hwtimer.hwtimer_periph = &gp16c4t0_hwtimer_periph;
  302. gp16c4t0_hwtimer.parent.info = &gp16c4t0_info;
  303. gp16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  304. ret = rt_device_hwtimer_register(&gp16c4t0_hwtimer.parent, ES_DEVICE_NAME_GP16C4T0_HWTIMER, &gp16c4t0_hwtimer);
  305. #endif
  306. #ifdef BSP_USING_GP16C4T1_HWTIMER
  307. static timer_handle_t gp16c4t1_hwtimer_periph;
  308. gp16c4t1_hwtimer_periph.perh = GP16C4T1;
  309. gp16c4t1_hwtimer.IRQn = GP16C4T1_IRQn;
  310. gp16c4t1_hwtimer_periph.init.prescaler = ES_GP16C4T1_HWTIMER_PRES - 1;
  311. gp16c4t1_hwtimer_periph.init.mode = ( ES_GP16C4T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  312. gp16c4t1_hwtimer.hwtimer_periph = &gp16c4t1_hwtimer_periph;
  313. gp16c4t1_hwtimer.parent.info = &gp16c4t1_info;
  314. gp16c4t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  315. ret = rt_device_hwtimer_register(&gp16c4t1_hwtimer.parent, ES_DEVICE_NAME_GP16C4T1_HWTIMER, &gp16c4t1_hwtimer);
  316. #endif
  317. #ifdef BSP_USING_BS16T0_HWTIMER
  318. static timer_handle_t bs16t0_hwtimer_periph;
  319. bs16t0_hwtimer_periph.perh = BS16T0;
  320. bs16t0_hwtimer.IRQn = BS16T0_IRQn;
  321. bs16t0_hwtimer_periph.init.prescaler = ES_BS16T0_HWTIMER_PRES - 1;
  322. bs16t0_hwtimer_periph.init.mode = ( ES_BS16T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  323. bs16t0_hwtimer.hwtimer_periph = &bs16t0_hwtimer_periph;
  324. bs16t0_hwtimer.parent.info = &bs16t0_info;
  325. bs16t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  326. ret = rt_device_hwtimer_register(&bs16t0_hwtimer.parent, ES_DEVICE_NAME_BS16T0_HWTIMER, &bs16t0_hwtimer);
  327. #endif
  328. #ifdef BSP_USING_BS16T1_HWTIMER
  329. static timer_handle_t bs16t1_hwtimer_periph;
  330. bs16t1_hwtimer_periph.perh = BS16T1;
  331. bs16t1_hwtimer.IRQn = BS16T1_IRQn;
  332. bs16t1_hwtimer_periph.init.prescaler = ES_BS16T1_HWTIMER_PRES - 1;
  333. bs16t1_hwtimer_periph.init.mode = ( ES_BS16T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  334. bs16t1_hwtimer.hwtimer_periph = &bs16t1_hwtimer_periph;
  335. bs16t1_hwtimer.parent.info = &bs16t1_info;
  336. bs16t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  337. ret = rt_device_hwtimer_register(&bs16t1_hwtimer.parent, ES_DEVICE_NAME_BS16T1_HWTIMER, &bs16t1_hwtimer);
  338. #endif
  339. return ret;
  340. }
  341. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  342. #endif