diff --git a/ports/zephyr/CMakeLists.txt b/ports/zephyr/CMakeLists.txt index a5cc477204eb5..899cfd0361bb9 100644 --- a/ports/zephyr/CMakeLists.txt +++ b/ports/zephyr/CMakeLists.txt @@ -30,6 +30,7 @@ project(micropython) set(MICROPY_PORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(MICROPY_DIR ${MICROPY_PORT_DIR}/../..) set(MICROPY_TARGET micropython) +set(MICROPY_BOARD ${BOARD}) # maybe zephyr_${BOARD} or even uppercase version of that? include(${MICROPY_DIR}/py/py.cmake) include(${MICROPY_DIR}/extmod/extmod.cmake) diff --git a/tests/extmod/machine_uart_irq_txidle.py b/tests/extmod/machine_uart_irq_txidle.py index 084e9825768a8..16052ce4fb58b 100644 --- a/tests/extmod/machine_uart_irq_txidle.py +++ b/tests/extmod/machine_uart_irq_txidle.py @@ -10,32 +10,7 @@ raise SystemExit import time, sys - -# Configure pins based on the target. -if "alif" in sys.platform: - uart_id = 1 - tx_pin = None -elif "rp2" in sys.platform: - uart_id = 0 - tx_pin = "GPIO0" - rx_pin = "GPIO1" -elif "samd" in sys.platform and "ItsyBitsy M0" in sys.implementation._machine: - uart_id = 0 - tx_pin = "D1" - rx_pin = "D0" -elif "samd" in sys.platform and "ItsyBitsy M4" in sys.implementation._machine: - uart_id = 3 - tx_pin = "D1" - rx_pin = "D0" -elif "mimxrt" in sys.platform: - uart_id = 1 - tx_pin = None -elif "nrf" in sys.platform: - uart_id = 0 - tx_pin = None -else: - print("Please add support for this test on this platform.") - raise SystemExit +from target_wiring import uart_loopback_args, uart_loopback_kwargs def irq(u): @@ -46,11 +21,7 @@ def irq(u): # Test that the IRQ is called after the write has completed. for bits_per_s in (2400, 9600, 115200): - if tx_pin is None: - uart = UART(uart_id, bits_per_s) - else: - uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin) - + uart = UART(*uart_loopback_args, bits_per_s, **uart_loopback_kwargs) uart.irq(irq, uart.IRQ_TXIDLE) # The IRQ_TXIDLE shall trigger after the message has been sent. Thus diff --git a/tests/extmod/machine_uart_tx.py b/tests/extmod/machine_uart_tx.py index 85bf7e9fb878a..53aebce4d7671 100644 --- a/tests/extmod/machine_uart_tx.py +++ b/tests/extmod/machine_uart_tx.py @@ -8,50 +8,40 @@ raise SystemExit import time, sys +from target_wiring import uart_loopback_args, uart_loopback_kwargs initial_delay_ms = 0 bit_margin = 0 timing_margin_us = 100 -# Configure pins based on the target. +# Tune test parameters based on the target. if "alif" in sys.platform: - uart_id = 1 - pins = {} bit_margin = 1 elif "esp32" in sys.platform: - uart_id = 1 - pins = {} timing_margin_us = 400 elif "mimxrt" in sys.platform: - uart_id = 1 - pins = {} initial_delay_ms = 20 # UART sends idle frame after init, so wait for that bit_margin = 1 elif "pyboard" in sys.platform: - if "STM32WB" in sys.implementation._machine: - uart_id = "LP1" - else: - uart_id = 4 - pins = {} initial_delay_ms = 50 # UART sends idle frame after init, so wait for that bit_margin = 1 # first start-bit must wait to sync with the UART clock elif "rp2" in sys.platform: - uart_id = 0 - pins = {"tx": "GPIO0", "rx": "GPIO1"} timing_margin_us = 180 elif "samd" in sys.platform: - uart_id = 2 - pins = {"tx": "D1", "rx": "D0"} timing_margin_us = 300 bit_margin = 1 -else: - print("SKIP") - raise SystemExit # Test that write+flush takes the expected amount of time to execute. for bits_per_s in (2400, 9600, 115200): text = "Hello World" - uart = UART(uart_id, bits_per_s, bits=8, parity=None, stop=1, **pins) + uart = UART( + *uart_loopback_args, + baudrate=bits_per_s, + bits=8, + parity=None, + stop=1, + **uart_loopback_kwargs, + ) time.sleep_ms(initial_delay_ms) start_us = time.ticks_us() diff --git a/tests/extmod_hardware/machine_uart_irq_break.py b/tests/extmod_hardware/machine_uart_irq_break.py index 879f9cee6762f..1832d9883ba54 100644 --- a/tests/extmod_hardware/machine_uart_irq_break.py +++ b/tests/extmod_hardware/machine_uart_irq_break.py @@ -12,23 +12,7 @@ raise SystemExit import time, sys - -# Configure pins based on the target. -if "esp32" in sys.platform: - _machine = sys.implementation._machine - if "ESP32S2" in _machine or "ESP32C3" in _machine or "ESP32C6" in _machine: - print("SKIP") - raise SystemExit - uart_id = 1 - tx_pin = 4 - rx_pin = 5 -elif "rp2" in sys.platform: - uart_id = 0 - tx_pin = "GPIO0" - rx_pin = "GPIO1" -else: - print("Please add support for this test on this platform.") - raise SystemExit +from target_wiring import uart_loopback_args, uart_loopback_kwargs def irq(u): @@ -37,7 +21,7 @@ def irq(u): # Test that the IRQ is called for each break received. for bits_per_s in (2400, 9600, 57600): - uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin) + uart = UART(*uart_loopback_args, baudrate=bits_per_s, **uart_loopback_kwargs) uart.irq(irq, uart.IRQ_BREAK) print("write", bits_per_s) diff --git a/tests/extmod_hardware/machine_uart_irq_rx.py b/tests/extmod_hardware/machine_uart_irq_rx.py index 3602c260e396d..92fe218835d73 100644 --- a/tests/extmod_hardware/machine_uart_irq_rx.py +++ b/tests/extmod_hardware/machine_uart_irq_rx.py @@ -13,49 +13,14 @@ import time, sys -byte_by_byte = False -# Configure pins based on the target. -if "alif" in sys.platform: - uart_id = 1 - tx_pin = None - rx_pin = None -elif "esp32" in sys.platform: - uart_id = 1 - tx_pin = 4 - rx_pin = 5 -elif "pyboard" in sys.platform: - if "STM32WB" in sys.implementation._machine: - # LPUART(1) is on PA2/PA3 - uart_id = "LP1" - else: - # UART(4) is on PA0/PA1 - uart_id = 4 - tx_pin = None - rx_pin = None -elif "samd" in sys.platform and "ItsyBitsy M0" in sys.implementation._machine: - uart_id = 0 - tx_pin = "D1" - rx_pin = "D0" - byte_by_byte = True -elif "samd" in sys.platform and "ItsyBitsy M4" in sys.implementation._machine: - uart_id = 3 - tx_pin = "D1" - rx_pin = "D0" -elif "nrf" in sys.platform: - uart_id = 0 - tx_pin = None - rx_pin = None -elif "renesas-ra" in sys.platform: - uart_id = 9 - tx_pin = None # P602 @ RA6M2 - rx_pin = None # P601 @ RA6M2 -elif "CC3200" in sys.implementation._machine: +if "CC3200" in sys.implementation._machine: # CC3200 doesn't work because it's too slow and has an allocation error in the handler. print("SKIP") raise SystemExit -else: - print("Please add support for this test on this platform.") - raise SystemExit + +from target_wiring import uart_loopback_args, uart_loopback_kwargs + +byte_by_byte = "ItsyBitsy M0" in sys.implementation._machine def irq(u): @@ -67,11 +32,7 @@ def irq(u): # Test that the IRQ is called for each byte received. # Use slow baudrates so that the IRQ has time to run. for bits_per_s in (2400, 9600): - if tx_pin is None: - uart = UART(uart_id, bits_per_s) - else: - uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin) - + uart = UART(*uart_loopback_args, baudrate=bits_per_s, **uart_loopback_kwargs) uart.irq(irq, uart.IRQ_RX) print("write", bits_per_s) diff --git a/tests/extmod_hardware/machine_uart_irq_rxidle.py b/tests/extmod_hardware/machine_uart_irq_rxidle.py index 3c743c9e0c1c0..40f781d078822 100644 --- a/tests/extmod_hardware/machine_uart_irq_rxidle.py +++ b/tests/extmod_hardware/machine_uart_irq_rxidle.py @@ -12,52 +12,10 @@ raise SystemExit import time, sys +from target_wiring import uart_loopback_args, uart_loopback_kwargs # Target tuning options. -tune_wait_initial_rxidle = False - -# Configure pins based on the target. -if "alif" in sys.platform: - uart_id = 1 - tx_pin = None - rx_pin = None -elif "esp32" in sys.platform: - uart_id = 1 - tx_pin = 4 - rx_pin = 5 -elif "mimxrt" in sys.platform: - uart_id = 1 - tx_pin = None -elif "pyboard" in sys.platform: - tune_wait_initial_rxidle = True - if "STM32WB" in sys.implementation._machine: - # LPUART(1) is on PA2/PA3 - uart_id = "LP1" - else: - # UART(4) is on PA0/PA1 - uart_id = 4 - tx_pin = None - rx_pin = None -elif "renesas-ra" in sys.platform: - uart_id = 9 - tx_pin = None # P602 @ RA6M2 - rx_pin = None # P601 @ RA6M2 -elif "rp2" in sys.platform: - uart_id = 0 - tx_pin = "GPIO0" - rx_pin = "GPIO1" -elif "samd" in sys.platform and "ItsyBitsy M0" in sys.implementation._machine: - uart_id = 0 - tx_pin = "D1" - rx_pin = "D0" - byte_by_byte = True -elif "samd" in sys.platform and "ItsyBitsy M4" in sys.implementation._machine: - uart_id = 3 - tx_pin = "D1" - rx_pin = "D0" -else: - print("Please add support for this test on this platform.") - raise SystemExit +tune_wait_initial_rxidle = sys.platform == "pyboard" def irq(u): @@ -71,10 +29,7 @@ def irq(u): print("========") print("bits_per_s:", bits_per_s) - if tx_pin is None: - uart = UART(uart_id, bits_per_s) - else: - uart = UART(uart_id, bits_per_s, tx=tx_pin, rx=rx_pin) + uart = UART(*uart_loopback_args, baudrate=bits_per_s, **uart_loopback_kwargs) # Ignore a possible initial RXIDLE condition after creating UART. if tune_wait_initial_rxidle: diff --git a/tests/feature_check/target_info.py b/tests/feature_check/target_info.py index 962ebf4154b5c..5367eb6a47d64 100644 --- a/tests/feature_check/target_info.py +++ b/tests/feature_check/target_info.py @@ -20,6 +20,7 @@ "xtensawin", "rv32imc", ][sys_mpy >> 10] +build = getattr(sys.implementation, "_build", "unknown") thread = getattr(sys.implementation, "_thread", None) # Detect how many bits of precision the floating point implementation has. @@ -33,4 +34,4 @@ except NameError: float_prec = 0 -print(platform, arch, thread, float_prec, len("α") == 1) +print(platform, arch, build, thread, float_prec, len("α") == 1) diff --git a/tests/run-tests.py b/tests/run-tests.py index aeea0bad5e779..ec47157d4ac2e 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -224,6 +224,15 @@ def open(self, path, mode): ), } +# Tests that require `import target_wiring` to work. +tests_requiring_target_wiring = ( + "extmod/machine_uart_irq_txidle.py", + "extmod/machine_uart_tx.py", + "extmod_hardware/machine_uart_irq_break.py", + "extmod_hardware/machine_uart_irq_rx.py", + "extmod_hardware/machine_uart_irq_rxidle.py", +) + def rm_f(fname): if os.path.exists(fname): @@ -294,7 +303,7 @@ def detect_test_platform(pyb, args): output = run_feature_check(pyb, args, "target_info.py") if output.endswith(b"CRASH"): raise ValueError("cannot detect platform: {}".format(output)) - platform, arch, thread, float_prec, unicode = str(output, "ascii").strip().split() + platform, arch, build, thread, float_prec, unicode = str(output, "ascii").strip().split() if arch == "None": arch = None inlineasm_arch = detect_inline_asm_arch(pyb, args) @@ -308,10 +317,12 @@ def detect_test_platform(pyb, args): if arch and not args.mpy_cross_flags: args.mpy_cross_flags = "-march=" + arch args.inlineasm_arch = inlineasm_arch + args.build = build args.thread = thread args.float_prec = float_prec args.unicode = unicode + # Print the detected information about the target. print("platform={}".format(platform), end="") if arch: print(" arch={}".format(arch), end="") @@ -323,7 +334,43 @@ def detect_test_platform(pyb, args): print(" float={}-bit".format(float_prec), end="") if unicode: print(" unicode", end="") - print() + + +def detect_target_wiring_script(pyb, args): + tw_data = b"" + tw_source = None + has_target_wiring = ( + hasattr(pyb, "exec_") + and pyb.exec_("try:\n import target_wiring\n print(True)\nexcept:\n print(False)").strip() + == b"True" + ) + if has_target_wiring: + # The board already has a target_wiring module available, so use that. + tw_source = "on-device" + else: + port = platform_to_port(args.platform) + build = args.build + tw_board_exact = None + tw_board_partial = None + tw_port = None + for file in os.listdir("target_wiring"): + file_base = file.removesuffix(".py") + if file_base == build: + # A file matching the target's board/build name. + tw_board_exact = file + elif file_base.endswith("x") and build.startswith(file_base.removesuffix("x")): + # A file with a partial match to the target's board/build name. + tw_board_partial = file + elif file_base == port: + # A file matching the target's port. + tw_port = file + tw_source = tw_board_exact or tw_board_partial or tw_port + if tw_source: + with open("target_wiring/" + tw_source, "rb") as f: + tw_data = f.read() + if tw_source: + print(" target_wiring={}".format(tw_source), end="") + pyb.target_wiring_script = tw_data def prepare_script_for_target(args, *, script_text=None, force_plain=False): @@ -384,6 +431,11 @@ def run_script_on_remote_target(pyb, args, test_file, is_special): try: had_crash = False pyb.enter_raw_repl() + if test_file.endswith(tests_requiring_target_wiring) and pyb.target_wiring_script: + pyb.exec_("__target_wiring=" + repr(pyb.target_wiring_script)) + pyb.exec_( + "import sys;sys.modules['target_wiring']=__build_class__(lambda:exec(__target_wiring),'target_wiring')" + ) output_mupy = pyb.exec_(script, timeout=TEST_TIMEOUT) except pyboard.PyboardError as e: had_crash = True @@ -1382,6 +1434,13 @@ def main(): # tests explicitly given tests = args.files + # If any tests need it, prepare the target_wiring script for the target. + if pyb and any(test.endswith(tests_requiring_target_wiring) for test in tests): + detect_target_wiring_script(pyb, args) + + # End the target information line. + print() + if not args.keep_path: # Clear search path to make sure tests use only builtin modules, those in # extmod, and a path to unittest in case it's needed. diff --git a/tests/target_wiring/ADAFRUIT_ITSYBITSY_M0_EXPRESS.py b/tests/target_wiring/ADAFRUIT_ITSYBITSY_M0_EXPRESS.py new file mode 100644 index 0000000000000..0414c7b54894e --- /dev/null +++ b/tests/target_wiring/ADAFRUIT_ITSYBITSY_M0_EXPRESS.py @@ -0,0 +1,8 @@ +# Target wiring for ADAFRUIT_ITSYBITSY_M0_EXPRESS. +# +# Connect: +# - D0 to D1 + +# For UART loopback tests. +uart_loopback_args = (0,) +uart_loopback_kwargs = {"tx": "D1", "rx": "D0"} diff --git a/tests/target_wiring/ADAFRUIT_ITSYBITSY_M4_EXPRESS.py b/tests/target_wiring/ADAFRUIT_ITSYBITSY_M4_EXPRESS.py new file mode 100644 index 0000000000000..bbda2c917cb83 --- /dev/null +++ b/tests/target_wiring/ADAFRUIT_ITSYBITSY_M4_EXPRESS.py @@ -0,0 +1,8 @@ +# Target wiring for ADAFRUIT_ITSYBITSY_M4_EXPRESS. +# +# Connect: +# - D0 to D1 + +# For UART loopback tests. +uart_loopback_args = 3 +uart_loopback_kwargs = {"tx": "D1", "rx": "D0"} diff --git a/tests/target_wiring/EK_RA6M2.py b/tests/target_wiring/EK_RA6M2.py new file mode 100644 index 0000000000000..c5be6020c7081 --- /dev/null +++ b/tests/target_wiring/EK_RA6M2.py @@ -0,0 +1,9 @@ +# Target wiring for EK_RA6M2. +# +# Connect: +# - P601 to P602 + +# For UART loopback tests. +# UART(9) is on P602/P601. +uart_loopback_args = 9 +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/NUCLEO_WB55.py b/tests/target_wiring/NUCLEO_WB55.py new file mode 100644 index 0000000000000..f91b1e79d886a --- /dev/null +++ b/tests/target_wiring/NUCLEO_WB55.py @@ -0,0 +1,8 @@ +# Target wiring for NUCLEO_WB55. +# +# Connect: +# - PA2 to PA3 + +# LPUART(1) is on PA2/PA3. +uart_loopback_args = "LP1" +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/PYBx.py b/tests/target_wiring/PYBx.py new file mode 100644 index 0000000000000..71789ba40d3bc --- /dev/null +++ b/tests/target_wiring/PYBx.py @@ -0,0 +1,9 @@ +# Target wiring for PYBV10, PYBV11, PYBLITEV10, PYBD_SF2, PYBD_SF3, PYBD_SF6. +# +# Connect: +# - X1 to X2 + +# For UART loopback tests. +# UART("XA") is on X1/X2 (usually UART(4) on PA0/PA1). +uart_loopback_args = ("XA",) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/alif.py b/tests/target_wiring/alif.py new file mode 100644 index 0000000000000..db2852a1a0e62 --- /dev/null +++ b/tests/target_wiring/alif.py @@ -0,0 +1,8 @@ +# Target wiring for general alif board. +# +# Connect: +# - ? + +# UART(1). +uart_loopback_args = 1 +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/esp32.py b/tests/target_wiring/esp32.py new file mode 100644 index 0000000000000..511320ca7b83a --- /dev/null +++ b/tests/target_wiring/esp32.py @@ -0,0 +1,9 @@ +# Target wiring for general esp32 board. +# TODO: test on C3, C6 (irq_break may not work) +# +# Connect: +# - GPIO4 to GPIO5. + +# For UART loopback tests. +uart_loopback_args = (1,) +uart_loopback_kwargs = {"tx": 4, "rx": 5} diff --git a/tests/target_wiring/mimxrt.py b/tests/target_wiring/mimxrt.py new file mode 100644 index 0000000000000..b2c0f3c588597 --- /dev/null +++ b/tests/target_wiring/mimxrt.py @@ -0,0 +1,8 @@ +# Target wiring for general mimxrt board. +# +# Connect: +# - ? + +# For UART loopback tests. +uart_loopback_args = 1 +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/nrf.py b/tests/target_wiring/nrf.py new file mode 100644 index 0000000000000..9af8b9451bd98 --- /dev/null +++ b/tests/target_wiring/nrf.py @@ -0,0 +1,8 @@ +# Target wiring for general nrf board. +# +# Connect: +# - ? + +# For UART loopback tests. +uart_loopback_args = 0 +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/rp2.py b/tests/target_wiring/rp2.py new file mode 100644 index 0000000000000..c00baf508cff5 --- /dev/null +++ b/tests/target_wiring/rp2.py @@ -0,0 +1,8 @@ +# Target wiring for general rp2 board. +# +# Connect: +# - GPIO0 to GPIO1 + +# For UART loopback tests. +uart_loopback_args = 0 +uart_loopback_kwargs = {"tx": "GPIO0", "rx": "GPIO1"} diff --git a/tests/target_wiring/samd.py b/tests/target_wiring/samd.py new file mode 100644 index 0000000000000..4d5045f41ea2e --- /dev/null +++ b/tests/target_wiring/samd.py @@ -0,0 +1,8 @@ +# Target wiring for general samd board. +# +# Connect: +# - D0 to D1 + +# For UART loopback tests. +uart_loopback_args = 2 +uart_loopback_kwargs = {"tx": "D1", "rx": "D0"}