Hi, I'm using Nick Gammon's Hex Uploader sketch (arduino_sketches/Atmega_Hex_Uploader.ino at master · nickgammon/arduino_sketches · GitHub) and I managed to correctly upload hex files. The MCU I'm programming has bootloader, correct fuses and I usually program it with a FTDI - whenever I'm not programming it via Hex Uploader sketch... However, when I'm finished programming it with Hex Uploader, I am no longer able to keep programming it with a FTDI... I can keep programming it with Hex Uploader but I need to use an AVRISP MKII to program its bootloader and fuses so I can use again the FTDI. It seems like Hex Uploader overwrites the bootloader/fuses.
Which processor chip? Do you have a crystal, if so which? Please copy and paste the fuse settings from the hex uploader sketch.
If you need to change fuses, please state what they were before the change, and after the change. In other words, what did you change? It is true that the uploaded changes a couple of fuses, mainly to make them match the sketch you have uploaded.
I should point out too that uploading a hex file, which is not a bootloader, will indeed remove the bootloader (it does a chip erase). If you want to use the FTDI port afterwards you need to upload a bootloader.
A simple procedure is to save the bootloader back to the SD card (once you have a working one on it) and then just put it back when you need it to be programmed via FTDI.
Unfortunately it won't be possible for me to run the sketch and paste here the fuse settings in the following days but I'll do it for sure as soon as possible.
I have a custom board with an ATMEGA328P and two ATMEGA2560. What I'm trying to do is to upload code to the ATMEGA2560 with the ATMEGA328P. I managed to do it but since my .hex file is not a bootloader, I am no longer able to program the MCU via FTDI unless I burn a bootloader. By the way, is it possible to incorporate the bootloader in the .hex files of an Arduino sketch? The idea would be to have the sketch + bootloader and so it would be possible to keep programming it via FTDI.
Your suggestion of having the bootloader in the SD card is a good workaround.
Uploading a file erases the chip. Therefore the bootloader is removed. Also the fuses are changed to boot straight into the code. It auto-detects if you are uploading a bootloader (based on the start address). If you are uploading a bootloader the fuses are set to jump to it, otherwise it starts at address 0x0000 which is the start of the main sketch.
The file I am uploading is a simple sketch to blink a led in the board.
I already followed your suggestion and placed the ATMEGA2560 bootloader in the SD card. I wrote a simple console for the ATMEGA328P and now I use it to program the bootloader and hence be able to program the ATMEGA2560 again via FTDI.
Is there a way to do not erase the chip or to write the sketch but keeping the bootloader? Or to "merge" the sketch and the bootloader?
You have to erase the chip. Programming sets the bits from 1 to 0 and can't do it the other way around. Erasing sets them all back to 1.
However you could edit the hex file and copy and paste the bootloader to the end of it. For example at the end of the sketch you might have:
...
:106AC0000000E80EE40EE00EDC0ED80EB6091E0043
:106AD000FCFF00002200000000005D285D285D280A
:106AE0005D285D285D281E000000000000000000F9
:106AF000A327B531000000006128B5310000000077
:0C6B00000431B531A830D530BA30F43083
<---------------- paste here as described below
:00000001FF
So before the "end of file" line (the last one with ":00000001FF" in it), copy and paste the bootloader code from the bootloader .hex file.
Now the one file contains the sketch and the bootloader. However you would need to find the place in the hex uploader where it decides what way to set the BOOTRST fuse (in updateFuses) and change appropriately.
Look at the updateFuses function. The correct value depends on the size of the bootloader, and I don't know which one you are going to use. However the code in that function should guide you.
Today I followed your suggestion and merged the bootloader (default stk500v2 included in arduino folders) and the program into a single .hex file.
With your directions and this site http://www.engbedded.com/fusecalc I found that the correct BOOTRST value (boot reset address 0x00) would lead on a 0xD8 high fuse (ATMEGA2560) - it is the same that is described in boards.txt file under Arduino folder.
I uploaded the merged .hex file but I got no luck. After this step I still can't upload code to the processor via FTDI .
Dear Nick, some days ago I decided to go back a few steps and before trying again your hexUploader sketch, I uploaded the .hex file (containing bootloader + program) with my AVRISP. The following line shows the avrdude instruction I wrote:
Atmega chip detector.
Entered programming mode OK.
Signature = 1E 98 01
Processor = ATmega2560
Flash memory size = 262144
LFuse = FF
HFuse = D8
EFuse = FD
Lock byte = CF
Clock calibration = 98
Bootloader in use: Yes
EEPROM preserved through erase: No
Watchdog timer always on: No
Bootloader is 8192 bytes starting at 3E000
Bootloader:
3E000: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E010: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E020: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E030: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3E090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
(...)
3FFC0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3FFD0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3FFE0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
3FFF0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
MD5 sum of bootloader = 84 D0 4C 9D 6C C8 EF 35 BF 82 5D 51 A5 27 76 99
First 256 bytes of program memory:
0: 0C 94 C1 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
10: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
20: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 9B 2F
30: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
40: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
50: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 B5 71
60: 0C 94 EE 01 0C 94 22 6A 0C 94 6A 6B 0C 94 EE 01
70: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
80: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
90: 0C 94 62 6A 0C 94 A9 6B 0C 94 EE 01 0C 94 CF 02
A0: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
B0: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01
C0: 0C 94 EE 01 0C 94 EE 01 0C 94 EE 01 0C 94 A2 6A
D0: 0C 94 E8 6B 0C 94 EE 01 0C 94 E2 6A 0C 94 27 6C
E0: 0C 94 EE 01 7C 3C 3E 5E 2B 3D 3F 2F 5B 5D 3B 2C
F0: 2A 22 5C 00 1F 1C 1F 1E 1F 1E 1F 1F 1E 1F 1E 1F
With your sketch I notice two things:
1 -Despite the fact that I used the avrdude with this option "-Ulock:w:0x0F:m" it seems like the lock byte is 0xCF instead of 0x0F.
2 - All my bootloader section is filled with 1 (not programmed). I followed your instructions to generate a .hex file containing bootloader + program but I might have mistaken somewhere...
Can you post the exact file you uploaded? The 2560 chips need an extra line (which should be in the bootloader file) to change the high-order byte of the address.
Oops, I noticed I made a mistake generating the .hex file!
Some minutes ago I made a try removing the last line of the program .hex file and pasting the whole bootloader to that file. I was able to program the processor (with AVRISP) with it and after that it was also possible to upload code to it via FTDI.
One step is missing to have this problem solved: I programmed the processor with hex uploader sketch and the high fuse was changed to 0xD9 instead of 0xD8. I need to check the code to know why it happened because whenever I upload a bootloader .hex the 0xD8 high fuse is written... It has something to do with the BOOTRST, right?
Ok, I guess it's solved (I did not remove the last post so you can see my line of thought).
In updateFuses() I commented the following line:
if (lowestAddress == 0)
{
Serial.println (F("No bootloader."));
// don't use bootloader
//fuses [fusenumber] |= 1; //commented line
}
Now the high fuse 0xD8 is written and the processor can be programmed via FTDI. What's your opinion? Is it a "valid solution"?
One last thing, I noticed that when I try to program the .hex containing bootloader + program via FTDI the avrdude warns me of a verification error (after programming it). Does it have to do with the "merge" of the two .hex?
It uses avrdude (which as far as I know is included in arduino packages) to upload code.
Here is an example of an upload operation (Eclipse console):
Launching /Applications/Arduino1.app/Contents/Resources/Java/hardware/tools/avr/bin/avrdude -patmega2560 -cwiring -P/dev/cu.usbserial-AD026670 -b115200 -Uflash:w:test.hex:a -C/Applications/Arduino1.app/Contents/Resources/Java/hardware/tools/avr/etc/avrdude.conf
Output:
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.05s
avrdude: Device signature = 0x1e9801
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "test.hex"
avrdude: input file test.hex auto detected as Intel Hex
avrdude: writing flash (65616 bytes):
Writing | ################################################## | 100% 12.34s
avrdude: 65616 bytes of flash written
avrdude: verifying flash memory against test.hex:
avrdude: load data flash data from input file test.hex:
avrdude: input file test.hex auto detected as Intel Hex
avrdude: input file test.hex contains 65616 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 10.76s
avrdude: verifying ...
avrdude: 65616 bytes of flash verified
avrdude done. Thank you.
avrdude finished
Since my test.hex was generated "the normal way" the upload process ran well.
When I try to upload my .hex file containing bootloader and program (I have to run avrdude directly from the command line) I receive a different output message:
vrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.05s
avrdude: Device signature = 0x1e9801
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "test.hex"
avrdude: input file test.hex auto detected as Intel Hex
avrdude: writing flash (262106 bytes):
Writing | ################################################## | 100% 1.90s
avrdude: 262106 bytes of flash written
avrdude: verifying flash memory against test.hex:
avrdude: load data flash data from input file test.hex:
avrdude: input file test.hex auto detected as Intel Hex
avrdude: input file test.hex contains 262106 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 42.87s
avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x2700
0xff != 0x9d
avrdude: verification error; content mismatch
avrdude: safemode: Fuses OK
avrdude done. Thank you.
As you can see, the Writing step is faster (1.90s vs 12.34s) and the Reading is much slower (42.87s vs 10.76s). I receive this verification error but it seems the code runs properly (but I am not sure because it is a simple sketch to simply blink a LED).
This situation doesn't worry me because it works when I upload with AVRISP and with hex uploader. I was simply sharing to have your opinion. For some reason I don't know the .hex upload (containing bootloader and program) has a verification problem when it is made via FTDI and apparently doesn't have any issue when uploaded via AVRISP or hex uploader.