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
12 #include "ls1c_public.h"
13 #include "ls1c_regs.h"
14 #include "ls1c_gpio.h"
15 #include "ls1c_pin.h"
16
17
18 /*
19 * 获取指定gpio的CFG寄存器
20 * @gpio gpio编号
21 * @ret CFG寄存器
22 */
gpio_get_cfg_reg(unsigned int gpio)23 volatile unsigned int *gpio_get_cfg_reg(unsigned int gpio)
24 {
25 volatile unsigned int *gpio_cfgx = NULL; // GPIO_CFGx寄存器
26 unsigned int port = GPIO_GET_PORT(gpio);
27
28 switch (port)
29 {
30 case 0:
31 gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG0;
32 break;
33
34 case 1:
35 gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG1;
36 break;
37
38 case 2:
39 gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG2;
40 break;
41
42 case 3:
43 gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG3;
44 break;
45
46 default:
47 gpio_cfgx = NULL;
48 break;
49 }
50
51 return gpio_cfgx;
52 }
53
54
55 /*
56 * 获取指定gpio的EN寄存器
57 * @gpio gpio编号
58 * @ret EN寄存器
59 */
gpio_get_en_reg(unsigned int gpio)60 volatile unsigned int *gpio_get_en_reg(unsigned int gpio)
61 {
62 volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
63 unsigned int port = GPIO_GET_PORT(gpio);
64
65 switch (port)
66 {
67 case 0:
68 gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN0;
69 break;
70
71 case 1:
72 gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN1;
73 break;
74
75 case 2:
76 gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN2;
77 break;
78
79 case 3:
80 gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN3;
81 break;
82
83 default:
84 gpio_enx = NULL;
85 return gpio_enx;
86 }
87
88 return gpio_enx;
89 }
90
91 /*
92 * gpio初始化
93 * @gpio gpio引脚,取值范围[0, 127]
94 * @mode gpio的工作模式(输入、输出)
95 *
96 * 例: 将gpio50初始化为输出
97 * gpio_init(50, gpio_mode_output);
98 */
gpio_init(unsigned int gpio,gpio_mode_t mode)99 void gpio_init(unsigned int gpio, gpio_mode_t mode)
100 {
101 volatile unsigned int *gpio_enx = NULL; // GPIO_ENx寄存器
102 unsigned int pin = GPIO_GET_PIN(gpio);
103
104 // 将pin设为普通GPIO
105 pin_set_purpose(gpio, PIN_PURPOSE_GPIO);
106
107 // 设置gpio工作模式(输入、输出)
108 gpio_enx = gpio_get_en_reg(gpio);
109 if (gpio_mode_output == mode) // 输出
110 {
111 reg_clr_one_bit(gpio_enx, pin);
112 }
113 else // 输入
114 {
115 reg_set_one_bit(gpio_enx, pin);
116 }
117
118 return ;
119 }
120
121
122 /*
123 * 在指定gpio输出高电平或低电平
124 * @gpio gpio引脚,取值范围[0, 127]
125 * @level 电平值
126 *
127 * 例: 在gpio50上输出低电平
128 * gpio_set(50, gpio_level_low);
129 */
gpio_set(unsigned int gpio,gpio_level_t level)130 void gpio_set(unsigned int gpio, gpio_level_t level)
131 {
132 volatile unsigned int *gpio_outx = NULL; // GPIO_OUTx寄存器
133 unsigned int port = GPIO_GET_PORT(gpio);
134 unsigned int pin = GPIO_GET_PIN(gpio);
135
136 // 获取寄存器地址
137 switch (port)
138 {
139 case 0:
140 gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT0;
141 break;
142
143 case 1:
144 gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT1;
145 break;
146
147 case 2:
148 gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT2;
149 break;
150
151 case 3:
152 gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT3;
153 break;
154
155 default: // 正确的程序不应该走到这里,直接返回
156 return ;
157 }
158
159 // 输出
160 if (gpio_level_low == level)
161 {
162 reg_clr_one_bit(gpio_outx, pin);
163 }
164 else
165 {
166 reg_set_one_bit(gpio_outx, pin);
167 }
168
169 return ;
170 }
171
172
173 /*
174 * 读取指定gpio引脚的值
175 * @gpio gpio引脚,取值范围[0,127]
176 *
177 * 例: 读取gpio50引脚上的值
178 * gpio_level_t level;
179 * level = gpio_get(50);
180 */
gpio_get(unsigned int gpio)181 unsigned int gpio_get(unsigned int gpio)
182 {
183 volatile unsigned int *gpio_inx = NULL; // GPIO_INx寄存器
184 unsigned int port = GPIO_GET_PORT(gpio);
185 unsigned int pin = GPIO_GET_PIN(gpio);
186
187 // 获取寄存器地址
188 switch (port)
189 {
190 case 0:
191 gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN0;
192 break;
193
194 case 1:
195 gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN1;
196 break;
197
198 case 2:
199 gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN2;
200 break;
201
202 case 3:
203 gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN3;
204 break;
205
206 default: // 正常的流程不应该走到这里,直接返回
207 return 0;
208 }
209
210 // 读取
211 return reg_get_bit(gpio_inx, pin);
212 }
213
214
215 /**
216 * 设置中断类型
217 * @gpio gpio引脚
218 * @type 触发中断的条件。高电平触发、低电平触发、上升沿触发 or 下降沿触发
219 */
gpio_set_irq_type(unsigned int gpio,gpio_irq_type_t type)220 void gpio_set_irq_type(unsigned int gpio, gpio_irq_type_t type)
221 {
222 volatile unsigned int *int_pol = NULL; // 中断极性选择寄存器
223 volatile unsigned int *int_edge = NULL; // 中断边沿选择寄存器
224 unsigned int port = GPIO_GET_PORT(gpio);
225 unsigned int pin = GPIO_GET_PIN(gpio);
226
227 // 获取寄存器地址
228 switch (port)
229 {
230 case 0: // GPIO[31:0]
231 int_pol = (volatile unsigned int *)LS1C_INT2_POL;
232 int_edge = (volatile unsigned int *)LS1C_INT2_EDGE;
233 break;
234
235 case 1: // GPIO[63:32]
236 int_pol = (volatile unsigned int *)LS1C_INT3_POL;
237 int_edge = (volatile unsigned int *)LS1C_INT3_EDGE;
238 break;
239
240 case 2: // GPIO[95:64]
241 int_pol = (volatile unsigned int *)LS1C_INT4_POL;
242 int_edge = (volatile unsigned int *)LS1C_INT4_EDGE;
243 break;
244 }
245
246 // 设置中断类型
247 switch (type)
248 {
249 case IRQ_TYPE_EDGE_RISING:
250 *int_pol |= (1 << pin);
251 *int_edge |= (1 << pin);
252 break;
253
254 case IRQ_TYPE_EDGE_FALLING:
255 *int_pol &= ~(1 << pin);
256 *int_edge |= (1 << pin);
257 break;
258
259 case IRQ_TYPE_LEVEL_HIGH:
260 *int_pol |= (1 << pin);
261 *int_edge &= ~(1 << pin);
262 break;
263
264 case IRQ_TYPE_LEVEL_LOW:
265 *int_pol &= ~(1 << pin);
266 *int_edge &= ~(1 << pin);
267 break;
268
269 default:
270 break;
271 }
272
273 return ;
274 }
275
276
277
278