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