1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "aos_hal_gpio.h"
6 #include "board_mgr.h"
7 #include "py/builtin.h"
8 #include "py/gc.h"
9 #include "py/mperrno.h"
10 #include "py/obj.h"
11 #include "py/runtime.h"
12 #include "py/stackctrl.h"
13 #include "ulog/ulog.h"
14
15 #define LOG_TAG "DRIVER_GPIO"
16
17 extern const mp_obj_type_t driver_gpio_type;
18
19 typedef enum {
20 IRQ_RISING_EDGE = 0x1, /**< Interrupt triggered at input signal's rising edge */
21 IRQ_FALLING_EDGE = 0x2, /**< Interrupt triggered at input signal's falling edge */
22 IRQ_BOTH_EDGES = IRQ_RISING_EDGE | IRQ_FALLING_EDGE,
23 } gpio_irq_trigger_params_t;
24
25 // this is the actual C-structure for our new object
26 typedef struct {
27 // base represents some basic information, like type
28 mp_obj_base_t Base;
29 // a member created by us
30 char *ModuleName;
31 item_handle_t gpio_handle;
32 gpio_dev_t *gpio_device;
33 mp_obj_t callback;
34 } mp_gpio_obj_t;
35
gpio_driver_irq_handler(int polarity,void * arg)36 void gpio_driver_irq_handler(int polarity, void *arg)
37 {
38 mp_gpio_obj_t *self = (mp_gpio_obj_t *)arg;
39 if (self->callback != mp_const_none) {
40 callback_to_python(self->callback, self);
41 }
42 }
43
gpio_obj_print(const mp_print_t * print,mp_obj_t self_in,mp_print_kind_t kind)44 void gpio_obj_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
45 {
46 mp_gpio_obj_t *self = MP_OBJ_TO_PTR(self_in);
47 mp_printf(print, "ModuleName(%s)", self->ModuleName);
48 }
49
gpio_obj_make_new(const mp_obj_type_t * type,size_t n_args,size_t n_kw,const mp_obj_t * args)50 STATIC mp_obj_t gpio_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args)
51 {
52 mp_gpio_obj_t *driver_obj = m_new_obj(mp_gpio_obj_t);
53 if (!driver_obj) {
54 LOGE(LOG_TAG, "%s: alloc mem failed;\n", __func__);
55 mp_raise_OSError(ENOMEM);
56 }
57
58 driver_obj->Base.type = &driver_gpio_type;
59 driver_obj->ModuleName = "gpio";
60 driver_obj->gpio_handle.handle = NULL;
61 driver_obj->gpio_device = NULL;
62
63 return MP_OBJ_FROM_PTR(driver_obj);
64 }
65
obj_open(size_t n_args,const mp_obj_t * args)66 STATIC mp_obj_t obj_open(size_t n_args, const mp_obj_t *args)
67 {
68 if (n_args != 2) {
69 LOGE(LOG_TAG, "%s: illegal args;\n", __func__);
70 mp_raise_OSError(EINVAL);
71 }
72 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
73 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
74 if (driver_obj == NULL) {
75 LOGE(LOG_TAG, "driver_obj is NULL\n");
76 mp_raise_OSError(EINVAL);
77 }
78
79 if (driver_obj->gpio_device != NULL) {
80 LOGE(LOG_TAG, "device hass opened\n");
81 return MP_ROM_INT(-ENXIO);
82 }
83
84 int ret = -1;
85 gpio_dev_t *gpio_device = NULL;
86 char *id = (char *)mp_obj_str_get_str(args[1]);
87
88 if (id == NULL) {
89 LOGE(LOG_TAG, "%s:illegal par id =%s;\n", __func__, id);
90 mp_raise_OSError(EINVAL);
91 }
92
93 if (py_board_mgr_init() != 0) {
94 LOGE(LOG_TAG, "%s:py_board_mgr_init failed\n", __func__);
95 mp_raise_OSError(EINVAL);
96 }
97
98 if (py_board_attach_item(MODULE_GPIO, id, &(driver_obj->gpio_handle)) != 0) {
99 LOGE(LOG_TAG, "%s: py_board_attach_item failed ret = %d;\n", __func__, ret);
100 py_board_disattach_item(MODULE_GPIO, &(driver_obj->gpio_handle));
101 mp_raise_OSError(EINVAL);
102 }
103
104 gpio_device = py_board_get_node_by_handle(MODULE_GPIO, &(driver_obj->gpio_handle));
105 if (NULL == gpio_device) {
106 LOGE(LOG_TAG, "%s: py_board_get_node_by_handle failed;\n", __func__);
107 py_board_disattach_item(MODULE_GPIO, &(driver_obj->gpio_handle));
108 gpio_device = NULL;
109 mp_raise_OSError(EINVAL);
110 }
111 driver_obj->gpio_device = gpio_device;
112
113
114 ret = aos_hal_gpio_init(gpio_device);
115 if (ret) {
116 mp_raise_OSError(ret);
117 }
118
119 return MP_ROM_INT(0);
120 }
121 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(gpio_obj_open, 2, obj_open);
122
obj_close(size_t n_args,const mp_obj_t * args)123 STATIC mp_obj_t obj_close(size_t n_args, const mp_obj_t *args)
124 {
125 int ret = -1;
126 if (n_args < 1) {
127 LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__, n_args);
128 return MP_ROM_INT(-EINVAL);
129 }
130 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
131 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
132 if (driver_obj == NULL) {
133 LOGE(LOG_TAG, "driver_obj is NULL\n");
134 return MP_ROM_INT(-EINVAL);
135 }
136 if (NULL == driver_obj->gpio_device) {
137 LOGE(LOG_TAG, "driver_obj has closed\n");
138 return MP_ROM_INT(-ENXIO);
139 }
140
141 ret = aos_hal_gpio_finalize(driver_obj->gpio_device);
142 if (ret != 0) {
143 LOGE(LOG_TAG, "%s: aos_hal_gpio_finalize failed;\n", __func__);
144 return MP_ROM_INT(-EINVAL);
145 }
146 py_board_disattach_item(MODULE_GPIO, &(driver_obj->gpio_handle));
147 driver_obj->gpio_device = NULL;
148 return MP_ROM_INT(0);
149 }
150 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(gpio_obj_close, 1, obj_close);
151
obj_read(size_t n_args,const mp_obj_t * args)152 STATIC mp_obj_t obj_read(size_t n_args, const mp_obj_t *args)
153 {
154 int ret = -1;
155 uint32_t level = 0;
156 if (n_args < 1) {
157 LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__, n_args);
158 return MP_ROM_INT(-EINVAL);
159 }
160 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
161 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
162 if (NULL == driver_obj) {
163 LOGE(LOG_TAG, "driver_obj is NULL\n");
164 return MP_ROM_INT(-EINVAL);
165 }
166 if (NULL == driver_obj->gpio_device) {
167 LOGE(LOG_TAG, "driver_obj has closed\n");
168 return MP_ROM_INT(-ENXIO);
169 }
170
171 level = aos_hal_gpio_get(driver_obj->gpio_device);
172
173 return MP_ROM_INT(level);
174 }
175 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(gpio_obj_read, 1, obj_read);
176
obj_write(size_t n_args,const mp_obj_t * args)177 STATIC mp_obj_t obj_write(size_t n_args, const mp_obj_t *args)
178 {
179 int ret = -1;
180 uint32_t level = 0;
181 if (n_args < 2) {
182 LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__, n_args);
183 return MP_ROM_INT(-EINVAL);
184 }
185 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
186 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
187 if (NULL == driver_obj) {
188 LOGE(LOG_TAG, "driver_obj is NULL\n");
189 return MP_ROM_INT(-EINVAL);
190 }
191 if (NULL == driver_obj->gpio_device) {
192 LOGE(LOG_TAG, "driver_obj has closed\n");
193 return MP_ROM_INT(-ENXIO);
194 }
195
196 level = (uint32_t)mp_obj_get_int(args[1]);
197
198 if (level) {
199 ret = aos_hal_gpio_output_high(driver_obj->gpio_device);
200 } else {
201 ret = aos_hal_gpio_output_low(driver_obj->gpio_device);
202 }
203
204 return MP_ROM_INT(ret);
205 }
206 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(gpio_obj_write, 2, obj_write);
207
obj_toggle(size_t n_args,const mp_obj_t * args)208 STATIC mp_obj_t obj_toggle(size_t n_args, const mp_obj_t *args)
209 {
210 int ret = -1;
211 if (n_args < 1) {
212 LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__, n_args);
213 return MP_ROM_INT(-EINVAL);
214 }
215 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
216 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
217 if (driver_obj == NULL) {
218 LOGE(LOG_TAG, "driver_obj is NULL\n");
219 return MP_ROM_INT(-EINVAL);
220 }
221
222 ret = aos_hal_gpio_output_toggle(driver_obj->gpio_device);
223 if (ret == -1) {
224 LOGE(LOG_TAG, "aos_hal_gpio_output_toggle failed\n");
225 }
226
227 return MP_ROM_INT(ret);
228 }
229 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR(gpio_obj_toggle, 1, obj_toggle);
230
obj_on(size_t n_args,const mp_obj_t * args)231 STATIC mp_obj_t obj_on(size_t n_args, const mp_obj_t *args)
232 {
233 int ret = -1;
234 uint32_t irq_edge = 0;
235 if (n_args < 2 || args[1] == mp_const_none) {
236 LOGE(LOG_TAG, "%s: args num is illegal :n_args = %d;\n", __func__, n_args);
237 return MP_ROM_INT(-EINVAL);
238 }
239 mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
240 mp_gpio_obj_t *driver_obj = (mp_gpio_obj_t *)self;
241 if (driver_obj == NULL) {
242 LOGE(LOG_TAG, "driver_obj is NULL\n");
243 return MP_ROM_INT(-EINVAL);
244 }
245 if (driver_obj->gpio_device == NULL) {
246 LOGE(LOG_TAG, "driver_obj has closed\n");
247 return MP_ROM_INT(-ENXIO);
248 }
249
250 driver_obj->callback = args[1];
251
252 // judge callback function if callback == None disable IQR
253 // ret = aos_hal_gpio_clear_irq(driver_obj->gpio_device);
254 gpio_params_t *priv = (gpio_params_t *)driver_obj->gpio_device->priv;
255
256 driver_obj->callback = args[1];
257 if (n_args == 3) {
258 irq_edge = (uint32_t)mp_obj_get_int(args[2]);
259 } else {
260 irq_edge = priv->irq_mode;
261 }
262
263 ret = aos_hal_gpio_enable_irq(driver_obj->gpio_device, (int8_t)irq_edge, gpio_driver_irq_handler, (void *)driver_obj);
264 if (ret < 0) {
265 LOGE(LOG_TAG, "%s:aos_hal_gpio_enable_irq failed, %d\n", __func__, ret);
266 }
267
268 return MP_ROM_INT(ret);
269 }
270 STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gpio_on_obj, 2, 3, obj_on);
271
272
273 STATIC const mp_rom_map_elem_t gpio_locals_dict_table[] = {
274 { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_GPIO) },
275 { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&gpio_obj_open) },
276 { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&gpio_obj_close) },
277 { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&gpio_obj_read) },
278 { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&gpio_obj_write) },
279 { MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&gpio_on_obj) },
280 { MP_ROM_QSTR(MP_QSTR_RisingEdge), MP_ROM_INT(IRQ_RISING_EDGE) },
281 { MP_ROM_QSTR(MP_QSTR_FallingEdge), MP_ROM_INT(IRQ_FALLING_EDGE) },
282 };
283
284 STATIC MP_DEFINE_CONST_DICT(gpio_locals_dict, gpio_locals_dict_table);
285
286 const mp_obj_type_t driver_gpio_type = {
287 .base = { &mp_type_type },
288 .name = MP_QSTR_GPIO,
289 .print = gpio_obj_print,
290 .make_new = gpio_obj_make_new,
291 .locals_dict = (mp_obj_dict_t *)&gpio_locals_dict,
292 };
293