Best way to Bootload w/ Adjustable Fuse Settings?


So I've spent the last day trying to figure it out.

Using Nick Gammon's "Atmega_Board_Programmer" allowed me to bootload onto a chip easy-enough, but then in order to change the fuse settings I ended up having to use AVRdude after, making it a two-step process: (bootload, then change fuse settings).

Using Adafruit's "adaLoader" allowed me to modify the code, which enabled me to bootload with the fuse settings all in one operation.

But here are the issues I have with either approach:

Gammon's: I can't figure out how to modify the code to allow for different fuse settings, requiring me to use AVRdude post-bootloading.

Adafruit's: Only comes with the HEX (formatted in a particular way with "" in code) for the ATMega328P, so if you want to bootload onto another chip then you would need to find the correct HEX and copy the formatting into the code.

My questions: 1. How could I modify Gammon's code to allow for different fuse-settings? 2. Where can I find the arduino bootloader HEX for different chips (specifically: ATTINY85-20PU-ND and ATTINY84A-PU-ND) in order to use Adafruit's adaLoader w/ non 328P chips? 3. Does anyone know of a simpler way to bootload w/ (user-adjustable) fuse settings all in one go?

Thanks. -Josh!

Why would you not just use the IDE's 'burn bootloader' feature and an appropriate ISP programmer? (either arduino running ArduinoAsISP or something like a USBAsp - usb asps and arduino nano clones are both under $5 shipped on ebay)

If you use one of my ATTiny cores (see sig links), you can choose the common fuse settings from the tools menu.

The eXtremeBurner AVR program is a lovely GUI for flashing .hex files and setting fuses on windows, if you have a USBAsp.

In any event....

There is no standard bootloader for ATTiny84/85. Most people just program them via the ISP header, so burn bootloader is used only to set the fuses.

Some people have built one, but it costs a lot of flash because it needs an implementation of software serial - they're not widely used, and software serial is kinda flaky to begin with, and the inaccurate internal oscillator on the Tiny84/85 doesn't make that any easier. For that one that uses VUSB for programming (I think adafruit makes the board), there's a special bootloader for that.

Hi DrAzzy. In the core files for ATtiny85, I suppose the boards.txt bootloader.file setting empty_all.hex is there just because the IDE expects some sort of file to upload when using the Burn Bootloader function to set the fuses. Is that correct?

Yes, that's correct - the way the IDE does 'burn bootloader', it will choke if there's nothing there, because it's trying to substitute that value into the command.

In fact, if the empty hex file is truly empty (ie would result in no data being written), AVRdude will refuse to proceed, so it has to write something, even if it does nothing.

  1. How could I modify Gammon's code to allow for different fuse-settings?

The fuses it changes are in the table near the start, eg.

  // ATmega328P
  { { 0x1E, 0x95, 0x0F }, 
        0x7E00,               // start address
        atmega328_optiboot,   // loader image
        sizeof atmega328_optiboot,
        0xFF,         // fuse low byte: external clock, max start-up time
        0xDE,         // fuse high byte: SPI enable, boot into bootloader, 512 byte bootloader
        0x05,         // fuse extended byte: brown-out detection at 2.7V
        0x2F },       // lock bits: SPM is not allowed to write to the Boot Loader section.

Note that if you use the Lilypad bootloader the fuses are changed later inline:

      newlFuse = 0xE2;  // internal 8 MHz oscillator
      newhFuse = 0xDA;  //  2048 byte bootloader, SPI enabled

After programming the bootloader it writes the fuses:

    Serial.println (F("Writing fuses ..."));

    writeFuse (newlFuse, lowFuse);
    writeFuse (newhFuse, highFuse);
    writeFuse (newextFuse, extFuse);
    writeFuse (newlockByte, lockByte);

So fixing up the table to be what you want should do it.

Thanks Gammon, That worked great.

Bootloaded and fuse change all-in-one.

to streamline the process even more: I was hoping to "upload (a sketch) using programmer" (w/ arduino as ISP) immediately after bootloading. But for some reason I wasn't able to do that with your programmer. Maybe it wasn't designed to do that. (thoughts?)

So what I ended up doing was: - upload the arduinoISP example to the Uno. (to use the uno as a programmer) - installed my programming shield on top of the Uno (or wire your own version on a breadboard, as explained in Nick Gammon's blog) - created my own "hardware" folder in MyDocuments/Arduino/ - dropped in the "Bootloader" folder w/ atmega sub-folder w/ ATmegaBOOT_168_atmega328_pro_8MHz.hex - also under that same "hardware" folder is a "boards" txt file (sorry, can't remember where I downloaded it) that had something like this: (clock: 8MHz internal)(BOD: 2.7V)

atmega328bb.upload.protocol=arduino atmega328bb.upload.maximum_size=30720 atmega328bb.upload.speed=57600

atmega328bb.bootloader.low_fuses=0xE2 atmega328bb.bootloader.high_fuses=0xDA atmega328bb.bootloader.extended_fuses=0x05

atmega328bb.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex atmega328bb.bootloader.unlock_bits=0x3F atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.bootloader.tool=arduino:avrdude atmega328bb.upload.tool=arduino:avrdude

I added this to the txt file, changing names and fuse-values accordingly: (clock: 8MHz internal)(BOD: 1.8V)

atmega328bbv1.upload.protocol=arduino atmega328bbv1.upload.maximum_size=30720 atmega328bbv1.upload.speed=57600

atmega328bbv1.bootloader.low_fuses=0xE2 atmega328bbv1.bootloader.high_fuses=0xDA atmega328bbv1.bootloader.extended_fuses=0x06

atmega328bbv1.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex atmega328bbv1.bootloader.unlock_bits=0x3F atmega328bbv1.bootloader.lock_bits=0x0F

atmega328bbv1.bootloader.tool=arduino:avrdude atmega328bbv1.upload.tool=arduino:avrdude (clock: 8MHz internal)(BOD: Disabled)

atmega328bbv2.upload.protocol=arduino atmega328bbv2.upload.maximum_size=30720 atmega328bbv2.upload.speed=57600

atmega328bbv2.bootloader.low_fuses=0xE2 atmega328bbv2.bootloader.high_fuses=0xDA atmega328bbv2.bootloader.extended_fuses=0x07

atmega328bbv2.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex atmega328bbv2.bootloader.unlock_bits=0x3F atmega328bbv2.bootloader.lock_bits=0x0F

atmega328bbv2.bootloader.tool=arduino:avrdude atmega328bbv2.upload.tool=arduino:avrdude

That then allowed me to simply select the board through the arduino IDE, then "burn bootloader", then "upload using programmer".

Anyhow, hope that helps someone.

That is good! If you want to make it fancier, versions 1.5 and up of the IDE allow you to create menu items in the IDE. So you could select BB 328 on the Tools, Board menu. Then create a Tools, Features menu with your various fuse settings. Kind of like a sub-menu. You can see the way they do that with the built-in board selections for Pro Mini. When you select Pro Mini for your Board, another menu appears under Tools, Processor, where you get to select what processor and frequency it has. You can do the same sort of thing with your BB 328 Board.