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