Closed MCUdude closed 2 years ago
This fails for me.
>pio run -t fuses -v
Processing nano_every (platform: https://github.com/MCUdude/platform-atmelmegaavr.git#improve-fuses-script; board: nano_every; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------
CONFIGURATION: https://docs.platformio.org/page/boards/atmelmegaavr/nano_every.html
PLATFORM: Atmel megaAVR (1.5.0+sha.60e74f9) (git+https://github.com/MCUdude/platform-atmelmegaavr.git#improve-fuses-script) > Arduino Nano Every
HARDWARE: ATMEGA4809 16MHz, 6KB RAM, 47.50KB Flash
PACKAGES:
- framework-arduino-megaavr 1.8.7
- tool-avrdude-megaavr 1.60300.191015 (6.3.0)
- toolchain-atmelavr 1.70300.191015 (7.3.0)
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 5 compatible libraries
Scanning dependencies...
No dependencies
Building in release mode
Auto-detected: COM11
Selected fuses:
-------------------------
[fuse2 / osccfg = 0x01]
[fuse5 / syscfg0 = 0xC9]
[lock / lockbit = 0xC5]
-------------------------
avrdude -p atmega4809 -C C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf -v -P "COM11" -c jtag2updi -Ufuse2:w:0x01:m -Ufuse5:w:0xC9:m -Ulock:w:0xC5:m
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf"
Using Port : COM11
Using Programmer : jtag2updi
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
^Cscons: *** [fuses] Build interrupted.
Error: Aborted by user
Testing with
[env:nano_every]
platform = https://github.com/MCUdude/platform-atmelmegaavr.git#improve-fuses-script
board = nano_every
framework = arduino
Uploading still works as normal.
BeforeUpload(["upload"], [".pio\build\nano_every\firmware.hex"])
Use manually specified: COM11
Forcing reset using 1200bps open/close on port COM11
avrdude -v -p atmega4809 -C C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf -c jtag2updi -Ufuse2:w:0x01:m -Ufuse5:w:0xC9:m -Ulock:w:0xC5:m -b 115200 -V -e -D -P "COM11" -U flash:w:.pio\build\nano_every\firmware.hex:i
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf"
Using Port : COM11
Using Programmer : jtag2updi
Overriding Baud Rate : 115200
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
boot-loader FW version: 1
firmware version: 6.00
hardware version: 1
S_MCU:
boot-loader FW version: 1
firmware version: 6.00
hardware version: 1
Serial number: 00:00:00:00:00:00
Device ID: JTAGICE mkII
AVR Part : ATmega4809
Chip Erase delay : 0 us
PAGEL : P00
BS2 : P00
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 0
StabDelay : 0
CmdexeDelay : 0
SyncLoops : 0
ByteDelay : 0
PollIndex : 0
PollValue : 0x00
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
prodsig 0 0 0 0 no 61 61 0 0 0 0x00 0x00
fuses 0 0 0 0 no 9 0 0 0 0 0x00 0x00
fuse0 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse1 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse2 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse4 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse5 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse6 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse7 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse8 0 0 0 0 no 1 0 0 0 0 0x00 0x00
lock 0 0 0 0 no 1 0 0 0 0 0x00 0x00
data 0 0 0 0 no 0 0 0 0 0 0x00 0x00
usersig 0 0 0 0 no 64 64 0 0 0 0x00 0x00
flash 0 0 0 0 no 49152 128 0 0 0 0x00 0x00
eeprom 0 0 0 0 no 256 64 0 0 0 0x00 0x00
Programmer Type : JTAGMKII_PDI
Description : JTAGv2 to UPDI bridge
M_MCU hardware version: 1
M_MCU firmware version: 6.00
S_MCU hardware version: 1
S_MCU firmware version: 6.00
Serial number: 00:00:00:00:00:00
Vtarget : 5.0 V
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.27s
avrdude: Device signature = 0x1e9651 (probably m4809)
avrdude: erasing chip
avrdude: reading input file "0x01"
avrdude: writing fuse2 (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of fuse2 written
avrdude: verifying fuse2 memory against 0x01:
avrdude: load data fuse2 data from input file 0x01:
avrdude: input file 0x01 contains 1 bytes
avrdude: reading on-chip fuse2 data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of fuse2 verified
avrdude: reading input file "0xC9"
avrdude: writing fuse5 (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of fuse5 written
avrdude: verifying fuse5 memory against 0xC9:
avrdude: load data fuse5 data from input file 0xC9:
avrdude: input file 0xC9 contains 1 bytes
avrdude: reading on-chip fuse5 data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of fuse5 verified
avrdude: reading input file "0xC5"
avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0xC5:
avrdude: load data lock data from input file 0xC5:
avrdude: input file 0xC5 contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file ".pio\build\nano_every\firmware.hex"
avrdude: writing flash (802 bytes):
Writing | ################################################## | 100% 0.65s
avrdude: 802 bytes of flash written
avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)
avrdude done. Thank you.
======================================================= [SUCCESS] Took 5.84 seconds =======================================================
What happends if you add board_upload.use_1200bps_touch = true
to platformio.ini?
It does set the fuses, but funny enough it stops for about 2 seconds waiting for a "new upload port" after doing the 1200bps reset.
Building in release mode
Auto-detected: COM11
Selected fuses:
-------------------------
[fuse2 / osccfg = 0x01]
[fuse5 / syscfg0 = 0xC9]
[lock / lockbit = 0xC5]
-------------------------
Use manually specified: COM11
Forcing reset using 1200bps open/close on port COM11
Waiting for the new upload port...
avrdude -p atmega4809 -C C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf -v -P "COM11" -c jtag2updi -Ufuse2:w:0x01:m -Ufuse5:w:0xC9:m -Ulock:w:0xC5:m
avrdude: Version 6.3-20190619
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "C:\Users\Max\.platformio\packages\tool-avrdude-megaavr@1.60300.191015\avrdude.conf"
Using Port : COM11
Using Programmer : jtag2updi
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
boot-loader FW version: 1
firmware version: 6.00
hardware version: 1
S_MCU:
boot-loader FW version: 1
firmware version: 6.00
hardware version: 1
Serial number: 00:00:00:00:00:00
Device ID: JTAGICE mkII
AVR Part : ATmega4809
Chip Erase delay : 0 us
PAGEL : P00
BS2 : P00
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 0
StabDelay : 0
CmdexeDelay : 0
SyncLoops : 0
ByteDelay : 0
PollIndex : 0
PollValue : 0x00
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
prodsig 0 0 0 0 no 61 61 0 0 0 0x00 0x00
fuses 0 0 0 0 no 9 0 0 0 0 0x00 0x00
fuse0 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse1 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse2 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse4 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse5 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse6 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse7 0 0 0 0 no 1 0 0 0 0 0x00 0x00
fuse8 0 0 0 0 no 1 0 0 0 0 0x00 0x00
lock 0 0 0 0 no 1 0 0 0 0 0x00 0x00
data 0 0 0 0 no 0 0 0 0 0 0x00 0x00
usersig 0 0 0 0 no 64 64 0 0 0 0x00 0x00
flash 0 0 0 0 no 49152 128 0 0 0 0x00 0x00
eeprom 0 0 0 0 no 256 64 0 0 0 0x00 0x00
Programmer Type : JTAGMKII_PDI
Description : JTAGv2 to UPDI bridge
M_MCU hardware version: 1
M_MCU firmware version: 6.00
S_MCU hardware version: 1
S_MCU firmware version: 6.00
Serial number: 00:00:00:00:00:00
Vtarget : 5.0 V
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.27s
avrdude: Device signature = 0x1e9651 (probably m4809)
avrdude: reading input file "0x01"
avrdude: writing fuse2 (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of fuse2 written
avrdude: verifying fuse2 memory against 0x01:
avrdude: load data fuse2 data from input file 0x01:
avrdude: input file 0x01 contains 1 bytes
avrdude: reading on-chip fuse2 data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of fuse2 verified
avrdude: reading input file "0xC9"
avrdude: writing fuse5 (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of fuse5 written
avrdude: verifying fuse5 memory against 0xC9:
avrdude: load data fuse5 data from input file 0xC9:
avrdude: input file 0xC9 contains 1 bytes
avrdude: reading on-chip fuse5 data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of fuse5 verified
avrdude: reading input file "0xC5"
avrdude: writing lock (1 bytes):
Writing | ################################################## | 100% 0.01s
avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0xC5:
avrdude: load data lock data from input file 0xC5:
avrdude: input file 0xC5 contains 1 bytes
avrdude: reading on-chip lock data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: safemode: Fuses OK (E:FF, H:FF, L:FF)
avrdude done. Thank you.
======================================================= [SUCCESS] Took 10.66 seconds =======================================================
It does set the fuses, but funny enough it stops for about 2 seconds waiting for a "new upload port" after doing the 1200bps reset.
This is intended. PlatformIO connects with a baudrate of 1200bps. When connection is established the jtag2updi programmer resets, port disappear, and starts up again, but this time in programming mode. Arduino Leonardo works the same way.
Can you try to remove board_upload.use_1200bps_touch = true
form platformio.ini and add "use_1200bps_touch": true,
to nano_every.json, like shown below? If this works the 1200bps touch will always happens automatically if using a Nano Every and the official Arduino core, not MegaCoreX.
"upload": {
"extra_flags": ["-V", "-e", "-D"],
"maximum_ram_size": 6144,
"maximum_size": 48640,
"protocol": "jtag2updi",
"use_1200bps_touch": true,
"speed": 115200
},
Can you try to remove board_upload.use_1200bps_touch = true form platformio.ini and add "use_1200bps_touch": true, to nano_every.json, like shown below?
Interestingly enough, then it does not work anymore, no reset is done. I'd also think that the changes were equivalent. It only works when I edit the JSON file as
"use_1200bps_touch": "true"
aka, as a string, not a bool. Possibly there's some type mismatch in the Python script?
aka, as a string, not a bool. Possibly there's some type mismatch in the Python script?
I'm by no means a Python expert, but from what I understand, everything that's defined in platformio.ini are treated as trings, hence why "yes" were in quotes. However, true/false in the json manifest file are treated as bools.
Try replacing line 261 in fuses.py with this line. This would make use_1200bps_touch
work in the json manifest file and in platformio.ini.
if upload_options.get("use_1200bps_touch", False) in (True, "true"):
Reference boards from official platforms like
https://github.com/platformio/platform-atmelavr/blob/develop/boards/pro8MHzatmega328.json#L31
do not use a string for boolean values in the board JSON, so this should be the way to go.
if upload_options.get("use_1200bps_touch", False) in (True, "true"):
This works in conjunction with "use_1200bps_touch": true
in the board manifest.
Thanks for the feedback! I've pushed some changes. First, use_1200bps_touch is now added to nano_every.json by default, and the fuses.py scripts can handle both bools and strings
Hi @MCUdude , thanks for the PR. I believe the platform already has similar functionality in the main.py
script. Why don't we reuse the "touch" logic from the main script? This way we won't duplicate similar code in two places. It may look something line this:
#
# Target: Setup fuses
#
fuses_action = None
if "fuses" in COMMAND_LINE_TARGETS:
fuses_actions = [
env.VerboseAction(BeforeUpload, "Looking for port..."),
env.SConscript("fuses.py", exports="env")
]
env.AddPlatformTarget("fuses", None, fuses_actions, "Set Fuses")
@valeros this will work in this case, because Arduino Nano Every has pre-defined fuses, and the Uno Wifi Rev2 uses fuses_file instead.
But for everyone else, it's not straightforward why this would work. just because fuses
is present in the manifest file shouldn't automatically enable 1200bps touch. What if newer boards get added in the future that has pre-defined fuses but uses a different kind of programmer? That would break this logic.
I'm not sure I'm following. The presence of the fuses
section in any manifest has nothing to do with the changes I proposed above. If you take a look at the content of the BeforeUpload
function https://github.com/platformio/platform-atmelmegaavr/blob/develop/builder/main.py#L24-L50 it won't run the 1200bps
touch unless it's set in the manifest.
If you take a look at the content of the BeforeUpload function https://github.com/platformio/platform-atmelmegaavr/blob/develop/builder/main.py#L24-L50 it won't run the 1200bps touch unless it's set in the manifest.
OK, then I understand. But it's important that 1200bps touch works if not defined in the manifest file, but instead in platformio.ini. Will this work? For instance, if the Nano Every is used with MegaCoreX (ATmega4809.json), and the user wants to set the fuses
From the standpoint of the main build script there is no difference if this setting is set in the board manifest or via the board_upload.use_1200bps_touch
option directly in the platformio.ini
file.
So I tried replacing the existing code in main.py with the one below and removed the 1200bps touch handler I added to fuses.py. However, now it's always trying to do a 1200bps touch, even if there's no use_1200bps_touch: true
line in the manifest file. For some reason, upload_options.get("use_1200bps_touch", False)
in BeforeUpload
always returns true.
#
# Target: Setup fuses
#
fuses_action = None
if "fuses" in COMMAND_LINE_TARGETS:
fuses_actions = [
env.VerboseAction(BeforeUpload, "Looking for port..."),
env.SConscript("fuses.py", exports="env")
]
env.AddPlatformTarget("fuses", None, fuses_actions, "Set Fuses")
It seems the use_1200bps_touch
option is dynamically set to True
for the jtag2updi
protocol:
https://github.com/platformio/platform-atmelmegaavr/blob/develop/builder/main.py#L204
I guess it isn't necessary always true for the fuses programming? It can be easily fixed by checking the current target:
if upload_protocol == "jtag2updi" and "fuses" not in COMMAND_LINE_TARGETS:
upload_options["require_upload_port"] = True
upload_options["use_1200bps_touch"] = True
upload_options["wait_for_upload_port"] = False
elif upload_protocol == "arduino":
upload_options["require_upload_port"] = True
upload_options["use_1200bps_touch"] = False
upload_options["wait_for_upload_port"] = False
env.Append(UPLOADERFLAGS=["-D"])
Yes, I realized this right after I wrote the previous message. I think I found a solution that will work.
BTW what is the default return value for upload_options["wait_for_upload_port"]
if not present in the manifest file or platformio.ini?
(BTW I've taken the liberty to future-proof this script by adding a new programmer, "Serialupdi". This will be present in the next version of Avrdude (7.0), and lets you upload to any UPDI target using standard USB to serial adapter, identical to how pyupdi/pymcuprog does it).
if upload_protocol in ("jtag2updi", "serialupdi"):
upload_options["require_upload_port"] = True
elif upload_protocol == "arduino":
upload_options["require_upload_port"] = True
upload_options["use_1200bps_touch"] = False
upload_options["wait_for_upload_port"] = False
env.Append(UPLOADERFLAGS=["-D"])
BTW what is the default return value for upload_options["wait_for_upload_port"] if not present in the manifest file or platformio.ini?
It returns , Didn't notice you asked for a different way of accessing values. Basically it's just a generic Python dictionary, so it will raise an exception. It's a good practice to use None
.get
and set a safe default value just in case.
if upload_protocol in ("jtag2updi", "serialupdi"):
upload_options["require_upload_port"] = True
Shouldn't two other options use_1200bps_touch
and wait_for_upload_port
be properly configured as well for these two protocols?
use_1200bps_touch
is a Nano Every specific thing and is not needed on generic jtag2updi programmers, Only on the Nano Every. Usually, wait_for_upload_port
is required when use_1200bps_touch
has been used, for some reason, this has not been done here, but it works fine without any wait time.
A 1200bps touch is needed on the Nano Every since the programming chip has a dual purpose, a jtag2updi programmer and a USB to serial adapter. I can always add wait_for_upload_port: true
to the Nano every manifest file just to be on the safe side. It should have been true
from the beginning.
The same applies to SerialUPDI. SerialUPDI does not require a 1200bps touch or want_for_upload_port.
EDIT: FYI I do have a Nano Every that I test with to confirm that everything works as expected on real hardware
I believe the use_1200bps_touch
option originated in your PR #5 that suggested using it even for generic ATmega targets with jtag2updi
. I guess it safe to disable these dynamic configuration for jtag2updi
and specify it explicitly only for Nano Every
?
I guess it safe to disable these dynamic configuration for jtag2updi and specify it explicitly only for Nano Every?
Yes, I've also tested with a standalone jtag2updi programmer (just an Arduino UNO running the jtag2updi firmware), and it works perfectly without a 1200bps touch. Not sure why I added this to all jtag2updi programmers in #5...
The PR has been updated to reflect these changes.
EDIT: I've just rebased and force-pushed an update that hopefully addresses the issue the CI picked up.
The last question is, should the Nano Every really have "wait_for_upload_port": true,
in its manifest file or not? It has worked excellent before without, and uploading is actually faster without since there isn't really necessary to wait for the new port to arrive.
@valeros do you have any preferences? Do it like it has been done in the past that has been proven to work, or to it "by the book"?
I'm no expert here, if it works just fine without that field, then feel free to remove it.
I'm no expert here, if it works just fine without that field, then feel free to remove it.
Thanks! I've removed the commit that added the line in the manifest file
LGTM, Let me know if you don't plan to add any further changes, I'll merge.
Let me know if you don't plan to add any further changes, I'll merge.
I think we're good now. I'll open a separate issue or PR if there are other bugs or features that need to be addressed. Thank you for your support!
Thanks, merged.
Add support for 1200bps touch improve upload port handling. Now -P USB is added if the programmer is not a jtag2updi, and -P $UPLOAD_PORT if the programmer is a jtag2updi. This can be done because the jtag2updi programmer is currently the only UPDI programmer that communicates over UART.
Would be great if you can test and verify that it works for you @maxgerhardt
Closes #34