Skip to content

Commit 2f96b19

Browse files
committed
stmhal: Bring Pin class close to new machine module specification.
Looks like we can use the same Pin class for legacy pyb module and new machine module.
1 parent bedab23 commit 2f96b19

3 files changed

Lines changed: 71 additions & 60 deletions

File tree

stmhal/modmachine.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "irq.h"
3636
#include "rng.h"
3737
#include "storage.h"
38+
#include "pin.h"
3839
#include "timer.h"
3940
#include "usb.h"
4041

@@ -409,9 +410,11 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = {
409410

410411
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
411412
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
413+
414+
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
415+
412416
#if 0
413417
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
414-
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
415418
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
416419
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
417420
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },

stmhal/pin.c

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,24 @@ STATIC mp_obj_t pin_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw,
260260
return (mp_obj_t)pin;
261261
}
262262

263+
// fast method for getting/setting pin value
264+
STATIC mp_obj_t pin_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
265+
mp_arg_check_num(n_args, n_kw, 0, 1, false);
266+
pin_obj_t *self = self_in;
267+
if (n_args == 0) {
268+
// get pin
269+
return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
270+
} else {
271+
// set pin
272+
if (mp_obj_is_true(args[0])) {
273+
GPIO_set_pin(self->gpio, self->pin_mask);
274+
} else {
275+
GPIO_clear_pin(self->gpio, self->pin_mask);
276+
}
277+
return mp_const_none;
278+
}
279+
}
280+
263281
/// \classmethod mapper([fun])
264282
/// Get or set the pin mapper function.
265283
STATIC mp_obj_t pin_mapper(mp_uint_t n_args, const mp_obj_t *args) {
@@ -310,57 +328,56 @@ STATIC mp_obj_t pin_debug(mp_uint_t n_args, const mp_obj_t *args) {
310328
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_debug_fun_obj, 1, 2, pin_debug);
311329
STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, (mp_obj_t)&pin_debug_fun_obj);
312330

313-
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
314-
/// Initialise the pin:
315-
///
316-
/// - `mode` can be one of:
317-
/// - `Pin.IN` - configure the pin for input;
318-
/// - `Pin.OUT_PP` - configure the pin for output, with push-pull control;
319-
/// - `Pin.OUT_OD` - configure the pin for output, with open-drain control;
320-
/// - `Pin.AF_PP` - configure the pin for alternate function, pull-pull;
321-
/// - `Pin.AF_OD` - configure the pin for alternate function, open-drain;
322-
/// - `Pin.ANALOG` - configure the pin for analog.
323-
/// - `pull` can be one of:
324-
/// - `Pin.PULL_NONE` - no pull up or down resistors;
325-
/// - `Pin.PULL_UP` - enable the pull-up resistor;
326-
/// - `Pin.PULL_DOWN` - enable the pull-down resistor.
327-
/// - when mode is Pin.AF_PP or Pin.AF_OD, then af can be the index or name
328-
/// of one of the alternate functions associated with a pin.
329-
///
330-
/// Returns: `None`.
331-
STATIC const mp_arg_t pin_init_args[] = {
332-
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
333-
{ MP_QSTR_pull, MP_ARG_INT, {.u_int = GPIO_NOPULL}},
334-
{ MP_QSTR_af, MP_ARG_INT, {.u_int = -1}},
335-
};
336-
#define PIN_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
331+
// init(mode, pull=None, af=-1, *, value, alt)
332+
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
333+
static const mp_arg_t allowed_args[] = {
334+
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
335+
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none}},
336+
{ MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy
337+
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
338+
{ MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},
339+
};
337340

338-
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
339341
// parse args
340-
mp_arg_val_t vals[PIN_INIT_NUM_ARGS];
341-
mp_arg_parse_all(n_args, args, kw_args, PIN_INIT_NUM_ARGS, pin_init_args, vals);
342+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
343+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
342344

343345
// get io mode
344-
uint mode = vals[0].u_int;
346+
uint mode = args[0].u_int;
345347
if (!IS_GPIO_MODE(mode)) {
346348
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode));
347349
}
348350

349351
// get pull mode
350-
uint pull = vals[1].u_int;
352+
uint pull = GPIO_NOPULL;
353+
if (args[1].u_obj != mp_const_none) {
354+
pull = mp_obj_get_int(args[1].u_obj);
355+
}
351356
if (!IS_GPIO_PULL(pull)) {
352357
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull));
353358
}
354359

