Sketch uploaded to Mega (2560) with programmer doesn't run

I use a USBasp programmer, this one, for programming ATMega micros, and have used it on Arduino boards too.

I tried to program an Arduino Mega (2560), and couldn't get it to work. So I've tried a few things, and it turns out that I can successfully upload the bootloader, and can then use its onboard USB-serial for uploading a sample sketch (blink). This works fine, but if I try to upload the sketch directly with the programmer, the upload seems to work, but the blink sketch doesn't do anything (digital pin doesn't change).

It's particularly strange that the sketch upload seems to work, but that the sketch then either doesn't run, or the upload wasn't actually successful. Here's the (verbose) output from the programmer sketch upload:

/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega2560 -cusbasp -Pusb -Uflash:w:/var/folders/j0/h5xk48qx5jnfkltj14d1hvnw0000gn/T/build7227909872368675137.tmp/sketch_mar08a.cpp.hex:i 

avrdude: Version 6.0.1, compiled on Apr 14 2015 at 16:30:25
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/jmusther/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : usbasp
         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 : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

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: auto set sck period (because given equals null)
avrdude: reading input file "/var/folders/j0/h5xk48qx5jnfkltj14d1hvnw0000gn/T/build7227909872368675137.tmp/sketch_mar08a.cpp.hex"
avrdude: writing flash (1518 bytes):

Writing | ################################################## | 100% 0.73s

avrdude: 1518 bytes of flash written
avrdude: verifying flash memory against /var/folders/j0/h5xk48qx5jnfkltj14d1hvnw0000gn/T/build7227909872368675137.tmp/sketch_mar08a.cpp.hex:
avrdude: load data flash data from input file /var/folders/j0/h5xk48qx5jnfkltj14d1hvnw0000gn/T/build7227909872368675137.tmp/sketch_mar08a.cpp.hex:
avrdude: input file /var/folders/j0/h5xk48qx5jnfkltj14d1hvnw0000gn/T/build7227909872368675137.tmp/sketch_mar08a.cpp.hex contains 1518 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.40s

avrdude: verifying ...
avrdude: 1518 bytes of flash verified

avrdude done.  Thank you.

unfortunately programmers based on the "official" firmware will not do chips with >128k properly. some solutions can be found here: USBasp Update Warning - Microcontrollers - Arduino Forum. one can change the fuse to load applications but must change it back for the serial bootloader. there is also a problem programming new/raw avrs. i find using the $2 chinese usbasp with proper firmware a better solution.

jmusther:
I tried to program an Arduino Mega (2560), and couldn't get it to work. So I've tried a few things, and it turns out that I can successfully upload the bootloader, and can then use its onboard USB-serial for uploading a sample sketch (blink). This works fine, but if I try to upload the sketch directly with the programmer, the upload seems to work, but the blink sketch doesn't do anything (digital pin doesn't change).

PeterVH explains in this very recent other post that you need to set the high fuse to D9 when want to load a user sketch via a programmer. The default fuse D8 runs a bootloader, D9 runs the user program.

http://forum.arduino.cc/index.php?topic=384243.0

Thanks very much for the link!

A full explanation of the issue I believe is below from another thread that I responded to.

With the issues with the Mega2560 that I have discovered when using it with the USBasp ICSP programmer I thought I would try to make several other people’s lives easier but putting the full facts out there. Feel free to correct me if I have things wrong in the summary below.

This issue with the Mega 2560 and the USBasp programmer connected to the ICSP port has got unfortunately three facets to it which I will go over below.

BACKGROUND
The first is that the Mega 2560 with 256KB is the only AVR micro-controller that I am aware of in common use that exceeds the 128KB program size (flash). Most other micro-controllers are in the program size (flash) range of 8-32KB.

ISSUE 1 – NEW ISSUE CAUSED BY LARGE FLASH SIZE OF MEGA 2560
The first issue relates to the operation of the ICSP port on the Mega2560 (not the ICSP port for the 8U2 or 16U2 micro-controller for USB<->Serial comms). The issue here is that the ICSP protocol uses two functions to set the address:

  1. The Load Program Memory Page (LPMP) which takes a 16 bit address (ie. 0x0000 – 0xFFFF).

  2. The Load Extended Address Byte (LEAB) which deals with addresses that exceed what 1) can handle. This sets the part of the address higher than the 16 bits allowed in LPMP.

For most processors the LEAB is not needed as the address fits within the LPMP range. The address of 0xFFFF corresponds to the 64KB boundary but because this is a WORD address (not BYTE address) the actual memory range LPMP handles is therefore 128KB. A byte is 8bits and a word is 16bits.

TAKEHOME MESSAGE:
The take home message is that the Mega 2560 needs to use the Load Extended Address Byte (LEAB) function to access all of memory correctly. Any programmer using the ICSP interface MUST implement the LEAB function correctly. This will not be an issue for any other AVR micro-controller that has less than 128KB of flash, eeprom etc. Most other micro-controllers do not have more than 128KB of program space (flash).

