1  /*
2  * Copyright (c) 2006-2018, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  *                             first version
9  */
10 // Ӳ����ʱ��Դ��
11 
12 #include <ls1c.h>
13 #include "ls1c_public.h"
14 #include "ls1c_pin.h"
15 #include "ls1c_clock.h"
16 #include "ls1c_regs.h"
17 #include "ls1c_pwm.h"
18 #include "ls1c_timer.h"
19 
20 
21 // ��ʱ���м�����(CNTR��HRC��LRC)�����ֵ
22 #define TIMER_COUNTER_MAX               (0xffffff)
23 
24 
25 
26 /*
27  * ��ȡָ����ʱ���ļĴ�������ַ
28  * @timer Ӳ����ʱ��
29  * @ret ����ַ
30  */
timer_get_reg_base(ls1c_timer_t timer)31 unsigned int timer_get_reg_base(ls1c_timer_t timer)
32 {
33     unsigned int reg_base = 0;
34 
35     switch (timer)
36     {
37         case TIMER_PWM0:
38             reg_base = LS1C_REG_BASE_PWM0;
39             break;
40 
41         case TIMER_PWM1:
42             reg_base = LS1C_REG_BASE_PWM1;
43             break;
44 
45         case TIMER_PWM2:
46             reg_base = LS1C_REG_BASE_PWM2;
47             break;
48 
49         case TIMER_PWM3:
50             reg_base = LS1C_REG_BASE_PWM3;
51             break;
52     }
53 
54     return reg_base;
55 }
56 
57 
58 /*
59  * ��ʼ����ʱ��������ʼ��ʱ
60  * @timer_info ��ʱ���Ͷ�ʱʱ����Ϣ
61  */
timer_init(timer_info_t * timer_info)62 void timer_init(timer_info_t *timer_info)
63 {
64     unsigned int timer_reg_base = 0;        // �Ĵ�������ַ
65     unsigned long timer_clk = 0;            // Ӳ����ʱ����ʱ��
66     unsigned long tmp;
67     unsigned int ctrl = 0;                  // ���ƼĴ����еĿ�����Ϣ
68 
69     // �ж����
70     if (NULL == timer_info)
71     {
72         return ;
73     }
74 
75     /*
76      * �Ѷ�ʱʱ�任��Ϊ��������ֵ
77      * ������ֵ = ��ʱ����ʱ�� * ��ʱʱ��(��λns) / 1000000000
78      * ��о1c�Ķ�ʱ��ʱ��ΪAPBʱ�ӣ��ﵽ126Mhz��
79      * Ϊ���������̷����������������ֶ��Ż�����ļ���ʽ��Ҳ���Բ��ø�������
80      */
81     timer_clk = clk_get_apb_rate();
82     tmp = (timer_clk / 1000000) * (timer_info->time_ns / 1000);     // ��1000000000���Ϊ1000000��1000
83     tmp = MIN(tmp, TIMER_COUNTER_MAX);
84 
85     // ���ƼĴ�����Ϣ
86     ctrl = (1 << LS1C_PWM_INT_LRC_EN)
87            | (0 << LS1C_PWM_INT_HRC_EN)
88            | (0 << LS1C_PWM_CNTR_RST)
89            | (0 << LS1C_PWM_INT_SR)
90            | (1 << LS1C_PWM_INTEN)
91            | (1 << LS1C_PWM_SINGLE)
92            | (1 << LS1C_PWM_OE)
93            | (1 << LS1C_PWM_CNT_EN);
94 
95     // ���ø����Ĵ���
96     timer_reg_base = timer_get_reg_base(timer_info->timer);     // ��ȡ�Ĵ�������ַ
97     reg_write_32(0,                     (volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC));
98     reg_write_32(tmp--,                 (volatile unsigned int *)(timer_reg_base + LS1C_PWM_LRC));
99     reg_write_32(0,                     (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR));
100     reg_write_32(ctrl,                  (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
101 
102     return ;
103 }
104 
105 
106 /*
107  * �ж�ָ����ʱ���Ƿ�ʱ(ʵ�ֶ�ʱ)
108  * @timer_info ��ʱ��
109  * @ret TRUE or FALSE
110  */
timer_is_time_out(timer_info_t * timer_info)111 BOOL timer_is_time_out(timer_info_t *timer_info)
112 {
113     unsigned int timer_reg_base = 0;        // �Ĵ�������ַ
114     unsigned int ctrl;                      // ���ƼĴ�����ֵ
115 
116     // �ж����
117     if (NULL == timer_info)
118     {
119         return FALSE;
120     }
121 
122     // ��ȡ���ƼĴ���
123     timer_reg_base = timer_get_reg_base(timer_info->timer);
124     ctrl = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
125 
126     // �ж��ж�״̬λ
127     if (ctrl & (1 << LS1C_PWM_INT_SR))
128     {
129         return TRUE;
130     }
131     else
132     {
133         return FALSE;
134     }
135 }
136 
137 
138 
139 /*
140  * ֹͣ��ʱ��
141  * @timer_info ��ʱ��
142  */
timer_stop(timer_info_t * timer_info)143 void timer_stop(timer_info_t *timer_info)
144 {
145     unsigned int timer_reg_base = 0;
146 
147     // �ж����
148     if (NULL == timer_info)
149     {
150         return ;
151     }
152 
153     timer_reg_base = timer_get_reg_base(timer_info->timer);
154     reg_write_32(0, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
155 
156     return ;
157 }
158 
159 /*
160  * ��ȡ��ʱ���ӳ�ʼ�������ڵ�ʱ��(ʵ�ּ�ʱ����)����λns
161  * @timer_info Ӳ����ʱ��
162  * @ret ʱ�䣬��λns
163  */
timer_get_time_ns(timer_info_t * timer_info)164 unsigned long timer_get_time_ns(timer_info_t *timer_info)
165 {
166     unsigned int timer_reg_base = 0;
167     unsigned int cntr = 0;                  // �Ĵ���CNTR��ֵ
168     unsigned long time_ns = 0;              // ʱ�䣬��λns
169     unsigned long timer_clk = 0;            // ��ʱ��ʱ��
170 
171     // ��ȡ�Ĵ���CNTR��ֵ
172     timer_reg_base = timer_get_reg_base(timer_info->timer);
173     cntr = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR));
174 
175     /*
176      * ��CNTRֵ����Ϊʱ�䣬��λus
177      * ʱ�� = (������ֵCNTR * 1000000000) / ��ʱ��ʱ��Ƶ��
178      * Ϊ�������������ֶ��Ż���ʽΪ ʱ�� = (������ֵCNTR * 1000) / (��ʱ��ʱ��Ƶ�� / 1000000)
179      */
180     timer_clk = clk_get_apb_rate();
181     time_ns = (cntr * 1000 ) / (timer_clk /1000000);
182 //    printf("[%s] time_us=%lu, cntr=%d, timer_clk=%d\n", __FUNCTION__, time_ns, cntr, timer_clk);
183 
184     return time_ns;
185 }
186 
187 /*
188  * ��ӡtimer��ؼĴ�����ֵ
189  * @timer_info Ӳ����ʱ��
190  */
timer_print_regs(timer_info_t * timer_info)191 void timer_print_regs(timer_info_t *timer_info)
192 {
193     unsigned int timer_reg_base = 0;
194 
195     timer_reg_base = timer_get_reg_base(timer_info->timer);
196     printf("CNTR=0x%x, HRC=0x%x, LRC=0x%x, CTRL=0x%x\n",
197               reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR)),
198               reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC)),
199               reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_LRC)),
200               reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL)));
201 
202     return ;
203 }
204 
205 /*
206  * ��ʱ���ж���
207  * @timer_info ��ʱ����Ϣ
208  */
timer_int_clr(timer_info_t * timer_info)209 void timer_int_clr(timer_info_t *timer_info)
210 {
211     unsigned int timer_reg_base = 0;        // �Ĵ�������ַ
212     unsigned int ctrl ;
213 
214     // �ж����
215     if (NULL == timer_info)
216     {
217         return ;
218     }
219     timer_reg_base = timer_get_reg_base(timer_info->timer);     // ��ȡ�Ĵ�������ַ
220     ctrl = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
221     ctrl = ctrl | (1<<LS1C_PWM_INT_SR) ;
222     reg_write_32(ctrl , (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
223     ctrl = ctrl & (~(1<<LS1C_PWM_INT_SR))  ;
224     reg_write_32(ctrl , (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
225 
226     return ;
227 }
228 /*
229  * ��ʱ��������
230  * @timer_info ��ʱ����Ϣ
231  */
timer_cnt_clr(timer_info_t * timer_info)232 void timer_cnt_clr(timer_info_t *timer_info)
233 {
234     unsigned int timer_reg_base = 0;        // �Ĵ�������ַ
235     unsigned int ctrl ;
236 
237     // �ж����
238     if (NULL == timer_info)
239     {
240         return ;
241     }
242     timer_reg_base = timer_get_reg_base(timer_info->timer);     // ��ȡ�Ĵ�������ַ
243     ctrl = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
244     ctrl = ctrl | (1<<LS1C_PWM_CNTR_RST);
245     reg_write_32(ctrl , (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
246     ctrl = ctrl & (~(1<<LS1C_PWM_CNTR_RST)) ;
247     reg_write_32(ctrl , (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
248 
249     return ;
250 }
251 
252 /*
253  * ��ʼ����ʱ��������ʼ�ж϶�ʱ
254  * @timer_info ��ʱ���Ͷ�ʱʱ����Ϣ
255  * @hrc ���ж� lrc ���ж� Ϊ1����Ϊ0�ر�
256 */
timer_int_init(timer_info_t * timer_info,int hrc,int lrc)257 void timer_int_init(timer_info_t *timer_info, int hrc, int lrc)
258 {
259     unsigned int timer_reg_base = 0;        // �Ĵ�������ַ
260     unsigned long timer_clk = 0;            // Ӳ����ʱ����ʱ��
261     unsigned long h_value, l_value;
262     unsigned int ctrl = 0;                  // ���ƼĴ����еĿ�����Ϣ
263 
264     // �ж����
265     if (NULL == timer_info)
266     {
267         return ;
268     }
269 
270     /*
271      * �Ѷ�ʱʱ�任��Ϊ��������ֵ
272      * ������ֵ = ��ʱ����ʱ�� * ��ʱʱ��(��λns) / 1000000000
273      * ��о1c�Ķ�ʱ��ʱ��ΪAPBʱ�ӣ��ﵽ126Mhz��
274      * Ϊ���������̷����������������ֶ��Ż�����ļ���ʽ��Ҳ���Բ��ø�������
275      */
276     timer_clk = clk_get_apb_rate();
277     l_value = (timer_clk / 1000000) * (timer_info->time_ns / 1000);     // ��1000000000���Ϊ1000000��1000
278     l_value = MIN(l_value, TIMER_COUNTER_MAX);
279     h_value = (timer_clk / 1000000) * (timer_info->time_h_ns / 1000);     // ��1000000000���Ϊ1000000��1000
280     h_value = MIN(h_value, l_value);
281 
282     // ���ƼĴ�����Ϣ
283     ctrl = (lrc << LS1C_PWM_INT_LRC_EN)
284            | (hrc << LS1C_PWM_INT_HRC_EN)
285            | (0 << LS1C_PWM_CNTR_RST)
286            | (0 << LS1C_PWM_INT_SR)
287            | (1 << LS1C_PWM_INTEN)
288            | (1 << LS1C_PWM_SINGLE)
289            | (1 << LS1C_PWM_OE)
290            | (1 << LS1C_PWM_CNT_EN);
291 
292     // ���ø����Ĵ���
293     timer_reg_base = timer_get_reg_base(timer_info->timer);     // ��ȡ�Ĵ�������ַ
294     reg_write_32(0,                     (volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC));
295     reg_write_32(l_value--,                 (volatile unsigned int *)(timer_reg_base + LS1C_PWM_LRC));
296     reg_write_32(h_value--,                 (volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC));
297     reg_write_32(0,                     (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR));
298     reg_write_32(ctrl,                  (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
299 
300     return ;
301 }
302