blob: 20661cfcebdd55aa8fa78d192d6cc2b48469a936 [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
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 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
Dave Hylandsf14b92b2014-03-12 18:06:26 -070027#include <stdio.h>
28#include <stdint.h>
29#include <string.h>
Dave Hylandsf14b92b2014-03-12 18:06:26 -070030
Paul Sokolovsky9b71b162014-05-02 18:03:04 +030031#include "mpconfig.h"
Damien Georgec66d86c2014-04-18 22:38:09 +010032#include "nlr.h"
Dave Hylandsf14b92b2014-03-12 18:06:26 -070033#include "misc.h"
Dave Hylandsf14b92b2014-03-12 18:06:26 -070034#include "qstr.h"
35#include "obj.h"
Damien Georgec66d86c2014-04-18 22:38:09 +010036#include "runtime.h"
Damien George7a37f642014-07-02 13:42:37 +010037#include MICROPY_HAL_H
Dave Hylandsf14b92b2014-03-12 18:06:26 -070038#include "pin.h"
39
Damien George8d096402014-04-29 22:55:34 +010040/// \moduleref pyb
41/// \class Pin - control I/O pins
42///
43/// A pin is the basic object to control I/O pins. It has methods to set
44/// the mode of the pin (input, output, etc) and methods to get and set the
45/// digital logic level. For analog control of a pin, see the ADC class.
46///
47/// Usage Model:
48///
49/// All Board Pins are predefined as pyb.Pin.board.Name
50///
51/// x1_pin = pyb.Pin.board.X1
52///
53/// g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN)
54///
55/// CPU pins which correspond to the board pins are available
56/// as `pyb.cpu.Name`. For the CPU pins, the names are the port letter
57/// followed by the pin number. On the PYBv1.0, `pyb.Pin.board.X1` and
58/// `pyb.Pin.cpu.B6` are the same pin.
59///
60/// You can also use strings:
61///
62/// g = pyb.Pin('X1', pyb.Pin.OUT_PP)
63///
64/// Users can add their own names:
65///
66/// pyb.Pin.dict["LeftMotorDir"] = pyb.Pin.cpu.C12
67/// g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)
68///
69/// and can query mappings
70///
71/// pin = pyb.Pin("LeftMotorDir")
72///
73/// Users can also add their own mapping function:
74///
75/// def MyMapper(pin_name):
76/// if pin_name == "LeftMotorDir":
77/// return pyb.Pin.cpu.A0
78///
79/// pyb.Pin.mapper(MyMapper)
80///
81/// So, if you were to call: `pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP)`
82/// then `"LeftMotorDir"` is passed directly to the mapper function.
83///
84/// To summarise, the following order determines how things get mapped into
85/// an ordinal pin number:
86///
87/// 1. Directly specify a pin object
88/// 2. User supplied mapping function
89/// 3. User supplied mapping (object must be usable as a dictionary key)
90/// 4. Supply a string which matches a board pin
91/// 5. Supply a string which matches a CPU port/pin
92///
93/// You can set `pyb.Pin.debug(True)` to get some debug information about
94/// how a particular object gets mapped to a pin.
Damien Georgec66d86c2014-04-18 22:38:09 +010095
96// Pin class variables
97STATIC mp_obj_t pin_class_mapper;
98STATIC mp_obj_t pin_class_map_dict;
99STATIC bool pin_class_debug;
100
101void pin_init(void) {
Dave Hylandsf1707352014-06-25 16:01:19 -0700102 pin_class_mapper = mp_const_none;
103 pin_class_map_dict = mp_const_none;
Damien Georgec66d86c2014-04-18 22:38:09 +0100104 pin_class_debug = false;
105}
106
107// C API used to convert a user-supplied pin name into an ordinal pin number.
108const pin_obj_t *pin_find(mp_obj_t user_obj) {
109 const pin_obj_t *pin_obj;
110
111 // If a pin was provided, then use it
112 if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) {
113 pin_obj = user_obj;
114 if (pin_class_debug) {
115 printf("Pin map passed pin ");
116 mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
117 printf("\n");
118 }
119 return pin_obj;
120 }
121
Dave Hylandsf1707352014-06-25 16:01:19 -0700122 if (pin_class_mapper != mp_const_none) {
Damien Georgec66d86c2014-04-18 22:38:09 +0100123 pin_obj = mp_call_function_1(pin_class_mapper, user_obj);
124 if (pin_obj != mp_const_none) {
125 if (!MP_OBJ_IS_TYPE(pin_obj, &pin_type)) {
126 nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin.mapper didn't return a Pin object"));
127 }
128 if (pin_class_debug) {
129 printf("Pin.mapper maps ");
130 mp_obj_print(user_obj, PRINT_REPR);
131 printf(" to ");
132 mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
133 printf("\n");
134 }
135 return pin_obj;
136 }
137 // The pin mapping function returned mp_const_none, fall through to
138 // other lookup methods.
139 }
140
Dave Hylandsf1707352014-06-25 16:01:19 -0700141 if (pin_class_map_dict != mp_const_none) {
Damien Georgec66d86c2014-04-18 22:38:09 +0100142 mp_map_t *pin_map_map = mp_obj_dict_get_map(pin_class_map_dict);
143 mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP);
144 if (elem != NULL && elem->value != NULL) {
145 pin_obj = elem->value;
146 if (pin_class_debug) {
147 printf("Pin.map_dict maps ");
148 mp_obj_print(user_obj, PRINT_REPR);
149 printf(" to ");
150 mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
151 printf("\n");
152 }
153 return pin_obj;
154 }
155 }
156
157 // See if the pin name matches a board pin
158 const char *pin_name = mp_obj_str_get_str(user_obj);
159 pin_obj = pin_find_named_pin(pin_board_pins, pin_name);
160 if (pin_obj) {
161 if (pin_class_debug) {
162 printf("Pin.board maps ");
163 mp_obj_print(user_obj, PRINT_REPR);
164 printf(" to ");
165 mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
166 printf("\n");
167 }
168 return pin_obj;
169 }
170
171 // See if the pin name matches a cpu pin
172 pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name);
173 if (pin_obj) {
174 if (pin_class_debug) {
175 printf("Pin.cpu maps ");
176 mp_obj_print(user_obj, PRINT_REPR);
177 printf(" to ");
178 mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
179 printf("\n");
180 }
181 return pin_obj;
182 }
183
184 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name));
185}
186
Damien George8d096402014-04-29 22:55:34 +0100187/// \method __str__()
188/// Return a string describing the pin object.
Damien Georgec66d86c2014-04-18 22:38:09 +0100189STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700190 pin_obj_t *self = self_in;
191 print(env, "<Pin %s>", self->name);
192}
193
Damien George3d191372014-04-19 02:17:57 +0100194STATIC mp_obj_t pin_obj_init(uint n_args, mp_obj_t *args);
195
Damien George8d096402014-04-29 22:55:34 +0100196/// \classmethod \constructor(id, ...)
197/// Create a new Pin object associated with the id. If additional arguments are given,
198/// they are used to initialise the pin. See `init`.
Damien Georgec66d86c2014-04-18 22:38:09 +0100199STATIC mp_obj_t pin_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
Damien Georged6894302014-04-20 00:16:30 +0100200 mp_arg_check_num(n_args, n_kw, 1, 3, false);
Damien Georgec66d86c2014-04-18 22:38:09 +0100201
202 // Run an argument through the mapper and return the result.
203 const pin_obj_t *pin = pin_find(args[0]);
204
205 if (n_args >= 2) {
206 // pin mode given, so configure this GPIO
Dave Hylandse911cfd2014-05-01 12:15:37 -0700207 mp_obj_t args2[3] = {(mp_obj_t)pin, args[1], MP_OBJ_NULL};
Damien George3d191372014-04-19 02:17:57 +0100208 if (n_args == 3) {
209 args2[2] = args[2];
Damien Georgec66d86c2014-04-18 22:38:09 +0100210 }
Damien George3d191372014-04-19 02:17:57 +0100211 pin_obj_init(n_args, args2);
Damien Georgec66d86c2014-04-18 22:38:09 +0100212 }
213
214 return (mp_obj_t)pin;
215}
216
Damien George8d096402014-04-29 22:55:34 +0100217/// \classmethod mapper([fun])
218/// Get or set the pin mapper function.
Damien Georgec66d86c2014-04-18 22:38:09 +0100219STATIC mp_obj_t pin_mapper(uint n_args, mp_obj_t *args) {
220 if (n_args > 1) {
221 pin_class_mapper = args[1];
222 return mp_const_none;
223 }
224 return pin_class_mapper;
225}
226STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_mapper_fun_obj, 1, 2, pin_mapper);
227STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_mapper_obj, (mp_obj_t)&pin_mapper_fun_obj);
228
Damien George8d096402014-04-29 22:55:34 +0100229/// \classmethod dict([dict])
230/// Get or set the pin mapper dictionary.
Damien Georgec66d86c2014-04-18 22:38:09 +0100231STATIC mp_obj_t pin_map_dict(uint n_args, mp_obj_t *args) {
232 if (n_args > 1) {
233 pin_class_map_dict = args[1];
234 return mp_const_none;
235 }
236 return pin_class_map_dict;
237}
238STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_dict_fun_obj, 1, 2, pin_map_dict);
239STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_map_dict_obj, (mp_obj_t)&pin_map_dict_fun_obj);
240
Damien George8d096402014-04-29 22:55:34 +0100241/// \classmethod debug([state])
242/// Get or set the debugging state (`True` or `False` for on or off).
Damien Georgec66d86c2014-04-18 22:38:09 +0100243STATIC mp_obj_t pin_debug(uint n_args, mp_obj_t *args) {
244 if (n_args > 1) {
245 pin_class_debug = mp_obj_is_true(args[1]);
246 return mp_const_none;
247 }
248 return MP_BOOL(pin_class_debug);
249}
250STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_debug_fun_obj, 1, 2, pin_debug);
251STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, (mp_obj_t)&pin_debug_fun_obj);
252
Damien George8d096402014-04-29 22:55:34 +0100253/// \method init(mode, pull=Pin.PULL_NONE)
254/// Initialise the pin:
255///
256/// - `mode` can be one of:
257/// - `Pin.IN` - configure the pin for input;
258/// - `Pin.OUT_PP` - configure the pin for output, with push-pull control;
259/// - `Pin.OUT_OD` - configure the pin for output, with open-drain control;
260/// - `Pin.AF_PP` - configure the pin for alternate function, pull-pull;
261/// - `Pin.AF_OD` - configure the pin for alternate function, open-drain;
262/// - `Pin.ANALOG` - configure the pin for analog.
263/// - `pull` can be one of:
264/// - `Pin.PULL_NONE` - no pull up or down resistors;
265/// - `Pin.PULL_UP` - enable the pull-up resistor;
266/// - `Pin.PULL_DOWN` - enable the pull-down resistor.
267///
268/// Returns: `None`.
Damien Georgebaa2afb2014-05-03 16:42:27 +0100269// TODO allow keyword args
Damien George3d191372014-04-19 02:17:57 +0100270STATIC mp_obj_t pin_obj_init(uint n_args, mp_obj_t *args) {
271 pin_obj_t *self = args[0];
272
273 // get io mode
274 uint mode = mp_obj_get_int(args[1]);
275 if (!IS_GPIO_MODE(mode)) {
276 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode));
277 }
278
279 // get pull mode
280 uint pull = GPIO_NOPULL;
281 if (n_args >= 3) {
282 pull = mp_obj_get_int(args[2]);
283 if (!IS_GPIO_PULL(pull)) {
284 nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull));
285 }
286 }
287
288 // configure the GPIO as requested
289 GPIO_InitTypeDef GPIO_InitStructure;
290 GPIO_InitStructure.Pin = self->pin_mask;
291 GPIO_InitStructure.Mode = mode;
292 GPIO_InitStructure.Pull = pull;
293 GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
294 GPIO_InitStructure.Alternate = 0;
295 HAL_GPIO_Init(self->gpio, &GPIO_InitStructure);
296
297 return mp_const_none;
298}
299STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_init_obj, 2, 3, pin_obj_init);
300
Damien George8d096402014-04-29 22:55:34 +0100301/// \method value([value])
302/// Get or set the digital logic level of the pin:
303///
304/// - With no argument, return 0 or 1 depending on the logic level of the pin.
305/// - With `value` given, set the logic level of the pin. `value` can be
306/// anything that converts to a boolean. If it converts to `True`, the pin
307/// is set high, otherwise it is set low.
Damien Georgec66d86c2014-04-18 22:38:09 +0100308STATIC mp_obj_t pin_value(uint n_args, mp_obj_t *args) {
309 pin_obj_t *self = args[0];
310 if (n_args == 1) {
311 // get pin
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700312 return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
Damien Georgec66d86c2014-04-18 22:38:09 +0100313 } else {
314 // set pin
315 if (mp_obj_is_true(args[1])) {
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700316 GPIO_set_pin(self->gpio, self->pin_mask);
Damien Georgec66d86c2014-04-18 22:38:09 +0100317 } else {
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700318 GPIO_clear_pin(self->gpio, self->pin_mask);
Damien Georgec66d86c2014-04-18 22:38:09 +0100319 }
320 return mp_const_none;
321 }
322}
323STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
324
Damien George8d096402014-04-29 22:55:34 +0100325/// \method low()
326/// Set the pin to a low logic level.
Damien Georgec66d86c2014-04-18 22:38:09 +0100327STATIC mp_obj_t pin_low(mp_obj_t self_in) {
328 pin_obj_t *self = self_in;
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700329 GPIO_clear_pin(self->gpio, self->pin_mask);;
Damien Georgec66d86c2014-04-18 22:38:09 +0100330 return mp_const_none;
331}
332STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
333
Damien George8d096402014-04-29 22:55:34 +0100334/// \method high()
335/// Set the pin to a high logic level.
Damien Georgec66d86c2014-04-18 22:38:09 +0100336STATIC mp_obj_t pin_high(mp_obj_t self_in) {
337 pin_obj_t *self = self_in;
Dave Hylands4f1b7fe2014-06-15 22:33:14 -0700338 GPIO_set_pin(self->gpio, self->pin_mask);;
Damien Georgec66d86c2014-04-18 22:38:09 +0100339 return mp_const_none;
340}
341STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);
342
Damien George8d096402014-04-29 22:55:34 +0100343/// \method name()
344/// Get the pin name.
Damien Georgec66d86c2014-04-18 22:38:09 +0100345STATIC mp_obj_t pin_name(mp_obj_t self_in) {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700346 pin_obj_t *self = self_in;
347 return MP_OBJ_NEW_QSTR(qstr_from_str(self->name));
348}
Damien Georgec66d86c2014-04-18 22:38:09 +0100349STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name);
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700350
Damien George8d096402014-04-29 22:55:34 +0100351/// \method port()
352/// Get the pin port.
Damien Georgec66d86c2014-04-18 22:38:09 +0100353STATIC mp_obj_t pin_port(mp_obj_t self_in) {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700354 pin_obj_t *self = self_in;
Damien Georgebb4c6f32014-07-31 10:49:14 +0100355 return MP_OBJ_NEW_SMALL_INT(self->port);
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700356}
Damien Georgec66d86c2014-04-18 22:38:09 +0100357STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_port_obj, pin_port);
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700358
Damien George8d096402014-04-29 22:55:34 +0100359/// \method pin()
360/// Get the pin number.
Damien Georgec66d86c2014-04-18 22:38:09 +0100361STATIC mp_obj_t pin_pin(mp_obj_t self_in) {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700362 pin_obj_t *self = self_in;
Damien Georgebb4c6f32014-07-31 10:49:14 +0100363 return MP_OBJ_NEW_SMALL_INT(self->pin);
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700364}
Damien Georgec66d86c2014-04-18 22:38:09 +0100365STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin);
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700366
Damien Georgec66d86c2014-04-18 22:38:09 +0100367STATIC const mp_map_elem_t pin_locals_dict_table[] = {
368 // instance methods
Damien George3d191372014-04-19 02:17:57 +0100369 { MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
Damien Georgec66d86c2014-04-18 22:38:09 +0100370 { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj },
371 { MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
372 { MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
373 { MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
374 { MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
375 { MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700376
Damien Georgec66d86c2014-04-18 22:38:09 +0100377 // class methods
378 { MP_OBJ_NEW_QSTR(MP_QSTR_mapper), (mp_obj_t)&pin_mapper_obj },
379 { MP_OBJ_NEW_QSTR(MP_QSTR_dict), (mp_obj_t)&pin_map_dict_obj },
380 { MP_OBJ_NEW_QSTR(MP_QSTR_debug), (mp_obj_t)&pin_debug_obj },
381
382 // class attributes
383 { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&pin_board_pins_obj },
384 { MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj },
385
386 // class constants
Damien George8d096402014-04-29 22:55:34 +0100387 /// \constant IN - initialise the pin to input mode
388 /// \constant OUT_PP - initialise the pin to output mode with a push-pull drive
389 /// \constant OUT_OD - initialise the pin to output mode with an open-drain drive
390 /// \constant PULL_NONE - don't enable any pull up or down resistors on the pin
391 /// \constant PULL_UP - enable the pull-up resistor on the pin
392 /// \constant PULL_DOWN - enable the pull-down resistor on the pin
Damien Georgec66d86c2014-04-18 22:38:09 +0100393 { MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) },
394 { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
395 { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
396 { MP_OBJ_NEW_QSTR(MP_QSTR_AF_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
397 { MP_OBJ_NEW_QSTR(MP_QSTR_AF_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
398 { MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
399 { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) },
400 { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
401 { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700402};
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700403
Damien Georgec66d86c2014-04-18 22:38:09 +0100404STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
405
406const mp_obj_type_t pin_type = {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700407 { &mp_type_type },
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700408 .name = MP_QSTR_Pin,
Damien Georgec66d86c2014-04-18 22:38:09 +0100409 .print = pin_print,
410 .make_new = pin_make_new,
411 .locals_dict = (mp_obj_t)&pin_locals_dict,
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700412};
413
Damien Georgec66d86c2014-04-18 22:38:09 +0100414STATIC void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700415 pin_af_obj_t *self = self_in;
416 print(env, "<Pin AF %d fn:%d unit:%d typ:%d>", self->idx, self->fn,
417 self->unit, self->type);
418}
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700419
Damien Georgec66d86c2014-04-18 22:38:09 +0100420const mp_obj_type_t pin_af_type = {
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700421 { &mp_type_type },
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700422 .name = MP_QSTR_PinAF,
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700423 .print = pin_af_obj_print,
Dave Hylandsf14b92b2014-03-12 18:06:26 -0700424};