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