Merge branch 'pin-af' of https://github.com/dhylands/micropython into dhylands-pin-af
This commit is contained in:
commit
196773505a
|
@ -11,7 +11,7 @@ BUILD ?= build-$(BOARD)
|
|||
include ../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
@ -74,6 +74,7 @@ SRC_C = \
|
|||
timer.c \
|
||||
led.c \
|
||||
pin.c \
|
||||
pin_defs_stmhal.c \
|
||||
pin_named_pins.c \
|
||||
bufhelper.c \
|
||||
i2c.c \
|
||||
|
@ -227,6 +228,8 @@ AF_FILE = boards/stm32f4xx-af.csv
|
|||
PREFIX_FILE = boards/stm32f4xx-prefix.c
|
||||
GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c
|
||||
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
|
||||
GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
|
||||
GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins-af-const.h
|
||||
|
||||
INSERT_USB_IDS = ../tools/insert-usb-ids.py
|
||||
FILE2H = ../tools/file2h.py
|
||||
|
@ -247,9 +250,9 @@ $(BUILD)/main.o: $(GEN_CDCINF_HEADER)
|
|||
|
||||
# Use a pattern rule here so that make will only call make-pins.py once to make
|
||||
# both pins_$(BOARD).c and pins.h
|
||||
$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE)
|
||||
$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%-af-const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC)
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) > $(GEN_PINS_SRC)
|
||||
|
||||
$(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c
|
||||
$(call compile_c)
|
||||
|
|
|
@ -72,6 +72,9 @@ class AlternateFunction(object):
|
|||
return self.func
|
||||
return '{:s}{:d}'.format(self.func, self.fn_num)
|
||||
|
||||
def mux_name(self):
|
||||
return 'AF{:d}_{:s}'.format(self.idx, self.ptr())
|
||||
|
||||
def print(self):
|
||||
"""Prints the C representation of this AF."""
|
||||
if self.supported:
|
||||
|
@ -84,6 +87,9 @@ class AlternateFunction(object):
|
|||
print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx,
|
||||
self.func, fn_num, self.pin_type, self.ptr(), self.af_str))
|
||||
|
||||
def qstr_list(self):
|
||||
return [self.mux_name()]
|
||||
|
||||
|
||||
class Pin(object):
|
||||
"""Holds the information associated with a pin."""
|
||||
|
@ -170,6 +176,14 @@ class Pin(object):
|
|||
hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'.
|
||||
format(self.cpu_pin_name()))
|
||||
|
||||
def qstr_list(self):
|
||||
result = []
|
||||
for alt_fn in self.alt_fn:
|
||||
if alt_fn.is_supported():
|
||||
result += alt_fn.qstr_list()
|
||||
return result
|
||||
|
||||
|
||||
class NamedPin(object):
|
||||
|
||||
def __init__(self, name, pin):
|
||||
|
@ -225,13 +239,13 @@ class Pins(object):
|
|||
self.board_pins.append(NamedPin(row[0], pin))
|
||||
|
||||
def print_named(self, label, named_pins):
|
||||
print('const pin_named_pin_t pin_{:s}_pins[] = {{'.format(label))
|
||||
print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
|
||||
for named_pin in named_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
print(' {{ "{:s}", &pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
|
||||
print(' { NULL, NULL }')
|
||||
print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:s}), (mp_obj_t)&pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
|
||||
print('};')
|
||||
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
|
||||
|
||||
def print(self):
|
||||
for named_pin in self.cpu_pins:
|
||||
|
@ -269,6 +283,38 @@ class Pins(object):
|
|||
hdr_file.write('extern const pin_obj_t * const pin_adc2[];\n')
|
||||
hdr_file.write('extern const pin_obj_t * const pin_adc3[];\n')
|
||||
|
||||
def print_qstr(self, qstr_filename):
|
||||
with open(qstr_filename, 'wt') as qstr_file:
|
||||
qstr_set = set([])
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
qstr_set |= set(pin.qstr_list())
|
||||
qstr_set |= set([named_pin.name()])
|
||||
for named_pin in self.board_pins:
|
||||
qstr_set |= set([named_pin.name()])
|
||||
for qstr in sorted(qstr_set):
|
||||
print('Q({})'.format(qstr), file=qstr_file)
|
||||
|
||||
def print_af_hdr(self, af_const_filename):
|
||||
with open(af_const_filename, 'wt') as af_const_file:
|
||||
af_hdr_set = set([])
|
||||
mux_name_width = 0
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
for af in pin.alt_fn:
|
||||
if af.is_supported():
|
||||
mux_name = af.mux_name()
|
||||
af_hdr_set |= set([mux_name])
|
||||
if len(mux_name) > mux_name_width:
|
||||
mux_name_width = len(mux_name)
|
||||
for mux_name in sorted(af_hdr_set):
|
||||
key = 'MP_OBJ_NEW_QSTR(MP_QSTR_{}),'.format(mux_name)
|
||||
val = 'MP_OBJ_NEW_SMALL_INT(GPIO_{})'.format(mux_name)
|
||||
print(' { %-*s %s },' % (mux_name_width + 26, key, val),
|
||||
file=af_const_file)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
|
@ -282,6 +328,12 @@ def main():
|
|||
help="Specifies the alternate function file for the chip",
|
||||
default="stm32f4xx-af.csv"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--af-const",
|
||||
dest="af_const_filename",
|
||||
help="Specifies header file for alternate function constants.",
|
||||
default="build/pins-af-const.h"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-b", "--board",
|
||||
dest="board_filename",
|
||||
|
@ -293,6 +345,12 @@ def main():
|
|||
help="Specifies beginning portion of generated pins file",
|
||||
default="stm32f4xx-prefix.c"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", "--qstr",
|
||||
dest="qstr_filename",
|
||||
help="Specifies name of generated qstr header file",
|
||||
default="build/pins-qstr.h"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r", "--hdr",
|
||||
dest="hdr_filename",
|
||||
|
@ -323,6 +381,8 @@ def main():
|
|||
pins.print_adc(2)
|
||||
pins.print_adc(3)
|
||||
pins.print_header(args.hdr_filename)
|
||||
pins.print_qstr(args.qstr_filename)
|
||||
pins.print_af_hdr(args.af_const_filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
|
||||
{ \
|
||||
{ &pin_af_type }, \
|
||||
.name = MP_QSTR_AF ## af_idx ## _ ## af_fn ## af_unit, \
|
||||
.idx = (af_idx), \
|
||||
.fn = AF_FN_ ## af_fn, \
|
||||
.unit = (af_unit), \
|
||||
|
@ -24,7 +25,7 @@
|
|||
#define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \
|
||||
{ \
|
||||
{ &pin_type }, \
|
||||
.name = #p_port #p_pin, \
|
||||
.name = MP_QSTR_ ## p_port ## p_pin, \
|
||||
.port = PORT_ ## p_port, \
|
||||
.pin = (p_pin), \
|
||||
.num_af = (p_num_af), \
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
#define GPIO_read_pin(gpio, pin) (((gpio)->IDR >> (pin)) & 1)
|
||||
#define GPIO_set_pin(gpio, pin_mask) (((gpio)->BSRRL) = (pin_mask))
|
||||
#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->BSRRH) = (pin_mask))
|
||||
#define GPIO_read_output_pin(gpio, pin) (((gpio)->ODR >> (pin)) & 1)
|
||||
|
|
234
stmhal/pin.c
234
stmhal/pin.c
|
@ -63,7 +63,8 @@
|
|||
///
|
||||
/// Users can add their own names:
|
||||
///
|
||||
/// pyb.Pin.dict["LeftMotorDir"] = pyb.Pin.cpu.C12
|
||||
/// MyMapperDict = { 'LeftMotorDir' : pyb.Pin.cpu.C12 }
|
||||
/// pyb.Pin.dict(MyMapperDict)
|
||||
/// g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)
|
||||
///
|
||||
/// and can query mappings
|
||||
|
@ -155,8 +156,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
|
|||
}
|
||||
|
||||
// See if the pin name matches a board pin
|
||||
const char *pin_name = mp_obj_str_get_str(user_obj);
|
||||
pin_obj = pin_find_named_pin(pin_board_pins, pin_name);
|
||||
pin_obj = pin_find_named_pin(&pin_board_pins_locals_dict, user_obj);
|
||||
if (pin_obj) {
|
||||
if (pin_class_debug) {
|
||||
printf("Pin.board maps ");
|
||||
|
@ -169,7 +169,7 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
|
|||
}
|
||||
|
||||
// See if the pin name matches a cpu pin
|
||||
pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name);
|
||||
pin_obj = pin_find_named_pin(&pin_cpu_pins_locals_dict, user_obj);
|
||||
if (pin_obj) {
|
||||
if (pin_class_debug) {
|
||||
printf("Pin.cpu maps ");
|
||||
|
@ -181,34 +181,69 @@ const pin_obj_t *pin_find(mp_obj_t user_obj) {
|
|||
return pin_obj;
|
||||
}
|
||||
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name));
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", mp_obj_str_get_str(user_obj)));
|
||||
}
|
||||
|
||||
/// \method __str__()
|
||||
/// Return a string describing the pin object.
|
||||
STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_obj_t *self = self_in;
|
||||
print(env, "<Pin %s>", self->name);
|
||||
|
||||
// Need to query mode, pull, af
|
||||
|
||||
print(env, "Pin(Pin.cpu.%s", qstr_str(self->name));
|
||||
uint32_t mode = pin_get_mode(self);
|
||||
if (mode == GPIO_MODE_ANALOG) {
|
||||
print(env, ", mode=Pin.ANALOG)", qstr_str(self->name));
|
||||
} else {
|
||||
const char *pull_str = "";
|
||||
uint32_t pull = pin_get_pull(self);
|
||||
if (pull == GPIO_PULLUP) {
|
||||
pull_str = ", pull=Pin.PULL_UP";
|
||||
} else if (pull == GPIO_PULLDOWN) {
|
||||
pull_str = ", pull=Pin.PULL_DOWN";
|
||||
}
|
||||
if (mode == GPIO_MODE_INPUT) {
|
||||
print(env, ", mode=Pin.IN%s)", pull_str);
|
||||
} else if (mode == GPIO_MODE_OUTPUT_PP || mode == GPIO_MODE_OUTPUT_OD) {
|
||||
if (mode == GPIO_MODE_OUTPUT_PP) {
|
||||
print(env, ", mode=Pin.OUT_PP%s)", pull_str);
|
||||
} else {
|
||||
print(env, ", mode=Pin.OUT_OD%s)", pull_str);
|
||||
}
|
||||
} else {
|
||||
if (mode == GPIO_MODE_AF_PP) {
|
||||
print(env, ", mode=Pin.AF_PP");
|
||||
} else {
|
||||
print(env, ", mode=Pin.AF_OD");
|
||||
}
|
||||
mp_uint_t af_idx = pin_get_af(self);
|
||||
const pin_af_obj_t *af = pin_find_af_by_index(self, af_idx);
|
||||
if (af == NULL) {
|
||||
print(env, ", af=%d%s)", af_idx, pull_str);
|
||||
} else {
|
||||
print(env, ", af=Pin.%s)", qstr_str(af->name), pull_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pin_obj_init(uint n_args, mp_obj_t *args);
|
||||
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *pin, uint n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||
|
||||
/// \classmethod \constructor(id, ...)
|
||||
/// Create a new Pin object associated with the id. If additional arguments are given,
|
||||
/// they are used to initialise the pin. See `init`.
|
||||
STATIC mp_obj_t pin_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 3, false);
|
||||
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
// Run an argument through the mapper and return the result.
|
||||
const pin_obj_t *pin = pin_find(args[0]);
|
||||
|
||||
if (n_args >= 2) {
|
||||
if (n_args > 1 || n_kw > 0) {
|
||||
// pin mode given, so configure this GPIO
|
||||
mp_obj_t args2[3] = {(mp_obj_t)pin, args[1], MP_OBJ_NULL};
|
||||
if (n_args == 3) {
|
||||
args2[2] = args[2];
|
||||
}
|
||||
pin_obj_init(n_args, args2);
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
|
||||
return (mp_obj_t)pin;
|
||||
|
@ -238,6 +273,20 @@ STATIC mp_obj_t pin_map_dict(uint n_args, mp_obj_t *args) {
|
|||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_dict_fun_obj, 1, 2, pin_map_dict);
|
||||
STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_map_dict_obj, (mp_obj_t)&pin_map_dict_fun_obj);
|
||||
|
||||
/// |classmethod af_list()
|
||||
/// Returns an array of alternate functions available for this pin.
|
||||
STATIC mp_obj_t pin_af_list(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
mp_obj_t result = mp_obj_new_list(0, NULL);
|
||||
|
||||
const pin_af_obj_t *af = self->af;
|
||||
for (mp_uint_t i = 0; i < self->num_af; i++, af++) {
|
||||
mp_obj_list_append(result, (mp_obj_t)af);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_list_obj, pin_af_list);
|
||||
|
||||
/// \classmethod debug([state])
|
||||
/// Get or set the debugging state (`True` or `False` for on or off).
|
||||
STATIC mp_obj_t pin_debug(uint n_args, mp_obj_t *args) {
|
||||
|
@ -250,7 +299,7 @@ STATIC mp_obj_t pin_debug(uint n_args, 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)
|
||||
/// \method init(mode, pull=Pin.PULL_NONE, af)
|
||||
/// Initialise the pin:
|
||||
///
|
||||
/// - `mode` can be one of:
|
||||
|
@ -264,26 +313,53 @@ STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, (mp_obj_t)&pin_debug_fun_o
|
|||
/// - `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`.
|
||||
// TODO allow keyword args
|
||||
STATIC mp_obj_t pin_obj_init(uint n_args, mp_obj_t *args) {
|
||||
pin_obj_t *self = args[0];
|
||||
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_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none}},
|
||||
};
|
||||
#define PIN_INIT_NUM_ARGS MP_ARRAY_SIZE(pin_init_args)
|
||||
|
||||
STATIC mp_obj_t pin_obj_init_helper(const pin_obj_t *self, uint 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);
|
||||
|
||||
// get io mode
|
||||
uint mode = mp_obj_get_int(args[1]);
|
||||
uint mode = vals[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 = GPIO_NOPULL;
|
||||
if (n_args >= 3) {
|
||||
pull = mp_obj_get_int(args[2]);
|
||||
if (!IS_GPIO_PULL(pull)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull));
|
||||
uint pull = vals[1].u_int;
|
||||
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_idx = -1;
|
||||
mp_obj_t af_obj = vals[2].u_obj;
|
||||
if (af_obj != mp_const_none) {
|
||||
if (MP_OBJ_IS_STR(af_obj)) {
|
||||
const pin_af_obj_t *af;
|
||||
const char *af_str = mp_obj_str_get_str(af_obj);
|
||||
af = pin_find_af_by_name(self, af_str);
|
||||
if (af == NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin af: %s", af_str));
|
||||
}
|
||||
af_idx = af->idx;
|
||||
} else {
|
||||
af_idx = mp_obj_get_int(af_obj);
|
||||
}
|
||||
}
|
||||
if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af_idx)) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin af: %d", af_idx));
|
||||
}
|
||||
|
||||
// enable the peripheral clock for the port of this pin
|
||||
switch (self->port) {
|
||||
|
@ -325,12 +401,15 @@ STATIC mp_obj_t pin_obj_init(uint n_args, mp_obj_t *args) {
|
|||
GPIO_InitStructure.Mode = mode;
|
||||
GPIO_InitStructure.Pull = pull;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Alternate = af_idx;
|
||||
HAL_GPIO_Init(self->gpio, &GPIO_InitStructure);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_init_obj, 2, 3, pin_obj_init);
|
||||
STATIC mp_obj_t pin_obj_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);
|
||||
|
||||
/// \method value([value])
|
||||
/// Get or set the digital logic level of the pin:
|
||||
|
@ -378,10 +457,29 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);
|
|||
/// Get the pin name.
|
||||
STATIC mp_obj_t pin_name(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_str(self->name));
|
||||
return MP_OBJ_NEW_QSTR(self->name);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name);
|
||||
|
||||
/// \method names()
|
||||
/// Returns the cpu and board names for this pin.
|
||||
STATIC mp_obj_t pin_names(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
mp_obj_t result = mp_obj_new_list(0, NULL);
|
||||
mp_obj_list_append(result, MP_OBJ_NEW_QSTR(self->name));
|
||||
|
||||
mp_map_t *map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
|
||||
mp_map_elem_t *elem = map->table;
|
||||
|
||||
for (mp_uint_t i = 0; i < map->used; i++, elem++) {
|
||||
if (elem->value == self) {
|
||||
mp_obj_list_append(result, elem->key);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_names_obj, pin_names);
|
||||
|
||||
/// \method port()
|
||||
/// Get the pin port.
|
||||
STATIC mp_obj_t pin_port(mp_obj_t self_in) {
|
||||
|
@ -398,6 +496,14 @@ STATIC mp_obj_t pin_pin(mp_obj_t self_in) {
|
|||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin);
|
||||
|
||||
/// \method gpio()
|
||||
/// Returns the base address of the GPIO block associated with this pin.
|
||||
STATIC mp_obj_t pin_gpio(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_int_t)self->gpio);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_gpio_obj, pin_gpio);
|
||||
|
||||
STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pin_init_obj },
|
||||
|
@ -405,8 +511,11 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_names), (mp_obj_t)&pin_names_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_af_list), (mp_obj_t)&pin_af_list_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pin_gpio_obj },
|
||||
|
||||
// class methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_mapper), (mp_obj_t)&pin_mapper_obj },
|
||||
|
@ -414,8 +523,8 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
|||
{ MP_OBJ_NEW_QSTR(MP_QSTR_debug), (mp_obj_t)&pin_debug_obj },
|
||||
|
||||
// class attributes
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&pin_board_pins_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&pin_board_pins_obj_type },
|
||||
{ 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
|
||||
|
@ -433,6 +542,7 @@ STATIC const mp_map_elem_t pin_locals_dict_table[] = {
|
|||
{ 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"
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table);
|
||||
|
@ -445,14 +555,76 @@ const mp_obj_type_t pin_type = {
|
|||
.locals_dict = (mp_obj_t)&pin_locals_dict,
|
||||
};
|
||||
|
||||
/// \moduleref pyb
|
||||
/// \class PinAF - Pin Alternate Functions
|
||||
///
|
||||
/// A Pin represents a physical pin on the microcprocessor. Each pin
|
||||
/// can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF
|
||||
/// object represents a particular function for a pin.
|
||||
///
|
||||
/// Usage Model:
|
||||
///
|
||||
/// x3 = pyb.Pin.board.X3
|
||||
/// x3_af = x3.af_list()
|
||||
///
|
||||
/// x3_af will now contain an array of PinAF objects which are availble on
|
||||
/// pin X3.
|
||||
///
|
||||
/// For the pyboard, x3_af would contain:
|
||||
/// [Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM9, Pin.AF7_USART2]
|
||||
///
|
||||
/// Normally, each peripheral would configure the af automatically, but sometimes
|
||||
/// the same function is available on multiple pins, and having more control
|
||||
/// is desired.
|
||||
///
|
||||
/// To configure X3 to expose TIM2_CH3, you could use:
|
||||
/// pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=pyb.Pin.AF1_TIM2)
|
||||
/// or:
|
||||
/// pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, af=1)
|
||||
|
||||
/// \method __str__()
|
||||
/// Return a string describing the alternate function.
|
||||
STATIC void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_af_obj_t *self = self_in;
|
||||
print(env, "<Pin AF %d fn:%d unit:%d typ:%d>", self->idx, self->fn,
|
||||
self->unit, self->type);
|
||||
print(env, "Pin.%s", qstr_str(self->name));
|
||||
}
|
||||
|
||||
/// \method index()
|
||||
/// Return the alternate function index.
|
||||
STATIC mp_obj_t pin_af_index(mp_obj_t self_in) {
|
||||
pin_af_obj_t *af = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT(af->idx);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_index_obj, pin_af_index);
|
||||
|
||||
/// \method index()
|
||||
/// Return the name of the alternate function.
|
||||
STATIC mp_obj_t pin_af_name(mp_obj_t self_in) {
|
||||
pin_af_obj_t *af = self_in;
|
||||
return MP_OBJ_NEW_QSTR(af->name);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_name_obj, pin_af_name);
|
||||
|
||||
/// \method index()
|
||||
/// Return the base register associated with the peripheral assigned to this
|
||||
/// alternate function. For example, if the alternate function were TIM2_CH3
|
||||
/// this would return stm.TIM2
|
||||
STATIC mp_obj_t pin_af_reg(mp_obj_t self_in) {
|
||||
pin_af_obj_t *af = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)af->reg);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_reg_obj, pin_af_reg);
|
||||
|
||||
STATIC const mp_map_elem_t pin_af_locals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_index), (mp_obj_t)&pin_af_index_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_af_name_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reg), (mp_obj_t)&pin_af_reg_obj },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_af_locals_dict, pin_af_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pin_af_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinAF,
|
||||
.print = pin_af_obj_print,
|
||||
.locals_dict = (mp_obj_t)&pin_af_locals_dict,
|
||||
};
|
||||
|
|
17
stmhal/pin.h
17
stmhal/pin.h
|
@ -31,6 +31,7 @@
|
|||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
qstr name;
|
||||
uint8_t idx;
|
||||
uint8_t fn;
|
||||
uint8_t unit;
|
||||
|
@ -45,7 +46,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const char *name;
|
||||
qstr name;
|
||||
uint32_t port : 4;
|
||||
uint32_t pin : 5; // Some ARM processors use 32 bits/PORT
|
||||
uint32_t num_af : 4;
|
||||
|
@ -75,10 +76,18 @@ typedef struct {
|
|||
const pin_named_pin_t *named_pins;
|
||||
} pin_named_pins_obj_t;
|
||||
|
||||
extern const pin_named_pins_obj_t pin_board_pins_obj;
|
||||
extern const pin_named_pins_obj_t pin_cpu_pins_obj;
|
||||
extern const mp_obj_type_t pin_board_pins_obj_type;
|
||||
extern const mp_obj_type_t pin_cpu_pins_obj_type;
|
||||
|
||||
extern const mp_obj_dict_t pin_cpu_pins_locals_dict;
|
||||
extern const mp_obj_dict_t pin_board_pins_locals_dict;
|
||||
|
||||
void pin_init0(void);
|
||||
uint32_t pin_get_mode(const pin_obj_t *pin);
|
||||
uint32_t pin_get_pull(const pin_obj_t *pin);
|
||||
uint32_t pin_get_af(const pin_obj_t *pin);
|
||||
const pin_obj_t *pin_find(mp_obj_t user_obj);
|
||||
const pin_obj_t *pin_find_named_pin(const pin_named_pin_t *pins, const char *name);
|
||||
const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name);
|
||||
const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit, uint8_t pin_type);
|
||||
const pin_af_obj_t *pin_find_af_by_index(const pin_obj_t *pin, mp_uint_t af_idx);
|
||||
const pin_af_obj_t *pin_find_af_by_name(const pin_obj_t *pin, const char *name);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "pin.h"
|
||||
|
||||
// Returns the pin mode. This value returned by this macro should be one of:
|
||||
// GPIO_MODE_INPUT, GPIO_MODE_OUTPUT_PP, GPIO_MODE_OUTPUT_OD,
|
||||
// GPIO_MODE_AF_PP, GPIO_MODE_AF_OD, or GPIO_MODE_ANALOG.
|
||||
|
||||
uint32_t pin_get_mode(const pin_obj_t *pin) {
|
||||
GPIO_TypeDef *gpio = pin->gpio;
|
||||
uint32_t mode = (gpio->MODER >> (pin->pin * 2)) & 3;
|
||||
if (mode != GPIO_MODE_ANALOG) {
|
||||
if (gpio->OTYPER & pin->pin_mask) {
|
||||
mode |= 1 << 4;
|
||||
}
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
// Returns the pin pullup/pulldown. The value returned by this macro should
|
||||
// be one of GPIO_NOPULL, GPIO_PULLUP, or GPIO_PULLDOWN.
|
||||
|
||||
uint32_t pin_get_pull(const pin_obj_t *pin) {
|
||||
return (pin->gpio->PUPDR >> (pin->pin * 2)) & 3;
|
||||
}
|
||||
|
||||
// Returns the af (alternate function) index currently set for a pin.
|
||||
|
||||
uint32_t pin_get_af(const pin_obj_t *pin) {
|
||||
return (pin->gpio->AFR[pin->pin >> 3] >> ((pin->pin & 7) * 4)) & 0xf;
|
||||
}
|
||||
|
|
@ -41,52 +41,55 @@ STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, .
|
|||
print(env, "<Pin.%s>", qstr_str(self->name));
|
||||
}
|
||||
|
||||
STATIC void pin_named_pins_obj_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) {
|
||||
pin_named_pins_obj_t *self = self_in;
|
||||
const char *attr = qstr_str(attr_qstr);
|
||||
const pin_obj_t *pin = pin_find_named_pin(self->named_pins, attr);
|
||||
if (pin) {
|
||||
dest[0] = (mp_obj_t)pin;
|
||||
dest[1] = MP_OBJ_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static const mp_obj_type_t pin_named_pins_obj_type = {
|
||||
const mp_obj_type_t pin_cpu_pins_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PinNamed,
|
||||
.print = pin_named_pins_obj_print,
|
||||
.load_attr = pin_named_pins_obj_load_attr,
|
||||
};
|
||||
|
||||
const pin_named_pins_obj_t pin_board_pins_obj = {
|
||||
{ &pin_named_pins_obj_type },
|
||||
.name = MP_QSTR_board,
|
||||
.named_pins = pin_board_pins,
|
||||
};
|
||||
|
||||
const pin_named_pins_obj_t pin_cpu_pins_obj = {
|
||||
{ &pin_named_pins_obj_type },
|
||||
.name = MP_QSTR_cpu,
|
||||
.named_pins = pin_cpu_pins,
|
||||
.print = pin_named_pins_obj_print,
|
||||
.locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict,
|
||||
};
|
||||
|
||||
const pin_obj_t *pin_find_named_pin(const pin_named_pin_t *named_pins, const char *name) {
|
||||
const pin_named_pin_t *named_pin = named_pins;
|
||||
while (named_pin->name) {
|
||||
if (!strcmp(name, named_pin->name)) {
|
||||
return named_pin->pin;
|
||||
}
|
||||
named_pin++;
|
||||
const mp_obj_type_t pin_board_pins_obj_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_board,
|
||||
.print = pin_named_pins_obj_print,
|
||||
.locals_dict = (mp_obj_t)&pin_board_pins_locals_dict,
|
||||
};
|
||||
|
||||
const pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
|
||||
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
|
||||
mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP);
|
||||
if (named_elem != NULL && named_elem->value != NULL) {
|
||||
return named_elem->value;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit, uint8_t type) {
|
||||
const pin_af_obj_t *af = pin->af;
|
||||
for (int i = 0; i < pin->num_af; i++, af++) {
|
||||
for (mp_uint_t i = 0; i < pin->num_af; i++, af++) {
|
||||
if (af->fn == fn && af->unit == unit && af->type == type) {
|
||||
return af;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pin_af_obj_t *pin_find_af_by_index(const pin_obj_t *pin, mp_uint_t af_idx) {
|
||||
const pin_af_obj_t *af = pin->af;
|
||||
for (mp_uint_t i = 0; i < pin->num_af; i++, af++) {
|
||||
if (af->idx == af_idx) {
|
||||
return af;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const pin_af_obj_t *pin_find_af_by_name(const pin_obj_t *pin, const char *name) {
|
||||
const pin_af_obj_t *af = pin->af;
|
||||
for (mp_uint_t i = 0; i < pin->num_af; i++, af++) {
|
||||
if (strcmp(name, qstr_str(af->name)) == 0) {
|
||||
return af;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -93,13 +93,22 @@ Q(value)
|
|||
Q(low)
|
||||
Q(high)
|
||||
Q(name)
|
||||
Q(names)
|
||||
Q(af)
|
||||
Q(af_list)
|
||||
Q(port)
|
||||
Q(pin)
|
||||
Q(gpio)
|
||||
Q(mapper)
|
||||
Q(dict)
|
||||
Q(debug)
|
||||
Q(board)
|
||||
Q(cpu)
|
||||
Q(af)
|
||||
Q(mode)
|
||||
Q(pull)
|
||||
Q(index)
|
||||
Q(reg)
|
||||
Q(IN)
|
||||
Q(OUT_PP)
|
||||
Q(OUT_OD)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
include ../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h
|
||||
QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
|
||||
|
||||
# include py core make definitions
|
||||
include ../py/py.mk
|
||||
|
@ -53,6 +53,7 @@ SRC_C = \
|
|||
lexermemzip.c \
|
||||
memzip.c \
|
||||
modpyb.c \
|
||||
pin_defs_teensy.c \
|
||||
teensy_hal.c \
|
||||
uart.c \
|
||||
usb.c \
|
||||
|
@ -137,6 +138,8 @@ AF_FILE = mk20dx256-af.csv
|
|||
PREFIX_FILE = mk20dx256-prefix.c
|
||||
GEN_PINS_SRC = $(BUILD)/pins_gen.c
|
||||
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
|
||||
GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
|
||||
GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins-af-const.h
|
||||
|
||||
# Making OBJ use an order-only depenedency on the generated pins.h file
|
||||
# has the side effect of making the pins.h file before we actually compile
|
||||
|
@ -147,9 +150,9 @@ $(OBJ): | $(HEADER_BUILD)/pins.h
|
|||
|
||||
# Use a pattern rule here so that make will only call make-pins.py once to make
|
||||
# both pins_$(BOARD).c and pins.h
|
||||
$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: teensy-%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE)
|
||||
$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%-af-const.h $(BUILD)/%_qstr.h: teensy-%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC)
|
||||
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) > $(GEN_PINS_SRC)
|
||||
|
||||
$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
|
||||
$(call compile_c)
|
||||
|
|
|
@ -25,11 +25,17 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||
if ((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {
|
||||
/* Check the Alternate function parameter */
|
||||
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
|
||||
*port_pcr &= ~PORT_PCR_MUX_MASK;
|
||||
*port_pcr |= PORT_PCR_MUX(GPIO_Init->Alternate);
|
||||
}
|
||||
else if (GPIO_Init->Mode == GPIO_MODE_ANALOG) {
|
||||
GPIO_Init->Alternate = 0;
|
||||
}
|
||||
else {
|
||||
GPIO_Init->Alternate = 1;
|
||||
}
|
||||
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
*port_pcr &= ~PORT_PCR_MUX_MASK;
|
||||
*port_pcr |= PORT_PCR_MUX(GPIO_Init->Alternate);
|
||||
|
||||
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||
if (GPIO_Init->Mode == GPIO_MODE_INPUT || GPIO_Init->Mode == GPIO_MODE_ANALOG) {
|
||||
|
@ -112,4 +118,3 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "usb.h"
|
||||
#include "led.h"
|
||||
#include "uart.h"
|
||||
//#include "pin.h"
|
||||
#include "pin.h"
|
||||
#include "pybstdio.h"
|
||||
|
||||
|
||||
|
@ -272,7 +272,7 @@ soft_reset:
|
|||
|
||||
readline_init0();
|
||||
|
||||
//pin_init();
|
||||
pin_init0();
|
||||
|
||||
#if 0
|
||||
// add some functions to the python namespace
|
||||
|
|
|
@ -71,6 +71,9 @@ class AlternateFunction(object):
|
|||
return self.func
|
||||
return '{:s}{:d}'.format(self.func, self.fn_num)
|
||||
|
||||
def mux_name(self):
|
||||
return 'AF{:d}_{:s}'.format(self.idx, self.ptr())
|
||||
|
||||
def print(self):
|
||||
"""Prints the C representation of this AF."""
|
||||
if self.supported:
|
||||
|
@ -83,6 +86,9 @@ class AlternateFunction(object):
|
|||
print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx,
|
||||
self.func, fn_num, self.pin_type, self.ptr(), self.af_str))
|
||||
|
||||
def qstr_list(self):
|
||||
return [self.mux_name()]
|
||||
|
||||
|
||||
class Pin(object):
|
||||
"""Holds the information associated with a pin."""
|
||||
|
@ -169,6 +175,14 @@ class Pin(object):
|
|||
hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'.
|
||||
format(self.cpu_pin_name()))
|
||||
|
||||
def qstr_list(self):
|
||||
result = []
|
||||
for alt_fn in self.alt_fn:
|
||||
if alt_fn.is_supported():
|
||||
result += alt_fn.qstr_list()
|
||||
return result
|
||||
|
||||
|
||||
class NamedPin(object):
|
||||
|
||||
def __init__(self, name, pin):
|
||||
|
@ -222,13 +236,13 @@ class Pins(object):
|
|||
self.board_pins.append(NamedPin(row[0], pin))
|
||||
|
||||
def print_named(self, label, named_pins):
|
||||
print('const pin_named_pin_t pin_{:s}_pins[] = {{'.format(label))
|
||||
print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.format(label))
|
||||
for named_pin in named_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
print(' {{ "{:s}", &pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
|
||||
print(' { NULL, NULL }')
|
||||
print(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:s}), (mp_obj_t)&pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
|
||||
print('};')
|
||||
print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
|
||||
|
||||
def print(self):
|
||||
for named_pin in self.cpu_pins:
|
||||
|
@ -266,6 +280,39 @@ class Pins(object):
|
|||
hdr_file.write('extern const pin_obj_t * const pin_adc2[];\n')
|
||||
hdr_file.write('extern const pin_obj_t * const pin_adc3[];\n')
|
||||
|
||||
def print_qstr(self, qstr_filename):
|
||||
with open(qstr_filename, 'wt') as qstr_file:
|
||||
qstr_set = set([])
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
qstr_set |= set(pin.qstr_list())
|
||||
qstr_set |= set([named_pin.name()])
|
||||
for named_pin in self.board_pins:
|
||||
qstr_set |= set([named_pin.name()])
|
||||
for qstr in sorted(qstr_set):
|
||||
print('Q({})'.format(qstr), file=qstr_file)
|
||||
|
||||
|
||||
def print_af_hdr(self, af_const_filename):
|
||||
with open(af_const_filename, 'wt') as af_const_file:
|
||||
af_hdr_set = set([])
|
||||
mux_name_width = 0
|
||||
for named_pin in self.cpu_pins:
|
||||
pin = named_pin.pin()
|
||||
if pin.is_board_pin():
|
||||
for af in pin.alt_fn:
|
||||
if af.is_supported():
|
||||
mux_name = af.mux_name()
|
||||
af_hdr_set |= set([mux_name])
|
||||
if len(mux_name) > mux_name_width:
|
||||
mux_name_width = len(mux_name)
|
||||
for mux_name in sorted(af_hdr_set):
|
||||
key = 'MP_OBJ_NEW_QSTR(MP_QSTR_{}),'.format(mux_name)
|
||||
val = 'MP_OBJ_NEW_SMALL_INT(GPIO_{})'.format(mux_name)
|
||||
print(' { %-*s %s },' % (mux_name_width + 26, key, val),
|
||||
file=af_const_file)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
|
@ -279,6 +326,12 @@ def main():
|
|||
help="Specifies the alternate function file for the chip",
|
||||
default="stm32f4xx-af.csv"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--af-const",
|
||||
dest="af_const_filename",
|
||||
help="Specifies header file for alternate function constants.",
|
||||
default="build/pins-af-const.h"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-b", "--board",
|
||||
dest="board_filename",
|
||||
|
@ -290,6 +343,12 @@ def main():
|
|||
help="Specifies beginning portion of generated pins file",
|
||||
default="stm32f4xx-prefix.c"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", "--qstr",
|
||||
dest="qstr_filename",
|
||||
help="Specifies name of generated qstr header file",
|
||||
default="build/pins-qstr.h"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-r", "--hdr",
|
||||
dest="hdr_filename",
|
||||
|
@ -320,6 +379,8 @@ def main():
|
|||
pins.print_adc(2)
|
||||
pins.print_adc(3)
|
||||
pins.print_header(args.hdr_filename)
|
||||
pins.print_qstr(args.qstr_filename)
|
||||
pins.print_af_hdr(args.af_const_filename)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
import pyb
|
||||
print("Executing boot.py")
|
||||
|
||||
def pins():
|
||||
for pin_name in dir(pyb.Pin.board):
|
||||
pin = pyb.Pin(pin_name)
|
||||
print('{:10s} {:s}'.format(pin_name, str(pin)))
|
||||
|
||||
def af():
|
||||
for pin_name in dir(pyb.Pin.board):
|
||||
pin = pyb.Pin(pin_name)
|
||||
print('{:10s} {:s}'.format(pin_name, str(pin.af_list())))
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
|
||||
{ \
|
||||
{ &pin_af_type }, \
|
||||
.name = MP_QSTR_AF ## af_idx ## _ ## af_fn ## af_unit, \
|
||||
.idx = (af_idx), \
|
||||
.fn = AF_FN_ ## af_fn, \
|
||||
.unit = (af_unit), \
|
||||
|
@ -25,7 +26,7 @@
|
|||
#define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \
|
||||
{ \
|
||||
{ &pin_type }, \
|
||||
.name = #p_port #p_pin, \
|
||||
.name = MP_QSTR_ ## p_port ## p_pin, \
|
||||
.port = PORT_ ## p_port, \
|
||||
.pin = (p_pin), \
|
||||
.num_af = (p_num_af), \
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#include <stdint.h>
|
||||
#include <mk20dx128.h>
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include MICROPY_HAL_H
|
||||
#include "pin.h"
|
||||
|
||||
// Returns the pin mode. This value returned by this macro should be one of:
|
||||
// GPIO_MODE_INPUT, GPIO_MODE_OUTPUT_PP, GPIO_MODE_OUTPUT_OD,
|
||||
// GPIO_MODE_AF_PP, GPIO_MODE_AF_OD, or GPIO_MODE_ANALOG.
|
||||
|
||||
uint32_t pin_get_mode(const pin_obj_t *pin) {
|
||||
volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
|
||||
uint32_t pcr = *port_pcr;
|
||||
uint32_t af = (*port_pcr & PORT_PCR_MUX_MASK) >> 8;;
|
||||
|
||||
if (af == 0) {
|
||||
return GPIO_MODE_ANALOG;
|
||||
}
|
||||
if (af == 1) {
|
||||
if (pin->gpio->PDDR & (1 << pin->pin)) {
|
||||
if (pcr & PORT_PCR_ODE) {
|
||||
return GPIO_MODE_OUTPUT_OD;
|
||||
}
|
||||
return GPIO_MODE_OUTPUT_PP;
|
||||
}
|
||||
return GPIO_MODE_INPUT;
|
||||
}
|
||||
|
||||
if (pcr & PORT_PCR_ODE) {
|
||||
return GPIO_MODE_AF_OD;
|
||||
}
|
||||
return GPIO_MODE_AF_PP;
|
||||
}
|
||||
|
||||
// Returns the pin pullup/pulldown. The value returned by this macro should
|
||||
// be one of GPIO_NOPULL, GPIO_PULLUP, or GPIO_PULLDOWN.
|
||||
|
||||
uint32_t pin_get_pull(const pin_obj_t *pin) {
|
||||
volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
|
||||
|
||||
uint32_t pcr = *port_pcr;
|
||||
if (pcr & PORT_PCR_PE) {
|
||||
if (pcr & PORT_PCR_PS) {
|
||||
return GPIO_PULLUP;
|
||||
}
|
||||
return GPIO_PULLDOWN;
|
||||
}
|
||||
return GPIO_NOPULL;
|
||||
}
|
||||
|
||||
// Returns the af (alternate function) index currently set for a pin.
|
||||
|
||||
uint32_t pin_get_af(const pin_obj_t *pin) {
|
||||
volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
|
||||
return (*port_pcr & PORT_PCR_MUX_MASK) >> 8;
|
||||
}
|
|
@ -43,4 +43,3 @@ enum {
|
|||
SPI_TypeDef *SPI;
|
||||
|
||||
typedef GPIO_TypeDef pin_gpio_t;
|
||||
|
||||
|
|
|
@ -62,13 +62,21 @@ Q(value)
|
|||
Q(low)
|
||||
Q(high)
|
||||
Q(name)
|
||||
Q(names)
|
||||
Q(af)
|
||||
Q(af_list)
|
||||
Q(port)
|
||||
Q(pin)
|
||||
Q(gpio)
|
||||
Q(mapper)
|
||||
Q(dict)
|
||||
Q(debug)
|
||||
Q(board)
|
||||
Q(cpu)
|
||||
Q(mode)
|
||||
Q(pull)
|
||||
Q(index)
|
||||
Q(reg)
|
||||
Q(IN)
|
||||
Q(OUT_PP)
|
||||
Q(OUT_OD)
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct {
|
|||
#define GPIO_SPEED_FAST ((uint32_t)2)
|
||||
#define GPIO_SPEED_HIGH ((uint32_t)3)
|
||||
|
||||
#define IS_GPIO_AF(af) ((af) >= 0 && (af) <= 7)
|
||||
|
||||
typedef struct {
|
||||
uint32_t Pin;
|
||||
|
@ -96,6 +97,22 @@ typedef struct {
|
|||
#define GPIO_PIN_TO_PORT_PCR(GPIOx, pin) \
|
||||
(&PORTA_PCR0 + GPIO_PORT_TO_PORT_NUM(GPIOx) * 32 + (pin))
|
||||
|
||||
#define GPIO_AF2_I2C0 2
|
||||
#define GPIO_AF2_I2C1 2
|
||||
#define GPIO_AF2_SPI0 2
|
||||
#define GPIO_AF3_FTM0 3
|
||||
#define GPIO_AF3_FTM1 3
|
||||
#define GPIO_AF3_FTM2 3
|
||||
#define GPIO_AF3_UART0 3
|
||||
#define GPIO_AF3_UART1 3
|
||||
#define GPIO_AF3_UART2 3
|
||||
#define GPIO_AF4_FTM0 4
|
||||
#define GPIO_AF6_FTM1 6
|
||||
#define GPIO_AF6_FTM2 6
|
||||
#define GPIO_AF6_I2C1 6
|
||||
#define GPIO_AF7_FTM1 7
|
||||
|
||||
|
||||
__attribute__(( always_inline )) static inline void __WFI(void)
|
||||
{
|
||||
__asm volatile ("wfi");
|
||||
|
@ -109,3 +126,4 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *init);
|
|||
#define GPIO_read_pin(gpio, pin) (((gpio)->PDIR >> (pin)) & 1)
|
||||
#define GPIO_set_pin(gpio, pin_mask) (((gpio)->PSOR) = (pin_mask))
|
||||
#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->PCOR) = (pin_mask))
|
||||
#define GPIO_read_output_pin(gpio, pin) (((gpio)->PDOR >> (pin)) & 1)
|
||||
|
|
Loading…
Reference in New Issue