This project is intended to allow you to program your Atmega chips without having to buy a dedicated ICSP programmer. Instead, it uses a Uno (or similar) board to act as a programmer.
The programming sketch is running on the Uno. The hex (binary) file to be uploaded to the target chip has been compiled in the Arduino IDE (Integrated Development Environment) and copied to the SD card.
The (micro) SD card is plugged into a Micro SD breakout board, similar to this:
These boards can be purchased for around $US 15, and let you plug in an ordinary micro-SD card, which you can then swap into your PC / Mac / Linux box to upload or download .hex files.
Arduino Ethernet Shield support
Version 1.27 onwards of the sketch allows you to use the Arduino Ethernet Shield (which has a micro-SD card connector on it) instead of using a SD card adapter.
If you are using the Ethernet Shield then you have to make USE_ETHERNET_SHIELD true, a little way from the top of the sketch, as follows:
#define USE_ETHERNET_SHIELD true
When using the Ethernet shield there is a wiring change (described below) because the Ethernet shield uses D4 as the "slave select" pin for the SD card.
Example session
Upon starting the sketch it reads the SD card and locates all the .hex files in the root directory, like this:
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
The size and date/time modified are shown to help you to choose the appropriate file. Note that the file names are the old "8.3" style, so you may not see the exact name you saved them as.
The sketch then detects the type of chip it is connected to, like this:
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
You are then asked to choose which file to upload/process:
I'll choose BLINK3.HEX (type into input box, or copy and paste):
Processing file: BLINK3.HEX
Checking file ...
##
Lowest address = 0x0
Highest address = 0x439
Bytes to write = 1082
No bootloader.
Suggest making high fuse = 0xDB
The file is read to verify that it is the correct format for an Intel hex file, including checking the sumcheck bytes for each line.
It also checks that the file will fit into the memory of the target processor.
If the file is too large you may see a message like this:
Highest address of 0x3FFD9 exceeds available flash memory top 0x8000
Or if the file appears to be a bootloader, but does not start on one of the bootloader boundaries for this particular chip:
Start address is not a bootloader boundary.
If all is well you will see this:
Type 'V' to verify, or 'G' to program the chip with this file ...
You can type V to verify an earlier upload, or G (Go) to upload the file to the target chip:
If you type G you will see something like:
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.
The flash memory is erased, the file written, and then the flash verified to confirm it agrees with what should have been uploaded.
Also the appropriate fuse byte is set so that the processor boots into this file. If the file starts at address 0 then the reset vector is set to be the one at address 0. Otherwise, it programmed to boot into the bootloader address.
Speed
The examples above programmed in about a second. A larger file (170228 bytes on disk, 60518 bytes to be written to flash memory) takes:
- 10 seconds to check the disk file
- 20 seconds to program the chip
- 18 seconds to verify the chip contents
By comparison, uploading the same sketch through the bootloader took about 18 seconds. So this method is comparable in speed. Well, it's slower if you include verifying the board afterwards, but I don't think the bootloader does that. You could always remove the verify step from the sketch to save time.
Wiring
SD card
If you are using the Arduino Ethernet Shield you can skip this part, because the shield has an SD card connector on it.
Since the SD card uses SPI we have used "hardware" SPI to access the Flash card. This is wired up like this:
Arduino SD Card
-------------------------------------
D10 (SS) CS (chip select) (green)
D11 (MOSI) DI (data in) (blue)
D12 (MISO) DO (data out) (orange)
D13 (SCK) CLK (clock) (yellow)
+5V 5V (red)
Gnd GND (green)
Then for the target chip we use "bit banged" SPI, so that both devices can be active at once.
Target device
Arduino Atmega328
-------------------------------------
D4 (SCK) Pin 19 (black) (or D3, see below)
D5 (SS) Pin 1 (reset) (green)
D6 (MISO) Pin 18 (orange)
D7 (MOSI) Pin 17 (white)
+5V 5V (red)
Gnd GND (blue)
If you are using the Arduino Ethernet Shield, use D3 for SCK rather than D4, as D4 is used as the Slave Select pin for the SD card interface.
If the target device requires an external clock the sketch provides an 8 MHz clock output on pin D9, so connect pin D9 to the clock input (pin 9 on an Atmega328).
Producing a .hex file
To produce the .hex file you need to Verify your sketch in the IDE.
If you select "verbose" mode in the IDE you will see the file names scroll by in the message box. The last file name will be the .hex file which you need to put onto your chip:
/var/folders/1l/43x8v10s1v36trvjz3v92m900000gn/T/build5801712006257958435.tmp/Blink2.cpp.hex
Binary sketch size: 1082 bytes (of a 30720 byte maximum)
Make sure you have selected the correct target board in the IDE before you verify your sketch, this ensures that the correct code is generated for the chip you upload it to.
Then copy that hex file onto the SD card, unmount (eject) the SD card from your PC, and insert it into the SD reader. Then you are ready to program your chip.
Tip
In recent versions of the Arduino IDE you can produce the .hex file by using the Sketch menu -> Export Compiled Binary. This puts the .hex file into the same directory as your sketch. (You do not want the file with the bootloader, choose the file without the bootloader).
Starting addresses
For chips which support a bootloader, there are 5 possible starting address, depending on the size of the bootloader. For example, with the Atmega328:
- 0000: no bootloader, boots straight into target sketch
- 7000: 4096 byte bootloader
- 7800: 2048 byte bootloader
- 7C00: 1024 byte bootloader
- 7E00: 512 byte bootloader
Any other starting address will invalid, because the processor would not start executing the sketch program from that location.
The programming sketch endeavours to work out the valid starting addresses, and rejects any .hex file that does not start on those boundaries, for a particular target chip.
It also sets the fuse byte appropriately to make it boots at the requested address. Other fuse bits are not changed.
Wiring for Mega2560 board
Code
Source on GitHub
The latest version will be available on GitHub:
https://github.com/nickgammon/arduino_sketches
You can see from that what recent changes were.
Also you require the SDFat library:
https://github.com/greiman/SdFat
Tip:
The SdFat library seems to be undergoing changes/improvements as at April 2015. The hex uploader may not compile with the new version of the SdFat library.
An archived version of the SdFat library (which works with the hex uploader sketch) is available from:
http://gammon.com.au/Arduino/SdFat-master.zip (2.2 Mb)
Unzip that file, and from within the folders inside it, copy the SdFat folder into your "libraries" folder (which is under your Arduino sketchbook folder - not inside the Arduino application folder). Then restart the Arduino IDE.
If you try to compile under older versions of the Arduino IDE, which do not support the F macro, you will get errors. You can get a copy of that here:
http://arduiniana.org/libraries/flash/
Disclaimer
This sketch is a work-in-progress. Please be advised that it has not been tested on every possible chip. Various chip signatures and configurations have been allowed for but it is possible that there was a transcription error for some of them. You are advised to verify the settings for your chip. Use at your own risk.
Custom cable
You can save yourself some time and effort by making up a custom ICSP cable, like this:
Now for boards (like the Sanguino, Uno, Mega2560) that have an ICSP header, just plug one end of the cable into it, and the other end into your programming board, like this:
Easy cabling for Micro SD board
You can easily connect to the Micro SD board by getting a 4-wire female-to-female wire, and two extra ones, like this:
(Or just get 6 female-to-female wires).
The 4-wire cable just plugs into the SD card reader starting at the CS pin (chip select) and ending with CLK (clock). Then plug the red wire into the +5V pin and the black wire into the Gnd pin. I put some heat-shrink over it to stop the pins shorting against something:
The red and black (power) wires can pick up 5V and Gnd from the ICSP header (pin 2 is 5V, pin 6 is Gnd) like this:
(Note the middle pin (pin 4) is not used).
The other four wires just plug into pins D10 (CS) through to D13 (CLK) like this:
I used a longer version of the pin header to make a male-to-male gender changer:
Or you could save yourself the trouble and use male-to-female cable.
If you use both this and the custom cable suggested earlier, you can have a compact "chip programmer" like this:
Updated user interface
Since the sessions were captured above, the sketch has been modified to allow you to read from flash and save back to disk, erase flash memory, and modify fuses. Now you enter an action code like this:
--------- Starting ---------
Attempting to enter programming mode ...
Entered programming mode OK.
Signature = 0x1E 0x95 0x0F
Processor = ATmega328P
Flash memory size = 32768 bytes.
LFuse = 0xFF
HFuse = 0xDE
EFuse = 0xFD
Lock byte = 0xCF
Actions:
[E] erase flash
[F] modify fuses
[R] read from flash (save to disk)
[V] verify flash (compare to disk)
[W] write to flash (read from disk)
Enter action:
Example of reading flash memory:
Enter action:
R
Choose file to save as:
TEST.HEX
Copying flash memory to SD card (disk) ...
################################################################
################################################################
################################################################
###############################################################
File TEST.HEX saved.
Example of changing the low fuse:
Enter action:
F
LFuse = 0xFF
HFuse = 0xDE
EFuse = 0xFD
Lock byte = 0xCF
Choose fuse (LOW/HIGH/EXT/LOCK) ...
LOW
Current value of low fuse = 0xFF
Enter new value for low fuse (2 hex digits) ...
C2
WARNING: Fuse changes may make the processor unresponsive.
Confirm change low fuse from 0xFF to 0xC2 . Type 'YES' to confirm ...
YES
Changing low fuse ...
Fuse written.
LFuse = 0xC2
HFuse = 0xDE
EFuse = 0xFD
Lock byte = 0xCF
|