Stand-alone .hex file uploader for your chips - testers wanted

There seems to be post after post from people having problems uploading their sketches to their chips, particularly for those chips which are less “mainstream”.

The project below attempts to address that.

It uses a Uno as a stand-alone programmer. It reads the file you wish to program from an SD card (you need an SD card shield, or a card adapter like the one I used).

You compile the file in the IDE, copy it to the SD card, hook your chip up as shown, and then run the sketch. Example session:

Atmega hex file uploader.
Written by Nick Gammon.
Version 1.0
Reading SD card ...

HEX files in root directory:

BLINK2~1.HEX : 4595 bytes.  Created: 2012-05-11 07:47:40.  Modified: 2012-05-11 10:50:06
OPTI328.HEX : 1467 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
MEGA2560.HEX : 22989 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
ATMEGA8.HEX : 2870 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
LILYPAD.HEX : 5484 bytes.  Created: 2010-09-25 22:52:34.  Modified: 2010-09-25 22:52:34
SKETCH~1.HEX : 170228 bytes.  Created: 2012-05-11 09:40:24.  Modified: 2012-05-11 09:40:24
LARGE_~1.HEX : 170228 bytes.  Created: 2012-05-11 10:54:48.  Modified: 2012-05-11 10:54:48
BLINK3.HEX : 3061 bytes.  Created: 2012-05-11 11:08:00.  Modified: 2012-05-11 11:08:00
---------
Attempting to enter programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x95 0x0F 
Processor = ATmega328P
Flash memory size = 32768 bytes.
LFuse = 0xE2 
HFuse = 0xDB 
EFuse = 0xFD 
Lock byte = 0xFF 
---------
Choose a file [  ] ...
Processing file: BLINK3.HEX
Checking file ...

##
Lowest address  = 0x0
Highest address = 0x439
Bytes to write  = 1082
No bootloader.
Suggest making high fuse = 0xDB 
Type 'V' to verify, or 'G' to program the chip with this file ...
Processing file: BLINK3.HEX
Erasing chip ...
Writing flash ...

#########
Written.
Processing file: BLINK3.HEX
Verifying flash ...

########
No errors found.
No bootloader.
Setting high fuse = 0xDB 
Done.

In this case the whole process took a couple of seconds.

More details, and source code here:

http://www.gammon.com.au/forum/?id=11638

This is a bit of a work-in-progress, but if anyone would like to download it and test it, any feedback is welcome.

You can use this to upload “standalone” sketches, or bootloaders.


Here is an example of uploading a somewhat larger file to a Mega2560.

Atmega hex file uploader.
Written by Nick Gammon.
Version 1.0
Reading SD card ...

HEX files in root directory:

BLINK2~1.HEX : 4595 bytes.  Created: 2012-05-11 07:47:40.  Modified: 2012-05-11 10:50:06
OPTI328.HEX : 1467 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
MEGA2560.HEX : 22989 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
ATMEGA8.HEX : 2870 bytes.  Created: 2011-11-29 10:11:44.  Modified: 2011-11-29 10:11:44
LILYPAD.HEX : 5484 bytes.  Created: 2010-09-25 22:52:34.  Modified: 2010-09-25 22:52:34
SKETCH~1.HEX : 170228 bytes.  Created: 2012-05-11 09:40:24.  Modified: 2012-05-11 09:40:24
LARGE_~1.HEX : 170228 bytes.  Created: 2012-05-11 10:54:48.  Modified: 2012-05-11 10:54:48
BLINK3.HEX : 3061 bytes.  Created: 2012-05-11 11:08:00.  Modified: 2012-05-11 11:08:00
---------
Attempting to enter programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x98 0x01 
Processor = ATmega2560
Flash memory size = 262144 bytes.
LFuse = 0xFF 
HFuse = 0xD9 
EFuse = 0xFD 
Lock byte = 0xFF 
---------
Choose a file [  ] ...
Processing file: LARGE_~1.HEX
Checking file ...

################################################################
###############################
Lowest address  = 0x0
Highest address = 0xEC65
Bytes to write  = 60518
No bootloader.
Suggest making high fuse = 0xD9 
Type 'V' to verify, or 'G' to program the chip with this file ...
Processing file: LARGE_~1.HEX
Erasing chip ...
Writing flash ...

################################################################
################################################################
################################################################
#############################################
Written.
Processing file: LARGE_~1.HEX
Verifying flash ...

################################################################
################################################################
################################################################
############################################
No errors found.
No bootloader.
Setting high fuse = 0xD9 
Done.

The whole process took about 50 seconds.

Damn Nick, you are getting into this! I'm trying to juggle 6 designs, you are cranking out new stuff!

Thanks Bob!

I'm just trying to get ready for when my Atmega1284P arrives. :)

Here is a test using an ATtiny85:

And an Atmega644P:

Cool, 1284P will work just like the 644P. Could make to handle all the 40-pin 1284 family parts for times when lots of IO is needed and not so much memory:

ATmega164A ATmega164PA ATmega324A ATmega324PA ATmega644A ATmega644PA ATmega1284 ATmega1284P

Nick you are something man... seriously awesome.... :D This is just what I needed... Would hove to test this out but dont have SD card breakout board though... :( I will test it out as soon as make one... :)

https://www.adafruit.com/products/254

$US 15

(deleted)

Wow Nick, this is just awesome! I'm almost sure I have a few of those 4050s lying around somewhere, I'll try it out as soon as I can.

Any explanation for the battlescars on that attiny85?

