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? diff --git a/tools/psoc6/mpy-psoc6.py b/tools/psoc6/mpy-psoc6.py new file mode 100644 index 000000000000..a17374b496e9 --- /dev/null +++ b/tools/psoc6/mpy-psoc6.py @@ -0,0 +1,625 @@ +import argparse, os, sys, shlex, shutil, subprocess, time, requests, tarfile, zipfile + +boards = [ + {"name": "CY8CPROTO-062-4343W", "ocd_cfg_file": "psoc6_2m.cfg"}, + {"name": "CY8CPROTO-063-BLE", "ocd_cfg_file": "psoc6.cfg"}, +] + +opsys = "" +version = "0.1.0" + + +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": + opsys = "linux" + elif sys.platform == "win32" or sys.platform == "cygwin": + opsys = "win" + os.system("color") # Enable colouring in cmd and powershell + elif sys.platform == "darwin": + opsys = "mac" + raise Exception(colour_str_error("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) + print(colour_str_success("Firmware deployed successfully")) + + +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 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(colour_str_error("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(): + 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" + fwloader_args = shlex.split(fwloader_cmd) + + fwl_proc = subprocess.Popen(fwloader_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + try: + 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")) + + +def fwloader_remove(): + file_extension = ".zip" + fwloader_compressed = "fwloader" + 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" + 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(colour_str_error("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;"' + ) + openocd_args = shlex.split(openocd_cmd) + + ocd_proc = subprocess.Popen(openocd_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE) + try: + 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": + 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(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(colour_str_error("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(colour_str_highlight("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( + colour_str_highlight( + "Please CONNECT THE BOARD and PRESS ENTER to start the firmware deployment\n" + ) + ) + + +def wait_user_termination(): + input(colour_str_highlight("Press ENTER to continue...\n")) + + +def device_setup(board, version, update_dbg_fw=False, 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) + + if not quiet: + wait_and_request_board_connect() + + if update_dbg_fw: + fwloader_download_install() + try: + fwloader_update_kitprog() + finally: + fwloader_remove() + time.sleep(10) # Wait for the device to restart + + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("hello-world", board, "v0.3.0") + mpy_firmware_download("mpy-psoc6", board, version) + + 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 :)")) + + if not quiet: + wait_user_termination() + + +def device_erase(board, quiet=False): + if board != "CY8CPROTO-062-4343W": + raise Exception(colour_str_error("error: board is not supported")) + + if not quiet: + wait_and_request_board_connect() + + openocd_download_install() + openocd_board_conf_download(board) + mpy_firmware_download("device-erase", board, "v0.3.0") + + try: + mpy_firmware_deploy("device-erase", board) + finally: + openocd_remove() + mpy_firmware_remove("device-erase", board) + + print(colour_str_success("Device erase completed :)")) + + 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(colour_str_error("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(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) + 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.u, 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 + 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 + + 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 + ) + parser.add_argument("-v", "--version", action=ver_action, help="mpy-psoc6 version") + 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 device. \ + 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 device. \ + 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.add_argument( + "-u", action="store_true", help="Update board Kitprog3 debugger firmware" + ) + 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 device. \ + 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) + + # Parser call + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + set_environment() + parser()