1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: Provides V150 HAL gpio \n
16 *
17 * History: \n
18 * 2022-11-26, Create file. \n
19 */
20
21 #include <stdint.h>
22 #include "interrupt/osal_interrupt.h"
23 #include "common_def.h"
24 #include "gpio_porting.h"
25 #include "hal_gpio_v150.h"
26
27 #pragma weak hal_gpio_init = hal_gpio_v150_init
hal_gpio_v150_init(void)28 void hal_gpio_v150_init(void)
29 {
30 uint32_t channel, group;
31
32 hal_gpio_regs_init();
33 hal_gpio_v150_callback_list_clean();
34 for (channel = GPIO_CHANNEL_0; channel < GPIO_CHANNEL_MAX_NUM; channel++) {
35 for (group = 0; group < hal_gpio_v150_group_num_get(channel); group++) {
36 hal_gpio_v150_intr_rebase(channel, group);
37 }
38 gpio_porting_channel_context_clean(channel, hal_gpio_v150_group_num_get(channel));
39 hal_gpio_v150_register_irq(hal_gpio_v150_irq_num_get(channel));
40 }
41 }
42
43 #pragma weak hal_gpio_deinit = hal_gpio_v150_deinit
hal_gpio_v150_deinit(void)44 void hal_gpio_v150_deinit(void)
45 {
46 uint32_t channel, group;
47
48 for (channel = GPIO_CHANNEL_0; channel < GPIO_CHANNEL_MAX_NUM; channel++) {
49 hal_gpio_v150_unregister_irq(hal_gpio_v150_irq_num_get(channel));
50 gpio_porting_channel_context_clean(channel, hal_gpio_v150_group_num_get(channel));
51 for (group = 0; group < hal_gpio_v150_group_num_get(channel); group++) {
52 hal_gpio_v150_intr_rebase(channel, group);
53 }
54 }
55 hal_gpio_v150_callback_list_clean();
56 }
57
58 #pragma weak hal_gpio_setdir = hal_gpio_v150_setdir
hal_gpio_v150_setdir(pin_t pin,gpio_direction_t dir)59 errcode_t hal_gpio_v150_setdir(pin_t pin, gpio_direction_t dir)
60 {
61 if (dir != GPIO_DIRECTION_INPUT && dir != GPIO_DIRECTION_OUTPUT) {
62 return ERRCODE_INVALID_PARAM;
63 }
64
65 errcode_t ret;
66 uint32_t channel, group, group_pin;
67 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
68 if (ret != ERRCODE_SUCC) {
69 return ret;
70 }
71
72 if (dir == GPIO_DIRECTION_INPUT) {
73 // 输入模式默认使能去毛刺
74 hal_gpio_gpio_int_debounce_set_bit(channel, group, group_pin, HAL_GPIO_DEBOUNCE_ENABLED);
75 hal_gpio_gpio_sw_oen_set_bit(channel, group, group_pin, HAL_GPIO_DIRECTION_INPUT);
76 } else {
77 hal_gpio_gpio_int_debounce_set_bit(channel, group, group_pin, HAL_GPIO_DEBOUNCE_DISABLED);
78 hal_gpio_gpio_sw_oen_set_bit(channel, group, group_pin, HAL_GPIO_DIRECTION_OUTPUT);
79 }
80
81 return ERRCODE_SUCC;
82 }
83
84 #pragma weak hal_gpio_getdir = hal_gpio_v150_getdir
hal_gpio_v150_getdir(pin_t pin)85 gpio_direction_t hal_gpio_v150_getdir(pin_t pin)
86 {
87 errcode_t ret;
88 gpio_direction_t direction;
89 uint32_t channel, group, group_pin;
90 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
91 if (ret != ERRCODE_SUCC) {
92 return ret;
93 }
94 direction = hal_gpio_gpio_sw_oen_get_bit(channel, group, group_pin);
95 if (direction == (gpio_direction_t)HAL_GPIO_DIRECTION_OUTPUT) {
96 direction = GPIO_DIRECTION_OUTPUT;
97 } else {
98 direction = GPIO_DIRECTION_INPUT;
99 }
100
101 return direction;
102 }
103
hal_gpio_v150_set_output(uint32_t channel,uint32_t group,uint32_t group_pin,gpio_level_t level)104 static void hal_gpio_v150_set_output(uint32_t channel, uint32_t group, uint32_t group_pin, gpio_level_t level)
105 {
106 if (level == GPIO_LEVEL_LOW) {
107 hal_gpio_gpio_data_clr_set_bit(channel, group, group_pin, HAL_GPIO_LEVEL_HIGH);
108 } else {
109 hal_gpio_gpio_data_set_set_bit(channel, group, group_pin, HAL_GPIO_LEVEL_HIGH);
110 }
111 }
112
113 #pragma weak hal_gpio_output = hal_gpio_v150_output
hal_gpio_v150_output(pin_t pin,gpio_level_t level)114 errcode_t hal_gpio_v150_output(pin_t pin, gpio_level_t level)
115 {
116 if (level != GPIO_LEVEL_LOW && level != GPIO_LEVEL_HIGH) {
117 return ERRCODE_INVALID_PARAM;
118 }
119
120 errcode_t ret;
121 uint32_t channel, group, group_pin;
122 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
123 if (ret != ERRCODE_SUCC) {
124 return ret;
125 }
126
127 if (hal_gpio_gpio_sw_oen_get_bit(channel, group, group_pin) != HAL_GPIO_DIRECTION_OUTPUT) {
128 return ERRCODE_GPIO_STATE_MISMATCH;
129 }
130
131 hal_gpio_v150_set_output(channel, group, group_pin, level);
132 return ERRCODE_SUCC;
133 }
134
135 #pragma weak hal_gpio_get_outval = hal_gpio_v150_get_outval
hal_gpio_v150_get_outval(pin_t pin)136 gpio_level_t hal_gpio_v150_get_outval(pin_t pin)
137 {
138 gpio_level_t level;
139 errcode_t ret;
140 uint32_t channel, group, group_pin;
141 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
142 if (ret != ERRCODE_SUCC) {
143 return ret;
144 }
145 level = (gpio_level_t)hal_gpio_gpio_sw_out_get_bit(channel, group, group_pin);
146 return level;
147 }
148
149 #pragma weak hal_gpio_get_inval = hal_gpio_v150_get_inval
hal_gpio_v150_get_inval(pin_t pin)150 gpio_level_t hal_gpio_v150_get_inval(pin_t pin)
151 {
152 errcode_t ret;
153 uint32_t channel, group, group_pin, hal_level;
154 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
155 if (ret != ERRCODE_SUCC) {
156 return GPIO_LEVEL_LOW;
157 }
158
159 hal_level = hal_gpio_gpio_sw_out_get_bit(channel, group, group_pin);
160 return (hal_level == HAL_GPIO_LEVEL_HIGH) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
161 }
162
163 #pragma weak hal_gpio_unregister = hal_gpio_v150_unregister
hal_gpio_v150_unregister(pin_t pin)164 errcode_t hal_gpio_v150_unregister(pin_t pin)
165 {
166 errcode_t ret;
167 uint32_t channel, group, group_pin;
168 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
169 if (ret != ERRCODE_SUCC) {
170 return ret;
171 }
172
173 // 屏蔽中断
174 hal_gpio_gpio_int_mask_set_bit(channel, group, group_pin, HAL_GPIO_INTR_MASK);
175 hal_gpio_gpio_int_eoi_set_bit(channel, group, group_pin, HAL_GPIO_INTR_CLEAR);
176
177 // 去注册中断回调
178 hal_gpio_v150_unregister_cb(channel, group, group_pin);
179 return ERRCODE_SUCC;
180 }
181
hal_gpio_v150_ctrl_toggle(pin_t pin,hal_gpio_ctrl_id_t id)182 static errcode_t hal_gpio_v150_ctrl_toggle(pin_t pin, hal_gpio_ctrl_id_t id)
183 {
184 unused(id);
185
186 errcode_t ret;
187 uint32_t channel, group, group_pin;
188 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
189 if (ret != ERRCODE_SUCC) {
190 return ret;
191 }
192
193 if (hal_gpio_gpio_sw_oen_get_bit(channel, group, group_pin) != HAL_GPIO_DIRECTION_OUTPUT) {
194 return ERRCODE_GPIO_STATE_MISMATCH;
195 }
196
197 uint32_t level = hal_gpio_gpio_sw_out_get_bit(channel, group, group_pin);
198 hal_gpio_v150_set_output(channel, group, group_pin, HAL_GPIO_LEVEL_HIGH - level);
199 return ERRCODE_SUCC;
200 }
201
hal_gpio_v150_ctrl_enable_interrupt(pin_t pin,hal_gpio_ctrl_id_t id)202 static errcode_t hal_gpio_v150_ctrl_enable_interrupt(pin_t pin, hal_gpio_ctrl_id_t id)
203 {
204 unused(id);
205
206 errcode_t ret;
207 uint32_t channel, group, group_pin;
208 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
209 if (ret != ERRCODE_SUCC) {
210 return ret;
211 }
212 if (hal_gpio_gpio_get_int_en(channel, group) == 0) {
213 osal_irq_enable(hal_gpio_v150_irq_num_get(channel));
214 }
215 hal_gpio_gpio_int_en_set_bit(channel, group, group_pin, HAL_GPIO_INTR_ENABLE);
216
217 return ERRCODE_SUCC;
218 }
219
hal_gpio_v150_ctrl_disable_interrupt(pin_t pin,hal_gpio_ctrl_id_t id)220 static errcode_t hal_gpio_v150_ctrl_disable_interrupt(pin_t pin, hal_gpio_ctrl_id_t id)
221 {
222 unused(id);
223
224 errcode_t ret;
225 uint32_t channel, group, group_pin;
226 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
227 if (ret != ERRCODE_SUCC) {
228 return ret;
229 }
230
231 hal_gpio_gpio_int_en_set_bit(channel, group, group_pin, HAL_GPIO_INTR_DISABLE);
232 if (hal_gpio_gpio_get_int_en(channel, group) == 0) {
233 osal_irq_disable(hal_gpio_v150_irq_num_get(channel));
234 }
235
236 return ERRCODE_SUCC;
237 }
238
hal_gpio_v150_ctrl_clear_interrupt(pin_t pin,hal_gpio_ctrl_id_t id)239 static errcode_t hal_gpio_v150_ctrl_clear_interrupt(pin_t pin, hal_gpio_ctrl_id_t id)
240 {
241 unused(id);
242
243 errcode_t ret;
244 uint32_t channel, group, group_pin;
245 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
246 if (ret != ERRCODE_SUCC) {
247 return ret;
248 }
249
250 hal_gpio_gpio_int_eoi_set_bit(channel, group, group_pin, HAL_GPIO_INTR_CLEAR);
251 osal_irq_clear(hal_gpio_v150_irq_num_get(channel));
252
253 return ERRCODE_SUCC;
254 }
255
256 #pragma weak hal_gpio_register = hal_gpio_v150_register
hal_gpio_v150_register(pin_t pin,uint32_t trigger,gpio_callback_t callback,bool need_callback)257 errcode_t hal_gpio_v150_register(pin_t pin, uint32_t trigger, gpio_callback_t callback, bool need_callback)
258 {
259 if ((need_callback == true && callback == NULL) || (need_callback == false && callback != NULL)) {
260 return ERRCODE_INVALID_PARAM;
261 }
262 errcode_t ret;
263 uint32_t channel, group, group_pin;
264 ret = hal_gpio_v150_pin_info_get(pin, &channel, &group, &group_pin);
265 if (ret != ERRCODE_SUCC) { return ret; }
266 if (need_callback) {
267 // 注册中断回调
268 ret = hal_gpio_v150_register_cb(channel, group, group_pin, callback);
269 if (ret != ERRCODE_SUCC) {
270 return ret;
271 }
272 }
273 // 屏蔽中断
274 hal_gpio_gpio_int_mask_set_bit(channel, group, group_pin, HAL_GPIO_INTR_MASK);
275 hal_gpio_gpio_int_eoi_set_bit(channel, group, group_pin, HAL_GPIO_INTR_CLEAR);
276 // 配置中断极性
277 switch (trigger) {
278 case GPIO_INTERRUPT_LOW:
279 hal_gpio_gpio_int_type_set_bit(channel, group, group_pin, GPIO_LVL_LEVEL_SENSITIVE);
280 hal_gpio_v150_gpio_int_polarity_set_bit(channel, group, group_pin, GPIO_ACTIVE_LOW);
281 hal_gpio_gpio_int_dedge_set_bit(channel, group, group_pin, GPIO_DEDGE_DISABLED);
282 break;
283 case GPIO_INTERRUPT_HIGH:
284 hal_gpio_gpio_int_type_set_bit(channel, group, group_pin, GPIO_LVL_LEVEL_SENSITIVE);
285 hal_gpio_v150_gpio_int_polarity_set_bit(channel, group, group_pin, GPIO_ACTIVE_HIGH);
286 hal_gpio_gpio_int_dedge_set_bit(channel, group, group_pin, GPIO_DEDGE_DISABLED);
287 break;
288 case GPIO_INTERRUPT_FALLING_EDGE:
289 hal_gpio_gpio_int_type_set_bit(channel, group, group_pin, GPIO_LVL_EDGE_SENSITIVE);
290 hal_gpio_v150_gpio_int_polarity_set_bit(channel, group, group_pin, GPIO_ACTIVE_LOW);
291 hal_gpio_gpio_int_dedge_set_bit(channel, group, group_pin, GPIO_DEDGE_DISABLED);
292 break;
293 case GPIO_INTERRUPT_RISING_EDGE:
294 hal_gpio_gpio_int_type_set_bit(channel, group, group_pin, GPIO_LVL_EDGE_SENSITIVE);
295 hal_gpio_v150_gpio_int_polarity_set_bit(channel, group, group_pin, GPIO_ACTIVE_HIGH);
296 hal_gpio_gpio_int_dedge_set_bit(channel, group, group_pin, GPIO_DEDGE_DISABLED);
297 break;
298 case GPIO_INTERRUPT_DEDGE:
299 hal_gpio_gpio_int_type_set_bit(channel, group, group_pin, GPIO_LVL_EDGE_SENSITIVE);
300 hal_gpio_v150_gpio_int_polarity_set_bit(channel, group, group_pin, GPIO_ACTIVE_LOW);
301 hal_gpio_gpio_int_dedge_set_bit(channel, group, group_pin, GPIO_DEDGE_ENABLED);
302 break;
303 default:
304 hal_gpio_v150_unregister_cb(channel, group, group_pin);
305 return ERRCODE_INVALID_PARAM;
306 }
307 // 去屏蔽中断
308 hal_gpio_gpio_int_mask_set_bit(channel, group, group_pin, HAL_GPIO_INTR_UNMASK);
309 // 继承原逻辑, 注册回调后默认使能中断
310 hal_gpio_v150_ctrl_enable_interrupt(pin, GPIO_CTRL_ENABLE_INTERRUPT);
311 return ERRCODE_SUCC;
312 }
313
314 #if defined(CONFIG_GPIO_SUPPORT_LPM)
hal_gpio_v150_ctrl_suspend(pin_t pin,hal_gpio_ctrl_id_t id)315 static errcode_t hal_gpio_v150_ctrl_suspend(pin_t pin, hal_gpio_ctrl_id_t id)
316 {
317 unused(pin);
318 unused(id);
319
320 return ERRCODE_SUCC;
321 }
322
hal_gpio_v150_ctrl_resume(pin_t pin,hal_gpio_ctrl_id_t id)323 static errcode_t hal_gpio_v150_ctrl_resume(pin_t pin, hal_gpio_ctrl_id_t id)
324 {
325 unused(pin);
326 unused(id);
327
328 return ERRCODE_SUCC;
329 }
330 #endif
331
332 static hal_gpio_ctrl_t g_hal_gpio_ctrl_func_array[GPIO_CTRL_MAX] = {
333 hal_gpio_v150_ctrl_toggle, /* uapi_gpio_toggle */
334 hal_gpio_v150_ctrl_enable_interrupt, /* uapi_gpio_enable_interrupt */
335 hal_gpio_v150_ctrl_disable_interrupt, /* uapi_gpio_disable_interrupt */
336 hal_gpio_v150_ctrl_clear_interrupt, /* uapi_gpio_clear_interrupt */
337 #if defined(CONFIG_GPIO_SUPPORT_LPM)
338 hal_gpio_v150_ctrl_suspend, /* GPIO_CTRL_SUSPEND */
339 hal_gpio_v150_ctrl_resume /* GPIO_CTRL_RESUME */
340 #endif
341 };
342
343 #pragma weak hal_gpio_ctrl = hal_gpio_v150_ctrl
hal_gpio_v150_ctrl(pin_t pin,hal_gpio_ctrl_id_t id)344 errcode_t hal_gpio_v150_ctrl(pin_t pin, hal_gpio_ctrl_id_t id)
345 {
346 return g_hal_gpio_ctrl_func_array[id](pin, id);
347 }