kopia lustrzana https://github.com/micropython/micropython
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.pull/1403/merge
rodzic
bedab235f9
commit
2f96b1982a
|
@ -35,6 +35,7 @@
|
|||
#include "irq.h"
|
||||
#include "rng.h"
|
||||
#include "storage.h"
|
||||
#include "pin.h"
|
||||
#include "timer.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
@ -409,9 +410,11 @@ STATIC const mp_map_elem_t machine_module_globals_table[] = {
|
|||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
|
||||
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
|
||||
|
||||
#if 0
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },
|
||||
|
|
115
stmhal/pin.c
115
stmhal/pin.c
|
@ -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,
|
|||
return (mp_obj_t)pin;
|
||||
}
|
||||
|
||||
// fast method for getting/setting pin value
|
||||
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) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
pin_obj_t *self = self_in;
|
||||
if (n_args == 0) {
|
||||
// get pin
|
||||
return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
|
||||
} else {
|
||||
// set pin
|
||||
if (mp_obj_is_true(args[0])) {
|
||||
GPIO_set_pin(self->gpio, self->pin_mask);
|
||||
} else {
|
||||
GPIO_clear_pin(self->gpio, self->pin_mask);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
/// \classmethod mapper([fun])
|
||||
/// Get or set the pin mapper function.
|
||||
STATIC mp_obj_t pin_mapper(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
|
@ -310,50 +328,40 @@ STATIC mp_obj_t pin_debug(mp_uint_t n_args, const mp_obj_t *args) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_debug_fun_obj, 1, 2, pin_debug);
|
||||
STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, (mp_obj_t)&pin_debug_fun_obj);
|
||||
|
||||
/// \method init(mode, pull=Pin.PULL_NONE, af=-1)
|
||||
/// Initialise the pin:
|
||||
///
|
||||
/// - `mode` can be one of:
|
||||
/// - `Pin.IN` - configure the pin for input;
|
||||
/// - `Pin.OUT_PP` - configure the pin for output, with push-pull control;
|
||||
/// - `Pin.OUT_OD` - configure the pin for output, with open-drain control;
|
||||
/// - `Pin.AF_PP` - configure the pin for alternate function, pull-pull;
|
||||
/// - `Pin.AF_OD` - configure the pin for alternate function, open-drain;
|
||||
/// - `Pin.ANALOG` - configure the pin for analog.
|
||||
/// - `pull` can be one of:
|
||||
/// - `Pin.PULL_NONE` - no pull up or down resistors;
|
||||
/// - `Pin.PULL_UP` - enable the pull-up resistor;
|
||||
/// - `Pin.PULL_DOWN` - enable the pull-down resistor.
|
||||
/// - when mode is Pin.AF_PP or Pin.AF_OD, then af can be the index or name
|
||||
/// of one of the alternate functions associated with a pin.
|
||||
///
|
||||
/// Returns: `None`.
|
||||
STATIC const mp_arg_t pin_init_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_pull, MP_ARG_INT, {.u_int = GPIO_NOPULL}},
|
||||
{ MP_QSTR_af, MP_ARG_INT, {.u_int = -1}},
|
||||
};
|
||||
#define PIN_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
// init(mode, pull=None, af=-1, *, value, alt)
|
||||
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) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none}},
|
||||
{ MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
|
||||
{ MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}},
|
||||
};
|
||||
|
||||
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) {
|
||||
// parse args
|
||||
mp_arg_val_t vals[PIN_INIT_NUM_ARGS];
|
||||
mp_arg_parse_all(n_args, args, kw_args, PIN_INIT_NUM_ARGS, pin_init_args, vals);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// get io mode
|
||||
uint mode = vals[0].u_int;
|
||||
uint mode = args[0].u_int;
|
||||
if (!IS_GPIO_MODE(mode)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode));
|
||||
}
|
||||
|
||||
// get pull mode
|
||||
uint pull = vals[1].u_int;
|
||||
uint pull = GPIO_NOPULL;
|
||||
if (args[1].u_obj != mp_const_none) {
|
||||
pull = mp_obj_get_int(args[1].u_obj);
|
||||
}
|
||||
if (!IS_GPIO_PULL(pull)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull));
|
||||
}
|
||||
|
||||
// get af (alternate function)
|
||||
mp_int_t af = vals[2].u_int;
|
||||
// get af (alternate function); alt-arg overrides af-arg
|
||||
mp_int_t af = args[4].u_int;
|
||||
if (af == -1) {
|
||||
af = args[2].u_int;
|
||||
}
|
||||
if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin af: %d", af));
|
||||
}
|
||||
|
@ -361,6 +369,15 @@ STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, mp_uint_t n_args, con
|
|||
// enable the peripheral clock for the port of this pin
|
||||
mp_hal_gpio_clock_enable(self->gpio);
|
||||
|
||||
// if given, set the pin value before initialising to prevent glitches
|
||||
if (args[3].u_obj != MP_OBJ_NULL) {
|
||||
if (mp_obj_is_true(args[3].u_obj)) {
|
||||
GPIO_set_pin(self->gpio, self->pin_mask);
|
||||
} else {
|
||||
GPIO_clear_pin(self->gpio, self->pin_mask);
|
||||
}
|
||||
}
|
||||
|
||||
// configure the GPIO as requested
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
GPIO_InitStructure.Pin = self->pin_mask;
|
||||
|
@ -386,19 +403,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);
|
|||
/// anything that converts to a boolean. If it converts to `True`, the pin
|
||||
/// is set high, otherwise it is set low.
|
||||
STATIC mp_obj_t pin_value(mp_uint_t n_args, const mp_obj_t *args) {
|
||||
pin_obj_t *self = args[0];
|
||||
if (n_args == 1) {
|
||||
// get pin
|
||||
return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
|
||||
} else {
|
||||
// set pin
|
||||
if (mp_obj_is_true(args[1])) {
|
||||
GPIO_set_pin(self->gpio, self->pin_mask);
|
||||
} else {
|
||||
GPIO_clear_pin(self->gpio, self->pin_mask);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
return pin_call(args[0], n_args - 1, 0, args + 1);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
|
||||
|
||||
|
@ -524,24 +529,21 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj_type },
|
||||
|
||||
// class constants
|
||||
/// \constant IN - initialise the pin to input mode
|
||||
/// \constant OUT_PP - initialise the pin to output mode with a push-pull drive
|
||||
/// \constant OUT_OD - initialise the pin to output mode with an open-drain drive
|
||||
/// \constant AF_PP - initialise the pin to alternate-function mode with a push-pull drive
|
||||
/// \constant AF_OD - initialise the pin to alternate-function mode with an open-drain drive
|
||||
/// \constant ANALOG - initialise the pin to analog mode
|
||||
/// \constant PULL_NONE - don't enable any pull up or down resistors on the pin
|
||||
/// \constant PULL_UP - enable the pull-up resistor on the pin
|
||||
/// \constant PULL_DOWN - enable the pull-down resistor on the pin
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ALT), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ALT_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
|
||||
|
||||
// legacy class constants
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_OUT_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_AF_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) },
|
||||
|
||||
#include "genhdr/pins_af_const.h"
|
||||
};
|
||||
|
@ -553,6 +555,7 @@ const mp_obj_type_t pin_type = {
|
|||
.name = MP_QSTR_Pin,
|
||||
.print = pin_print,
|
||||
.make_new = pin_make_new,
|
||||
.call = pin_call,
|
||||
.locals_dict = (mp_obj_t)&pin_locals_dict,
|
||||
};
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ Q(PinAF)
|
|||
Q(PinNamed)
|
||||
Q(init)
|
||||
Q(value)
|
||||
Q(alt)
|
||||
Q(low)
|
||||
Q(high)
|
||||
Q(name)
|
||||
|
@ -164,14 +165,18 @@ Q(pull)
|
|||
Q(index)
|
||||
Q(reg)
|
||||
Q(IN)
|
||||
Q(OUT)
|
||||
Q(OPEN_DRAIN)
|
||||
Q(ALT)
|
||||
Q(ALT_OPEN_DRAIN)
|
||||
Q(ANALOG)
|
||||
Q(PULL_UP)
|
||||
Q(PULL_DOWN)
|
||||
Q(OUT_PP)
|
||||
Q(OUT_OD)
|
||||
Q(AF_PP)
|
||||
Q(AF_OD)
|
||||
Q(ANALOG)
|
||||
Q(PULL_NONE)
|
||||
Q(PULL_UP)
|
||||
Q(PULL_DOWN)
|
||||
|
||||
// for LED object
|
||||
Q(LED)
|
||||
|
|
Ładowanie…
Reference in New Issue