Standalone bootload burner for Atmega8/168/328 micro controllers without arduino board and computer

*Install the Library mentioned in the above schematic.

  • Use these changes in atmega328_optiboot.ino
#include "Adafruit_AVRProg.h"

Adafruit_AVRProg avrprog = Adafruit_AVRProg();

/*
 * Pins to target
 */
#define AVRPROG_SCK   13
#define AVRPROG_MISO  12
#define AVRPROG_MOSI  11
#define AVRPROG_RESET 10
//If we have clock out enabled, it will be on pin 9

#define BUTTON        17  //A3
#define PIEZOPIN      16  //A2
#define LED_ERR       15  //A1
#define LED_PROGMODE  14  //A0

extern const image_t *images[];

void setup() {
  Serial.begin(115200); /* Initialize serial for status msgs */

  while (!Serial)
    ;
  delay(100);

  Serial.println("\nAdaBootLoader Bootstrap programmer (originally OptiLoader "
                 "Bill Westfield (WestfW))");

  pinMode(PIEZOPIN, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP); // button for next programming

  avrprog.setProgramLED(LED_PROGMODE);
  avrprog.setErrorLED(LED_ERR);
  
  avrprog.generateClock();  // on pin 9

  avrprog.setSPI(AVRPROG_RESET, AVRPROG_SCK, AVRPROG_MOSI, AVRPROG_MISO);

}

void loop(void) {
  Serial.println("\nType 'G' or hit BUTTON for next chip");
  while (1) {
//    if (Serial.read() == 'G') {
//      break;
//    }
    if (!digitalRead(BUTTON)) {
      while (!digitalRead(BUTTON)) {
        delay(10);
      }          // wait for release
      delay(10); // debounce
      break;
    }
  }

  if (!avrprog.targetPower(true)) {
    avrprog.error("Failed to connect to target");
  }

  Serial.print(F("\nReading signature: "));
  uint16_t signature = avrprog.readSignature();
  Serial.println(signature, HEX);
  if (signature == 0 || signature == 0xFFFF) {
    avrprog.error(F("No target attached?"));
  }

  const image_t *targetimage = images[0];
  if (targetimage->image_chipsig != signature) {
    avrprog.error(F("Signature doesn't match image"));
  }
  Serial.println(F("Found matching chip/image"));

  Serial.print(F("Erasing chip..."));
  avrprog.eraseChip();
  Serial.println(F("Done!"));

  if (!avrprog.programFuses(
          targetimage->image_progfuses)) { // get fuses ready to program
    avrprog.error(F("Programming Fuses fail"));
  }

  if (!avrprog.verifyFuses(targetimage->image_progfuses,
                           targetimage->fusemask)) {
    avrprog.error(F("Failed to verify fuses"));
  }

  if (!avrprog.writeImage(targetimage->image_hexcode,
                          pgm_read_byte(&targetimage->image_pagesize),
                          pgm_read_word(&targetimage->chipsize))) {
    avrprog.error(F("Failed to write flash"));
  }

  Serial.println(F("\nVerifing flash..."));
  if (!avrprog.verifyImage(targetimage->image_hexcode)) {
    avrprog.error(F("Failed to verify flash"));
  }
  Serial.println(F("\nFlash verified correctly!"));

  // Set fuses to 'final' state
  if (!avrprog.programFuses(targetimage->image_normfuses)) {
    avrprog.error("Programming fuses fail");
  }

  if (!avrprog.verifyFuses(targetimage->image_normfuses,
                           targetimage->fusemask)) {
    avrprog.error("Failed to verify fuses");
  } else {
    Serial.println("Fuses verified correctly!");
  }

#if !defined(ESP32)
  // no 'tone' on ESP32
  tone(PIEZOPIN, 4000, 200);
#endif

  while (1)
    ;
}