I'm not going to go into depth - this is just really a sketch of what's happening in my bonce right now. I'll be abstracting quite heavily and using my own terms because it doesn't make sense to just repeat all the detail in the datasheets. Code and schematics will be posted as and when available.
All the information I needed for V0.1 is in the atmega32 data sheet. It looks like it'll be quite easy to reset the fuses.
I've come across a design for a parallel port programmer which looks like it would be simple to build but I don't relish the thought of soldering up yet another DB25 connector. So I've decided to drive this project with an Arduino. I'm imagining nothing more than a socket on some stripboard connected to some header pins that will mate with my Diecimila, some power regulation and switching. I would have built a shield but for whatever reason the designers of the board decided to use a non-standard spacing between 2 sets of sockets which makes building shields on protoboard difficult. Grrrr.
The procedure will simply be:- Erase chip, reset fuses. Job done. The chip erase step has the effect of resetting any lock bits. As one of the locks controls our ability to write fuses this is essential. The state of the EEPROM will be indeterminate after this step, however, as there is a fuse controlling whether the erase cycle also clears EEPROM. And we don't know how this is set.
There are two ways to enter high voltage programming mode. The first involves gently tickling a port but it relies upon the clock settings for the chip being set to external. I think this might have been how I borked my chip, but as I couldn't ressurect it with an attached clock signal this could well not not be the case. So I'm going to go for the second method. Brute force!
Powering up the target with 12v @ 250uA on its reset line, logic low on four specific pins and a wait of 100uS should be enough for it to become willing to accept programming commands. Which are loaded thus:
- Set the 'mode select' pins to 'load command'.
- Present the desired command to the DATA pins.
- Pulse the clock pin to latch the command. All pulses need to last at least 250nS.
Commands are executed by giving a pulse to ~wr. Progress can be tracked by monitoring the rdy/~bsy pin, which will go low until the action has finished.
Addresses are loaded in the same manner, we just substitute 'load address' as the mode.
All the dirty details of the required pulsing is clearly outlined in the timing waveform diagrams in the data sheet.
In order to check how the hardware and code is functioning I'll read the signature bytes of the chip as my first step.
- Load the 'read signature' command.
- Load the address of the desired signature byte, 0-2, to be accessed.
- Set ~oe low.
- The target presents the requested byte on the DATA bits.
- Set ~oe high.
When this is returning what I expect then we'll start on the fuses. First though - some erasing.
- Load 'erase chip' command.
- Pulse ~wr.
- Wait for the command to complete. This will take between 7-9mS.
Once this is done happily then we're ready to blow the fuses! We'll do low, then high.
- Load the 'write fuse' command.
- Load DATA with the low fuse byte.
- Give ~wr a pulse and wait for rdy/~bsy to indicate the process has completed.
- Load the 'write fuse' command.
- Load DATA with the high fuse value.
- Give ~wr a pulse and wait for rdy/~bsy.
And that should be that!
I'll let you know how I get on :)
Here's an untested arduino sketch that I've hacked up, which should give a better idea of the specifics. It should be read in concert with the data sheet chapter 'Memory programming'.
/* CUT DUE TO ITS TEMPORARY NATURE - PLEASE SEE LATER POST */