blob: 8916da64f67e2ace89922723e7c379f3bc15deac [file] [log] [blame]
Damien George87c62502015-02-13 22:21:44 +00001/*
2 * This file is part of the Micro Python project, http://micropython.org/
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014, 2015 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27#include <stdio.h>
28#include <stdint.h>
29#include <string.h>
30
Damien George674bf1b2016-04-14 11:15:43 +010031#include "etshal.h"
Damien George87c62502015-02-13 22:21:44 +000032#include "c_types.h"
33#include "user_interface.h"
34#include "gpio.h"
35
36#include "py/nlr.h"
37#include "py/runtime.h"
Damien George674bf1b2016-04-14 11:15:43 +010038#include "py/gc.h"
Damien George68e222a2016-05-26 15:42:27 +010039#include "py/mphal.h"
Damien George87c62502015-02-13 22:21:44 +000040#include "modpyb.h"
Damien George674bf1b2016-04-14 11:15:43 +010041
42#define GET_TRIGGER(phys_port) \
43 GPIO_PIN_INT_TYPE_GET(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)))
44#define SET_TRIGGER(phys_port, trig) \
45 (GPIO_REG_WRITE(GPIO_PIN_ADDR(phys_port), \
46 (GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)) & ~GPIO_PIN_INT_TYPE_MASK) \
47 | GPIO_PIN_INT_TYPE_SET(trig))) \
Damien George87c62502015-02-13 22:21:44 +000048
49#define GPIO_MODE_INPUT (0)
50#define GPIO_MODE_OUTPUT (1)
Damien Georgecdad2b62015-12-28 17:42:20 +000051#define GPIO_MODE_OPEN_DRAIN (2) // synthesised
Damien George87c62502015-02-13 22:21:44 +000052#define GPIO_PULL_NONE (0)
53#define GPIO_PULL_UP (1)
Josef Gajdusek7d8edef2015-05-26 18:54:55 +020054// Removed in SDK 1.1.0
55//#define GPIO_PULL_DOWN (2)
Damien George87c62502015-02-13 22:21:44 +000056
Damien George674bf1b2016-04-14 11:15:43 +010057typedef struct _pin_irq_obj_t {
58 mp_obj_base_t base;
59 uint16_t phys_port;
60} pin_irq_obj_t;
61
Damien Georgea2d5d842016-04-22 10:04:12 +010062const pyb_pin_obj_t pyb_pin_obj[16 + 1] = {
Damien Georgea9a732a2016-04-13 22:38:44 +010063 {{&pyb_pin_type}, 0, FUNC_GPIO0, PERIPHS_IO_MUX_GPIO0_U},
64 {{&pyb_pin_type}, 1, FUNC_GPIO1, PERIPHS_IO_MUX_U0TXD_U},
65 {{&pyb_pin_type}, 2, FUNC_GPIO2, PERIPHS_IO_MUX_GPIO2_U},
66 {{&pyb_pin_type}, 3, FUNC_GPIO3, PERIPHS_IO_MUX_U0RXD_U},
67 {{&pyb_pin_type}, 4, FUNC_GPIO4, PERIPHS_IO_MUX_GPIO4_U},
68 {{&pyb_pin_type}, 5, FUNC_GPIO5, PERIPHS_IO_MUX_GPIO5_U},
Damien Georged9d40812016-04-13 22:45:51 +010069 {{NULL}, 0, 0, 0},
70 {{NULL}, 0, 0, 0},
71 {{NULL}, 0, 0, 0},
Damien Georgea9a732a2016-04-13 22:38:44 +010072 {{&pyb_pin_type}, 9, FUNC_GPIO9, PERIPHS_IO_MUX_SD_DATA2_U},
73 {{&pyb_pin_type}, 10, FUNC_GPIO10, PERIPHS_IO_MUX_SD_DATA3_U},
Damien Georged9d40812016-04-13 22:45:51 +010074 {{NULL}, 0, 0, 0},
Damien Georgea9a732a2016-04-13 22:38:44 +010075 {{&pyb_pin_type}, 12, FUNC_GPIO12, PERIPHS_IO_MUX_MTDI_U},
76 {{&pyb_pin_type}, 13, FUNC_GPIO13, PERIPHS_IO_MUX_MTCK_U},
77 {{&pyb_pin_type}, 14, FUNC_GPIO14, PERIPHS_IO_MUX_MTMS_U},
78 {{&pyb_pin_type}, 15, FUNC_GPIO15, PERIPHS_IO_MUX_MTDO_U},
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +020079 // GPIO16 is special, belongs to different register set, and
80 // otherwise handled specially.
Damien Georgea9a732a2016-04-13 22:38:44 +010081 {{&pyb_pin_type}, 16, -1, -1},
Damien George87c62502015-02-13 22:21:44 +000082};
83
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +020084STATIC uint8_t pin_mode[16 + 1];
Damien Georgecdad2b62015-12-28 17:42:20 +000085
Damien George674bf1b2016-04-14 11:15:43 +010086// forward declaration
87STATIC const pin_irq_obj_t pin_irq_obj[16];
88
89void pin_init0(void) {
90 ETS_GPIO_INTR_DISABLE();
91 ETS_GPIO_INTR_ATTACH(pin_intr_handler_iram, NULL);
92 // disable all interrupts
93 memset(&MP_STATE_PORT(pin_irq_handler)[0], 0, 16 * sizeof(mp_obj_t));
94 for (int p = 0; p < 16; ++p) {
95 GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << p);
96 SET_TRIGGER(p, 0);
97 }
98 ETS_GPIO_INTR_ENABLE();
99}
100
101void pin_intr_handler(uint32_t status) {
102 gc_lock();
103 status &= 0xffff;
104 for (int p = 0; status; ++p, status >>= 1) {
105 if (status & 1) {
106 mp_obj_t handler = MP_STATE_PORT(pin_irq_handler)[p];
107 if (handler != MP_OBJ_NULL) {
Paul Sokolovsky6d103b62016-04-25 19:28:12 +0300108 mp_call_function_1_protected(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
Damien George674bf1b2016-04-14 11:15:43 +0100109 }
110 }
111 }
112 gc_unlock();
113}
114
Damien George7059c8c2016-02-11 11:41:58 +0000115pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) {
Damien George342d9032015-12-29 00:19:23 +0000116 if (mp_obj_get_type(pin_in) != &pyb_pin_type) {
117 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "expecting a pin"));
118 }
119 pyb_pin_obj_t *self = pin_in;
Damien George7059c8c2016-02-11 11:41:58 +0000120 return self;
121}
122
123uint mp_obj_get_pin(mp_obj_t pin_in) {
124 return mp_obj_get_pin_obj(pin_in)->phys_port;
Damien George342d9032015-12-29 00:19:23 +0000125}
126
Damien George68e222a2016-05-26 15:42:27 +0100127void mp_hal_pin_input(mp_hal_pin_obj_t pin_id) {
128 pin_mode[pin_id] = GPIO_MODE_INPUT;
129 if (pin_id == 16) {
130 WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
131 WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
132 WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input
133 } else {
134 const pyb_pin_obj_t *self = &pyb_pin_obj[pin_id];
135 PIN_FUNC_SELECT(self->periph, self->func);
136 PIN_PULLUP_DIS(self->periph);
137 gpio_output_set(0, 0, 0, 1 << self->phys_port);
138 }
139}
140
141void mp_hal_pin_output(mp_hal_pin_obj_t pin_id) {
142 pin_mode[pin_id] = GPIO_MODE_OUTPUT;
143 if (pin_id == 16) {
144 WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
145 WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
146 WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output
147 } else {
148 const pyb_pin_obj_t *self = &pyb_pin_obj[pin_id];
149 PIN_FUNC_SELECT(self->periph, self->func);
150 PIN_PULLUP_DIS(self->periph);
151 gpio_output_set(0, 0, 1 << self->phys_port, 0);
152 }
153}
154
Damien George342d9032015-12-29 00:19:23 +0000155int pin_get(uint pin) {
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +0200156 if (pin == 16) {
157 return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1;
158 }
Damien George342d9032015-12-29 00:19:23 +0000159 return GPIO_INPUT_GET(pin);
160}
161
162void pin_set(uint pin, int value) {
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +0200163 if (pin == 16) {
164 int out_en = (pin_mode[pin] == GPIO_MODE_OUTPUT);
165 WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
166 WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
167 WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | out_en);
168 WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1) | value);
169 return;
170 }
171
Damien Georgecdad2b62015-12-28 17:42:20 +0000172 uint32_t enable = 0;
173 uint32_t disable = 0;
Damien George342d9032015-12-29 00:19:23 +0000174 switch (pin_mode[pin]) {
Damien Georgecdad2b62015-12-28 17:42:20 +0000175 case GPIO_MODE_INPUT:
176 value = -1;
177 disable = 1;
178 break;
179
180 case GPIO_MODE_OUTPUT:
181 enable = 1;
182 break;
183
184 case GPIO_MODE_OPEN_DRAIN:
185 if (value == -1) {
186 return;
187 } else if (value == 0) {
188 enable = 1;
189 } else {
190 value = -1;
191 disable = 1;
192 }
193 break;
194 }
195
196 enable <<= pin;
197 disable <<= pin;
198 if (value == -1) {
199 gpio_output_set(0, 0, enable, disable);
200 } else {
201 gpio_output_set(value << pin, (1 - value) << pin, enable, disable);
202 }
203}
204
Damien George7f9d1d62015-04-09 23:56:15 +0100205STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
Damien George87c62502015-02-13 22:21:44 +0000206 pyb_pin_obj_t *self = self_in;
207
208 // pin name
Damien Georgea9a732a2016-04-13 22:38:44 +0100209 mp_printf(print, "Pin(%u)", self->phys_port);
Damien George87c62502015-02-13 22:21:44 +0000210}
211
Damien George8a3e9032016-05-03 13:13:56 +0100212// pin.init(mode, pull=None, *, value)
Damien George87c62502015-02-13 22:21:44 +0000213STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
Damien George9df6b3a2016-05-03 12:44:28 +0100214 enum { ARG_mode, ARG_pull, ARG_value };
Damien George87c62502015-02-13 22:21:44 +0000215 static const mp_arg_t allowed_args[] = {
216 { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
Damien George8a3e9032016-05-03 13:13:56 +0100217 { MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none}},
Damien Georgecdad2b62015-12-28 17:42:20 +0000218 { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
Damien George87c62502015-02-13 22:21:44 +0000219 };
220
221 // parse args
Damien George9df6b3a2016-05-03 12:44:28 +0100222 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
223 mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
Damien George87c62502015-02-13 22:21:44 +0000224
225 // get io mode
Damien George9df6b3a2016-05-03 12:44:28 +0100226 uint mode = args[ARG_mode].u_int;
Damien George87c62502015-02-13 22:21:44 +0000227
228 // get pull mode
Damien George8a3e9032016-05-03 13:13:56 +0100229 uint pull = GPIO_PULL_NONE;
230 if (args[ARG_pull].u_obj != mp_const_none) {
231 pull = mp_obj_get_int(args[ARG_pull].u_obj);
232 }
Damien Georgecdad2b62015-12-28 17:42:20 +0000233
234 // get initial value
235 int value;
Damien George9df6b3a2016-05-03 12:44:28 +0100236 if (args[ARG_value].u_obj == MP_OBJ_NULL) {
Damien Georgecdad2b62015-12-28 17:42:20 +0000237 value = -1;
238 } else {
Damien George9df6b3a2016-05-03 12:44:28 +0100239 value = mp_obj_is_true(args[ARG_value].u_obj);
Damien Georgecdad2b62015-12-28 17:42:20 +0000240 }
241
242 // save the mode
243 pin_mode[self->phys_port] = mode;
Damien George87c62502015-02-13 22:21:44 +0000244
245 // configure the GPIO as requested
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +0200246 if (self->phys_port == 16) {
Damien George8a15e0b2016-08-10 12:45:40 +1000247 // only pull-down seems to be supported by the hardware, and
248 // we only expose pull-up behaviour in software
249 if (pull != GPIO_PULL_NONE) {
250 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin(16) doesn't support pull"));
251 }
Paul Sokolovskyeb247ea2016-01-08 22:04:00 +0200252 } else {
253 PIN_FUNC_SELECT(self->periph, self->func);
254 #if 0
255 // Removed in SDK 1.1.0
256 if ((pull & GPIO_PULL_DOWN) == 0) {
257 PIN_PULLDWN_DIS(self->periph);
258 }
259 #endif
260 if ((pull & GPIO_PULL_UP) == 0) {
261 PIN_PULLUP_DIS(self->periph);
262 }
263 #if 0
264 if ((pull & GPIO_PULL_DOWN) != 0) {
265 PIN_PULLDWN_EN(self->periph);
266 }
267 #endif
268 if ((pull & GPIO_PULL_UP) != 0) {
269 PIN_PULLUP_EN(self->periph);
270 }
Damien George87c62502015-02-13 22:21:44 +0000271 }
272
Damien George342d9032015-12-29 00:19:23 +0000273 pin_set(self->phys_port, value);
Damien George87c62502015-02-13 22:21:44 +0000274
275 return mp_const_none;
276}
277
278// constructor(id, ...)
Damien George5b3f0b72016-01-03 15:55:55 +0000279STATIC mp_obj_t pyb_pin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
Damien George87c62502015-02-13 22:21:44 +0000280 mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
281
Damien Georged9d40812016-04-13 22:45:51 +0100282 // get the wanted pin object
Damien George87c62502015-02-13 22:21:44 +0000283 int wanted_pin = mp_obj_get_int(args[0]);
284 pyb_pin_obj_t *pin = NULL;
Damien Georged9d40812016-04-13 22:45:51 +0100285 if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(pyb_pin_obj)) {
286 pin = (pyb_pin_obj_t*)&pyb_pin_obj[wanted_pin];
Damien George87c62502015-02-13 22:21:44 +0000287 }
Damien Georged9d40812016-04-13 22:45:51 +0100288 if (pin == NULL || pin->base.type == NULL) {
Damien George87c62502015-02-13 22:21:44 +0000289 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "invalid pin"));
290 }
291
292 if (n_args > 1 || n_kw > 0) {
293 // pin mode given, so configure this GPIO
294 mp_map_t kw_args;
295 mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
296 pyb_pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
297 }
298
299 return (mp_obj_t)pin;
300}
301
Damien Georgecdad2b62015-12-28 17:42:20 +0000302// fast method for getting/setting pin value
303STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
304 mp_arg_check_num(n_args, n_kw, 0, 1, false);
305 pyb_pin_obj_t *self = self_in;
306 if (n_args == 0) {
307 // get pin
Damien Georgeb203c172016-08-10 12:44:47 +1000308 return MP_OBJ_NEW_SMALL_INT(pin_get(self->phys_port));
Damien Georgecdad2b62015-12-28 17:42:20 +0000309 } else {
310 // set pin
Damien George342d9032015-12-29 00:19:23 +0000311 pin_set(self->phys_port, mp_obj_is_true(args[0]));
Damien Georgecdad2b62015-12-28 17:42:20 +0000312 return mp_const_none;
313 }
314}
315
Damien George87c62502015-02-13 22:21:44 +0000316// pin.init(mode, pull)
317STATIC mp_obj_t pyb_pin_obj_init(mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
318 return pyb_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
319}
320MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_init_obj, 1, pyb_pin_obj_init);
321
322// pin.value([value])
323STATIC mp_obj_t pyb_pin_value(mp_uint_t n_args, const mp_obj_t *args) {
Damien Georgecdad2b62015-12-28 17:42:20 +0000324 return pyb_pin_call(args[0], n_args - 1, 0, args + 1);
Damien George87c62502015-02-13 22:21:44 +0000325}
326STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pin_value_obj, 1, 2, pyb_pin_value);
327
328// pin.low()
329STATIC mp_obj_t pyb_pin_low(mp_obj_t self_in) {
330 pyb_pin_obj_t *self = self_in;
Damien George342d9032015-12-29 00:19:23 +0000331 pin_set(self->phys_port, 0);
Damien George87c62502015-02-13 22:21:44 +0000332 return mp_const_none;
333}
334STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_low_obj, pyb_pin_low);
335
336// pin.high()
337STATIC mp_obj_t pyb_pin_high(mp_obj_t self_in) {
338 pyb_pin_obj_t *self = self_in;
Damien George342d9032015-12-29 00:19:23 +0000339 pin_set(self->phys_port, 1);
Damien George87c62502015-02-13 22:21:44 +0000340 return mp_const_none;
341}
342STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_high_obj, pyb_pin_high);
343
Damien George8e130fc2016-05-03 13:47:10 +0100344// pin.irq(*, trigger, handler=None)
345STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
346 enum { ARG_trigger, ARG_handler };
347 static const mp_arg_t allowed_args[] = {
348 { MP_QSTR_trigger, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
349 { MP_QSTR_handler, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
350 };
351 pyb_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
352 mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
353 mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
354
Damien George674bf1b2016-04-14 11:15:43 +0100355 if (self->phys_port >= 16) {
356 nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "pin does not have IRQ capabilities"));
357 }
358
Damien George8e130fc2016-05-03 13:47:10 +0100359 if (args[ARG_trigger].u_int != 0) {
Damien George674bf1b2016-04-14 11:15:43 +0100360 // configure irq
Damien George8e130fc2016-05-03 13:47:10 +0100361 mp_obj_t handler = args[ARG_handler].u_obj;
Damien George674bf1b2016-04-14 11:15:43 +0100362 if (handler == mp_const_none) {
363 handler = MP_OBJ_NULL;
364 }
365 ETS_GPIO_INTR_DISABLE();
366 MP_STATE_PORT(pin_irq_handler)[self->phys_port] = handler;
Damien George8e130fc2016-05-03 13:47:10 +0100367 SET_TRIGGER(self->phys_port, args[ARG_trigger].u_int);
Damien George674bf1b2016-04-14 11:15:43 +0100368 GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->phys_port);
369 ETS_GPIO_INTR_ENABLE();
370 }
371
372 // return the irq object
373 return MP_OBJ_FROM_PTR(&pin_irq_obj[self->phys_port]);
374}
Damien George8e130fc2016-05-03 13:47:10 +0100375STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_irq_obj, 1, pyb_pin_irq);
Damien George674bf1b2016-04-14 11:15:43 +0100376
Damien George87c62502015-02-13 22:21:44 +0000377STATIC const mp_map_elem_t pyb_pin_locals_dict_table[] = {
378 // instance methods
379 { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_pin_init_obj },
380 { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pyb_pin_value_obj },
381 { MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pyb_pin_low_obj },
382 { MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pyb_pin_high_obj },
Damien George674bf1b2016-04-14 11:15:43 +0100383 { MP_OBJ_NEW_QSTR(MP_QSTR_irq), (mp_obj_t)&pyb_pin_irq_obj },
Damien George87c62502015-02-13 22:21:44 +0000384
385 // class constants
386 { MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) },
Damien Georgecdad2b62015-12-28 17:42:20 +0000387 { MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT) },
388 { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OPEN_DRAIN) },
Damien George87c62502015-02-13 22:21:44 +0000389 { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULL_UP) },
Josef Gajdusek7d8edef2015-05-26 18:54:55 +0200390 //{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULL_DOWN) },
Damien George674bf1b2016-04-14 11:15:43 +0100391
392 // IRG triggers, can be or'd together
393 { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_PIN_INTR_POSEDGE) },
394 { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_PIN_INTR_NEGEDGE) },
Damien George87c62502015-02-13 22:21:44 +0000395};
396
397STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table);
398
399const mp_obj_type_t pyb_pin_type = {
400 { &mp_type_type },
401 .name = MP_QSTR_Pin,
402 .print = pyb_pin_print,
403 .make_new = pyb_pin_make_new,
Damien Georgecdad2b62015-12-28 17:42:20 +0000404 .call = pyb_pin_call,
Damien George87c62502015-02-13 22:21:44 +0000405 .locals_dict = (mp_obj_t)&pyb_pin_locals_dict,
406};
Damien George674bf1b2016-04-14 11:15:43 +0100407
408/******************************************************************************/
409// Pin IRQ object
410
411STATIC const mp_obj_type_t pin_irq_type;
412
413STATIC const pin_irq_obj_t pin_irq_obj[16] = {
414 {{&pin_irq_type}, 0},
415 {{&pin_irq_type}, 1},
416 {{&pin_irq_type}, 2},
417 {{&pin_irq_type}, 3},
418 {{&pin_irq_type}, 4},
419 {{&pin_irq_type}, 5},
420 {{&pin_irq_type}, 6},
421 {{&pin_irq_type}, 7},
422 {{&pin_irq_type}, 8},
423 {{&pin_irq_type}, 9},
424 {{&pin_irq_type}, 10},
425 {{&pin_irq_type}, 11},
426 {{&pin_irq_type}, 12},
427 {{&pin_irq_type}, 13},
428 {{&pin_irq_type}, 14},
429 {{&pin_irq_type}, 15},
430};
431
432STATIC mp_obj_t pin_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
433 pin_irq_obj_t *self = self_in;
434 mp_arg_check_num(n_args, n_kw, 0, 0, false);
435 pin_intr_handler(1 << self->phys_port);
436 return mp_const_none;
437}
438
439STATIC mp_obj_t pin_irq_trigger(size_t n_args, const mp_obj_t *args) {
440 pin_irq_obj_t *self = args[0];
441 uint32_t orig_trig = GET_TRIGGER(self->phys_port);
442 if (n_args == 2) {
443 // set trigger
444 SET_TRIGGER(self->phys_port, mp_obj_get_int(args[1]));
445 }
446 // return original trigger value
447 return MP_OBJ_NEW_SMALL_INT(orig_trig);
448}
449STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_irq_trigger_obj, 1, 2, pin_irq_trigger);
450
451STATIC const mp_rom_map_elem_t pin_irq_locals_dict_table[] = {
452 { MP_ROM_QSTR(MP_QSTR_trigger), MP_ROM_PTR(&pin_irq_trigger_obj) },
453};
454
455STATIC MP_DEFINE_CONST_DICT(pin_irq_locals_dict, pin_irq_locals_dict_table);
456
457STATIC const mp_obj_type_t pin_irq_type = {
458 { &mp_type_type },
459 .name = MP_QSTR_IRQ,
460 .call = pin_irq_call,
461 .locals_dict = (mp_obj_dict_t*)&pin_irq_locals_dict,
462};