If FUSE_MEMORY_SIZE > 3, there is a single field: byte, which is an array
of unsigned char with the size of the array being FUSE_MEMORY_SIZE.
……
If you are compiling in C++, you cannot use the designated intializers so
you must do:
\code
#include <avr/io.h>
FUSES =
{
LFUSE_DEFAULT, // .low
(FUSE_BOOTSZ0 & FUSE_BOOTSZ1 & FUSE_EESAVE & FUSE_SPIEN & FUSE_JTAGEN), // .high
EFUSE_DEFAULT, // .extended
};
int main(void)
{
return 0;
}
\endcode
I tested it:
// TestFuses.ino
FUSES = {
0x00, // WDT: off
0x04, // BOD: level 1.8V, active enabled
0x01, // OSCCFG: no lock, 16MHz
0x00, // reserved
0x00, // reserved
0xC9, // SYSCFG0: no CRC, pin = RESET, EESAVE
0x00, // SYSCFG1: no SetUpTime
0x00, // APPEND
0x00, // BOOTEND
};
int main(void)
{
return 0;
}
It compiled just fine, but uploading failed:
avrdude: jtagmkII_initialize(): Cannot locate "flash" and "boot" memories in description
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.15s
avrdude: Device signature = 0x1e9651 (probably m4809)
avrdude: erasing chip
avrdude: reading input file "C:\Users\xxxxx\AppData\Local\arduino\sketches\9A1467BDD7AD688E27928646F792363D/TestFuses.ino.hex"
avrdude: ERROR: address 0x820009 out of range at line 15 of C:\Users\xxxxx\AppData\Local\arduino\sketches\9A1467BDD7AD688E27928646F792363D/TestFuses.ino.hex
avrdude: read from file 'C:\Users\xxxxx\AppData\Local\arduino\sketches\9A1467BDD7AD688E27928646F792363D/TestFuses.ino.hex' failed
avrdude done. Thank you.
Failed uploading: uploading error: exit status 1
I can recognize the fuse-bytes in my disassembler:
Sketch uses 194 bytes (0%) of program storage space. Maximum is 49152 bytes.
Global variables use 0 bytes (0%) of dynamic memory, leaving 6144 bytes for local variables. Maximum is 6144 bytes.
Performing 1200-bps touch reset on serial port COM4
"C:\Users\hanss\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude" "-CC:\Users\hanss\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega4809 -cjtag2updi -PCOM4 -b115200 -e -D "-Uflash:w:C:\Users\hanss\AppData\Local\arduino\sketches\9A1467BDD7AD688E27928646F792363D/TestFuses.ino.hex:i" "-Ufuse2:w:0x01:m" "-Ufuse5:w:0xC9:m" "-Ufuse8:w:0x00:m" {upload.extra_files}
But it's output. I apparently need something in the input that I don't know about yet.
It would be nice if you took the initiative. https://github.com/avrdudes/avrdude/
You can also find manuals for older versions.
You can update avrdude within the IDE or save the latest version somewhere else.
To see it simple: I bought an original Arduino board. Arduino is supposed to support it. As for the fuses, Arduino offers support in the form of avr/fuses.h (#included automatically) probably thinking that it's sufficient.
The numbers for the fuses appear in the .ino.hex file, apparently the compiler processes them. The transfer of that file to the board is handled by the Arduino Integrated Development Environment, I should have no direct business with the third party that is invoked by the IDE, but that third party is where things go wrong.
Even then, the description in avr/fuses.h is clear. If that's not enough, something should be added.
Having said that, I will dive into the mentioned document, see what I can find.
Indeed the fuses are specified in the boards.txt file.
The Nano Every is best used with the MegaCoreX core file (available through the boards manager) and not the Arduino megaAVR core. It has more features and is better maintained.
There is good access to the fuse settings in the Tools menu. You don't need to work with boards.txt or get into avrdude.
I'm familiar with the content. However, I can't correctly map the values to any fuses. The only recognizable matches are 0x01, 0xFF, and 0x00. The rest is unclear to me.
Why do you want to change the fuses?
Apparently MegaCoreX sets the fuses to what's selected in Tools, and to some defaults, not what is given in the program.
I think setting the fuses at runtime in code uses the _PROTECTED_WRITE macro because
Fuse registers are protected by the Configuration Change Protection (CCP) mechanism. There needs to be a reset after the fuse change.
The critical detail is _PROTECTED_WRITE(). Fuse registers are protected by the Configuration Change Protection (CCP) mechanism — you can't just assign to them directly. The macro handles the required timed write sequence: it writes the unlock signature 0xD8 to the CCP register, which opens a 4-cycle window during which the protected register can be written.
The Full FUSE Struct
The named members map directly to the hardware registers:
Changes take effect after reset. Fuse writes don't take effect immediately — the new values are latched on the next power-on or reset. So writing FUSE.OSCCFG in your code and expecting the clock to change on the next line won't work. You'd need to trigger a software reset afterward:
SYSCFG0 (fuse5) is still dangerous. The same warning applies as with avrdude — if you accidentally set the UPDI pin to GPIO mode from running code, you'll lock yourself out. Be very careful with this one.
I skimmed through the avrdude document and I have some understanding of how it works. Now I have 2 ideas for a workaround:
. The line where the IDE calls avrdude has {upload.extra_files} at the end. Questions: Where to put those extra files? How to name them so they can be found? If the same fuse is assigned again, will NVMCTRL perform an and on them? (Or is this the next dead end?)
. Use the IDE to compile the program and upload outside the IDE. Questions: where do I find avrdude's commandline? Any interference from the Serial Monitor?
Which fuse settings are you wanted to change that are not available in the menus of MegaCoreX? Or are you trying to have different fuse settings for different sketches and don't want to have to manually select them each time?