Each virgin blink needs to be programmed with...
- The correct FUSE settings
- The BIOS code that lives in the flash bootloader area
- The application code that lives in the application flash area.
The only change from factory default is the fuse that enables jumping to the bootloader on reset (BOOTRST).
BOOTSZ = 1024W_1C00 BOOTRST = [X] RSTDISBL = [ ] DWEN = [ ] SPIEN = [X] WDTON = [ ] EESAVE = [ ] BODLEVEL = DISABLED CKDIV8 = [X] CKOUT = [ ] SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS
EXTENDED = 0xF8 (valid) HIGH = 0xDF (valid) LOW = 0x62 (valid)
Note that the high
and low
fuses are the same as their default values from the factory, but the extended
fuse must be reprogrammed from the default value.
The only change from factory default is the fuse that enables jumping to the bootloader on reset (BOOTRST).
BODLEVEL = DISABLED RSTDISBL = [ ] DWEN = [ ] SPIEN = [X] WDTON = [ ] EESAVE = [ ] BOOTSZ = 2048W_3800 BOOTRST = [X] CKDIV8 = [X] CKOUT = [ ] SUT_CKSEL = INTRCOSC_8MHZ_6CK_14CK_65MS
EXTENDED = 0xFF (valid) HIGH = 0xD8 (valid) LOW = 0x62 (valid)
Note that the extended
and low
fuses are the same as their default values from the factory, but the high
fuse must be reprogrammed from the default value.
The bootloader code comes from a different repo and can be found in the bootloaders
directory here.
The application code is generated by compiling a sketch in the Arduino IDE.
You can minimize the number of production programming steps by combining the application code and bootloader into a single HEX file using the Sketch->Export Compiled Binary
option from the IDE menus. This will create a file called SKETCHNAME.ino.with_bootloader.standard.hex
in the current sketch folder that contains both the application and the bootloader.
Here is and example command that will program a atmega168pb
blink using the AVRDUDE
utility and the USBtiny
programmer...
avrdude -B 5 -v -patmega168pb -cusbtiny -Uflash:w:SKETCHNAME.ino.with_bootloader.standard.hex:i -Uefuse:w:0xf8:m -u
-B
sets the clock programming speed. This must be less than 1/4 of the chip clock speed, which is 1Mhz by default, but here we make it slightly slower to account for chips that might have an extra slow internal clock.
-v
verifies the programming when complete
-p
specifies the chip model
-Uflash
specifies the file to program into flash memory (both bootloader and application in this case)
-Uefuse
specifies the new value for the extended fuse (note that the high and low fuses are left with their default values)
-u
disables AVRDUDE's normal behavior that blocks changing fuses.
Note that this assumes that avrdude
is in your search path and that it can find its config file. See avrdude
docs for details.
We can slightly reduce cycle using a command like this...
avrdude -B 4 -D -v -patmega168pb -cusbtiny -Uflash:w:D-TimerFlashX.ino.with_bootloader.standard.hex:i -Uefuse:w:0xf8:m -u
-D
skips erasing the flash before programming it. If you are programming virgin chips then the flash should be blank.
-B
lowered to 4 slightly increases the programmer clock, which reduces programming time. Note that some units might fail at this increased speed.
Note that these new options are both safe because the verify will fail if anything goes wrong.
Some programming errors may pass functional testing, but still contain latent errors, so you must check that the programming cycle verified successfully before passing a programmed unit.
You can use the error code returned by AVRDUDE to check if the verify succeeded.