355-
// get af (alternate function)
356-
mp_int_t af = vals[2].u_int;
360+
// get af (alternate function); alt-arg overrides af-arg
361+
mp_int_t af = args[4].u_int;
362+
if (af == -1) {
363+
af = args[2].u_int;
364+
}
357365
if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af)) {
358366
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin af: %d", af));
359367
}
360368

361369
// enable the peripheral clock for the port of this pin
362370
mp_hal_gpio_clock_enable(self->gpio);
363371

372+
// if given, set the pin value before initialising to prevent glitches
373+
if (args[3].u_obj != MP_OBJ_NULL) {
374+
if (mp_obj_is_true(args[3].u_obj)) {
375+
GPIO_set_pin(self->gpio, self->pin_mask);
376+
} else {
377+
GPIO_clear_pin(self->gpio, self->pin_mask);
378+
}
379+
}
380+
364381
// configure the GPIO as requested
365382
GPIO_InitTypeDef GPIO_InitStructure;
366383
GPIO_InitStructure.Pin = self->pin_mask;
@@ -386,19 +403,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);
386403
/// anything that converts to a boolean. If it converts to `True`, the pin
387404
/// is set high, otherwise it is set low.
388405
STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) {
389-
pin_obj_t *self = args[0];
390-
if (n_args == 1) {
391-
// get pin
392-
return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
393-
} else {
394-
// set pin
395-
if (mp_obj_is_true(args[1])) {
396-
GPIO_set_pin(self->gpio, self->pin_mask);
397-
} else {
398-
GPIO_clear_pin(self->gpio, self->pin_mask);
399-
}
400-
return mp_const_none;
401-
}
406+
return pin_call(args[0], n_args - 1, 0, args + 1);
402407
}
403408
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
404409

@@ -524,24 +529,21 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
524529
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
525530

526531
// class constants
527-
/// \constant IN - initialise the pin to input mode
528-
/// \constant OUT_PP - initialise the pin to output mode with a push-pull drive
529-
/// \constant OUT_OD - initialise the pin to output mode with an open-drain drive
530-
/// \constant AF_PP - initialise the pin to alternate-function mode with a push-pull drive
531-
/// \constant AF_OD - initialise the pin to alternate-function mode with an open-drain drive
532-
/// \constant ANALOG - initialise the pin to analog mode
533-
/// \constant PULL_NONE - don't enable any pull up or down resistors on the pin
534-
/// \constant PULL_UP - enable the pull-up resistor on the pin
535-
/// \constant PULL_DOWN - enable the pull-down resistor on the pin
536532
{ MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) },
533+
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
534+
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
535+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ALT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
536+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
537+
{ MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
538+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
539+
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
540+
541+
// legacy class constants
537542
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
538543
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
539544
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
540545
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
541-
{ MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
542546
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) },
543-
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
544-
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
545547

546548
#include "genhdr/pins_af_const.h"
547549
};
@@ -553,6 +555,7 @@ const mp_obj_type_t pin_type = {
553555
.name = MP_QSTR_Pin,
554556
.print = pin_print,
555557
.make_new = pin_make_new,
558+
.call = pin_call,
556559
.locals_dict = (mp_obj_t)&pin_locals_dict,
557560
};
558561

stmhal/qstrdefsport.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Q(PinAF)
144144
Q(PinNamed)
145145
Q(init)
146146
Q(value)
147+
Q(alt)
147148
Q(low)
148149
Q(high)
149150
Q(name)
@@ -164,14 +165,18 @@ Q(pull)
164165
Q(index)
165166
Q(reg)
166167
Q(IN)
168+
Q(OUT)
169+
Q(OPEN_DRAIN)
170+
Q(ALT)
171+
Q(ALT_OPEN_DRAIN)
172+
Q(ANALOG)
173+
Q(PULL_UP)
174+
Q(PULL_DOWN)
167175
Q(OUT_PP)
168176
Q(OUT_OD)
169177
Q(AF_PP)
170178
Q(AF_OD)
171-
Q(ANALOG)
172179
Q(PULL_NONE)
173-
Q(PULL_UP)
174-
Q(PULL_DOWN)
175180

176181
// for LED object
177182
Q(LED)

0 commit comments

Comments
 (0)