ISSUE 2 – THOMAS FISCHL FIRMWARE ISSUE
While there are several USBasp programmers made from different companies they largely operate off firmware from Thomas Fischl who looks to be a German chap. The second problem comes to a head with firmware V1.04 (usually dated as being 28 May 2011 version). This firmware purports to support Mega2560 extended address space but has a bug that causes another set of issues.

In summary the issues are:

a) PART A OF ISSUE 2 (HFUSE IS 0xD8)
If the hfuse of Mega2560 is set to 0xD8 then it will be possible to program the second half of the flash address space (corresponds to byte addresses from 0x20000 to 0x3FFFF). The fuse setting for the Mega2560 typically has the bootloader located at word address 0x1F000. This corresponds to byte address 0x3E000. This means the normal fuse setting of hfuse=0xD8 allows the bootloader to be burnt to flash. In fact it will also burn the bootloader at address 0x1E000 as well but it will never get run from there. This burning at 0x1E000 is pointless but is an issue related to not handling the 0x3 part of the address correctly.

b) PART B OF ISSUE 2 (HFUSE IS 0xD9)
The other scenario you get is if the hfuse is set to 0xD9. This will not execute the bootloader but instead immediately executes the users application. When this fuse is set it will be possible to correctly program the lower address space (bottom 128KB) but the top 128KB will just be a copy of the lower address space - the users program will be loaded a second time at an address that will not be used – like the situation with PART A ISSUE 2. The users program will basically be loaded at address 0x00000 and will also be loaded at 0x20000 (start of second 128KB of flash).
A related issue here is that I purchased my USBasp from Jaycar in 2018 and despite being well after the V1.04 firmware creation date in 2011 it still had V1.02 on it. Even though I upgraded it to the latest version (V1.04) the bug I have just documented here as issue 2 then raised its head.

TAKEHOME MESSAGE:
So even if you do the upgrade to USBasp V1.04 from Thomas Fischl you are stuffed if you are wanting to load both the bootloader AND your application into flash – or make a complete copy of flash in the Mega2560. In my case I wanted to make a full backup of the Mega2560 and that was also not possible. The file that is created has had no errors flagged in the process but it will not work if you use it to reload your Mega2560 and you want the bootloader AND your sketch (application) loaded back again.
The command to dump what is in flash should be (from cmd prompt):

avrdude -p m2560 -c usbasp -C -Uflash:r:flashbackup:r

but if written back to flash with hfuse = 0xD8 the bootloader will be there but not your application (sketch):
avrdude -p m2560 -c usbasp -C -Uflash:w:flashbackup:r
You need to download a version of the firmware which properly works with the Mega2560 and this one appears to do just this:

ISSUE 3 – USING AVRDUDE WITH -p wiring HAS TIMEOUT ISSUES
The last issue is that I thought given the Arduino IDE uses the wiring interface to program the sketches into the Arduino, and this works, could I bypass the USBasp programmer and just use the AtMega16U2 USB to Serial chip to do what I want. After all this is how the Arduino IDE uploads my sketches.

The answer is no – well not in terminal mode. When using avrdude to connect to the Mega2560 I ran it from a cmd prompt as follows:
avrdude -p m2560 -c wiring -C -B 19200 -P COM4 -t

With my limited understanding I would have thought this would have worked. Unfortunately reading the fuses was only partially successful and reading flash or eeprom was always unsuccessful:

in avrdude:
avrdude> dump flash 0 300 - FAILS
avrdude> dump eeprom 0 300 – FAILS
avrdude> dump hfuse or dump efuse etc – PARTIALLY SUCCESSFUL

When the -t switch is used with wiring because it talks via the Mega16U2 chip there is a timeout built into the firmware on this chip that largely makes using this method hopeless. It will timeout before the user generally enters too many commands.
You can use to wiring interface to dump the flash out:
avrdude -p m2560 -c wiring -C -B 19200 -P COM4 -Uflash:r:flashbackup.bin:r
because there is no delay waiting for the user to enter the command but unless you know about this timeout preventing -t (interactive terminal mode) from working you are stuffed again.

TAKEHOME MESSAGE:
The wiring interface which is what the Arduino IDE defaults to will work with the Mega2560 but unless you avoid terminal mode your mileage will vary. For the beginner in AVR & Arduino there are limitations which preclude the use of terminal mode as a second option to doing basic things like dumping flash or eeprom when using the USBasp programmer. Your output will show all 0x00’s which is crap. You will also get the occasional stk500_v2 error. When the USBasp programmer is connected instead the avrdude terminal mode there is no timeout issue.

Overall a painful learning experience and one that I hope may help you.