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