diff --git a/boards/ATmega1608.json b/boards/ATmega1608.json new file mode 100644 index 0000000..ae5a3e7 --- /dev/null +++ b/boards/ATmega1608.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA1608", + "f_cpu": "16000000L", + "mcu": "atmega1608", + "variant": "32pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega1608", + "upload": { + "maximum_ram_size": 2048, + "maximum_size": 16384, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA1608", + "vendor": "Microchip" +} diff --git a/boards/ATmega1609.json b/boards/ATmega1609.json new file mode 100644 index 0000000..83edca7 --- /dev/null +++ b/boards/ATmega1609.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA1609", + "f_cpu": "16000000L", + "mcu": "atmega1609", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega1609", + "upload": { + "maximum_ram_size": 2048, + "maximum_size": 16384, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA1609", + "vendor": "Microchip" +} diff --git a/boards/ATmega3208.json b/boards/ATmega3208.json new file mode 100644 index 0000000..9744be8 --- /dev/null +++ b/boards/ATmega3208.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA3208", + "f_cpu": "16000000L", + "mcu": "atmega3208", + "variant": "32pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega3208", + "upload": { + "maximum_ram_size": 4096, + "maximum_size": 32768, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA3208", + "vendor": "Microchip" +} diff --git a/boards/ATmega3209.json b/boards/ATmega3209.json new file mode 100644 index 0000000..6c7d3f3 --- /dev/null +++ b/boards/ATmega3209.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA3209", + "f_cpu": "16000000L", + "mcu": "atmega3209", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega3209", + "upload": { + "maximum_ram_size": 4096, + "maximum_size": 32768, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA3209", + "vendor": "Microchip" +} diff --git a/boards/ATmega4808.json b/boards/ATmega4808.json new file mode 100644 index 0000000..a0bd34c --- /dev/null +++ b/boards/ATmega4808.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA4808", + "f_cpu": "16000000L", + "mcu": "atmega4808", + "variant": "32pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega4808", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 49152, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA4808", + "vendor": "Microchip" +} diff --git a/boards/ATmega4809.json b/boards/ATmega4809.json new file mode 100644 index 0000000..8b56d51 --- /dev/null +++ b/boards/ATmega4809.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA4809", + "f_cpu": "16000000L", + "mcu": "atmega4809", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega4809", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 49152, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA4809", + "vendor": "Microchip" +} diff --git a/boards/ATmega808.json b/boards/ATmega808.json new file mode 100644 index 0000000..5e08df6 --- /dev/null +++ b/boards/ATmega808.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA808", + "f_cpu": "16000000L", + "mcu": "atmega808", + "variant": "32pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega808", + "upload": { + "maximum_ram_size": 1024, + "maximum_size": 8192, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA808", + "vendor": "Microchip" +} diff --git a/boards/ATmega809.json b/boards/ATmega809.json new file mode 100644 index 0000000..bbcbc04 --- /dev/null +++ b/boards/ATmega809.json @@ -0,0 +1,24 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA809", + "f_cpu": "16000000L", + "mcu": "atmega809", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "ATmega809", + "upload": { + "maximum_ram_size": 1024, + "maximum_size": 8192, + "protocol": "jtag2updi", + "speed": 115200 + }, + "url": "https://www.microchip.com/wwwproducts/en/ATMEGA809", + "vendor": "Microchip" +} diff --git a/boards/avr_iot_wg.json b/boards/avr_iot_wg.json new file mode 100644 index 0000000..3fad172 --- /dev/null +++ b/boards/avr_iot_wg.json @@ -0,0 +1,23 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA4808", + "f_cpu": "16000000L", + "mcu": "atmega4808", + "variant": "32pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "AVR-IoT WG Development Board", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 49152, + "protocol": "curiosity_updi" + }, + "url": "https://www.microchip.com/developmenttools/ProductDetails/AC164160", + "vendor": "Microchip" +} diff --git a/boards/curiosity_nano_4809.json b/boards/curiosity_nano_4809.json new file mode 100644 index 0000000..3f27fb2 --- /dev/null +++ b/boards/curiosity_nano_4809.json @@ -0,0 +1,23 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA4809", + "f_cpu": "16000000L", + "mcu": "atmega4809", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "Curiosity Nano ATmega4809", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 49152, + "protocol": "curiosity_updi" + }, + "url": "https://www.microchip.com/developmenttools/ProductDetails/DM320115", + "vendor": "Microchip" +} diff --git a/boards/nano_every.json b/boards/nano_every.json index f41d9f6..3dcc1da 100644 --- a/boards/nano_every.json +++ b/boards/nano_every.json @@ -13,25 +13,21 @@ "usb_product": "Arduino Nano Every", "variant": "nona4809" }, - "bootloader": { - "SYSCFG0": "0xC9", - "file": "atmega4809_uart_bl.hex", - "fuses_file": "fuses_4809.bin", - "BOOTEND": "0x00", - "OSCCFG": "0x01" + "fuses": { + "syscfg0": "0xc9", + "bootend": "0x00", + "osccfg": "0x01" }, "frameworks": [ "arduino" ], "name": "Arduino Nano Every", "upload": { + "extra_flags": ["-V", "-e", "-D"], "maximum_ram_size": 6144, "maximum_size": 48640, "protocol": "jtag2updi", - "require_upload_port": true, - "speed": 115200, - "use_1200bps_touch": true, - "wait_for_upload_port": true + "speed": 115200 }, "url": "https://www.arduino.cc/en/Guide/NANOEvery", "vendor": "Arduino" diff --git a/boards/uno_wifi_rev2.json b/boards/uno_wifi_rev2.json index 5d4f52a..6a7b65d 100644 --- a/boards/uno_wifi_rev2.json +++ b/boards/uno_wifi_rev2.json @@ -17,22 +17,20 @@ "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" ], "name": "Arduino Uno WiFi Rev2", "upload": { - "disable_flushing": true, + "extra_flags": ["-V", "-e", "-D"], "maximum_ram_size": 6144, "maximum_size": 48640, "protocol": "xplainedmini_updi", - "require_upload_port": true, - "speed": 115200, - "wait_for_upload_port": true + "speed": 115200 }, "url": "https://www.arduino.cc/en/Guide/ArduinoUnoWiFiRev2", "vendor": "Arduino" diff --git a/boards/xplained_pro_4809.json b/boards/xplained_pro_4809.json new file mode 100644 index 0000000..ce5c8da --- /dev/null +++ b/boards/xplained_pro_4809.json @@ -0,0 +1,23 @@ +{ + "build": { + "core": "MegaCoreX", + "extra_flags": "-DARDUINO_AVR_ATMEGA4809", + "f_cpu": "16000000L", + "mcu": "atmega4809", + "variant": "48pin-standard" + }, + "hardware": { + "oscillator": "internal" + }, + "frameworks": [ + "arduino" + ], + "name": "Xplained Pro ATmega4809", + "upload": { + "maximum_ram_size": 6144, + "maximum_size": 49152, + "protocol": "xplainedpro_updi" + }, + "url": "https://www.microchip.com/developmenttools/ProductDetails/atmega4809-xpro", + "vendor": "Microchip" +} diff --git a/builder/bootloader.py b/builder/bootloader.py new file mode 100644 index 0000000..499d95d --- /dev/null +++ b/builder/bootloader.py @@ -0,0 +1,109 @@ +# Copyright 2019-present PlatformIO +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import os + +from SCons.Script import Import, Return + +Import("env") + +board = env.BoardConfig() +platform = env.PioPlatform() +core = board.get("build.core", "") + + +def get_suitable_optiboot_binary(framework_dir, board_config): + uart = board_config.get("hardware.uart", "uart0").upper() + bootloader_led = board_config.get("bootloader.led_pin", "A7").upper() + bootloader_speed = board_config.get("bootloader.speed", env.subst("$UPLOAD_SPEED")) + bootloader_pins = board_config.get("bootloader.pins", "DEF").upper() + bootloader_file = "Optiboot_mega0_%s_%s_%s_%s.hex" % ( + uart, bootloader_pins, bootloader_speed, bootloader_led) + + bootloader_path = os.path.join( + framework_dir, "bootloaders", "optiboot", "bootloaders", "mega0", + bootloader_speed, bootloader_file + ) + + return bootloader_path + + +framework_dir = "" +if env.get("PIOFRAMEWORK", []): + framework_dir = platform.get_package_dir(platform.frameworks[env.get( + "PIOFRAMEWORK")[0]]["package"]) + +# +# Bootloader processing +# + +bootloader_path = board.get("bootloader.file", "") +if core == "MegaCoreX": + if not os.path.isfile(bootloader_path): + bootloader_path = get_suitable_optiboot_binary(framework_dir, board) +else: + 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") + env.Exit(1) + +if not os.path.isfile(bootloader_path): + bootloader_path = os.path.join(framework_dir, "bootloaders", 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) + +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: + env.AutodetectUploadPort() + env.Append(FUSESUPLOADERFLAGS=["-P", '"$UPLOAD_PORT"']) + +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" + ) + +fuses_action = env.SConscript("fuses.py", exports="env") + +bootloader_actions = [ + fuses_action, + env.VerboseAction("$UPLOADBOOTCMD", "Uploading bootloader"), +] + +Return("bootloader_actions") diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 7aac52f..6ec515c 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -22,19 +22,21 @@ http://arduino.cc/en/Reference/HomePage """ -import sys -from os.path import isdir, isfile, join +from os.path import isdir, join from SCons.Script import DefaultEnvironment env = DefaultEnvironment() platform = env.PioPlatform() +board = env.BoardConfig() +build_core = board.get("build.core", "") FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-megaavr") -assert isdir(FRAMEWORK_DIR) +if build_core != "arduino": + FRAMEWORK_DIR = platform.get_package_dir( + "framework-arduino-megaavr-%s" % build_core.lower()) -board = env.BoardConfig() -build_core = board.get("build.core", "") +assert isdir(FRAMEWORK_DIR) CPPDEFINES = [ "ARDUINO_ARCH_MEGAAVR", @@ -66,33 +68,6 @@ ] ) -# Bootloader and fuses for uploading purposes -bootloader_config = board.get("bootloader", {}) -if "BOOTLOADER_CMD" not in env: - if env.subst("$BOARD") == "uno_wifi_rev2": - bootloader_path = join( - FRAMEWORK_DIR, "bootloaders", board.get("bootloader.file", "")) - if isfile(bootloader_path): - env.Replace(BOOTLOADER_CMD='-Uflash:w:"%s":i' % bootloader_path) - else: - sys.stderr.write( - "Error: Couldn't find bootloader image %s\n" % bootloader_path) - env.Exit(1) - -if "FUSES_CMD" not in env: - for fuse in ("OSCCFG", "SYSCFG0", "BOOTEND"): - if not bootloader_config.get(fuse, ""): - sys.stderr.write("Error: Missing %s fuse value\n" % fuse) - env.Exit(1) - - env.Replace( - FUSES_CMD="-Ufuse2:w:%s:m -Ufuse5:w:%s:m -Ufuse8:w:%s:m" % ( - bootloader_config.get("OSCCFG"), - bootloader_config.get("SYSCFG0"), - bootloader_config.get("BOOTEND") - ) - ) - # # Target: Build Core Library # @@ -109,14 +84,14 @@ join(variants_dir, board.get("build.variant")) ] ) - env.BuildSources( + libs.append(env.BuildLibrary( join("$BUILD_DIR", "FrameworkArduinoVariant"), join(variants_dir, board.get("build.variant")) - ) + )) -env.BuildSources( +libs.append(env.BuildLibrary( join("$BUILD_DIR", "FrameworkArduino"), join(FRAMEWORK_DIR, "cores", build_core) -) +)) env.Prepend(LIBS=libs) diff --git a/builder/fuses.py b/builder/fuses.py new file mode 100644 index 0000000..6a4398c --- /dev/null +++ b/builder/fuses.py @@ -0,0 +1,91 @@ +import sys +import os + +from SCons.Script import ARGUMENTS, COMMAND_LINE_TARGETS, Import, Return + +Import("env") + + +def print_fuses_info(fuses, lock_fuse): + print("Selected fuses:") + for idx, value in enumerate(fuses): + if value: + print("[fuse%d = %s]" % (idx, value)) + if lock_fuse: + print("lock = %s" % lock_fuse) + + +board = env.BoardConfig() +platform = env.PioPlatform() + +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", ""), +) + +lock_fuse = board_fuses.get("LOCKBIT", "") + +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", +) + +env.Append( + FUSESFLAGS=[ + "-Ufuse%d:w:%s:m" % (idx, value) for idx, value in enumerate(fuses) if value + ] +) + +if 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("$SETFUSESCMD", "Setting fuses") + +Return("fuses_action") diff --git a/builder/main.py b/builder/main.py index 6c0038c..a4f7fb6 100644 --- a/builder/main.py +++ b/builder/main.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys from os.path import join from SCons.Script import (ARGUMENTS, COMMAND_LINE_TARGETS, AlwaysBuild, @@ -32,10 +33,9 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621 if "extra_flags" in upload_options: env.Append(UPLOADERFLAGS=upload_options.get("extra_flags")) - # disable erasing by default - env.Append(UPLOADERFLAGS=["-e"]) - if upload_options and not upload_options.get("require_upload_port", False): + # upload methods via USB + env.Append(UPLOADERFLAGS=["-P", "usb"]) return env.AutodetectUploadPort() @@ -74,9 +74,11 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621 UPLOADER="avrdude", UPLOADERFLAGS=[ "-p", "$BOARD_MCU", "-C", - join(env.PioPlatform().get_package_dir("tool-avrdude-megaavr") or "", - "avrdude.conf"), "-c", "$UPLOAD_PROTOCOL", "-D", "-V" + '"%s"' % join(env.PioPlatform().get_package_dir( + "tool-avrdude-megaavr") or "", "avrdude.conf"), + "-c", "$UPLOAD_PROTOCOL" ], + UPLOADCMD="$UPLOADER $UPLOADERFLAGS -U flash:w:$SOURCES:i", PROGSUFFIX=".elf" ) @@ -162,6 +164,24 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621 "Calculate program size", ) +# +# Target: Setup fuses +# + +fuses_action = None +if "fuses" in COMMAND_LINE_TARGETS: + fuses_action = env.SConscript("fuses.py", exports="env") +env.AddPlatformTarget("fuses", None, fuses_action, "Set Fuses") + +# +# Target: Upload bootloader +# + +bootloader_actions = None +if "bootloader" in COMMAND_LINE_TARGETS: + bootloader_actions = env.SConscript("bootloader.py", exports="env") +env.AddPlatformTarget("bootloader", None, bootloader_actions, "Burn Bootloader") + # # Target: Upload by default .hex file # @@ -170,41 +190,44 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621 if upload_protocol == "custom": upload_actions = [env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE")] -elif upload_protocol == "xplainedmini_updi": - env.Append(UPLOADERFLAGS=["-P", "usb", "-e", "-b", "$UPLOAD_SPEED"]) - upload_actions = [env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE")] else: upload_actions = [ env.VerboseAction(BeforeUpload, "Looking for upload port..."), env.VerboseAction("$UPLOADCMD", "Uploading $SOURCE") ] -if int(ARGUMENTS.get("PIOVERBOSE", 0)): - env.Prepend(UPLOADERFLAGS=["-v"]) - -upload_cmd = ["-U", "flash:w:$SOURCES:i"] + # jtag2updi seems to be the only protocol that requires serial port + if upload_protocol == "jtag2updi": + upload_options = env.BoardConfig().get("upload", {}) + for opt in ("require_upload_port", "use_1200bps_touch", "wait_for_upload_port"): + upload_options[opt] = True -if "FUSES_CMD" in env: - upload_cmd.append(env.get("FUSES_CMD")) + board = env.subst("$BOARD") + 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") -if "BOOTLOADER_CMD" in env: - upload_cmd.append(env.get("BOOTLOADER_CMD")) + elif board == "nano_every": + # Program fuses after programming flash + upload_actions.append(env.SConscript("fuses.py", exports="env")) -env.Replace( - UPLOADCMD='$UPLOADER $UPLOADERFLAGS %s' % " ".join(upload_cmd)) +if int(ARGUMENTS.get("PIOVERBOSE", 0)): + env.Prepend(UPLOADERFLAGS=["-v"]) env.AddPlatformTarget("upload", target_firm, upload_actions, "Upload") # -# Target: Upload firmware using external programmer +# Deprecated target: Upload firmware using external programmer # -env.AddPlatformTarget( - "program", - target_firm, - env.VerboseAction("$UPLOADCMD", "Programming $SOURCE"), - "Upload using Programmer", -) +if "program" in COMMAND_LINE_TARGETS: + sys.stderr.write( + "Error: `program` target is deprecated. To use a programmer for uploading " + "specify custom `upload_command`.\n" + "More details: https://docs.platformio.org/en/latest/platforms/" + "atmelavr.html#upload-using-programmer\n") + env.Exit(1) # # Setup default targets diff --git a/examples/arduino-blink/platformio.ini b/examples/arduino-blink/platformio.ini index 0672aa4..99a7554 100644 --- a/examples/arduino-blink/platformio.ini +++ b/examples/arduino-blink/platformio.ini @@ -16,3 +16,34 @@ board = uno_wifi_rev2 platform = atmelmegaavr framework = arduino board = nano_every + +[env:ATmega1608] +platform = atmelmegaavr +framework = arduino +board = ATmega1608 + +[env:ATmega3209] +platform = atmelmegaavr +framework = arduino +board = ATmega3209 + +[env:ATmega4808] +platform = atmelmegaavr +framework = arduino +board = ATmega4808 + +[env:ATmega809] +platform = atmelmegaavr +framework = arduino +board = ATmega809 + +[env:uno_wifi_rev2_megacorex] +platform = atmelmegaavr +framework = arduino +board = ATmega4809 +board_build.variant = uno-wifi + +[env:avr_iot_wg] +platform = atmelmegaavr +framework = arduino +board = avr_iot_wg diff --git a/platform.json b/platform.json index 495ae45..180ab0d 100644 --- a/platform.json +++ b/platform.json @@ -2,21 +2,23 @@ "name": "atmelmegaavr", "title": "Atmel megaAVR", "description": "8-bit MCUs Built for Real-time Control with Core Independent Peripherals combining intelligent hardware peripherals along with the low-power capability of an AVR core, megaAVR microcontrollers (MCUs) broaden the effectiveness of your real-time control systems.", - "url": "https://www.microchip.com/design-centers/8-bit/avr-mcus/device-selection/atmega4809", - "homepage": "http://platformio.org/platforms/atmelmegaavr", + "homepage": "https://www.microchip.com/design-centers/8-bit/avr-mcus/device-selection/atmega4809", "license": "Apache-2.0", + "keywords": [ + "dev-platform", + "Microchip", + "megaAVR", + "Atmel", + "8-bit" + ], "engines": { - "platformio": "<5" + "platformio": "^5" }, "repository": { "type": "git", "url": "https://github.com/platformio/platform-atmelmegaavr.git" }, - "version": "1.1.1", - "packageRepositories": [ - "https://dl.bintray.com/platformio/dl-packages/manifest.json", - "http://dl.platformio.org/packages/manifest.json" - ], + "version": "1.2.0", "frameworks": { "arduino": { "package": "framework-arduino-megaavr", @@ -26,16 +28,25 @@ "packages": { "toolchain-atmelavr": { "type": "toolchain", + "owner": "platformio", "version": "~1.70300.0" }, "framework-arduino-megaavr": { "type": "framework", "optional": true, + "owner": "platformio", "version": "~1.8.6" }, + "framework-arduino-megaavr-megacorex": { + "type": "framework", + "optional": true, + "owner": "platformio", + "version": "~1.0.5" + }, "tool-avrdude-megaavr": { "type": "uploader", "optional": true, + "owner": "platformio", "version": "~1.60300.0" } } diff --git a/platform.py b/platform.py new file mode 100644 index 0000000..88da715 --- /dev/null +++ b/platform.py @@ -0,0 +1,43 @@ +# Copyright 2014-present PlatformIO +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from platformio.managers.platform import PlatformBase + + +class AtmelmegaavrPlatform(PlatformBase): + + def configure_default_packages(self, variables, targets): + if not variables.get("board"): + return super(AtmelmegaavrPlatform, self).configure_default_packages( + variables, targets) + + build_core = variables.get( + "board_build.core", self.board_config(variables.get("board")).get( + "build.core", "arduino")) + + if "arduino" in variables.get("pioframework", []) and build_core != "arduino": + framework_package = "framework-arduino-megaavr-%s" % build_core.lower() + self.frameworks["arduino"]["package"] = framework_package + self.packages[framework_package]["optional"] = False + self.packages["framework-arduino-megaavr"]["optional"] = True + + if build_core == "MegaCoreX": + self.packages["toolchain-atmelavr"]["version"] = "~2.70300.0" + self.packages["tool-avrdude-megaavr"]["version"] = "~2.60300.0" + + if any(t in targets for t in ("fuses", "bootloader")): + self.packages["tool-avrdude-megaavr"]["optional"] = False + + return super(AtmelmegaavrPlatform, self).configure_default_packages( + variables, targets)