Code Upload to Arduino Mega hangs but Uploads Fine to Arduino Uno

I first hit this problem several years ago when writing a really big program that had to run on a Mega. Then I hit it again last night and had to try to remember the cause.

I believe this is a problem only on older Mega’s. I believe the new ones ship with a recent boot loader. The original one I had issue with 2+ years ago had come from china (an unrealized knock-off). The one I had trouble with last night was an old one at the local maker space.

This time I’ll document the fix here so next time I might be able to find the solution without referring to my faulting memory.

The basic issue is caused by having ‘!!!’ embedded in your code. The older boot loader uses this for something. Initially I did have a constant containing ‘!!!’. When I found the issue, I removed the constant, but i still had intermittent problems. The code was large enough that some of the code itself was just happened to contain the string. So fixing the boot loader was the only option.

These notes were taken largely verbatim from the software document I maintained during the project:

Arduino Mega 2560 “!!!” Problem

Here is a brilliant one: The boot loader for the Mega 2560 uses “!!!” for some special purpose. If you have that string in the code being uploaded, the upload will hang.

This has become a show stopper. although I yanked the literal “!!!” I was using periodically I still get object code generated with that sequence. Up to now I’ve been able to rearrange code to work around it, but now it is happening in the middle of a large array declaration and i cannot get around it. I am being forced to address the problem.

My immediate work around was to go back to the Arduino Mega which doesn’t have the bug. That is allowing me to continue development, but I need to fix the production board that the company purchased.

I researched the problem further and found that the boot loader has been patched. Here is the thread regarding the problem and patch:

http://code.google.com/p/arduino/issues/detail?id=392

and the code for the downloader:

http://www.xyfyx.com/files/stk500boot_v2_mega2560.hex

The problem is installing this boot loader. I can’t just do it with the hardware I have. One option is to purchase a bootloader programmer:

https://www.sparkfun.com/products/9825?

The other is to program an UNO to act as a programmer. Instructions for doing that are here:

http://www.sparkfun.com/tutorials/247

I also need all of the ‘fuse’ settings for the chip. I got these from boards.txt file that is in the arduino directory:

mega2560.name=Arduino Mega 2560 or Mega ADK

mega2560.upload.protocol=stk500v2
mega2560.upload.maximum_size=258048
mega2560.upload.speed=115200

mega2560.bootloader.low_fuses=0xFF
mega2560.bootloader.high_fuses=0xD8
mega2560.bootloader.extended_fuses=0xFD
mega2560.bootloader.path=stk500v2
mega2560.bootloader.file=stk500boot_v2_mega2560.hex
mega2560.bootloader.unlock_bits=0x3F
mega2560.bootloader.lock_bits=0x0F

mega2560.build.mcu=atmega2560
mega2560.build.f_cpu=16000000L
mega2560.build.core=arduino
mega2560.build.variant=mega

Here are instructions on using the monitor. Make sure baudrate is 11520

http://www.avr-developers.com/bootloaderdocs/index.html

Uploading Boot Loader with Pocket AVR Programmer

Purchased AVR programmer to resolve above error. Here are instructions from the sparkfun website:

To use this programmer, attach to a Windows machine and install the drivers listed below. Open a command prompt. Assuming WinAVR (and therefore AVRDUDE) have been installed, type:

avrdude -c usbtiny -B 1 -patmega328 -U flash:w:main.hex

Be sure to include the “-B 1” flag as this will significantly increase the programming speed! You may need to change -p flag to your appropriate microcontroller. You can setup a tool and hotkey in Programmers Notepad to do this automatically.

https://code.google.com/p/robot-exporers/source/browse/trunk/hardware/Programmers/Pocket+AVR+Programmer/AVR-Pocket-Programmer-v15.zip?r=485

I unzipped the above files into a new folder, plugged in the programmer, and pointed to that directory to find driver files. That worked fine.

AVRDUDE is located here:

C:\Program Files\Arduino-1.0.1\hardware\tools\avr\bin\

CD to that dir.

Move the HEX file to the avrdude directory.

connect cable to arduino, with cable going away from reset button.

connect USB cable to programmer.

Lights will turn on for both boards

To test the connection I type:

[C:\Program Files\Arduino-1.0.1\hardware\tools\avr\bin] avrdude -c usbtiny -p m2560 -C ..\etc\avrdude.conf -v

avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2009 Joerg Wunsch

System wide configuration file is "..\etc\avrdude.conf"

Using Port                    : lpt1
Using Programmer              : usbtiny
Overriding Baud Rate          : 19200
avrdude: usbdev_open(): Found USBtinyISP, bus:device: bus-0:\\.\libusb0-0001--0x1781-0x0c9f
AVR Part                      : ATMEGA2560
Chip Erase delay              : 9000 us
PAGEL                         : PD7
BS2                           : PA0
RESET disposition             : dedicated
RETRY pulse                   : SCK
serial program mode           : yes
parallel program mode         : yes
Timeout                       : 200
StabDelay                     : 100
CmdexeDelay                   : 25
SyncLoops                     : 32
ByteDelay                     : 0
PollIndex                     : 3
PollValue                     : 0x53
Memory Detail                 :

Block Poll               Page      Polled
Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom        65    10     8    0 no       4096    8      0  9000  9000 0x00 0x00
flash         65    10   256    0 yes    262144  256   1024  4500  4500 0x00 0x00
lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

Programmer Type : USBtiny
Description     : USBtiny simple USB programmer, http://www.ladyada.net/make/usbtinyisp/
avrdude: programmer operation not supported

avrdude: Using SCK period of 10 usec
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9801
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as FD

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D8
avrdude: safemode: efuse reads as FD
avrdude: safemode: Fuses OK

avrdude done.  Thank you.

I saved the existing bootloader (in case I need to go back) by doing this:

[C:\Program Files\Arduino-1.0.1\hardware\tools\avr\bin]avrdude -B 1 -c usbtiny -p m2560 -C ..\etc\avrdude.conf -Uflash:r:oldbootloader.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9801
avrdude: reading flash memory:

Reading | ################################################## | 100% 38.86s

avrdude: writing output file "oldbootloader.hex"

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

NOTE: the above looks like it worked, but it didn’t. The output file contains only a single line.

To install the new boot loader do the following:

[C:\Program Files\Arduino-1.0.1\hardware\tools\avr\bin] avrdude -B 1 -c usbtiny -p m2560 -C ..\etc\avrdude.conf -Uflash:w:stk500boot_v2_mega2560.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

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 "stk500boot_v2_mega2560.hex"
avrdude: input file stk500boot_v2_mega2560.hex auto detected as Intel Hex
avrdude: writing flash (261386 bytes):

Writing | ################################################## | 100% 52.16s

avrdude: 261386 bytes of flash written
avrdude: verifying flash memory against stk500boot_v2_mega2560.hex:
avrdude: load data flash data from input file stk500boot_v2_mega2560.hex:
avrdude: input file stk500boot_v2_mega2560.hex auto detected as Intel Hex
avrdude: input file stk500boot_v2_mega2560.hex contains 261386 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 38.89s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x3e000
0x0d != 0xff
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK

avrdude done.  Thank you.

NOTE the verification error above. This is OK. I don’t know why, but it is OK.

NOTE: you can also burn a new bootloader using the arduino IDE. Set board to correct board, set programmer to USBTinyISP and click on burn. Problem with this is it uses the default bootloader (found in booloader directory) which is wrong. I presume this can be replaced with the good one, but I haven’t played with that.

Advertisements
This entry was posted in c-arduino. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s