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
25 #include <rthw.h>
26 #include <rtthread.h>
27 #include <rtdevice.h>
28 #include <drv_hwtimer.h>
29 #include <board.h>
30
31
32 #ifdef RT_USING_HWTIMER
33
34 struct es32f3_hwtimer_dev
35 {
36 rt_hwtimer_t parent;
37 ald_timer_handle_t *hwtimer_periph;
38 IRQn_Type IRQn;
39 };
40
41 #ifdef BSP_USING_AD16C4T0_HWTIMER
42 static struct es32f3_hwtimer_dev ad16c4t0_hwtimer;
43
44 static struct rt_hwtimer_info ad16c4t0_info =
45 {
46 ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
47 (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
48 0xFFFF, /* counter maximum value */
49 ES_AD16C4T0_HWTIMER_MODE
50 };
51
AD16C4T_Handler(void)52 void __attribute__((interrupt)) AD16C4T_Handler(void)
53 {
54 rt_interrupt_enter();
55 ald_timer_clear_flag_status(ad16c4t0_hwtimer.hwtimer_periph, ALD_TIMER_FLAG_UPDATE);
56 rt_device_hwtimer_isr(&ad16c4t0_hwtimer.parent);
57 rt_interrupt_leave();
58 }
59
60 #endif
61
62 #ifdef BSP_USING_GP16C4T0_HWTIMER
63
64 static struct es32f3_hwtimer_dev gp16c4t0_hwtimer;
65
66 static struct rt_hwtimer_info gp16c4t0_info =
67 {
68 ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
69 (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
70 0xFFFF, /* counter maximum value */
71 ES_GP16C4T0_HWTIMER_MODE
72 };
73
GPTIMB0_Handler(void)74 void __attribute__((interrupt)) GPTIMB0_Handler(void)
75 {
76 rt_interrupt_enter();
77 ald_timer_clear_flag_status(gp16c4t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
78 rt_device_hwtimer_isr(&gp16c4t0_hwtimer.parent);
79 rt_interrupt_leave();
80 }
81
82 #endif
83 #ifdef BSP_USING_GP16C4T1_HWTIMER
84
85 static struct es32f3_hwtimer_dev gp16c4t1_hwtimer;
86
87 static struct rt_hwtimer_info gp16c4t1_info =
88 {
89 ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
90 (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
91 0xFFFF, /* counter maximum value */
92 ES_GP16C4T1_HWTIMER_MODE
93 };
94
GPTIMB1_Handler(void)95 void __attribute__((interrupt)) GPTIMB1_Handler(void)
96 {
97 rt_interrupt_enter();
98 ald_timer_clear_flag_status(gp16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
99 rt_device_hwtimer_isr(&gp16c4t1_hwtimer.parent);
100 rt_interrupt_leave();
101 }
102
103 #endif
104 #ifdef BSP_USING_GP16C4T1_HWTIMER
105
106 static struct es32f3_hwtimer_dev gp16c4t1_hwtimer;
107
108 static struct rt_hwtimer_info gp16c4t1_info =
109 {
110 ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
111 (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
112 0xFFFF, /* counter maximum value */
113 ES_GP16C4T1_HWTIMER_MODE
114 };
115
GPTIMB2_Handler(void)116 void __attribute__((interrupt)) GPTIMB2_Handler(void)
117 {
118 rt_interrupt_enter();
119 ald_timer_clear_flag_status(gp16c4t1_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
120 rt_device_hwtimer_isr(&gp16c4t1_hwtimer.parent);
121 rt_interrupt_leave();
122 }
123
124 #endif
125 #ifdef BSP_USING_BS16T0_HWTIMER
126
127 static struct es32f3_hwtimer_dev bs16t0_hwtimer;
128
129 static struct rt_hwtimer_info bs16t0_info =
130 {
131 ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV, /* maximum count frequency */
132 (ES_SYS_HCLK_CLK >> ES_CMU_PCLK_DIV)/(1U<<16), /* minimum count frequency */
133 0xFFFF, /* counter maximum value */
134 ES_BS16T0_HWTIMER_MODE
135 };
136
BSTIM0_Handler(void)137 void __attribute__((interrupt)) BSTIM0_Handler(void)
138 {
139 rt_interrupt_enter();
140 ald_timer_clear_flag_status(bs16t0_hwtimer.hwtimer_periph, TIMER_FLAG_UPDATE);
141 rt_device_hwtimer_isr(&bs16t0_hwtimer.parent);
142 rt_interrupt_leave();
143 }
144
145 #endif
146
es32f3_hwtimer_init(rt_hwtimer_t * timer,rt_uint32_t state)147 static void es32f3_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
148 {
149 struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
150
151 struct rt_hwtimer_info *hwtimer_info = (struct rt_hwtimer_info *)timer->info;
152
153 RT_ASSERT(hwtimer != RT_NULL);
154
155 if (1 == state)
156 {
157 ald_timer_base_init(hwtimer->hwtimer_periph);
158 ald_timer_interrupt_config(hwtimer->hwtimer_periph, ALD_TIMER_IT_UPDATE, ENABLE);
159 csi_vic_enable_sirq(hwtimer->IRQn);
160 }
161
162 hwtimer->parent.freq = ald_cmu_get_pclk_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
163 hwtimer_info->maxfreq = hwtimer->parent.freq;
164 hwtimer_info->minfreq = (hwtimer->parent.freq)/0xFFFF;
165
166 }
167
es32f3_hwtimer_start(rt_hwtimer_t * timer,rt_uint32_t cnt,rt_hwtimer_mode_t mode)168 static rt_err_t es32f3_hwtimer_start(rt_hwtimer_t *timer,
169 rt_uint32_t cnt,
170 rt_hwtimer_mode_t mode)
171 {
172 struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
173
174 RT_ASSERT(hwtimer != RT_NULL);
175
176 WRITE_REG(hwtimer->hwtimer_periph->perh->AR, cnt);
177 ald_timer_base_start(hwtimer->hwtimer_periph);
178
179 return RT_EOK;
180 }
181
es32f3_hwtimer_stop(rt_hwtimer_t * timer)182 static void es32f3_hwtimer_stop(rt_hwtimer_t *timer)
183 {
184 struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
185
186 RT_ASSERT(hwtimer != RT_NULL);
187
188 ald_timer_base_stop(hwtimer->hwtimer_periph);
189 }
190
es32f3_hwtimer_count_get(rt_hwtimer_t * timer)191 static rt_uint32_t es32f3_hwtimer_count_get(rt_hwtimer_t *timer)
192 {
193 struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
194 uint32_t hwtimer_count = 0;
195
196 RT_ASSERT(hwtimer != RT_NULL);
197
198 hwtimer_count = READ_REG(hwtimer->hwtimer_periph->perh->COUNT);
199
200 return hwtimer_count;
201 }
202
es32f3_hwtimer_control(rt_hwtimer_t * timer,rt_uint32_t cmd,void * args)203 static rt_err_t es32f3_hwtimer_control(rt_hwtimer_t *timer,
204 rt_uint32_t cmd,
205 void *args)
206 {
207 rt_err_t ret = RT_EOK;
208 rt_uint32_t freq = 0;
209 struct es32f3_hwtimer_dev *hwtimer = (struct es32f3_hwtimer_dev *)timer->parent.user_data;
210
211 RT_ASSERT(hwtimer != RT_NULL);
212
213 switch (cmd)
214 {
215 case HWTIMER_CTRL_FREQ_SET:
216 freq = *(rt_uint32_t *)args;
217
218 ret = -RT_ERROR;
219
220 if(freq)
221 {
222 double temp,target;
223 temp = (double)ald_cmu_get_pclk_clock();
224 target = temp/freq;
225
226 if(target < 0x10001) /*最大分频 = max(PRES)+1*/
227 {
228 temp = target - (int)(target);
229
230 if((temp > 0.998)&&(target < 0x10000))
231 {
232 hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target;
233 ret = RT_EOK;
234 }
235 if((temp < 0.002)&&(target >= 0x1))
236 {
237 hwtimer->hwtimer_periph->perh->PRES = (uint32_t)target - 1;
238 ret = RT_EOK;
239 }
240
241 }
242
243 if(ret == RT_EOK) /*更新信息*/
244 hwtimer->parent.freq = ald_cmu_get_pclk_clock()/((hwtimer->hwtimer_periph->perh->PRES & 0xFFFF)+1);
245
246 }
247
248 break;
249
250 case HWTIMER_CTRL_STOP:
251 ald_timer_base_stop(hwtimer->hwtimer_periph);
252 break;
253
254 default:
255 ret = RT_EINVAL;
256 break;
257 }
258
259 return ret;
260 }
261
262 static struct rt_hwtimer_ops es32f3_hwtimer_ops =
263 {
264 es32f3_hwtimer_init,
265 es32f3_hwtimer_start,
266 es32f3_hwtimer_stop,
267 es32f3_hwtimer_count_get,
268 es32f3_hwtimer_control
269 };
270
rt_hw_hwtimer_init(void)271 int rt_hw_hwtimer_init(void)
272 {
273 rt_err_t ret = RT_EOK;
274
275 #ifdef BSP_USING_AD16C4T0_HWTIMER
276 static ald_timer_handle_t ad16c4t0_hwtimer_periph;
277
278 ad16c4t0_hwtimer_periph.perh = AD16C4T;
279 ad16c4t0_hwtimer.IRQn = AD16C4T_IRQn;
280
281 ad16c4t0_hwtimer_periph.init.prescaler = ES_AD16C4T0_HWTIMER_PRES - 1;
282 ad16c4t0_hwtimer_periph.init.mode = ( ES_AD16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? ALD_TIMER_CNT_MODE_UP : ALD_TIMER_CNT_MODE_DOWN;
283 ad16c4t0_hwtimer.hwtimer_periph = &ad16c4t0_hwtimer_periph;
284
285 ad16c4t0_hwtimer.parent.info = &ad16c4t0_info;
286 ad16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
287 ret = rt_device_hwtimer_register(&ad16c4t0_hwtimer.parent, ES_DEVICE_NAME_AD16C4T0_HWTIMER, &ad16c4t0_hwtimer);
288 #endif
289
290 #ifdef BSP_USING_GP16C4T0_HWTIMER
291 static timer_handle_t gp16c4t0_hwtimer_periph;
292
293 gp16c4t0_hwtimer_periph.perh = GP16C4T0;
294 gp16c4t0_hwtimer.IRQn = GP16C4T0_IRQn;
295
296 gp16c4t0_hwtimer_periph.init.prescaler = ES_GP16C4T0_HWTIMER_PRES - 1;
297 gp16c4t0_hwtimer_periph.init.mode = ( ES_GP16C4T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
298 gp16c4t0_hwtimer.hwtimer_periph = &gp16c4t0_hwtimer_periph;
299
300 gp16c4t0_hwtimer.parent.info = &gp16c4t0_info;
301 gp16c4t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
302 ret = rt_device_hwtimer_register(&gp16c4t0_hwtimer.parent, ES_DEVICE_NAME_GP16C4T0_HWTIMER, &gp16c4t0_hwtimer);
303 #endif
304
305 #ifdef BSP_USING_GP16C4T1_HWTIMER
306 static timer_handle_t gp16c4t1_hwtimer_periph;
307
308 gp16c4t1_hwtimer_periph.perh = GP16C4T1;
309 gp16c4t1_hwtimer.IRQn = GP16C4T1_IRQn;
310
311 gp16c4t1_hwtimer_periph.init.prescaler = ES_GP16C4T1_HWTIMER_PRES - 1;
312 gp16c4t1_hwtimer_periph.init.mode = ( ES_GP16C4T1_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
313 gp16c4t1_hwtimer.hwtimer_periph = &gp16c4t1_hwtimer_periph;
314
315 gp16c4t1_hwtimer.parent.info = &gp16c4t1_info;
316 gp16c4t1_hwtimer.parent.ops = &es32f3_hwtimer_ops;
317 ret = rt_device_hwtimer_register(&gp16c4t1_hwtimer.parent, ES_DEVICE_NAME_GP16C4T1_HWTIMER, &gp16c4t1_hwtimer);
318 #endif
319
320 #ifdef BSP_USING_GP16C4T2_HWTIMER
321 static timer_handle_t gp16c4t2_hwtimer_periph;
322
323 gp16c4t2_hwtimer_periph.perh = GP16C4T2;
324 gp16c4t2_hwtimer.IRQn = GP16C4T2_IRQn;
325
326 gp16c4t2_hwtimer_periph.init.prescaler = ES_GP16C4T2_HWTIMER_PRES - 1;
327 gp16c4t2_hwtimer_periph.init.mode = ( ES_GP16C4T2_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
328 gp16c4t2_hwtimer.hwtimer_periph = &gp16c4t2_hwtimer_periph;
329
330 gp16c4t2_hwtimer.parent.info = &gp16c4t2_info;
331 gp16c4t2_hwtimer.parent.ops = &es32f3_hwtimer_ops;
332 ret = rt_device_hwtimer_register(&gp16c4t2_hwtimer.parent, ES_DEVICE_NAME_GP16C4T2_HWTIMER, &gp16c4t2_hwtimer);
333 #endif
334
335 #ifdef BSP_USING_BS16T0_HWTIMER
336 static timer_handle_t bs16t0_hwtimer_periph;
337
338 bs16t0_hwtimer_periph.perh = BS16T0;
339 bs16t0_hwtimer.IRQn = BS16T0_IRQn;
340
341 bs16t0_hwtimer_periph.init.prescaler = ES_BS16T0_HWTIMER_PRES - 1;
342 bs16t0_hwtimer_periph.init.mode = ( ES_BS16T0_HWTIMER_MODE == HWTIMER_CNTMODE_UP )? TIMER_CNT_MODE_UP : TIMER_CNT_MODE_DOWN;
343 bs16t0_hwtimer.hwtimer_periph = &bs16t0_hwtimer_periph;
344
345 bs16t0_hwtimer.parent.info = &bs16t0_info;
346 bs16t0_hwtimer.parent.ops = &es32f3_hwtimer_ops;
347 ret = rt_device_hwtimer_register(&bs16t0_hwtimer.parent, ES_DEVICE_NAME_BS16T0_HWTIMER, &bs16t0_hwtimer);
348 #endif
349
350 return ret;
351 }
352 INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
353
354 #endif
355