summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-08-08 22:41:06 +0100
committerDamien George <damien.p.george@gmail.com>2014-08-08 22:41:06 +0100
commit416227118150a6d3cac6ae94e4e9e8d7e482890f (patch)
tree586fae07925581402aa6f5dc22a6d290cc10d90b
parenta1d3ee376c25c0842096535c38e651431028d1b8 (diff)
parentb92e7533d3b40fd5129982370f177f47b2790df8 (diff)
downloadmicropython-416227118150a6d3cac6ae94e4e9e8d7e482890f.tar.gz
micropython-416227118150a6d3cac6ae94e4e9e8d7e482890f.zip
Merge branch 'dhylands-pin-af'
-rw-r--r--stmhal/Makefile13
-rwxr-xr-xstmhal/boards/make-pins.py70
-rw-r--r--stmhal/boards/stm32f4xx_af.csv (renamed from stmhal/boards/stm32f4xx-af.csv)0
-rw-r--r--stmhal/boards/stm32f4xx_prefix.c (renamed from stmhal/boards/stm32f4xx-prefix.c)5
-rw-r--r--stmhal/mphal.h1
-rw-r--r--stmhal/pin.c228
-rw-r--r--stmhal/pin.h17
-rw-r--r--stmhal/pin_defs_stmhal.c37
-rw-r--r--stmhal/pin_named_pins.c67
-rw-r--r--stmhal/qstrdefsport.h9
-rw-r--r--teensy/Makefile15
-rw-r--r--teensy/hal_gpio.c15
-rw-r--r--teensy/main.c4
-rwxr-xr-xteensy/make-pins.py67
-rw-r--r--teensy/memzip_files/boot.py10
-rw-r--r--teensy/mk20dx256_af.csv (renamed from teensy/mk20dx256-af.csv)0
-rw-r--r--teensy/mk20dx256_prefix.c (renamed from teensy/mk20dx256-prefix.c)3
-rw-r--r--teensy/pin_defs_teensy.c61
-rw-r--r--teensy/pin_defs_teensy.h1
-rw-r--r--teensy/qstrdefsport.h8
-rw-r--r--teensy/teensy_hal.h18
-rw-r--r--teensy/teensy_pins.csv (renamed from teensy/teensy-pins.csv)0
-rw-r--r--tests/pyb/pin.py10
-rw-r--r--tests/pyb/pin.py.exp4
24 files changed, 563 insertions, 100 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 4daf665fab..64c58151b4 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -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 \
@@ -223,10 +224,12 @@ $(BUILD)/firmware.elf: $(OBJ)
MAKE_PINS = boards/make-pins.py
BOARD_PINS = boards/$(BOARD)/pins.csv
-AF_FILE = boards/stm32f4xx-af.csv
-PREFIX_FILE = boards/stm32f4xx-prefix.c
+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)
diff --git a/stmhal/boards/make-pins.py b/stmhal/boards/make-pins.py
index e3a3f583a5..cc580f7cd7 100755
--- a/stmhal/boards/make-pins.py
+++ b/stmhal/boards/make-pins.py
@@ -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(
@@ -280,7 +326,13 @@ def main():
"-a", "--af",
dest="af_filename",
help="Specifies the alternate function file for the chip",
- default="stm32f4xx-af.csv"
+ 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",
@@ -291,7 +343,13 @@ def main():
"-p", "--prefix",
dest="prefix_filename",
help="Specifies beginning portion of generated pins file",
- default="stm32f4xx-prefix.c"
+ 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",
@@ -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__":
diff --git a/stmhal/boards/stm32f4xx-af.csv b/stmhal/boards/stm32f4xx_af.csv
index b9a308a82c..b9a308a82c 100644
--- a/stmhal/boards/stm32f4xx-af.csv
+++ b/stmhal/boards/stm32f4xx_af.csv
diff --git a/stmhal/boards/stm32f4xx-prefix.c b/stmhal/boards/stm32f4xx_prefix.c
index 3bbb6bda0e..c200301726 100644
--- a/stmhal/boards/stm32f4xx-prefix.c
+++ b/stmhal/boards/stm32f4xx_prefix.c
@@ -1,4 +1,4 @@
-// stm32fxx-prefix.c becomes the initial portion of the generated pins file.
+// stm32f4xx_prefix.c becomes the initial portion of the generated pins file.
#include <stdio.h>
#include <stdint.h>
@@ -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), \
diff --git a/stmhal/mphal.h b/stmhal/mphal.h
index 4e9a8b2bb8..33407622c0 100644
--- a/stmhal/mphal.h
+++ b/stmhal/mphal.h
@@ -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)
diff --git a/stmhal/pin.c b/stmhal/pin.c
index 0ef8b69508..0271ced30f 100644
--- a/stmhal/pin.c
+++ b/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=None)
/// Initialise the pin:
///
/// - `mode` can be one of:
@@ -264,25 +313,42 @@ 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_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) {
+ 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
@@ -325,12 +391,16 @@ 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 +448,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 +487,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 +502,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 +514,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 +533,8 @@ 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 +547,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,
};
diff --git a/stmhal/pin.h b/stmhal/pin.h
index 51a434f1d0..6ac73aabd2 100644
--- a/stmhal/pin.h
+++ b/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);
diff --git a/stmhal/pin_defs_stmhal.c b/stmhal/pin_defs_stmhal.c
new file mode 100644
index 0000000000..c2409dc6c0
--- /dev/null
+++ b/stmhal/pin_defs_stmhal.c
@@ -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;
+}
+
diff --git a/stmhal/pin_named_pins.c b/stmhal/pin_named_pins.c
index dbf03d1a0f..36442a0b0b 100644
--- a/stmhal/pin_named_pins.c
+++ b/stmhal/pin_named_pins.c
@@ -41,52 +41,59 @@ 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,
+ .name = MP_QSTR_cpu,
.print = pin_named_pins_obj_print,
- .load_attr = pin_named_pins_obj_load_attr,
+ .locals_dict = (mp_obj_t)&pin_cpu_pins_locals_dict,
};
-const pin_named_pins_obj_t pin_board_pins_obj = {
- { &pin_named_pins_obj_type },
+const mp_obj_type_t pin_board_pins_obj_type = {
+ { &mp_type_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_board_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 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;
}
+/* unused
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;
+}
+
+/* unused
+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;
+}
+*/
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index 719a81d124..2505ca7474 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -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)
diff --git a/teensy/Makefile b/teensy/Makefile
index 54e6ef050e..c627f2fa60 100644
--- a/teensy/Makefile
+++ b/teensy/Makefile
@@ -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 \
@@ -132,11 +133,13 @@ $(BUILD)/%.hex: $(BUILD)/%.elf
$(Q)$(OBJCOPY) -O ihex -R .eeprom "$<" "$@"
MAKE_PINS = make-pins.py
-BOARD_PINS = teensy-pins.csv
-AF_FILE = mk20dx256-af.csv
-PREFIX_FILE = mk20dx256-prefix.c
+BOARD_PINS = teensy_pins.csv
+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)
diff --git a/teensy/hal_gpio.c b/teensy/hal_gpio.c
index 0811f76fda..218560e29b 100644
--- a/teensy/hal_gpio.c
+++ b/teensy/hal_gpio.c
@@ -25,12 +25,18 @@ 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) {
GPIOx->PDDR &= ~bitmask;
@@ -112,4 +118,3 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
#endif
}
}
-
diff --git a/teensy/main.c b/teensy/main.c
index 53f500d571..8de26f25e8 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -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
diff --git a/teensy/make-pins.py b/teensy/make-pins.py
index 1fd05ec207..6df1e4162b 100755
--- a/teensy/make-pins.py
+++ b/teensy/make-pins.py
@@ -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(
@@ -280,6 +327,12 @@ def main():
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",
help="Specifies the board file",
@@ -291,6 +344,12 @@ def main():
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",
help="Specifies name of generated pin header file",
@@ -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__":
diff --git a/teensy/memzip_files/boot.py b/teensy/memzip_files/boot.py
index 4702d7b5d3..6dd5516a97 100644
--- a/teensy/memzip_files/boot.py
+++ b/teensy/memzip_files/boot.py
@@ -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())))
diff --git a/teensy/mk20dx256-af.csv b/teensy/mk20dx256_af.csv
index 3015c6c7a1..3015c6c7a1 100644
--- a/teensy/mk20dx256-af.csv
+++ b/teensy/mk20dx256_af.csv
diff --git a/teensy/mk20dx256-prefix.c b/teensy/mk20dx256_prefix.c
index 2485dc01ab..048b64316a 100644
--- a/teensy/mk20dx256-prefix.c
+++ b/teensy/mk20dx256_prefix.c
@@ -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), \
diff --git a/teensy/pin_defs_teensy.c b/teensy/pin_defs_teensy.c
new file mode 100644
index 0000000000..dd2f0dc21f
--- /dev/null
+++ b/teensy/pin_defs_teensy.c
@@ -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;
+}
diff --git a/teensy/pin_defs_teensy.h b/teensy/pin_defs_teensy.h
index 66942c2ea8..70fd47d8fd 100644
--- a/teensy/pin_defs_teensy.h
+++ b/teensy/pin_defs_teensy.h
@@ -43,4 +43,3 @@ enum {
SPI_TypeDef *SPI;
typedef GPIO_TypeDef pin_gpio_t;
-
diff --git a/teensy/qstrdefsport.h b/teensy/qstrdefsport.h
index 2fb70af7b4..bdafd14286 100644
--- a/teensy/qstrdefsport.h
+++ b/teensy/qstrdefsport.h
@@ -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)
diff --git a/teensy/teensy_hal.h b/teensy/teensy_hal.h
index ff16c98c5c..9c9e628424 100644
--- a/teensy/teensy_hal.h
+++ b/teensy/teensy_hal.h
@@ -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)
diff --git a/teensy/teensy-pins.csv b/teensy/teensy_pins.csv
index acaef63aad..acaef63aad 100644
--- a/teensy/teensy-pins.csv
+++ b/teensy/teensy_pins.csv
diff --git a/tests/pyb/pin.py b/tests/pyb/pin.py
index 448ce53998..b3eb87b608 100644
--- a/tests/pyb/pin.py
+++ b/tests/pyb/pin.py
@@ -1,17 +1,21 @@
from pyb import Pin
-p = Pin('X1')
+p = Pin('X1', Pin.IN)
print(p)
print(p.name())
print(p.pin())
print(p.port())
p = Pin('X1', Pin.IN, Pin.PULL_UP)
-#p = Pin('X1', Pin.IN, pull=Pin.PULL_UP)
+p = Pin('X1', Pin.IN, pull=Pin.PULL_UP)
+p = Pin('X1', mode=Pin.IN, pull=Pin.PULL_UP)
+print(p)
print(p.value())
p.init(p.IN, p.PULL_DOWN)
-#p.init(p.IN, pull=p.PULL_DOWN)
+p.init(p.IN, pull=p.PULL_DOWN)
+p.init(mode=p.IN, pull=p.PULL_DOWN)
+print(p)
print(p.value())
p.init(p.OUT_PP)
diff --git a/tests/pyb/pin.py.exp b/tests/pyb/pin.py.exp
index 4856f5b8e7..599374600a 100644
--- a/tests/pyb/pin.py.exp
+++ b/tests/pyb/pin.py.exp
@@ -1,8 +1,10 @@
-<Pin A0>
+Pin(Pin.cpu.A0, mode=Pin.IN)
A0
0
0
+Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_UP)
1
+Pin(Pin.cpu.A0, mode=Pin.IN, pull=Pin.PULL_DOWN)
0
0
1