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
16 #include "at_io.h"
17
18 #include <hi_stdlib.h>
19 #include <hi_at.h>
20 #include <at.h>
21 #include <hi_io.h>
22 #include <hi_gpio.h>
23 #include <hi_isr.h>
24
25 #ifdef __cplusplus
26 #if __cplusplus
27 extern "C" {
28 #endif
29 #endif
30
31 #define io_dir_get(cond, id, val_addr) \
32 if ((cond) & (hi_u16)(1 << (id))) { \
33 *(val_addr) = HI_GPIO_DIR_OUT; \
34 } else { \
35 *(val_addr) = HI_GPIO_DIR_IN; \
36 }
37
38 #define IO_MAX_WORK_MODE 7
39
gpio_get_dir(hi_gpio_idx id,hi_gpio_dir * dir)40 hi_u32 gpio_get_dir(hi_gpio_idx id, hi_gpio_dir *dir)
41 {
42 if (id >= HI_GPIO_IDX_MAX || dir == HI_NULL) {
43 return HI_ERR_GPIO_INVALID_PARAMETER;
44 }
45 hi_u32 int_val;
46 hi_u16 reg_val = 0;
47
48 int_val = hi_int_lock();
49 hi_reg_read16(0x50006004, reg_val);
50 io_dir_get(reg_val, (hi_u16) id, dir);
51 hi_int_restore(int_val);
52
53 return HI_ERR_SUCCESS;
54 }
55
at_setup_iosetmode_cmd(hi_s32 argc,const hi_char * argv[])56 hi_u32 at_setup_iosetmode_cmd(hi_s32 argc, const hi_char *argv[])
57 {
58 hi_io_name io_num;
59 hi_u8 io_mode;
60 hi_io_pull io_pull_stat;
61 hi_io_driver_strength io_power_level;
62 hi_u32 ret;
63 hi_s32 i;
64
65 if (argc < 3 || argc > 4) { /* argc 3/4 */
66 return HI_ERR_FAILURE;
67 }
68
69 for (i = 0; i < argc; i++) {
70 if (integer_check(argv[i]) != HI_ERR_SUCCESS) {
71 return HI_ERR_FAILURE;
72 }
73 }
74
75 io_num = (hi_io_name)atoi(argv[0]);
76 if (io_num > HI_IO_NAME_GPIO_14) {
77 return HI_ERR_FAILURE;
78 }
79
80 io_mode = (hi_u8)atoi(argv[1]);
81 if (io_mode > IO_MAX_WORK_MODE) {
82 return HI_ERR_FAILURE;
83 }
84
85 io_pull_stat = (hi_io_pull)atoi(argv[2]); /* argc 2 */
86 if (io_pull_stat > HI_IO_PULL_DOWN) {
87 return HI_ERR_FAILURE;
88 }
89
90 if (argc == 3) { /* argc 3 */
91 io_power_level = HI_IO_DRIVER_STRENGTH_3;
92 } else {
93 io_power_level = (hi_io_driver_strength)atoi(argv[3]); /* argc 3 */
94 }
95
96 ret = hi_io_set_func(io_num, io_mode);
97 if (ret != HI_ERR_SUCCESS) {
98 return HI_ERR_FAILURE;
99 }
100
101 ret = hi_io_set_pull(io_num, io_pull_stat);
102 if (ret != HI_ERR_SUCCESS) {
103 return HI_ERR_FAILURE;
104 }
105 ret = hi_io_set_driver_strength(io_num, io_power_level);
106 if (ret != HI_ERR_SUCCESS) {
107 return HI_ERR_FAILURE;
108 }
109
110 AT_RESPONSE_OK;
111 return HI_ERR_SUCCESS;
112 }
113
at_setup_iogetmode_cmd(hi_s32 argc,const hi_char * argv[])114 hi_u32 at_setup_iogetmode_cmd(hi_s32 argc, const hi_char *argv[])
115 {
116 hi_io_name io_num;
117 hi_u8 io_mode;
118 hi_io_pull io_pull_stat;
119 hi_io_driver_strength io_capalibity;
120 hi_u32 ret;
121
122 if (argc != 1) {
123 return HI_ERR_FAILURE;
124 }
125
126 if (integer_check(argv[0]) != HI_ERR_SUCCESS) {
127 return HI_ERR_FAILURE;
128 }
129
130 io_num = (hi_io_name)atoi(argv[0]);
131 if (io_num > HI_IO_NAME_GPIO_14) {
132 return HI_ERR_FAILURE;
133 }
134
135 ret = hi_io_get_func(io_num, &io_mode);
136 if (ret != HI_ERR_SUCCESS) {
137 return HI_ERR_FAILURE;
138 }
139
140 ret = hi_io_get_pull(io_num, &io_pull_stat);
141 if (ret != HI_ERR_SUCCESS) {
142 return HI_ERR_FAILURE;
143 }
144
145 ret = hi_io_get_driver_strength(io_num, &io_capalibity);
146 if (ret != HI_ERR_SUCCESS) {
147 return HI_ERR_FAILURE;
148 }
149
150 hi_at_printf("+GETIOMODE:%d,%d,%d,%d\r\n", io_num, io_mode, io_pull_stat, io_capalibity);
151 AT_RESPONSE_OK;
152 return HI_ERR_SUCCESS;
153 }
154
at_setup_gpiodir_cmd(hi_s32 argc,const hi_char * argv[])155 hi_u32 at_setup_gpiodir_cmd(hi_s32 argc, const hi_char *argv[])
156 {
157 hi_io_name io_num;
158 hi_gpio_dir io_dir;
159 hi_u8 io_mode;
160 hi_u32 ret;
161 hi_s32 i;
162
163 if (argc != 2) { /* argc 2 */
164 return HI_ERR_FAILURE;
165 }
166
167 for (i = 0; i < argc; i++) {
168 if (integer_check(argv[i]) != HI_ERR_SUCCESS) {
169 return HI_ERR_FAILURE;
170 }
171 }
172
173 io_num = (hi_io_name)atoi(argv[0]);
174 if (io_num > HI_IO_NAME_GPIO_14) {
175 return HI_ERR_FAILURE;
176 }
177
178 io_dir = (hi_gpio_dir)atoi(argv[1]);
179 if (io_dir > HI_GPIO_DIR_OUT) {
180 return HI_ERR_FAILURE;
181 }
182
183 ret = hi_io_get_func(io_num, &io_mode);
184 if (ret != HI_ERR_SUCCESS) {
185 return HI_ERR_FAILURE;
186 }
187
188 if ((io_num < HI_IO_NAME_GPIO_13) && (io_mode != 0)) {
189 return HI_ERR_FAILURE;
190 } else if ((io_num >= HI_IO_NAME_GPIO_13) && (io_mode != (hi_u8)HI_IO_FUNC_GPIO_13_GPIO)) {
191 return HI_ERR_FAILURE;
192 }
193
194 ret = hi_gpio_set_dir((hi_gpio_idx)io_num, io_dir);
195 if (ret != HI_ERR_SUCCESS) {
196 return HI_ERR_FAILURE;
197 }
198
199 AT_RESPONSE_OK;
200 return HI_ERR_SUCCESS;
201 }
202
at_setup_gpiowt_cmd(hi_s32 argc,const hi_char * argv[])203 hi_u32 at_setup_gpiowt_cmd(hi_s32 argc, const hi_char *argv[])
204 {
205 hi_io_name io_num;
206 hi_gpio_value io_level;
207 hi_u8 io_mode;
208 hi_gpio_dir io_dir;
209 hi_u32 ret;
210 hi_s32 i;
211
212 if (argc != 2) { /* argc 2 */
213 return HI_ERR_FAILURE;
214 }
215
216 for (i = 0; i < argc; i++) {
217 if (integer_check(argv[i]) != HI_ERR_SUCCESS) {
218 return HI_ERR_FAILURE;
219 }
220 }
221
222 io_num = (hi_io_name)atoi(argv[0]);
223 if (io_num > HI_IO_NAME_GPIO_14) {
224 return HI_ERR_FAILURE;
225 }
226
227 io_level = (hi_gpio_value)atoi(argv[1]);
228 if (io_level > HI_GPIO_VALUE1) {
229 return HI_ERR_FAILURE;
230 }
231
232 ret = hi_io_get_func(io_num, &io_mode);
233 if (ret != HI_ERR_SUCCESS) {
234 return HI_ERR_FAILURE;
235 }
236
237 if ((io_num < HI_IO_NAME_GPIO_13) && (io_mode != 0)) {
238 return HI_ERR_FAILURE;
239 } else if ((io_num >= HI_IO_NAME_GPIO_13) && (io_mode != (hi_u8)HI_IO_FUNC_GPIO_13_GPIO)) {
240 return HI_ERR_FAILURE;
241 }
242
243 ret = gpio_get_dir((hi_gpio_idx)io_num, &io_dir);
244 if ((ret != HI_ERR_SUCCESS) || (io_dir != HI_GPIO_DIR_OUT)) {
245 return HI_ERR_FAILURE;
246 }
247
248 ret = hi_gpio_set_ouput_val((hi_gpio_idx)io_num, io_level);
249 if (ret != HI_ERR_SUCCESS) {
250 return HI_ERR_FAILURE;
251 }
252
253 AT_RESPONSE_OK;
254 return HI_ERR_SUCCESS;
255 }
256
at_setup_gpiord_cmd(hi_s32 argc,const hi_char * argv[])257 hi_u32 at_setup_gpiord_cmd(hi_s32 argc, const hi_char *argv[])
258 {
259 hi_io_name io_num;
260 hi_gpio_value io_level;
261 hi_u8 io_mode;
262 hi_gpio_dir io_dir;
263 hi_u32 ret;
264
265 if (argc != 1) {
266 return HI_ERR_FAILURE;
267 }
268
269 if (integer_check(argv[0]) != HI_ERR_SUCCESS) {
270 return HI_ERR_FAILURE;
271 }
272
273 io_num = (hi_io_name)atoi(argv[0]);
274 if (io_num > HI_IO_NAME_GPIO_14) {
275 return HI_ERR_FAILURE;
276 }
277
278 ret = hi_io_get_func(io_num, &io_mode);
279 if (ret != HI_ERR_SUCCESS) {
280 return HI_ERR_FAILURE;
281 }
282
283 if ((io_num < HI_IO_NAME_GPIO_13) && (io_mode != 0)) {
284 return HI_ERR_FAILURE;
285 } else if ((io_num >= HI_IO_NAME_GPIO_13) && (io_mode != (hi_u8)HI_IO_FUNC_GPIO_13_GPIO)) {
286 return HI_ERR_FAILURE;
287 }
288
289 ret = gpio_get_dir((hi_gpio_idx)io_num, &io_dir);
290 if (ret != HI_ERR_SUCCESS) {
291 return HI_ERR_FAILURE;
292 }
293
294 ret = hi_gpio_get_input_val((hi_gpio_idx)io_num, &io_level);
295 if (ret != HI_ERR_SUCCESS) {
296 return HI_ERR_FAILURE;
297 }
298
299 hi_at_printf("+RDGPIO:%d,%d,%d\r\n", io_num, io_dir, io_level);
300 AT_RESPONSE_OK;
301 return HI_ERR_SUCCESS;
302 }
303
304 const at_cmd_func g_at_io_func_tbl[] = {
305 {"+SETIOMODE", 10, HI_NULL, HI_NULL, (at_call_back_func)at_setup_iosetmode_cmd, HI_NULL},
306 {"+GETIOMODE", 10, HI_NULL, HI_NULL, (at_call_back_func)at_setup_iogetmode_cmd, HI_NULL},
307 {"+GPIODIR", 8, HI_NULL, HI_NULL, (at_call_back_func)at_setup_gpiodir_cmd, HI_NULL},
308 {"+WTGPIO", 7, HI_NULL, HI_NULL, (at_call_back_func)at_setup_gpiowt_cmd, HI_NULL},
309 {"+RDGPIO", 7, HI_NULL, HI_NULL, (at_call_back_func)at_setup_gpiord_cmd, HI_NULL},
310 };
311
312 #define AT_IO_FUNC_NUM (sizeof(g_at_io_func_tbl) / sizeof(g_at_io_func_tbl[0]))
313
hi_at_io_cmd_register(void)314 void hi_at_io_cmd_register(void)
315 {
316 hi_at_register_cmd(g_at_io_func_tbl, AT_IO_FUNC_NUM);
317 }
318
319 #ifdef __cplusplus
320 #if __cplusplus
321 }
322 #endif
323 #endif
324