[quote author=Nick Gammon link=topic=105399.msg790617#msg790617 date=1336705007]any feedback is welcome[/quote]

"May you find what you are looking for." - an ancient Chinese curse (but probably a modern English curse).

I suggest excluding the .git folder when making the zip file.

Why do you disable interrupts in program?

In startProgramming, the quick RESET pulse is done with interrupts enabled. That should probably be changed to interrupts disabled. I think the goal is to reset the processor fast enough that it does not have time to do anything interesting.

In startProgramming, the quick RESET pulse is currently one millisecond. Two microseconds should be sufficient and is probably more appropriate.

In startProgramming, BB_MOSI is explicitly set to an OUTPUT. Is that necessary? Which is necessary because, in this sketch, SPI to the target is bit-banged.

[quote author=Coding Badly link=topic=105399.msg791418#msg791418 date=1336765755] I suggest excluding the .git folder when making the zip file. [/quote]

I knew it was there but was too lazy to remove it. To do that I have to make a copy of the folder and then compress that. Plus you don't see the folder in the normal Mac browser. Next time.

Why do you disable interrupts in program?

When I switched to bit-banging, somewhat reluctantly, I wanted to make sure the bits were clocked out at a constant rate. It may nor may not be necessary. It works with it in.

In startProgramming, the quick RESET pulse is done with interrupts enabled. That should probably be changed to interrupts disabled. I think the goal is to reset the processor fast enough that it does not have time to do anything interesting.

In startProgramming, the quick RESET pulse is currently one millisecond. Two microseconds should be sufficient and is probably more appropriate.

Well in ArduinoISP, which I glanced at for inspiration in this part, it has:

  digitalWrite(RESET, HIGH);
  pinMode(SCK, OUTPUT);
  digitalWrite(SCK, LOW);
  delay(50);
  digitalWrite(RESET, LOW);

I though 50 mS was way over spec so I cut it down.

But you are probably right. I turned off interrupts and cut it back to 2 uS. That would be about the minimum for programming a 1 Mhz processor, and probably a bit short if someone happens to be running under that. (edit) Made it 5 uS. After all the datasheet says:

In this case, RESET must be given a positive pulse of at least two CPU clock cycles duration after SCK has been set to “0”.

After all "at least" means 2 clock cycles or more.

In startProgramming, BB_MOSI is explicitly set to an OUTPUT. Is that necessary? Which is necessary because, in this sketch, SPI to the target is bit-banged.

Thanks for the suggestions. At least you found nothing major. :)

[quote author=Nick Gammon link=topic=105399.msg791495#msg791495 date=1336770870]Thanks for the suggestions. At least you found nothing major. :)[/quote]

Nope. Nothing major. Very nice work. Thank you!

boredat20: Any explanation for the battlescars on that attiny85?

The tape? That was to cover the holes on the ZIF socket so I didn't get an "out by one" error when inserting the chip after programming it.

And the cable ties are to hold the ZIF socket in place.

I think he meant what looks like a chipped corner on the tiny, but is probably a pin-1 dot. At least that was my train of thought.

You've just been pumping out the hits lately, man. I had it in mind to do something like this, but I'm busy reinventing the SD wheel. (I want LFN support.) Looks like you saved me the trouble. :D

SirNickity: I think he meant what looks like a chipped corner on the tiny, but is probably a pin-1 dot. At least that was my train of thought.

Oh that. I put a dot of White-Out (Liquid Paper or whatever you call it) on the corner because I have trouble seeing the dots at times. It's getting to the stage where, if I hold it a fair way away, it is sharp but too small to see, and if I hold it closer it's blurry. And that's with my glasses on. ;)

spycatcher2k: Excellent - Now I have a programmer to update units in the field, without carrying my laptop ;-)

You still need some sort of monitor to choose a file name and start programming.

Still you could make a modified version that automatically selected a particular file, and uploaded it when you closed a switch or something.

You might want to add "success" and "in progress" LEDs in that case.

I've uploaded version 1.1 that incorporates some extra comments and (some of) the suggestions made by Coding Badly.

For future versions I'll add more signatures. I prefer to test and check the datasheet, to make sure things like the flash memory page size is correct. At least, if it's wrong, the verify should pick it up.

I have updated this sketch to let you read from flash and save back to the disk (SD card). This lets you take a copy of flash memory before modifying it. Also you can erase the flash completely.

The user interface has changed slightly, now you enter an "action" letter, such as R to read or W to write.

--------- Starting ---------

Attempting to enter programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x96 0x0A 
Processor = ATmega644P
Flash memory size = 65536 bytes.
LFuse = 0xFF 
HFuse = 0xDD 
EFuse = 0xFD 
Lock byte = 0xFF 
Actions:
 [E] erase flash
 [R] read from flash (save to disk)
 [V] verify flash (compare to disk)
 [W] write to flash (read from disk)
Enter action:

Choose file to save as: 
File SANGMEM.HEX exists. Overwrite? Type 'YES' to confirm ...

Choose file to save as: 
Copying flash memory to SD card (disk) ...

################################################################
################################################################
################################################################
###############################################################
File SANGMEM2.HEX saved.

The code is now available on GitHub:

https://github.com/nickgammon/arduino_sketches/tree/master/Atmega_Hex_Uploader

Also the .zip file mentioned on this page has been updated:

http://www.gammon.com.au/forum/?id=11638

Fairly extensive testing on the Mega2560 appears to confirm that it correctly handles memory larger than 64 Kb.

Another nice one Nick.

I've returned to working on my RS485/Mega1284 sensor network and I will need to be able to program nodes over the network. I think this might be the place to start when the time comes.

How large is the excutable?


Rob

Binary sketch size: 25000 bytes (of a 32256 byte maximum)

Just been testing it out on a Atmega1284P board.

See new post in this thread:

http://www.gammon.com.au/forum/?id=11637

You could save some space by not making it as "user friendly". The code to ask questions, and get answers probably takes a bit of room.