diff --git a/boards/nano_every.json b/boards/nano_every.json index 1ac658b..3dcc1da 100644 --- a/boards/nano_every.json +++ b/boards/nano_every.json @@ -14,9 +14,9 @@ "variant": "nona4809" }, "fuses": { - "SYSCFG0": "0xC9", - "BOOTEND": "0x00", - "OSCCFG": "0x01" + "syscfg0": "0xc9", + "bootend": "0x00", + "osccfg": "0x01" }, "frameworks": [ "arduino" diff --git a/boards/uno_wifi_rev2.json b/boards/uno_wifi_rev2.json index 14f059b..6a7b65d 100644 --- a/boards/uno_wifi_rev2.json +++ b/boards/uno_wifi_rev2.json @@ -17,9 +17,9 @@ "bootloader": { "file": "atmega4809_uart_bl.hex", "fuses_file": "fuses_4809.bin", - "BOOTEND": "0x02", - "SYSCFG0": "0xC9", - "OSCCFG": "0x01" + "bootend": "0x02", + "syscfg0": "0xc9", + "osccfg": "0x01" }, "frameworks": [ "arduino" diff --git a/builder/bootloader.py b/builder/bootloader.py index f5969e3..499d95d 100644 --- a/builder/bootloader.py +++ b/builder/bootloader.py @@ -15,7 +15,7 @@ import sys import os -from SCons.Script import ARGUMENTS, Import, Return +from SCons.Script import Import, Return Import("env") @@ -40,14 +40,6 @@ def get_suitable_optiboot_binary(framework_dir, board_config): return bootloader_path -AVRDUDE_PATH = platform.get_package_dir("tool-avrdude-megaavr") or "" - -common_cmd = [ - "avrdude", "-p", "$BOARD_MCU", "-e", "-C", - '"%s"' % os.path.join(AVRDUDE_PATH, "avrdude.conf"), - "-c", "$UPLOAD_PROTOCOL", "$UPLOAD_FLAGS" -] - framework_dir = "" if env.get("PIOFRAMEWORK", []): framework_dir = platform.get_package_dir(platform.frameworks[env.get( @@ -62,9 +54,8 @@ def get_suitable_optiboot_binary(framework_dir, board_config): if not os.path.isfile(bootloader_path): bootloader_path = get_suitable_optiboot_binary(framework_dir, board) else: - if not isfile(bootloader_path): - bootloader_path = join( - framework_dir, "bootloaders", bootloader_path) + if not os.path.isfile(bootloader_path): + bootloader_path = os.path.join(framework_dir, "bootloaders", bootloader_path) if not board.get("bootloader", {}): sys.stderr.write("Error: missing bootloader configuration!\n") @@ -73,61 +64,46 @@ def get_suitable_optiboot_binary(framework_dir, board_config): if not os.path.isfile(bootloader_path): bootloader_path = os.path.join(framework_dir, "bootloaders", bootloader_path) -if not os.path.isfile(bootloader_path): +if not os.path.isfile(bootloader_path) and "BOOTFLAGS" not in env: sys.stderr.write("Error: Couldn't find bootloader image\n") env.Exit(1) -bootloader_flags = ['-Uflash:w:"%s":i' % bootloader_path] - -# -# Fuses processing -# - -fuses_action = None -if core == "MegaCoreX": - fuses_action = env.SConscript("fuses.py", exports="env") +env.Append( + BOOTUPLOADER="avrdude", + BOOTUPLOADERFLAGS=[ + "-p", + "$BOARD_MCU", + "-C", + '"%s"' + % os.path.join(env.PioPlatform().get_package_dir( + "tool-avrdude-megaavr") or "", "avrdude.conf"), + ], + BOOTFLAGS=['-Uflash:w:"%s":i' % bootloader_path], + UPLOADBOOTCMD="$BOOTUPLOADER $BOOTUPLOADERFLAGS $UPLOAD_FLAGS $BOOTFLAGS", +) + +if not env.BoardConfig().get("upload", {}).get("require_upload_port", False): + # upload methods via USB + env.Append(BOOTUPLOADERFLAGS=["-P", "usb"]) else: - bootloader_fuses = board.get("bootloader", {}) - if not bootloader_fuses: - sys.stderr.write("Error: missing bootloader configuration!\n") - env.Exit(1) + env.AutodetectUploadPort() + env.Append(FUSESUPLOADERFLAGS=["-P", '"$UPLOAD_PORT"']) - # Note: the index represents the fuse number - fuses = ( - bootloader_fuses.get("WDTCFG", ""), - bootloader_fuses.get("BODCFG", ""), - bootloader_fuses.get("OSCCFG", ""), - "", # Reserved - bootloader_fuses.get("TCD0CFG", ""), - bootloader_fuses.get("SYSCFG0", ""), - bootloader_fuses.get("SYSCFG1", ""), - bootloader_fuses.get("APPEND", ""), - bootloader_fuses.get("BOOTEND", ""), +if env.subst("$UPLOAD_PROTOCOL") != "custom": + env.Append(BOOTUPLOADERFLAGS=["-c", "$UPLOAD_PROTOCOL"]) +else: + print( + "Warning: The `custom` upload protocol is used! The upload and fuse flags may " + "conflict!\nMore information: " + "https://docs.platformio.org/en/latest/platforms/atmelavr.html" + "#overriding-default-bootloader-command\n" ) - lock_fuse = bootloader_fuses.get("LOCKBIT", "") - - fuses_cmd = [ - "avrdude", "-p", "$BOARD_MCU", "-C", - '"%s"' % os.path.join(AVRDUDE_PATH, "avrdude.conf"), - "-c", "$UPLOAD_PROTOCOL", "$UPLOAD_FLAGS" - ] - - if int(ARGUMENTS.get("PIOVERBOSE", 0)): - fuses_cmd.append("-v") - - for idx, value in enumerate(fuses): - if value: - fuses_cmd.append("-Ufuse%d:w:%s:m" % (idx, value)) - - if lock_fuse: - fuses_cmd.append("-Ulock:w:%s:m" % lock_fuse) - - fuses_action = env.VerboseAction(" ".join(fuses_cmd), "Setting fuses") +fuses_action = env.SConscript("fuses.py", exports="env") bootloader_actions = [ fuses_action, - env.VerboseAction(" ".join(common_cmd + bootloader_flags), "Uploading bootloader") + env.VerboseAction("$UPLOADBOOTCMD", "Uploading bootloader"), ] Return("bootloader_actions") diff --git a/builder/fuses.py b/builder/fuses.py index 6072f6b..6a4398c 100644 --- a/builder/fuses.py +++ b/builder/fuses.py @@ -1,7 +1,7 @@ import sys import os -from SCons.Script import ARGUMENTS, Import, Return +from SCons.Script import ARGUMENTS, COMMAND_LINE_TARGETS, Import, Return Import("env") @@ -15,49 +15,77 @@ def print_fuses_info(fuses, lock_fuse): print("lock = %s" % lock_fuse) - board = env.BoardConfig() platform = env.PioPlatform() -board_fuses = board.get("fuses", {}) -if not board_fuses: +fuses_section = "fuses" +if "bootloader" in COMMAND_LINE_TARGETS or "UPLOADBOOTCMD" in env: + fuses_section = "bootloader" + +board_fuses = board.get(fuses_section, {}) +if not board_fuses and "FUSESFLAGS" not in env: sys.stderr.write("Error: No fuse values specified!\n") env.Exit(1) # Note: the index represents the fuse number fuses = ( - board_fuses.get("WDTCFG", ""), - board_fuses.get("BODCFG", ""), - board_fuses.get("OSCCFG", ""), - "", # Reserved - board_fuses.get("TCD0CFG", ""), - board_fuses.get("SYSCFG0", ""), - board_fuses.get("SYSCFG1", ""), - board_fuses.get("APPEND", ""), - board_fuses.get("BOOTEND", ""), + board_fuses.get("wdtcfg", ""), + board_fuses.get("bodcfg", ""), + board_fuses.get("osccfg", ""), + "", # reserved + board_fuses.get("tcd0cfg", ""), + board_fuses.get("syscfg0", ""), + board_fuses.get("syscfg1", ""), + board_fuses.get("append", ""), + board_fuses.get("bootend", ""), ) lock_fuse = board_fuses.get("LOCKBIT", "") -fuses_cmd = [ - "avrdude", "-p", "$BOARD_MCU", "-C", - '"%s"' % os.path.join(platform.get_package_dir( - "tool-avrdude-megaavr") or "", "avrdude.conf"), - "-c", "$UPLOAD_PROTOCOL", "$UPLOAD_FLAGS" -] - -if int(ARGUMENTS.get("PIOVERBOSE", 0)): - fuses_cmd.append("-v") +env.Append( + FUSESUPLOADER="avrdude", + FUSESUPLOADERFLAGS=[ + "-p", + "$BOARD_MCU", + "-C", + '"%s"' + % os.path.join(env.PioPlatform().get_package_dir( + "tool-avrdude-megaavr") or "", "avrdude.conf"), + ], + SETFUSESCMD="$FUSESUPLOADER $FUSESUPLOADERFLAGS $UPLOAD_FLAGS $FUSESFLAGS", +) -for idx, value in enumerate(fuses): - if value: - fuses_cmd.append("-Ufuse%d:w:%s:m" % (idx, value)) +env.Append( + FUSESFLAGS=[ + "-Ufuse%d:w:%s:m" % (idx, value) for idx, value in enumerate(fuses) if value + ] +) if lock_fuse: - fuses_cmd.append("-Ulock:w:%s:m" % lock_fuse) + env.Append(FUSESFLAGS=["-Ulock:w:%s:m" % lock_fuse]) + +if int(ARGUMENTS.get("PIOVERBOSE", 0)): + env.Append(FUSESUPLOADERFLAGS=["-v"]) + +if not env.BoardConfig().get("upload", {}).get("require_upload_port", False): + # upload methods via USB + env.Append(FUSESUPLOADERFLAGS=["-P", "usb"]) +else: + env.AutodetectUploadPort() + env.Append(FUSESUPLOADERFLAGS=["-P", '"$UPLOAD_PORT"']) + +if env.subst("$UPLOAD_PROTOCOL") != "custom": + env.Append(FUSESUPLOADERFLAGS=["-c", "$UPLOAD_PROTOCOL"]) +else: + print( + "Warning: The `custom` upload protocol is used! The upload and fuse flags may " + "conflict!\nMore information: " + "https://docs.platformio.org/en/latest/platforms/atmelavr.html" + "#overriding-default-fuses-command\n" + ) print_fuses_info(fuses, lock_fuse) -fuses_action = env.VerboseAction(" ".join(fuses_cmd), "Setting fuses") +fuses_action = env.VerboseAction("$SETFUSESCMD", "Setting fuses") Return("fuses_action") diff --git a/builder/main.py b/builder/main.py index 038c081..a4f7fb6 100644 --- a/builder/main.py +++ b/builder/main.py @@ -206,8 +206,8 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621 if "upload" in COMMAND_LINE_TARGETS and "arduino" in env.subst("$PIOFRAMEWORK"): if board == "uno_wifi_rev2": # uno_wifi_rev2 requires bootloader to be uploaded in any case - upload_actions = env.SConscript( - "bootloader.py", exports="env") + upload_actions + upload_actions += env.SConscript("bootloader.py", exports="env") + elif board == "nano_every": # Program fuses after programming flash upload_actions.append(env.SConscript("fuses.py", exports="env"))