ATmega128 external clock recovery

From ivc wiki
Jump to navigationJump to search

If you accidentally programmed the Fuses to use the "External Clock" instead of "External crystal" in the SUT_CKSEL setting, the microcontroller is temporarily rendered useless.

Fix

To recover the micro with stuck in "External clock" mode, is to connect a 1-3MHz function generator to pin 24 on the ATmega128, here it's another micro. The ATmega128 should then be possible to program and boot normally on the next power cycle.

Connection

  1. Remove the crystal and the capacitor connected to pin 24, named XTAL1.
  2. Get another ATmega based microcontroller, I used a Arduino Uno with an ATmega323, download and program it with the code below
  3. Connect the other micro by connecting ground to ground on the ATmega128, usually pins 53 or 22,
  4. And connect PD3, digital pin 3 on Arduino Uno, to pin 24 on the ATmega128, check the datasheet to find the correct pin
  5. Connect the AVR programmer, I used a USBTinyAVR programmer that mimics the official AVRISP programmer

Program

  1. Open AVR Studio 4 and click the program icon in the tool bar to initialize a connection, select AVRISP and Auto, or the correct type and port for the programmer
  2. Once connected to the programmer, set the ISP speed to around 100-125kHz, I have 112.5kHz, click write
  3. If the entering programming fails, as it usually does, try resetting the other controller and the ATmega128, on that order
  4. Once the programming mode is successful, go to the Fuses tab, unpick CLOPT if selected, and pick "Int. RC Osc. 1MHz; Start-up time: 6 CK + 64 ms", click program
  5. The micro is now recovered and the external clock can be removed, reset to try

ATmega128 external failed.png ATmega128 external clock spi speed.png ATmega128 external clock recovery restore.png ATmega128 external clock recovery success.png

Function generator

Arduino

Paste into the Arduino editor, compile and upload.

void setup()
{
    cli();
    DDRD = 0xff;
}

void loop()
{
 while (1) {
   // uncomment the delay and comment out cli() to try with a led to find the correct pin
   PORTD |= 0x8;
   //delay(100);
   PORTD &= ~0x8;
   //delay(100);
 } 
}

AVR

Untested code, but it should work fine, compile and upload in AVR Studio or Eclipse.

#include <avr/io.h>
void main(void)
{
 cli();
 DDRD = 0xff;
 while (1) {
  PORTD |= 0x8;
  PORTD &= ~0x8;
 }
}

References