From 2f28933dc6454a2a9e64a007525192e746bc5122 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 15 Nov 2023 14:08:00 +0100 Subject: [PATCH 1/9] tools/psoc6/mpy-psoc6.py: Added python install utility. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 460 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 tools/psoc6/mpy-psoc6.py diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py new file mode 100644 index 000000000000..448253a69167 --- /dev/null +++ b/tools/psoc6/mpy-psoc6.py @@ -0,0 +1,460 @@ +import argparse, os, sys, shlex, shutil, subprocess, requests, tarfile, zipfile + +boards = [ + {"name": "CY8CPROTO-062-4343W", "ocd_cfg_file": "psoc6_2m.cfg"}, + {"name": "CY8CPROTO-063-BLE", "ocd_cfg_file": "psoc6.cfg"}, +] + +opsys = "" + + +def set_environment(): + global opsys + if sys.platform == "linux" or sys.platform == "linux2": + opsys = "linux" + elif sys.platform == "win32" or sys.platform == "cygwin": + opsys = "win" + elif sys.platform == "darwin": + opsys = "mac" + raise Exception("OS unsupported") + + +def mpy_get_fw_hex_file_name(file_name, board): + file_extension = ".hex" + return str(file_name) + "_" + str(board) + file_extension + + +def mpy_firmware_deploy(file_name, board, serial_adapter_sn=None): + print("Deploying firmware...") + hex_file = mpy_get_fw_hex_file_name(file_name, board) + openocd_program(board, hex_file, serial_adapter_sn) + + +def mpy_firmware_download(file_name, board, version): + print( + "Downloading " + str(file_name) + " " + str(version) + " for " + str(board) + " board..." + ) + + if version == "latest": + sub_url = "latest/download" + else: + sub_url = "download/" + str(version) + + file_name_for_board = mpy_get_fw_hex_file_name(file_name, board) + file_url = ( + "https://github.com/infineon/micropython/releases/" + sub_url + "/" + file_name_for_board + ) + + res = requests.get(file_url) + open(file_name_for_board, "wb").write(res.content) + + +def mpy_firmware_remove(file_name, board): + os.remove(mpy_get_fw_hex_file_name(file_name, board)) + + +def openocd_download_install(): + if opsys == "linux": + file_os_suffix = "linux" + file_extension = ".tar.gz" + elif opsys == "win": + file_os_suffix = "windows" + file_extension = ".zip" + + openocd_compressed = "openocd" + file_extension + + def get_openocd_file_url_name(): + filename_base = "openocd-4.4.0.2134-" + url_base = "https://github.com/Infineon/micropython/releases/download/v0.3.0/" + + file_name = filename_base + file_os_suffix + file_extension + file_url = url_base + file_name + + return file_url, file_name + + def download_openocd(file_url, file_name): + res = requests.get(file_url) + open(file_name, "wb").write(res.content) + os.rename(file_name, openocd_compressed) + + def extract_openocd(): + if opsys == "linux": + compress_file = tarfile.open(openocd_compressed) + compress_file.extractall(".") + compress_file.close() + elif opsys == "win": + compress_file = zipfile.ZipFile(openocd_compressed) + compress_file.extractall(".") + compress_file.close() + + def openocd_setup(): + # Add openocd to path + os.environ["PATH"] += os.pathsep + os.path.join("openocd", "bin") + + if opsys == "linux": + # Install udev rules + sh_args = ["sh", "openocd/udev_rules/install_rules.sh"] + try: + sh_proc = subprocess.Popen(sh_args) + sh_proc.wait() + except: + raise Exception("bash error") + + print("Downloading openocd...") + file_url, file_name = get_openocd_file_url_name() + download_openocd(file_url, file_name) + print("Extracting openocd...") + extract_openocd() + openocd_setup() + + +def openocd_board_conf_download(board): + print("Downloading openocd " + str(board) + " configuration...") + + # Create and move to board dir in openocd folder + parent_dir = os.path.abspath(os.curdir) + os.chdir("openocd") + if not os.path.exists("board"): + os.mkdir("board") + os.chdir("board") + + # Download config file + if board == "CY8CPROTO-062-4343W": + file_name = "qspi_config_" + str(board) + ".cfg" + file_url = "https://github.com/infineon/micropython/releases/download/v0.3.0/" + file_name + res = requests.get(file_url) + open(file_name, "wb").write(res.content) + + # Rename config file + os.rename(file_name, "qspi_config.cfg") + + # Move to parent dir + os.chdir(parent_dir) + + +def openocd_program(board, hex_file, serial_adapter_sn=None): + if opsys == "linux": + openocd = "openocd/bin/openocd" + elif opsys == "win": + openocd = "openocd.exe" + + for brd in boards: + if board == brd["name"]: + ocd_cfg_file = brd["ocd_cfg_file"] + + serial_adapter_opt = "" + if serial_adapter_sn is not None: + serial_adapter_opt = "adapter serial " + str(serial_adapter_sn) + + openocd_cmd = ( + openocd + + ' -s openocd/scripts -s openocd/board -c "source [find interface/kitprog3.cfg];' + + str(serial_adapter_opt) + + " ; source [find target/" + + str(ocd_cfg_file) + + "]; psoc6 allow_efuse_program off; psoc6 sflash_restrictions 1; program " + + str(hex_file) + + ' verify reset exit;"' + ) + print(openocd_cmd) + openocd_args = shlex.split(openocd_cmd) + + try: + ocd_proc = subprocess.Popen(openocd_args) + ocd_proc.wait() + except: + raise Exception("openocd error") + + +def openocd_remove(): + if opsys == "linux": + file_extension = ".tar.gz" + elif opsys == "win": + file_extension = ".zip" + + openocd_compressed = "openocd" + file_extension + + os.remove(openocd_compressed) + shutil.rmtree("openocd") + + +def validate_board_name(board_name): + board_supported = False + for brd in boards: + if board_name == brd["name"]: + board_supported = True + break + + if not board_supported: + raise Exception("error: board is not supported") + + +def select_board(): + def validate_board_index(board_index): + max_board_index = len(boards) + if board_index < 0 or board_index > max_board_index: + raise Exception("error: board ID not valid") + + print("") + print(" Supported MicroPython PSoC6 boards ") + print("+---------+-----------------------------------+") + print("| ID | Board |") + print("+---------+-----------------------------------+") + print("| 0 | CY8CPROTO-062-4343W |") + print("+---------+-----------------------------------+") + print("| 1 | CY8CPROTO-063-BLE |") + print("+---------+-----------------------------------+") + print("") + print("") + + board_index = int(input("Please type the desired board ID: ")) + validate_board_index(board_index) + board = boards[board_index]["name"] + + return board + + +def wait_and_request_board_connect(): + input("Please CONNECT THE BOARD and PRESS ENTER to start the firmware deployment\n") + + +def wait_user_termination(): + input("Press ENTER to continue...\n") + + +def device_setup(board, version, quiet=False): + if board is None: + board = select_board() + else: + validate_board_name(board) + + print("MicroPython PSoC6 Board :: ", board) + + if version is None: + version = "latest" + + print("MicroPython PSoC6 Version :: ", version) + + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("hello-world", board, "v0.3.0") + mpy_firmware_download("mpy-psoc6", board, version) + + if not quiet: + wait_and_request_board_connect() + + mpy_firmware_deploy("hello-world", board) + mpy_firmware_deploy("mpy-psoc6", board) + print(" Device firmware deployment completed.") + + openocd_remove() + mpy_firmware_remove("hello-world", board) + mpy_firmware_remove("mpy-psoc6", board) + + if not quiet: + wait_user_termination() + + +def device_erase(board, quiet=False): + if board != "CY8CPROTO-062-4343W": + raise Exception("error: board is not supported") + + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("device-erase", board, "v0.3.0") + + if not quiet: + wait_and_request_board_connect() + + mpy_firmware_deploy("device-erase", board) + + openocd_remove() + mpy_firmware_remove("device-erase", board) + + if not quiet: + wait_user_termination() + + +def arduino_lab_download_and_launch(): + def download_arduino_lab(): + print("Downloading Arduino Lab for Micropython...") + + if opsys == "linux": + file_os_suffix = "linux_x64" + elif opsys == "win": + file_os_suffix = "win_x64" + + url_base = "https://github.com/arduino/lab-micropython-editor/releases/download/0.8.0/" + file_name_extension = ".zip" + file_name = "Arduino.Lab.for.Micropython-" + file_os_suffix + file_name_extension + file_url = url_base + file_name + + res = requests.get(file_url) + open(file_name, "wb").write(res.content) + + os.rename(file_name, "arduino-for-micropython.zip") + + def extract_arduino_lab(): + print("Extracting Arduino Lab for Micropython...") + mpyinolab_dir = "arduino-lab-mpy" + if not os.path.exists(mpyinolab_dir): + os.mkdir(mpyinolab_dir) + + compress_file = zipfile.ZipFile("arduino-for-micropython.zip") + compress_file.extractall(mpyinolab_dir) + compress_file.close() + + def launch_arduino_lab(): + print("Launching Arduino Lab for Micropython...") + + mpyinolab_dir = "arduino-lab-mpy" + + if opsys == "linux": + mpy_ide = ["./arduino-lab-micropython-ide"] + os.chmod(os.path.join(mpyinolab_dir, "arduino-lab-micropython-ide"), 0o755) + elif opsys == "win": + mpy_ide = ["Arduino Lab for Micropython.exe"] + + parent_dir = os.path.abspath(os.curdir) + os.chdir(mpyinolab_dir) + + try: + ide_proc = subprocess.Popen(mpy_ide) + ide_proc.wait() + except: + raise Exception("error: Could not launch Arduino Lab IDE") + + os.chdir(parent_dir) + + download_arduino_lab() + extract_arduino_lab() + launch_arduino_lab() + + +def arduino_lab_install_package_remove(): + print("Cleaning up Arduino Lab for Micropython installation package...") + os.remove("arduino-for-micropython.zip") + + +def quick_start(board, version): + def print_retro_banner(): + print("################################################") + print(" Welcome to the ") + print(" __ __ _ ___ _ _ ") + print("| \/ (_)__ _ _ ___| _ \_ _| |_| |_ ___ _ _") + print("| |\/| | / _| '_/ _ \ _/ || | _| ' \/ _ \ ' \\") + print("|_|_ |_|_\__|_| \___/_| \_, |\__|_||_\___/_||_|") + print("| _ \/ __| ___ / __|/ / |__/") + print("| _/\__ \/ _ \ (__/ _ \\") + print("|_| |___/\___/\___\___/") + print("") + print(" Quick Start ") + print("################################################") + + def print_exit_banner(): + print("################################################") + print(" The installation is completed. Have fun :) ") + print("################################################") + + print_retro_banner() + device_setup(board, version) + arduino_lab_download_and_launch() + arduino_lab_install_package_remove() + print_exit_banner() + wait_user_termination() + + +def parser(): + def main_parser_func(args): + parser.print_help() + + def parser_quick_start(args): + quick_start(args.board, args.version) + + def parser_device_setup(args): + device_setup(args.board, args.version, args.q) + + def parser_firmware_deploy(args): + openocd_program(args.board, args.hexfile) + + def parser_device_erase(args): + device_erase(args.board, args.q) + + # Main parser + parser = argparse.ArgumentParser(description="Micropython PSoC6 utility script") + subparser = parser.add_subparsers() + parser.set_defaults(func=main_parser_func) + + # quick start + parser_qs = subparser.add_parser( + "quick-start", + description="Setup of MicroPython IDE and PSoC6 board. \ + Use this command for a guided installation and \ + quick start using MicroPython PSoC6.", + ) + parser_qs.add_argument( + "-b", "--board", default=None, type=str, help="PSoC6 prototyping kit name" + ) + parser_qs.add_argument( + "-v", "--version", default=None, type=str, help="MicroPython PSoC6 firmware version" + ) + parser_qs.set_defaults(func=parser_quick_start) + + # device setup + parser_ds = subparser.add_parser( + "device-setup", + description="Setup of MicroPython PSoC6 board. \ + Use this command to install the deployment tools \ + and MicroPython firmware binary, and deploy the \ + firmware on the PSoC6 device.", + ) + parser_ds.add_argument( + "-b", "--board", default=None, type=str, help="PSoC6 prototyping kit name" + ) + parser_ds.add_argument( + "-v", "--version", default=None, type=str, help="MicroPython PSoC6 firmware version" + ) + parser_ds.add_argument( + "-q", action="store_true", help="Quiet. Do not prompt any user confirmation request" + ) + parser_ds.set_defaults(func=parser_device_setup) + + # firmware deploy + parser_fd = subparser.add_parser( + "firmware-deploy", + description="Firmware deployment on MicroPython board. \ + Use this command to deploy an existing .hex file \ + on a PSoC6 board. \ + Requires openocd available on the system path.", + ) + parser_fd.add_argument( + "-b", "--board", default=None, type=str, required=True, help="PSoC6 prototyping kit name" + ) + parser_fd.add_argument( + "-f", "--hexfile", type=str, required=True, help="MicroPython PSoC6 firmware .hex file" + ) + parser_fd.set_defaults(func=parser_firmware_deploy) + + # device erase + parser_de = subparser.add_parser( + "device-erase", + description="Erase the external memory of the device. \ + Use this command to erase the external memory if available \ + for the selected board.", + ) + parser_de.add_argument( + "-b", "--board", default=None, type=str, required=True, help="PSoC6 prototyping kit name" + ) + parser_de.add_argument( + "-q", action="store_true", help="Quiet. Do not prompt any user confirmation request" + ) + parser_de.set_defaults(func=parser_device_erase) + + # Parser call + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + set_environment() + parser() From 46271b367740ac0faf19958a2c768f1f934e4dbf Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Tue, 21 Nov 2023 17:20:58 +0100 Subject: [PATCH 2/9] tools/psoc6/mpy-psoc6.py: WIP Adding fwloader kitprog3 fw update. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 89 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index 448253a69167..e346945117d9 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -53,6 +53,87 @@ def mpy_firmware_remove(file_name, board): os.remove(mpy_get_fw_hex_file_name(file_name, board)) +def fwloader_download_install(): + file_extension = ".zip" + fwloader_compressed = "fwloader" + file_extension + + def get_fwloader_file_url_name(): + if opsys == "linux": + file_os_suffix = "linux" + elif opsys == "win": + file_os_suffix = "windows" + + version = "3.5.0.2114" + package_version = "2.50.0.1383" + file_name = ( + "fw-loader-" + + version + + "-kitprog3-package-" + + package_version + + "-" + + file_os_suffix + + file_extension + ) + + base_url = "https://github.com/Infineon/Firmware-loader/releases/download/3.5.0/" + file_url = base_url + file_name + + return file_url, file_name + + def download_fwloader(file_url, file_name): + res = requests.get(file_url) + open(file_name, "wb").write(res.content) + os.rename(file_name, fwloader_compressed) + + def extract_fwloader(): + compress_file = zipfile.ZipFile(fwloader_compressed) + compress_file.extractall(".") + compress_file.close() + + def fwloader_setup(): + # Add fw-loader to path + os.environ["PATH"] += os.pathsep + os.path.join("fw-loader", "bin") + + if opsys == "linux": + # Install udev rules + sh_args = ["sh", "fw-loader/udev_rules/install_rules.sh"] + try: + sh_proc = subprocess.Popen(sh_args) + sh_proc.wait() + except: + raise Exception("bash error") + + os.chmod(os.path.join("fw-loader", "bin", "fw-loader"), 0o755) + + print("Downloading fw-loader...") + file_url, file_name = get_fwloader_file_url_name() + download_fwloader(file_url, file_name) + print("Extracting fw-loader...") + extract_fwloader() + fwloader_setup() + + +def fwloader_update_kitprog(): + print("Updating kitprog3 firmware...") + fwloader_cmd = "fw-loader --update-kp3 all" + print(fwloader_cmd) + fwloader_args = shlex.split(fwloader_cmd) + + try: + fwl_proc = subprocess.Popen(fwloader_args) + fwl_proc.wait() + except: + raise Exception("fwloader error") + + +def fwloader_remove(): + file_extension = ".zip" + fwloader_compressed = "fwlaoder" + file_extension + os.remove(fwloader_compressed) + shutil.rmtree("fw-loader") + shutil.rmtree("kp-firmware") + + def openocd_download_install(): if opsys == "linux": file_os_suffix = "linux" @@ -235,6 +316,10 @@ def device_setup(board, version, quiet=False): print("MicroPython PSoC6 Version :: ", version) + fwloader_download_install() + fwloader_update_kitprog() + fwloader_remove() + openocd_download_install() openocd_board_conf_download(board) mpy_firmware_download("hello-world", board, "v0.3.0") @@ -457,4 +542,6 @@ def parser_device_erase(args): if __name__ == "__main__": set_environment() - parser() + # parser() + fwloader_download_install() + fwloader_update_kitprog() From d93926bec467c41e30f67980e7067332472185db Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 10:45:26 +0100 Subject: [PATCH 3/9] tools/psoc6/mpy-psoc6.py: Added kitprog3 update option in device-setup. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index e346945117d9..d35969f867fd 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -128,7 +128,7 @@ def fwloader_update_kitprog(): def fwloader_remove(): file_extension = ".zip" - fwloader_compressed = "fwlaoder" + file_extension + fwloader_compressed = "fwloader" + file_extension os.remove(fwloader_compressed) shutil.rmtree("fw-loader") shutil.rmtree("kp-firmware") @@ -303,7 +303,7 @@ def wait_user_termination(): input("Press ENTER to continue...\n") -def device_setup(board, version, quiet=False): +def device_setup(board, version, update_dbg_fw=False, quiet=False): if board is None: board = select_board() else: @@ -316,9 +316,10 @@ def device_setup(board, version, quiet=False): print("MicroPython PSoC6 Version :: ", version) - fwloader_download_install() - fwloader_update_kitprog() - fwloader_remove() + if update_dbg_fw: + fwloader_download_install() + fwloader_update_kitprog() + fwloader_remove() openocd_download_install() openocd_board_conf_download(board) @@ -442,7 +443,7 @@ def print_exit_banner(): print("################################################") print_retro_banner() - device_setup(board, version) + device_setup(board, version, True) arduino_lab_download_and_launch() arduino_lab_install_package_remove() print_exit_banner() @@ -457,7 +458,7 @@ def parser_quick_start(args): quick_start(args.board, args.version) def parser_device_setup(args): - device_setup(args.board, args.version, args.q) + device_setup(args.board, args.version, args.u, args.q) def parser_firmware_deploy(args): openocd_program(args.board, args.hexfile) @@ -502,6 +503,9 @@ def parser_device_erase(args): parser_ds.add_argument( "-q", action="store_true", help="Quiet. Do not prompt any user confirmation request" ) + parser_ds.add_argument( + "-u", action="store_true", help="Update board Kitprog3 debugger firmware" + ) parser_ds.set_defaults(func=parser_device_setup) # firmware deploy @@ -542,6 +546,4 @@ def parser_device_erase(args): if __name__ == "__main__": set_environment() - # parser() - fwloader_download_install() - fwloader_update_kitprog() + parser() From fa1608724dc5ebb925246e52d79707569fb5448a Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 13:47:13 +0100 Subject: [PATCH 4/9] tools/psoc6/mpy-psoc6.py: Added extended help in main parser. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 54 ++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index d35969f867fd..900cfca54524 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -467,14 +467,28 @@ def parser_device_erase(args): device_erase(args.board, args.q) # Main parser - parser = argparse.ArgumentParser(description="Micropython PSoC6 utility script") + main_parser_desc = """ + Micropython PSoC6 utility script + + Available commands: + + quick-start Setup of MicroPython IDE and PSoC6 device + device-setup Setup of MicroPython PSoC6 device + device-erase Erase the external memory of the PSoC6 device + firmware-deploy Firmware deployment on PSoC6 device (user provided binary file) + + mpy-psoc6.py --help for more information about each specific command. + """ + parser = argparse.ArgumentParser( + formatter_class=argparse.RawTextHelpFormatter, description=main_parser_desc + ) subparser = parser.add_subparsers() parser.set_defaults(func=main_parser_func) # quick start parser_qs = subparser.add_parser( "quick-start", - description="Setup of MicroPython IDE and PSoC6 board. \ + description="Setup of MicroPython IDE and PSoC6 device. \ Use this command for a guided installation and \ quick start using MicroPython PSoC6.", ) @@ -489,7 +503,7 @@ def parser_device_erase(args): # device setup parser_ds = subparser.add_parser( "device-setup", - description="Setup of MicroPython PSoC6 board. \ + description="Setup of MicroPython PSoC6 device. \ Use this command to install the deployment tools \ and MicroPython firmware binary, and deploy the \ firmware on the PSoC6 device.", @@ -508,10 +522,27 @@ def parser_device_erase(args): ) parser_ds.set_defaults(func=parser_device_setup) + # device erase + parser_de = subparser.add_parser( + "device-erase", + description="Erase the external memory of the device. \ + Use this command to erase the external memory if available \ + for the selected board. \ + Running device-setup after this command \ + is required to re-enable MicroPython.", + ) + parser_de.add_argument( + "-b", "--board", default=None, type=str, required=True, help="PSoC6 prototyping kit name" + ) + parser_de.add_argument( + "-q", action="store_true", help="Quiet. Do not prompt any user confirmation request" + ) + parser_de.set_defaults(func=parser_device_erase) + # firmware deploy parser_fd = subparser.add_parser( "firmware-deploy", - description="Firmware deployment on MicroPython board. \ + description="Firmware deployment on MicroPython device. \ Use this command to deploy an existing .hex file \ on a PSoC6 board. \ Requires openocd available on the system path.", @@ -524,21 +555,6 @@ def parser_device_erase(args): ) parser_fd.set_defaults(func=parser_firmware_deploy) - # device erase - parser_de = subparser.add_parser( - "device-erase", - description="Erase the external memory of the device. \ - Use this command to erase the external memory if available \ - for the selected board.", - ) - parser_de.add_argument( - "-b", "--board", default=None, type=str, required=True, help="PSoC6 prototyping kit name" - ) - parser_de.add_argument( - "-q", action="store_true", help="Quiet. Do not prompt any user confirmation request" - ) - parser_de.set_defaults(func=parser_device_erase) - # Parser call args = parser.parse_args() args.func(args) From be877f3c564463a5a0b04bda11a6fc3a70b990ef Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 14:30:16 +0100 Subject: [PATCH 5/9] tools/psoc6/mpy-psoc6.py: Added colouring to progress messages. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 61 +++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index 900cfca54524..a2824e3cec3c 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -8,6 +8,24 @@ opsys = "" +def colour_str_success(msg): + green_str_start = "\x1b[1;32;40m" + str_color_end = "\x1b[0m" + return green_str_start + msg + str_color_end + + +def colour_str_error(msg): + green_str_start = "\x1b[1;31;40m" + str_color_end = "\x1b[0m" + return green_str_start + msg + str_color_end + + +def colour_str_highlight(msg): + green_str_start = "\x1b[1;35;40m" + str_color_end = "\x1b[0m" + return green_str_start + msg + str_color_end + + def set_environment(): global opsys if sys.platform == "linux" or sys.platform == "linux2": @@ -16,7 +34,7 @@ def set_environment(): opsys = "win" elif sys.platform == "darwin": opsys = "mac" - raise Exception("OS unsupported") + raise Exception(colour_str_error("OS unsupported")) def mpy_get_fw_hex_file_name(file_name, board): @@ -28,6 +46,7 @@ def mpy_firmware_deploy(file_name, board, serial_adapter_sn=None): print("Deploying firmware...") hex_file = mpy_get_fw_hex_file_name(file_name, board) openocd_program(board, hex_file, serial_adapter_sn) + print(colour_str_success("Firmware deployed successfully")) def mpy_firmware_download(file_name, board, version): @@ -101,7 +120,7 @@ def fwloader_setup(): sh_proc = subprocess.Popen(sh_args) sh_proc.wait() except: - raise Exception("bash error") + raise Exception(colour_str_error("bash error")) os.chmod(os.path.join("fw-loader", "bin", "fw-loader"), 0o755) @@ -123,7 +142,9 @@ def fwloader_update_kitprog(): fwl_proc = subprocess.Popen(fwloader_args) fwl_proc.wait() except: - raise Exception("fwloader error") + raise Exception(colour_str_error("fwloader error")) + + print(colour_str_success("Debugger kitprog3 firmware updated successfully")) def fwloader_remove(): @@ -179,7 +200,7 @@ def openocd_setup(): sh_proc = subprocess.Popen(sh_args) sh_proc.wait() except: - raise Exception("bash error") + raise Exception(colour_str_error("bash error")) print("Downloading openocd...") file_url, file_name = get_openocd_file_url_name() @@ -237,14 +258,13 @@ def openocd_program(board, hex_file, serial_adapter_sn=None): + str(hex_file) + ' verify reset exit;"' ) - print(openocd_cmd) openocd_args = shlex.split(openocd_cmd) try: ocd_proc = subprocess.Popen(openocd_args) ocd_proc.wait() except: - raise Exception("openocd error") + raise Exception(colour_str_error("openocd error")) def openocd_remove(): @@ -267,14 +287,14 @@ def validate_board_name(board_name): break if not board_supported: - raise Exception("error: board is not supported") + raise Exception(colour_str_error("error: board is not supported")) def select_board(): def validate_board_index(board_index): max_board_index = len(boards) if board_index < 0 or board_index > max_board_index: - raise Exception("error: board ID not valid") + raise Exception(colour_str_error("error: board ID not valid")) print("") print(" Supported MicroPython PSoC6 boards ") @@ -288,7 +308,7 @@ def validate_board_index(board_index): print("") print("") - board_index = int(input("Please type the desired board ID: ")) + board_index = int(input(colour_str_highlight("Please type the desired board ID: "))) validate_board_index(board_index) board = boards[board_index]["name"] @@ -296,11 +316,15 @@ def validate_board_index(board_index): def wait_and_request_board_connect(): - input("Please CONNECT THE BOARD and PRESS ENTER to start the firmware deployment\n") + input( + colour_str_highlight( + "Please CONNECT THE BOARD and PRESS ENTER to start the firmware deployment\n" + ) + ) def wait_user_termination(): - input("Press ENTER to continue...\n") + input(colour_str_highlight("Press ENTER to continue...\n")) def device_setup(board, version, update_dbg_fw=False, quiet=False): @@ -331,19 +355,20 @@ def device_setup(board, version, update_dbg_fw=False, quiet=False): mpy_firmware_deploy("hello-world", board) mpy_firmware_deploy("mpy-psoc6", board) - print(" Device firmware deployment completed.") openocd_remove() mpy_firmware_remove("hello-world", board) mpy_firmware_remove("mpy-psoc6", board) + print(colour_str_success("Device setup completed :)")) + if not quiet: wait_user_termination() def device_erase(board, quiet=False): if board != "CY8CPROTO-062-4343W": - raise Exception("error: board is not supported") + raise Exception(colour_str_error("error: board is not supported")) openocd_download_install() openocd_board_conf_download(board) @@ -357,6 +382,8 @@ def device_erase(board, quiet=False): openocd_remove() mpy_firmware_remove("device-erase", board) + print(colour_str_success("Device erase completed :)")) + if not quiet: wait_user_termination() @@ -408,7 +435,7 @@ def launch_arduino_lab(): ide_proc = subprocess.Popen(mpy_ide) ide_proc.wait() except: - raise Exception("error: Could not launch Arduino Lab IDE") + raise Exception(colour_str_error("error: Could not launch Arduino Lab IDE")) os.chdir(parent_dir) @@ -438,9 +465,9 @@ def print_retro_banner(): print("################################################") def print_exit_banner(): - print("################################################") - print(" The installation is completed. Have fun :) ") - print("################################################") + print(colour_str_success("################################################")) + print(colour_str_success(" The quick-start is completed. Have fun :) ")) + print(colour_str_success("################################################")) print_retro_banner() device_setup(board, version, True) From 84781a4e7de095595cb046d3ba395b24a6113457 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 14:44:16 +0100 Subject: [PATCH 6/9] tools/psoc6/mpy-psoc6.py: Fixed terminal coloring in windows. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index a2824e3cec3c..bdf11a0568fa 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -32,6 +32,7 @@ def set_environment(): opsys = "linux" elif sys.platform == "win32" or sys.platform == "cygwin": opsys = "win" + os.system('color') elif sys.platform == "darwin": opsys = "mac" raise Exception(colour_str_error("OS unsupported")) @@ -340,11 +341,6 @@ def device_setup(board, version, update_dbg_fw=False, quiet=False): print("MicroPython PSoC6 Version :: ", version) - if update_dbg_fw: - fwloader_download_install() - fwloader_update_kitprog() - fwloader_remove() - openocd_download_install() openocd_board_conf_download(board) mpy_firmware_download("hello-world", board, "v0.3.0") @@ -352,6 +348,11 @@ def device_setup(board, version, update_dbg_fw=False, quiet=False): if not quiet: wait_and_request_board_connect() + + if update_dbg_fw: + fwloader_download_install() + fwloader_update_kitprog() + fwloader_remove() mpy_firmware_deploy("hello-world", board) mpy_firmware_deploy("mpy-psoc6", board) From 787e583bd6ff7332a73611ec96e81b8a62e99895 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 15:11:09 +0100 Subject: [PATCH 7/9] tools/psoc6/mpy-psoc6.py: Added script version. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index bdf11a0568fa..82978887ce4b 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -6,6 +6,7 @@ ] opsys = "" +version = "0.1.0" def colour_str_success(msg): @@ -32,7 +33,7 @@ def set_environment(): opsys = "linux" elif sys.platform == "win32" or sys.platform == "cygwin": opsys = "win" - os.system('color') + os.system("color") # Enable colouring in cmd and powershell elif sys.platform == "darwin": opsys = "mac" raise Exception(colour_str_error("OS unsupported")) @@ -348,7 +349,7 @@ def device_setup(board, version, update_dbg_fw=False, quiet=False): if not quiet: wait_and_request_board_connect() - + if update_dbg_fw: fwloader_download_install() fwloader_update_kitprog() @@ -495,6 +496,16 @@ def parser_device_erase(args): device_erase(args.board, args.q) # Main parser + class ver_action(argparse.Action): + def __init__(self, option_strings, dest, **kwargs): + return super().__init__( + option_strings, dest, nargs=0, default=argparse.SUPPRESS, **kwargs + ) + + def __call__(self, parser, namespace, values, option_string, **kwargs): + print("mpy-psoc6 version: " + version) + parser.exit() + main_parser_desc = """ Micropython PSoC6 utility script @@ -510,6 +521,7 @@ def parser_device_erase(args): parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter, description=main_parser_desc ) + parser.add_argument("-v", "--version", action=ver_action, help="mpy-psoc6 version") subparser = parser.add_subparsers() parser.set_defaults(func=main_parser_func) From 5d4ced8b8d5db1318d538b9c42f0956038e3f2f8 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 15:42:12 +0100 Subject: [PATCH 8/9] tools/psoc6/mpy-psoc6.py: Added openocd fw-loader error handling. Signed-off-by: enriquezgarc --- tools/psoc6/mpy-psoc6.py | 70 ++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py index 82978887ce4b..a17374b496e9 100644 --- a/tools/psoc6/mpy-psoc6.py +++ b/tools/psoc6/mpy-psoc6.py @@ -1,4 +1,4 @@ -import argparse, os, sys, shlex, shutil, subprocess, requests, tarfile, zipfile +import argparse, os, sys, shlex, shutil, subprocess, time, requests, tarfile, zipfile boards = [ {"name": "CY8CPROTO-062-4343W", "ocd_cfg_file": "psoc6_2m.cfg"}, @@ -135,17 +135,28 @@ def fwloader_setup(): def fwloader_update_kitprog(): + def parse_output_for_error(fwloader_stdout): + fwloader_out_lines = fwloader_stdout.decode().split("\n") + for line in fwloader_out_lines: + if "Error" in line: + raise Exception(colour_str_error(line)) + print("Updating kitprog3 firmware...") fwloader_cmd = "fw-loader --update-kp3 all" - print(fwloader_cmd) fwloader_args = shlex.split(fwloader_cmd) + fwl_proc = subprocess.Popen(fwloader_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) try: - fwl_proc = subprocess.Popen(fwloader_args) - fwl_proc.wait() + out, err = fwl_proc.communicate(timeout=90) except: + fwl_proc.kill() raise Exception(colour_str_error("fwloader error")) + if err: + raise Exception(colour_str_error(err.decode())) + + parse_output_for_error(out) + print(colour_str_success("Debugger kitprog3 firmware updated successfully")) @@ -262,12 +273,16 @@ def openocd_program(board, hex_file, serial_adapter_sn=None): ) openocd_args = shlex.split(openocd_cmd) + ocd_proc = subprocess.Popen(openocd_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) try: - ocd_proc = subprocess.Popen(openocd_args) - ocd_proc.wait() + out, err = ocd_proc.communicate(timeout=20) except: + ocd_proc.kill() raise Exception(colour_str_error("openocd error")) + if err: + raise Exception(colour_str_error(err.decode())) + def openocd_remove(): if opsys == "linux": @@ -342,25 +357,29 @@ def device_setup(board, version, update_dbg_fw=False, quiet=False): print("MicroPython PSoC6 Version :: ", version) - openocd_download_install() - openocd_board_conf_download(board) - mpy_firmware_download("hello-world", board, "v0.3.0") - mpy_firmware_download("mpy-psoc6", board, version) - if not quiet: wait_and_request_board_connect() if update_dbg_fw: fwloader_download_install() - fwloader_update_kitprog() - fwloader_remove() + try: + fwloader_update_kitprog() + finally: + fwloader_remove() + time.sleep(10) # Wait for the device to restart - mpy_firmware_deploy("hello-world", board) - mpy_firmware_deploy("mpy-psoc6", board) + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("hello-world", board, "v0.3.0") + mpy_firmware_download("mpy-psoc6", board, version) - openocd_remove() - mpy_firmware_remove("hello-world", board) - mpy_firmware_remove("mpy-psoc6", board) + try: + mpy_firmware_deploy("hello-world", board) + mpy_firmware_deploy("mpy-psoc6", board) + finally: + openocd_remove() + mpy_firmware_remove("hello-world", board) + mpy_firmware_remove("mpy-psoc6", board) print(colour_str_success("Device setup completed :)")) @@ -372,17 +391,18 @@ def device_erase(board, quiet=False): if board != "CY8CPROTO-062-4343W": raise Exception(colour_str_error("error: board is not supported")) - openocd_download_install() - openocd_board_conf_download(board) - mpy_firmware_download("device-erase", board, "v0.3.0") - if not quiet: wait_and_request_board_connect() - mpy_firmware_deploy("device-erase", board) + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("device-erase", board, "v0.3.0") - openocd_remove() - mpy_firmware_remove("device-erase", board) + try: + mpy_firmware_deploy("device-erase", board) + finally: + openocd_remove() + mpy_firmware_remove("device-erase", board) print(colour_str_success("Device erase completed :)")) From 5e69743a453ca7f6540fa978b52b7a176d94ddd2 Mon Sep 17 00:00:00 2001 From: enriquezgarc Date: Wed, 22 Nov 2023 17:27:13 +0100 Subject: [PATCH 9/9] docs/psoc6: Added python utility docs to installation. Signed-off-by: enriquezgarc --- docs/psoc6/installation.rst | 102 ++++++++++++++++++++++++++++++++---- docs/psoc6/quickref.rst | 2 - 2 files changed, 92 insertions(+), 12 deletions(-) diff --git a/docs/psoc6/installation.rst b/docs/psoc6/installation.rst index d3725576b857..e974d1f052a7 100644 --- a/docs/psoc6/installation.rst +++ b/docs/psoc6/installation.rst @@ -4,13 +4,23 @@ Installing MicroPython ====================== To support the MicroPython PSoC6™ port installation the ``mpy-psoc6`` utility script is provided for Windows and -Linux. -You can easily download from your OS terminal with the following command: +Linux. Additionally, a python script is available also cross-platform for Linux and Windows. + + +.. warning:: + + The plan is to replace the native bash and cmd line scripts for Linux and Windows by executable programs generated for each OS (including MacOS) from the python script in future releases. + New features in the installation utility will be only added to the executable and python script versions, as the native OS scripts will be deprecated in the future. + + +You can easily download them terminal with the following command: .. tabs:: .. group-tab:: Linux + Download the mpy-psoc6 utility script: + .. code-block:: bash curl -s -L https://raw.githubusercontent.com/infineon/micropython/ports-psoc6-main/tools/psoc6/mpy-psoc6.sh > mpy-psoc6.sh @@ -29,6 +39,21 @@ You can easily download from your OS terminal with the following command: curl.exe -s -L https://raw.githubusercontent.com/infineon/micropython/ports-psoc6-main/tools/psoc6/mpy-psoc6.cmd > mpy-psoc6.cmd + .. group-tab:: Python + + Download the mpy-psoc6 utility script: + + .. code-block:: bash + + curl.exe -s -L https://raw.githubusercontent.com/infineon/micropython/ports-psoc6-main/tools/psoc6/mpy-psoc6.py > mpy-psoc6.py + + Make sure you have a recent version on `Python3.x `_ installed and the `pip `_ package installer. + Then install the following packages: + + .. code-block:: bash + + pip install requests + Find all the available commands and options by running the script with the command help: @@ -44,7 +69,13 @@ Find all the available commands and options by running the script with the comma .. code-block:: bash - mpy-psoc6.cmd help + .\mpy-psoc6.cmd help + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py --help .. _psoc6_quick_start: @@ -66,7 +97,13 @@ micropython is to run the ``quick-start`` command of the script: .. code-block:: bash - mpy-psoc6.cmd quick-start + .\mpy-psoc6.cmd quick-start + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py quick-start The command will take care of the following: @@ -97,7 +134,13 @@ MicropPython firmware version: .. code-block:: bash - mpy-psoc6.cmd device-setup + .\mpy-psoc6.cmd device-setup + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py device-setup You can run any command any time you want to upgrade to the latest MicroPython firmware version. @@ -127,7 +170,13 @@ version need to be passed as arguments. .. code-block:: bash - mpy-psoc6.cmd device-setup CY8CPROTO-062-4343W v0.1.1 + .\mpy-psoc6.cmd device-setup CY8CPROTO-062-4343W v0.1.1 + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py device-setup -b CY8CPROTO-062-4343W -v v0.1.1 .. warning:: @@ -135,8 +184,29 @@ version need to be passed as arguments. Equally, provide a valid tag existing in the release section with the format *v.x.y.z*. No fail safe mechanisms or error verifications are (yet) implemented on the ``mpy-psoc6`` utility, and the script will fail to retrieve the necessary firmware file. +Updating the flasher firmware +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The evaluation PSoC6™ boards include an integrated hardware programmer tool using `KitProg `_ firmware. +Some older boards will come preflashed with KitProg version 2. In MicroPython PSoC6™ port it is required to use KitProg version 3, and the setup process will fail for version 2. + +If you need to update the KitProg firmware, you can use the flag ``-u`` for updating the firmware version in the MicropPython device setup process. + +.. tabs:: + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py device-setup -u + + +.. warning:: + + This option is only available in the python script utility. + Direct binary flashing -^^^^^^^^^^^^^^^^^^^^^^ +---------------------- Another alternative to program the board is to directly provide the binary file. The ``firmware-deploy`` command is providing this option. This commands is skipping all the tools download and installation, neither download the MicoPython firmware. @@ -157,10 +227,16 @@ The board needs to be specified, and the path and name of the ``.hex`` file: .. code-block:: bash - mpy-psoc6.cmd firmware-deploy CY8CPROTO-062-4343W pathtodir/mpy-psoc6_CY8CPROTO-062-4343W.hex + .\mpy-psoc6.cmd firmware-deploy CY8CPROTO-062-4343W pathtodir/mpy-psoc6_CY8CPROTO-062-4343W.hex + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py firmware-deploy -b CY8CPROTO-062-4343W -f pathtodir/mpy-psoc6_CY8CPROTO-062-4343W.hex Erasing the device (external) file system -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------------------------------- Some PSoC6™ boards include an external flash memory which is used by the MicroPython file system. This memory will not be erased when reprogramming or erasing MicroPython firmware via ``device-setup`` or ``firmware-deploy``. @@ -178,7 +254,13 @@ Use the ``device-erase`` command to erase of the external memory of your PSoC6 .. code-block:: bash - mpy-psoc6.cmd device-erase + .\mpy-psoc6.cmd device-erase + + .. group-tab:: Python + + .. code-block:: bash + + python mpy-psoc6.py device-erase .. warning:: diff --git a/docs/psoc6/quickref.rst b/docs/psoc6/quickref.rst index 1ae75dadcfa9..e859f401ad5d 100644 --- a/docs/psoc6/quickref.rst +++ b/docs/psoc6/quickref.rst @@ -413,7 +413,6 @@ SCK P9_2 P6_2 P10_2 ===== =========== ============ ============ .. - TODO: This is only applicable to the CY8CPROTO-062-4343W. This does not belong here. TODO: Define approach on how the user gets to know the pinout diagram, alternate function of each board - From board manual? @@ -510,7 +509,6 @@ PSoC6 supports only 1 12-bit SAR ADC with the following channel to pin mapping a +---------+-------+ .. - TODO: This is only applicable to the CY8CPROTO-062-4343W. This does not belong here. TODO: Define approach on how the user gets to know the pinout diagram, alternate function of each board - From board manual?