drv_hwtimer.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  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. ald_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_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
  41. (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
  42. 0xFFFF, /* counter maximum value */
  43. ES_AD16C4T0_HWTIMER_MODE
  44. };
  45. void __attribute__((interrupt)) AD16C4T_Handler(void)
  46. {
  47. rt_interrupt_enter();
  48. ald_timer_clear_flag_status(ad16c4t0_hwtimer.hwtimer_periph, ALD_TIMER_FLAG_UPDATE);
  49. rt_device_hwtimer_isr(&ad16c4t0_hwtimer.parent);
  50. rt_interrupt_leave();
  51. }
  52. #endif
  53. #ifdef BSP_USING_GP16C4T0_HWTIMER
  54. static struct es32f3_hwtimer_dev gp16c4t0_hwtimer;
  55. static struct rt_hwtimer_info gp16c4t0_info =
  56. {
  57. ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
  58. (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
  59. 0xFFFF, /* counter maximum value */
  60. ES_GP16C4T0_HWTIMER_MODE
  61. };
  62. void __attribute__((interrupt)) GPTIMB0_Handler(void)
  63. {
  64. rt_interrupt_enter();
  65. ald_timer_clear_flag_status(gp16c4t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  66. rt_device_hwtimer_isr(&gp16c4t0_hwtimer.parent);
  67. rt_interrupt_leave();
  68. }
  69. #endif
  70. #ifdef BSP_USING_GP16C4T1_HWTIMER
  71. static struct es32f3_hwtimer_dev gp16c4t1_hwtimer;
  72. static struct rt_hwtimer_info gp16c4t1_info =
  73. {
  74. ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
  75. (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
  76. 0xFFFF, /* counter maximum value */
  77. ES_GP16C4T1_HWTIMER_MODE
  78. };
  79. void __attribute__((interrupt)) GPTIMB1_Handler(void)
  80. {
  81. rt_interrupt_enter();
  82. ald_timer_clear_flag_status(gp16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  83. rt_device_hwtimer_isr(&gp16c4t1_hwtimer.parent);
  84. rt_interrupt_leave();
  85. }
  86. #endif
  87. #ifdef BSP_USING_GP16C4T1_HWTIMER
  88. static struct es32f3_hwtimer_dev gp16c4t1_hwtimer;
  89. static struct rt_hwtimer_info gp16c4t1_info =
  90. {
  91. ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
  92. (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
  93. 0xFFFF, /* counter maximum value */
  94. ES_GP16C4T1_HWTIMER_MODE
  95. };
  96. void __attribute__((interrupt)) GPTIMB2_Handler(void)
  97. {
  98. rt_interrupt_enter();
  99. ald_timer_clear_flag_status(gp16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  100. rt_device_hwtimer_isr(&gp16c4t1_hwtimer.parent);
  101. rt_interrupt_leave();
  102. }
  103. #endif
  104. #ifdef BSP_USING_BS16T0_HWTIMER
  105. static struct es32f3_hwtimer_dev bs16t0_hwtimer;
  106. static struct rt_hwtimer_info bs16t0_info =
  107. {
  108. ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
  109. (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
  110. 0xFFFF, /* counter maximum value */
  111. ES_BS16T0_HWTIMER_MODE
  112. };
  113. void __attribute__((interrupt)) BSTIM0_Handler(void)
  114. {
  115. rt_interrupt_enter();
  116. ald_timer_clear_flag_status(bs16t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
  117. rt_device_hwtimer_isr(&bs16t0_hwtimer.parent);
  118. rt_interrupt_leave();
  119. }
  120. #endif
  121. static void es32f3_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  122. {
  123. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  124. struct rt_hwtimer_info *hwtimer_info = (struct rt_hwtimer_info *)timer->info;
  125. RT_ASSERT(hwtimer != RT_NULL);
  126. if (1 == state)
  127. {
  128. ald_timer_base_init(hwtimer->hwtimer_periph);
  129. ald_timer_interrupt_config(hwtimer->hwtimer_periph, ALD_TIMER_IT_UPDATE, ENABLE);
  130. csi_vic_enable_sirq(hwtimer->IRQn);
  131. }
  132. hwtimer->parent.freq = ald_cmu_get_pclk_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
  133. hwtimer_info->maxfreq = hwtimer->parent.freq;
  134. hwtimer_info->minfreq = (hwtimer->parent.freq)/0xFFFF;
  135. }
  136. static rt_err_t es32f3_hwtimer_start(rt_hwtimer_t *timer,
  137. rt_uint32_t cnt,
  138. rt_hwtimer_mode_t mode)
  139. {
  140. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  141. RT_ASSERT(hwtimer != RT_NULL);
  142. WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
  143. ald_timer_base_start(hwtimer->hwtimer_periph);
  144. return RT_EOK;
  145. }
  146. static void es32f3_hwtimer_stop(rt_hwtimer_t *timer)
  147. {
  148. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  149. RT_ASSERT(hwtimer != RT_NULL);
  150. ald_timer_base_stop(hwtimer->hwtimer_periph);
  151. }
  152. static rt_uint32_t es32f3_hwtimer_count_get(rt_hwtimer_t *timer)
  153. {
  154. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  155. uint32_t hwtimer_count = 0;
  156. RT_ASSERT(hwtimer != RT_NULL);
  157. hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
  158. return hwtimer_count;
  159. }
  160. static rt_err_t es32f3_hwtimer_control(rt_hwtimer_t *timer,
  161. rt_uint32_t cmd,
  162. void *args)
  163. {
  164. rt_err_t ret = RT_EOK;
  165. rt_uint32_t freq = 0;
  166. struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
  167. RT_ASSERT(hwtimer != RT_NULL);
  168. switch (cmd)
  169. {
  170. case HWTIMER_CTRL_FREQ_SET:
  171. freq = *(rt_uint32_t *)args;
  172. ret = -RT_ERROR;
  173. if(freq)
  174. {
  175. double temp,target;
  176. temp = (double)ald_cmu_get_pclk_clock();
  177. target = temp/freq;
  178. if(target < 0x10001) /*最大分频 = max(PRES)+1*/
  179. {
  180. temp = target - (int)(target);
  181. if((temp > 0.998)&&(target < 0x10000))
  182. {
  183. hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target;
  184. ret = RT_EOK;
  185. }
  186. if((temp < 0.002)&&(target >= 0x1))
  187. {
  188. hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target - 1;
  189. ret = RT_EOK;
  190. }
  191. }
  192. if(ret == RT_EOK) /*更新信息*/
  193. hwtimer->parent.freq = ald_cmu_get_pclk_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
  194. }
  195. break;
  196. case HWTIMER_CTRL_STOP:
  197. ald_timer_base_stop(hwtimer->hwtimer_periph);
  198. break;
  199. default:
  200. ret = RT_EINVAL;
  201. break;
  202. }
  203. return ret;
  204. }
  205. static struct rt_hwtimer_ops es32f3_hwtimer_ops =
  206. {
  207. es32f3_hwtimer_init,
  208. es32f3_hwtimer_start,
  209. es32f3_hwtimer_stop,
  210. es32f3_hwtimer_count_get,
  211. es32f3_hwtimer_control
  212. };
  213. int rt_hw_hwtimer_init(void)
  214. {
  215. rt_err_t ret = RT_EOK;
  216. #ifdef BSP_USING_AD16C4T0_HWTIMER
  217. static ald_timer_handle_t ad16c4t0_hwtimer_periph;
  218. ad16c4t0_hwtimer_periph.perh = AD16C4T;
  219. ad16c4t0_hwtimer.IRQn = AD16C4T_IRQn;
  220. ad16c4t0_hwtimer_periph.init.prescaler = ES_AD16C4T0_HWTIMER_PRES - 1;
  221. ad16c4t0_hwtimer_periph.init.mode = ( ES_AD16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? ALD_TIMER_CNT_MODE_UP : ALD_TIMER_CNT_MODE_DOWN;
  222. ad16c4t0_hwtimer.hwtimer_periph = &ad16c4t0_hwtimer_periph;
  223. ad16c4t0_hwtimer.parent.info = &ad16c4t0_info;
  224. ad16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  225. ret = rt_device_hwtimer_register(&ad16c4t0_hwtimer.parent, ES_DEVICE_NAME_AD16C4T0_HWTIMER, &ad16c4t0_hwtimer);
  226. #endif
  227. #ifdef BSP_USING_GP16C4T0_HWTIMER
  228. static timer_handle_t gp16c4t0_hwtimer_periph;
  229. gp16c4t0_hwtimer_periph.perh = GP16C4T0;
  230. gp16c4t0_hwtimer.IRQn = GP16C4T0_IRQn;
  231. gp16c4t0_hwtimer_periph.init.prescaler = ES_GP16C4T0_HWTIMER_PRES - 1;
  232. gp16c4t0_hwtimer_periph.init.mode = ( ES_GP16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  233. gp16c4t0_hwtimer.hwtimer_periph = &gp16c4t0_hwtimer_periph;
  234. gp16c4t0_hwtimer.parent.info = &gp16c4t0_info;
  235. gp16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  236. ret = rt_device_hwtimer_register(&gp16c4t0_hwtimer.parent, ES_DEVICE_NAME_GP16C4T0_HWTIMER, &gp16c4t0_hwtimer);
  237. #endif
  238. #ifdef BSP_USING_GP16C4T1_HWTIMER
  239. static timer_handle_t gp16c4t1_hwtimer_periph;
  240. gp16c4t1_hwtimer_periph.perh = GP16C4T1;
  241. gp16c4t1_hwtimer.IRQn = GP16C4T1_IRQn;
  242. gp16c4t1_hwtimer_periph.init.prescaler = ES_GP16C4T1_HWTIMER_PRES - 1;
  243. gp16c4t1_hwtimer_periph.init.mode = ( ES_GP16C4T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  244. gp16c4t1_hwtimer.hwtimer_periph = &gp16c4t1_hwtimer_periph;
  245. gp16c4t1_hwtimer.parent.info = &gp16c4t1_info;
  246. gp16c4t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  247. ret = rt_device_hwtimer_register(&gp16c4t1_hwtimer.parent, ES_DEVICE_NAME_GP16C4T1_HWTIMER, &gp16c4t1_hwtimer);
  248. #endif
  249. #ifdef BSP_USING_GP16C4T2_HWTIMER
  250. static timer_handle_t gp16c4t2_hwtimer_periph;
  251. gp16c4t2_hwtimer_periph.perh = GP16C4T2;
  252. gp16c4t2_hwtimer.IRQn = GP16C4T2_IRQn;
  253. gp16c4t2_hwtimer_periph.init.prescaler = ES_GP16C4T2_HWTIMER_PRES - 1;
  254. gp16c4t2_hwtimer_periph.init.mode = ( ES_GP16C4T2_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  255. gp16c4t2_hwtimer.hwtimer_periph = &gp16c4t2_hwtimer_periph;
  256. gp16c4t2_hwtimer.parent.info = &gp16c4t2_info;
  257. gp16c4t2_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  258. ret = rt_device_hwtimer_register(&gp16c4t2_hwtimer.parent, ES_DEVICE_NAME_GP16C4T2_HWTIMER, &gp16c4t2_hwtimer);
  259. #endif
  260. #ifdef BSP_USING_BS16T0_HWTIMER
  261. static timer_handle_t bs16t0_hwtimer_periph;
  262. bs16t0_hwtimer_periph.perh = BS16T0;
  263. bs16t0_hwtimer.IRQn = BS16T0_IRQn;
  264. bs16t0_hwtimer_periph.init.prescaler = ES_BS16T0_HWTIMER_PRES - 1;
  265. bs16t0_hwtimer_periph.init.mode = ( ES_BS16T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
  266. bs16t0_hwtimer.hwtimer_periph = &bs16t0_hwtimer_periph;
  267. bs16t0_hwtimer.parent.info = &bs16t0_info;
  268. bs16t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
  269. ret = rt_device_hwtimer_register(&bs16t0_hwtimer.parent, ES_DEVICE_NAME_BS16T0_HWTIMER, &bs16t0_hwtimer);
  270. #endif
  271. return ret;
  272. }
  273. INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
  274. #endif