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 * 2017-09-06 ���� first version
9 */
10
11 // ��װӲ��pwm�ӿ�
12
13 #include "ls1c_public.h"
14 #include "ls1c_pin.h"
15 #include "ls1c_pwm.h"
16 #include "ls1c_clock.h"
17 #include "ls1c_regs.h"
18
19 // pwm���������
20 #define PWM_MAX_PERIOD (0xFFFFFF) // ��������ֵ
21
22 /*
23 * ����gpio��ȡ��Ӧpwm�Ļ���ַ
24 * @gpio pwm����
25 * @ret pwm����ַ
26 */
pwm_get_reg_base(unsigned int gpio)27 unsigned int pwm_get_reg_base(unsigned int gpio)
28 {
29 unsigned int reg_base = 0;
30
31 switch (gpio)
32 {
33 case LS1C_PWM0_GPIO06:
34 case LS1C_PWM0_GPIO04:
35 reg_base = LS1C_REG_BASE_PWM0;
36 break;
37
38 case LS1C_PWM1_GPIO92:
39 case LS1C_PWM1_GPIO05:
40 reg_base = LS1C_REG_BASE_PWM1;
41 break;
42
43 case LS1C_PWM2_GPIO52:
44 case LS1C_PWM2_GPIO46:
45 reg_base = LS1C_REG_BASE_PWM2;
46 break;
47
48 case LS1C_PWM3_GPIO47:
49 case LS1C_PWM3_GPIO53:
50 reg_base = LS1C_REG_BASE_PWM3;
51 break;
52 }
53
54 return reg_base;
55 }
56
57
58 /*
59 * ��ֹpwm
60 * @pwm_info PWMn����ϸ��Ϣ
61 */
pwm_disable(pwm_info_t * pwm_info)62 void pwm_disable(pwm_info_t *pwm_info)
63 {
64 unsigned int pwm_reg_base = 0;
65
66 // ������
67 if (NULL == pwm_info)
68 {
69 return ;
70 }
71
72 pwm_reg_base = pwm_get_reg_base(pwm_info->gpio);
73 reg_write_32(0, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CTRL));
74
75 return ;
76 }
77
78
79
80 /*
81 * ʹ��PWM
82 * @pwm_info PWMn����ϸ��Ϣ
83 */
pwm_enable(pwm_info_t * pwm_info)84 void pwm_enable(pwm_info_t *pwm_info)
85 {
86 unsigned int pwm_reg_base = 0;
87 unsigned int ctrl = 0;
88
89 // ������
90 if (NULL == pwm_info)
91 {
92 return ;
93 }
94
95 // ��ȡ����ַ
96 pwm_reg_base = pwm_get_reg_base(pwm_info->gpio);
97
98 // ���������
99 reg_write_32(0, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CNTR));
100
101 // ���ÿ��ƼĴ���
102 ctrl = (0 << LS1C_PWM_INT_LRC_EN)
103 | (0 << LS1C_PWM_INT_HRC_EN)
104 | (0 << LS1C_PWM_CNTR_RST)
105 | (0 << LS1C_PWM_INT_SR)
106 | (0 << LS1C_PWM_INTEN)
107 | (0 << LS1C_PWM_OE)
108 | (1 << LS1C_PWM_CNT_EN);
109 if (PWM_MODE_PULSE == pwm_info->mode) // ������
110 {
111 ctrl |= (1 << LS1C_PWM_SINGLE);
112 }
113 else // ��������
114 {
115 ctrl &= ~(1 << LS1C_PWM_SINGLE);
116 }
117 reg_write_32(ctrl, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CTRL));
118
119 return ;
120 }
121
122
123
124 /*
125 * ��ʼ��PWMn
126 * @pwm_info PWMn����ϸ��Ϣ
127 */
pwm_init(pwm_info_t * pwm_info)128 void pwm_init(pwm_info_t *pwm_info)
129 {
130 unsigned int gpio;
131 unsigned long pwm_clk = 0; // pwmģ���ʱ��Ƶ��
132 unsigned long tmp = 0;
133 unsigned int pwm_reg_base = 0;
134 unsigned long period = 0;
135
136 // ����
137 if (NULL == pwm_info)
138 {
139 // ��ηǷ�����ֱ�ӷ���
140 return ;
141 }
142 gpio = pwm_info->gpio;
143
144 // ������Ӧ��������pwm������gpio
145 pin_set_purpose(gpio, PIN_PURPOSE_OTHER);
146
147 // ����
148 switch (gpio)
149 {
150 // ����Ҫ����
151 case LS1C_PWM0_GPIO06:
152 case LS1C_PWM1_GPIO92:
153 break;
154
155 case LS1C_PWM0_GPIO04: // gpio04�ĵ�������
156 pin_set_remap(LS1C_PWM0_GPIO04, PIN_REMAP_THIRD);
157 break;
158
159 case LS1C_PWM1_GPIO05: // gpio05�ĵ�������
160 pin_set_remap(LS1C_PWM1_GPIO05, PIN_REMAP_THIRD);
161 break;
162
163 case LS1C_PWM2_GPIO52: // gpio52�ĵ��ĸ���
164 pin_set_remap(LS1C_PWM2_GPIO52, PIN_REMAP_FOURTH);
165 break;
166
167 case LS1C_PWM2_GPIO46: // gpio46�ĵ��ĸ���
168 pin_set_remap(LS1C_PWM2_GPIO46, PIN_REMAP_FOURTH);
169 break;
170
171 case LS1C_PWM3_GPIO47: // gpio47�ĵ��ĸ���
172 pin_set_remap(LS1C_PWM3_GPIO47, PIN_REMAP_FOURTH);
173 break;
174
175 case LS1C_PWM3_GPIO53: // gpio53�ĵ��ĸ���
176 pin_set_remap(LS1C_PWM3_GPIO53, PIN_REMAP_FOURTH);
177 break;
178
179 default:
180 break;
181 }
182
183 // ����ռ�ձȺ�pwm���ڼ���Ĵ���HRC��LRC��ֵ
184 // ����64λ����ˣ�ֻ�ܵõ���32λ��linux��ȴ���Եõ�64λ�����
185 // �ݲ����ԭ���ø����������
186 pwm_clk = clk_get_apb_rate();
187 period = (1.0 * pwm_clk * pwm_info->period_ns) / 1000000000;
188 period = MIN(period, PWM_MAX_PERIOD); // �������ڲ��ܳ������ֵ
189 tmp = period - (period * pwm_info->duty);
190
191 // д�Ĵ���HRC��LRC
192 pwm_reg_base = pwm_get_reg_base(gpio);
193 reg_write_32(--tmp, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_HRC));
194 reg_write_32(--period, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_LRC));
195
196 // �������
197 pwm_enable(pwm_info);
198
199 return ;
200 }
201
202