Skip to content

Commit

Permalink
Merge branch 'release/v1.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
valeros committed Nov 9, 2020
2 parents e6eeb51 + 29ccb1a commit 56810e2
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 40 deletions.
2 changes: 1 addition & 1 deletion boards/nano_every.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"variant": "nona4809"
},
"fuses": {
"syscfg0": "0xc9",
"syscfg0": "0xC9",
"bootend": "0x00",
"osccfg": "0x01"
},
Expand Down
2 changes: 1 addition & 1 deletion boards/uno_wifi_rev2.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"file": "atmega4809_uart_bl.hex",
"fuses_file": "fuses_4809.bin",
"bootend": "0x02",
"syscfg0": "0xc9",
"syscfg0": "0xC9",
"osccfg": "0x01"
},
"frameworks": [
Expand Down
17 changes: 12 additions & 5 deletions builder/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@


def get_suitable_optiboot_binary(framework_dir, board_config):
uart = board_config.get("hardware.uart", "uart0").upper()
uart = board_config.get("hardware.uart", "no_bootloader").lower()
if uart == "no_bootloader":
return ""
if not uart.endswith(("_alt", "_def")):
uart = uart + "_def"

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_file = "Optiboot_mega0_%s_%s_%s.hex" % (
uart.upper(), bootloader_speed, bootloader_led)

bootloader_path = os.path.join(
framework_dir, "bootloaders", "optiboot", "bootloaders", "mega0",
Expand All @@ -52,6 +56,9 @@ def get_suitable_optiboot_binary(framework_dir, board_config):
bootloader_path = board.get("bootloader.file", "")
if core == "MegaCoreX":
if not os.path.isfile(bootloader_path):
if board.get("hardware.uart", "no_bootloader").lower() == "no_bootloader":
sys.stderr.write("Error: `no bootloader` selected in board config!\n")
env.Exit(1)
bootloader_path = get_suitable_optiboot_binary(framework_dir, board)
else:
if not os.path.isfile(bootloader_path):
Expand All @@ -65,7 +72,7 @@ def get_suitable_optiboot_binary(framework_dir, board_config):
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")
sys.stderr.write("Error: Couldn't find bootloader image %s\n" % bootloader_path)
env.Exit(1)

env.Append(
Expand Down
8 changes: 6 additions & 2 deletions builder/frameworks/_bare.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@
"-flto",
"-mmcu=$BOARD_MCU",
"-Wl,--gc-sections",
"-Wl,--section-start=.text=%s" % env.BoardConfig().get(
"build.text_section_start", "0x0"),
"-Wl,--section-start=.text=%s"
% (
"0x200"
if env.subst("$UPLOAD_PROTOCOL") == "arduino"
else env.BoardConfig().get("build.text_section_start", "0x0")
),
"-fuse-linker-plugin"
],

Expand Down
11 changes: 9 additions & 2 deletions builder/frameworks/arduino.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@
]
)

#
# Select oscillator using a special macro
#

if board.get("hardware", {}).get("oscillator", "internal") == "external":
env.Append(CPPDEFINES=["USE_EXTERNAL_OSCILLATOR"])

#
# Target: Build Core Library
#
Expand All @@ -84,10 +91,10 @@
join(variants_dir, board.get("build.variant"))
]
)
libs.append(env.BuildLibrary(
env.BuildSources(
join("$BUILD_DIR", "FrameworkArduinoVariant"),
join(variants_dir, board.get("build.variant"))
))
)

