From 4343c9330e126a78af1ece71c0767c75d16fc93f Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 18 Jul 2018 06:22:11 +1000 Subject: [PATCH] stm32: Add method for statically configuring pin alternate function. Works with pins declared normally in mpconfigboard.h, eg. (pin_XX), as well as (pyb_pin_XX). Provides new mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn_type) function declared in pin_static_af.h to allow configuring pin alternate functions by name at compile time. --- ports/stm32/Makefile | 5 ++-- ports/stm32/boards/make-pins.py | 36 +++++++++++++++++++++++--- ports/stm32/pin_defs_stm32.h | 1 + ports/stm32/pin_static_af.h | 46 +++++++++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 ports/stm32/pin_static_af.h diff --git a/ports/stm32/Makefile b/ports/stm32/Makefile index 3ee0d1934b..5cf8be79aa 100644 --- a/ports/stm32/Makefile +++ b/ports/stm32/Makefile @@ -519,6 +519,7 @@ 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 +GEN_PINS_AF_DEFS = $(HEADER_BUILD)/pins_af_defs.h GEN_PINS_AF_PY = $(BUILD)/pins_af.py INSERT_USB_IDS = $(TOP)/tools/insert-usb-ids.py @@ -551,9 +552,9 @@ main.c: $(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 $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) +$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(HEADER_BUILD)/%_af_defs.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) $(ECHO) "GEN $@" - $(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) --af-py $(GEN_PINS_AF_PY) > $(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) --af-defs $(GEN_PINS_AF_DEFS) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC) $(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c $(call compile_c) diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py index 70f154fde0..a7051b7a2f 100755 --- a/ports/stm32/boards/make-pins.py +++ b/ports/stm32/boards/make-pins.py @@ -7,6 +7,7 @@ import argparse import sys import csv +# Must have matching entries in AF_FN_* enum in ../pin_defs_stm32.h SUPPORTED_FN = { 'TIM' : ['CH1', 'CH2', 'CH3', 'CH4', 'CH1N', 'CH2N', 'CH3N', 'CH1_ETR', 'ETR', 'BKIN'], @@ -291,7 +292,7 @@ class Pins(object): if pin.is_board_pin(): print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}_obj) }},'.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)); + 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: @@ -303,7 +304,7 @@ class Pins(object): self.print_named('board', self.board_pins) def print_adc(self, adc_num): - print(''); + print('') print('const pin_obj_t * const pin_adc{:d}[] = {{'.format(adc_num)) for channel in range(17): if channel == 16: @@ -378,9 +379,31 @@ class Pins(object): file=af_const_file) print_conditional_endif(cond_var, file=af_const_file) + def print_af_defs(self, af_defs_filename): + with open(af_defs_filename, 'wt') as af_defs_file: + + STATIC_AF_TOKENS = {} + for named_pin in self.board_pins: + for af in named_pin.pin().alt_fn: + func = "%s%d" % (af.func, af.fn_num) if af.fn_num else af.func + pin_type = (af.pin_type or "NULL").split('(')[0] + tok = "#define STATIC_AF_%s_%s(pin_obj) ( \\" % (func, pin_type) + if tok not in STATIC_AF_TOKENS: + STATIC_AF_TOKENS[tok] = [] + STATIC_AF_TOKENS[tok].append( + ' ((strcmp( #pin_obj , "(&pin_%s_obj)") & strcmp( #pin_obj , "((&pin_%s_obj))")) == 0) ? (%d) : \\' % ( + named_pin.pin().cpu_pin_name(), named_pin.pin().cpu_pin_name(), af.idx + ) + ) + + for tok, pins in STATIC_AF_TOKENS.items(): + print(tok, file=af_defs_file) + print("\n".join(sorted(pins)), file=af_defs_file) + print(" (0xffffffffffffffffULL))\n", file=af_defs_file) + def print_af_py(self, af_py_filename): with open(af_py_filename, 'wt') as af_py_file: - print('PINS_AF = (', file=af_py_file); + print('PINS_AF = (', file=af_py_file) for named_pin in self.board_pins: print(" ('%s', " % named_pin.name(), end='', file=af_py_file) for af in named_pin.pin().alt_fn: @@ -414,6 +437,12 @@ def main(): help="Specifies the filename for the python alternate function mappings.", default="build/pins_af.py" ) + parser.add_argument( + "--af-defs", + dest="af_defs_filename", + help="Specifies the filename for the alternate function defines.", + default="build/pins_af_defs.h" + ) parser.add_argument( "-b", "--board", dest="board_filename", @@ -464,6 +493,7 @@ def main(): pins.print_qstr(args.qstr_filename) pins.print_af_hdr(args.af_const_filename) pins.print_af_py(args.af_py_filename) + pins.print_af_defs(args.af_defs_filename) if __name__ == "__main__": diff --git a/ports/stm32/pin_defs_stm32.h b/ports/stm32/pin_defs_stm32.h index 5c5c6be697..89b659de5d 100644 --- a/ports/stm32/pin_defs_stm32.h +++ b/ports/stm32/pin_defs_stm32.h @@ -41,6 +41,7 @@ enum { PORT_K, }; +// Must have matching entries in SUPPORTED_FN in boards/make-pins.py enum { AF_FN_TIM, AF_FN_I2C, diff --git a/ports/stm32/pin_static_af.h b/ports/stm32/pin_static_af.h new file mode 100644 index 0000000000..b73944d6f8 --- /dev/null +++ b/ports/stm32/pin_static_af.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_STM32_PIN_STATIC_AF_H +#define MICROPY_INCLUDED_STM32_PIN_STATIC_AF_H + +#include "py/mphal.h" +#include "genhdr/pins.h" +#include "genhdr/pins_af_defs.h" + +#if 0 // Enable to test if AF's are statically compiled +#define mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn_type) \ + mp_hal_pin_config(pin_obj, mode, pull, fn_type(pin_obj)); \ + _Static_assert(fn_type(pin_obj) != -1, ""); \ + _Static_assert(__builtin_constant_p(fn_type(pin_obj)) == 1, "") + +#else + +#define mp_hal_pin_config_alt_static(pin_obj, mode, pull, fn_type) \ + mp_hal_pin_config(pin_obj, mode, pull, fn_type(pin_obj)) /* Overflow Error => alt func not found */ + +#endif + +#endif // MICROPY_INCLUDED_STM32_PIN_STATIC_AF_H