libs.append(env.BuildLibrary(
join("$BUILD_DIR", "FrameworkArduino"),
Expand Down
167 changes: 142 additions & 25 deletions builder/fuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,154 @@
Import("env")


def print_fuses_info(fuses, lock_fuse):
print("Selected fuses:")
for idx, value in enumerate(fuses):
def get_wdtcfg_fuse():
return 0x00


def get_bodcfg_fuse(bod):
if bod == "4.3v":
return 0xF4
elif bod == "2.6v":
return 0x54
elif bod == "1.8v":
return 0x14
else: # bod disabled
return 0x00


def get_osccfg_fuse(f_cpu, oscillator):
if (
f_cpu == "20000000L" or f_cpu == "10000000L" or f_cpu == "5000000L"
) and oscillator == "internal":
return 0x02
else:
return 0x01


def get_tcd0cfg_fuse():
return 0x00


def get_syscfg0_fuse(eesave, rstpin, uart):
eesave_bit = 1 if eesave == "yes" else 0
if rstpin == "gpio":
if uart == "no_bootloader":
rstpin_bit = 0
else:
rstpin_bit = 1
else:
rstpin_bit = 1
return 0xC0 | rstpin_bit << 3 | eesave_bit


def get_syscfg1_fuse():
return 0x06


def get_append_fuse():
return 0x00


def get_bootend_fuse(uart):
if uart == "no_bootloader":
return 0x00
else:
return 0x02


def get_lockbit_fuse():
return 0xC5


def print_fuses_info(fuse_values, fuse_names, lock_fuse):
if "upload" in COMMAND_LINE_TARGETS:
return
print("\nSelected fuses:")
print("------------------------")
for idx, value in enumerate(fuse_values):
if value:
print("[fuse%d = %s]" % (idx, value))
print("[fuse%d / %-7s = %s]" % (idx, fuse_names[idx].upper(), value))
if lock_fuse:
print("lock = %s" % lock_fuse)
print("[lfuse / LOCKBIT = %s]" % lock_fuse)
print("------------------------\n")


def calculate_megacorex_fuses(board_config, predefined_fuses):
megacorex_fuses = []
f_cpu = board_config.get("build.f_cpu", "16000000L").upper()
oscillator = board_config.get("hardware.oscillator", "internal").lower()
bod = board_config.get("hardware.bod", "2.6v").lower()
uart = board_config.get("hardware.uart", "no_bootloader").lower()
eesave = board_config.get("hardware.eesave", "yes").lower()
rstpin = board_config.get("hardware.rstpin", "reset").lower()

# Guard that prevents the user from turning the reset pin
# into a GPIO while using a bootloader
if uart != "no_bootloader":
rstpin = "reset"

print("\nTARGET CONFIGURATION:")
print("------------------------")
print("Target = %s" % target)
print("Clock speed = %s" % f_cpu)
print("Oscillator = %s" % oscillator)
print("BOD level = %s" % bod)
print("Save EEPROM = %s" % eesave)
print("Reset pin mode = %s" % rstpin)
print("------------------------")

return (
predefined_fuses[0] or "0x%.2X" % get_wdtcfg_fuse(),
predefined_fuses[1] or "0x%.2X" % get_bodcfg_fuse(bod),
predefined_fuses[2] or "0x%.2X" % get_osccfg_fuse(f_cpu, oscillator),
"", # reserved
predefined_fuses[4] or "0x%.2X" % get_tcd0cfg_fuse(),
predefined_fuses[5] or "0x%.2X" % get_syscfg0_fuse(eesave, rstpin, uart),
predefined_fuses[6] or "0x%.2X" % get_syscfg1_fuse(),
predefined_fuses[7] or "0x%.2X" % get_append_fuse(),
predefined_fuses[8] or "0x%.2X" % get_bootend_fuse(uart),
)


board = env.BoardConfig()
platform = env.PioPlatform()
core = board.get("build.core", "")

target = (
board.get("build.mcu").lower()
if board.get("build.mcu", "")
else env.subst("$BOARD").lower()
)

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", ""),
fuse_names = (
"wdtcfg",
"bodcfg",
"osccfg",
"", # reserved
board_fuses.get("tcd0cfg", ""),
board_fuses.get("syscfg0", ""),
board_fuses.get("syscfg1", ""),
board_fuses.get("append", ""),
board_fuses.get("bootend", ""),
"tcd0cfg",
"syscfg0",
"syscfg1",
"append",
"bootend"
)

lock_fuse = board_fuses.get("LOCKBIT", "")
board_fuses = board.get(fuses_section, {})
if not board_fuses and "FUSESFLAGS" not in env and core != "MegaCoreX":
sys.stderr.write(
"Error: Dynamic fuses generation for %s / %s is not supported. "
"Please specify fuses in platformio.ini\n" % (core, env.subst("$BOARD"))
)
env.Exit(1)

fuse_values = [board_fuses.get(fname, "") for fname in fuse_names]
lock_fuse = board_fuses.get("lockbit", hex(get_lockbit_fuse()))
if core == "MegaCoreX":
fuse_values = calculate_megacorex_fuses(board, fuse_values)

env.Append(
FUSESUPLOADER="avrdude",
Expand All @@ -49,15 +162,19 @@ def print_fuses_info(fuses, lock_fuse):
"$BOARD_MCU",
"-C",
'"%s"'
% os.path.join(env.PioPlatform().get_package_dir(
"tool-avrdude-megaavr") or "", "avrdude.conf"),
% 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
"-Ufuse%d:w:%s:m" % (idx, value)
for idx, value in enumerate(fuse_values)
if value
]
)

Expand All @@ -84,8 +201,8 @@ def print_fuses_info(fuses, lock_fuse):
"#overriding-default-fuses-command\n"
)

print_fuses_info(fuses, lock_fuse)
print_fuses_info(fuse_values, fuse_names, lock_fuse)

fuses_action = env.VerboseAction("$SETFUSESCMD", "Setting fuses")
fuses_action = env.VerboseAction("$SETFUSESCMD", "Setting fuses...")

Return("fuses_action")
14 changes: 11 additions & 3 deletions builder/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,16 +201,24 @@ def BeforeUpload(target, source, env): # pylint: disable=W0613,W0621
upload_options = env.BoardConfig().get("upload", {})
for opt in ("require_upload_port", "use_1200bps_touch", "wait_for_upload_port"):
upload_options[opt] = True
elif upload_protocol == "arduino":
upload_options = env.BoardConfig().get("upload", {})
upload_options["require_upload_port"] = True
upload_options["use_1200bps_touch"] = False
upload_options["wait_for_upload_port"] = False
env.Append(UPLOADERFLAGS=["-D"])

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")
env.SConscript("bootloader.py", exports="env")
env.Append(UPLOADERFLAGS=env["FUSESFLAGS"])
env.Append(UPLOADERFLAGS=env["BOOTFLAGS"])

elif board == "nano_every":
# Program fuses after programming flash
upload_actions.append(env.SConscript("fuses.py", exports="env"))
env.SConscript("fuses.py", exports="env")
env.Append(UPLOADERFLAGS=env["FUSESFLAGS"])

if int(ARGUMENTS.get("PIOVERBOSE", 0)):
env.Prepend(UPLOADERFLAGS=["-v"])
Expand Down
2 changes: 1 addition & 1 deletion platform.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"type": "git",
"url": "https://github.com/platformio/platform-atmelmegaavr.git"
},
"version": "1.2.0",
"version": "1.3.0",
"frameworks": {
"arduino": {
"package": "framework-arduino-megaavr",
Expand Down

0 comments on commit 56810e2

Please sign in to comment.