[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  Electronics
. -> [Folder]  Microprocessors
. . -> [Subject]  Solving problems with uploading programs to your Arduino
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Solving problems with uploading programs to your Arduino

Postings by administrators only.

[Refresh] Refresh page


Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Mon 14 May 2012 10:09 AM (UTC)

Amended on Sat 19 May 2012 07:23 AM (UTC) by Nick Gammon

Message
When I first started using the Arduino I didn't know or care about the fuses. I read a few warnings about not playing with them "or else".

Now after working at some length on uploading bootloaders I feel a bit more qualified to offer some advice, about what to do if you can't upload things.

First ... an important message:

Three ways you can program your device



  1. Using a "high-voltage" programmer.
  2. Using ICSP (In Circuit Serial Programming) via the SPI interface
  3. Using a bootloader, generally taking instructions from the serial ports.


High voltage programming


This method always works, even if you have completely stuffed up your fuses. However you require a special programmer, like the AVR Dragon:



It's a bit fiddly to use because you have to "jumper" together lots of pins depending on the device you want to program:



A lot of people won't have one of these, however it's nice to know there is a fallback position of you mess around too much with the fuses.

"High voltage" refers to the fact that it involves placing around 12V on the Reset pin, more than you usually would. Another name for it is "Parallel Programming Mode".


ICSP programming


The next thing is to use ICSP programming by plugging a cable into the ICSP "header" (pins) on your Arduino. This header is usually labelled ICSP, like this:



The ICSP header should have a dot indicating pin 1, like this:



Typically the red line on the cable you plug in should align to the dot (be on the same side).

The ICSP header basically gives a convenient connection to the SPI pins:


  1. MISO
  2. +5V
  3. SCK
  4. MOSI
  5. /Reset
  6. Gnd


Strictly speaking Reset isn't an SPI pin, but the processor needs to have Reset pulled low in order to enter programming mode.

Providing SPI programming is enabled in the fuses, you can use the ICSP method to program the chip, even if there is no bootloader there (which is how you put the bootloader there in the first place).

In order to send the correct signals to the processor a device must be plugged into the ISCP header which is capable of "talking" the SPI protocol, such as the USBtinyISP:



Or the AVRISP:



You can even use another Arduino to do the programming, like this:




Using the bootloader


The bootloader is a small program permanently loaded into the "high" portion of the processor's flash memory. If present, and correctly configured, it can be used to load code into the rest of the flash memory, without needing to plug a special device into the ICSP header.



This is the simplest method because you are just using the serial port (via the USB interface of the Arduino board). What the bootloader does, upon being reset, is to take control, check if there is serial data present on the serial interface that conforms to the serial programming protocol, and if so, acknowledge it, and go into programming mode, erasing the existing program in the low part of flash memory, and then replacing it.




... so, what could possibly go wrong, you ask?

No clock


The first important fuse is the clock source:



Example from Atmega328P

If that is set to use a crystal (external clock) and one is not present, then the processor will not "tick over" and won't accept programming instructions from either the ICSP interface or the bootloader.

This is most likely to happen on a "bare bones" or "breadboard" circuit, if you have not provided an external clock, but the fuse is set to expect one.

Solution

Temporarily at least, connect up a crystal and a couple of 20 pF capacitors, like in this photo:



(22 pF capacitors shown in photo)

With the crystal there, the processor will tick over, and you can then program it. You might reconfigure it to no longer need the crystal.

Alternatively, if you have a spare board lying around, upload this sketch to it:


// For Atmega328

void setup ()
  {
  // set up 8 MHz timer on pin 9
  pinMode (9, OUTPUT); 
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaling
  OCR1A =  0;       // output every cycle
  }
  
void loop () {}


That will output an 8 MHz clock to pin 9, so you could connect pin 9 (and Gnd) from the board running the "clock" sketch to the board requiring a clock signal. Plug the clock line into the XTAL1 pin.

If you have an ATtiny85 lying around this version works for that chip:


// For ATtiny85

void setup ()
  {
  // set up 4 MHz timer on pin 3 (D4)
  pinMode (4, OUTPUT); 
  // set up Timer 1
  TCCR1 = _BV (CTC1) | _BV(CS10);  // CTC mode, no prescaler
  GTCCR = _BV (COM1B0);    // toggle OC1B on Compare Match
  TCNT1 = 0;  // set back to start
  OCR1C = 0;  // what to compare to for CTC mode
  }
  
void loop () {}


That outputs 4 MHz if your ATtiny85 is running at 8 MHz.

Clock too slow


If you have set the "divide by 8 fuse", or set the clock source to be the 128 KHz internal clock, the clock may be running too slowly for ICSP programming.

Solution

If that is the case you can tell avrdude to use a slower clock speed, like this:


avrdude -c usbtiny -p m328p -U lfuse:w:0xFF:m -B250


The -B250 part says to use a slower clock speed. In this case we are setting the fuses back to use a crystal.

Clock wrong speed


This probably won't affect ICSP programming that much, unless the clock is very slow, but even a small amount out will affect the bootloader. This is because the bootloader uses serial communications, and if the clock is wrong, the serial data will look like garbage. This is because the baud rate for serial communications is derived from the clock speed. So if the clock is 8 MHz when the bootloader expected a 16 MHz clock, the baud rate will be out by a factor of 2.

Solution


  • Reconfigure the clock if possible using an ICSP programmer. For example, if you have the "divide by 8" fuse set, unset it.

  • Ensure that the clock rate in the boards.txt file agrees with the speed the board is operating at.

  • Possibly replace the crystal with one of the expected speed (eg. replace an 8 MHz crystal with a 16 MHz one).

  • Upload the correct bootloader, which is configured for the clock speed you are actually using.



Other fuse settings




Example from Atmega328P

SPI enable


Another possible problem is if "SPI Enable" is turned off:

If so, then you can't use ICSP programming until it is turned back on, and the only way to do that is with the High Voltage (Parallel) programming.

Symptoms: You cannot use ICSP programming.

Solution: Fix the fuse with a high-voltage programmer like the AVR Dragon.

Bootloader size


For chips that support bootloaders (the larger ones, basically) then there are 5 possible booting (reset) addresses. For example, with the Atmega328:


  1. No bootloader: start at address 0x0000
  2. Small bootloader (512 bytes): start at address 0x7E00
  3. Larger bootloader (1024 bytes): start at address 0x7C00
  4. Even larger bootloader (2048 bytes): start at address 0x7800
  5. Largest bootloader (4096 bytes): start at address 0x7000


Note that each bootloader is twice as large as the previous one. Larger bootloaders can do more, but leave less room for your program.

The fuses BOOTSZ1 and BOOTSZ2 tell the processor where to start executing the bootloader. It is important that the fuses agree with the size of the bootloader, otherwise it will either start executing before the start of the bootloader, or in the middle of it.

Symptoms: Bootloader is installed but does not do anything.

Solution: Check that the bootloader start address (from the bootloader .hex file) corresponds to the fuse setting for the bootloader size.

Bootloader enabled


If you have no bootloader, then the BOOTRST fuse should be 1 (that is, not set). In that case, the processor will immediately execute the program loaded at address 0, and the bootloader will not be active.

However if you do have a bootloader, and the BOOTRST fuse is 1, then the bootloader will not be executed, because you have told it to not do so.

Symptoms: Bootloader is installed but does not do anything.

Solution: Check that the BOOTRST flag is programmed (that is, it should be 0).


Reset disabled


If the fuse RSTDISBL is programmed (0) then you cannot reset the processor (apart from powering it off). Since the bootloader starts at reset, and the IDE tries to reset the processor when it needs to upload a sketch, the upload will fail because the processor does not reset.

Symptoms: Bootloader is installed but does not do anything.

Solution: Check that the RSTDISBL flag is not programmed (that is, it should be 1).


Use the correct bootloader


Quite a few bootloader files ship with the Arduino. Each has been compiled for specific purposes:


  • A certain processor (so that it knows what hardware instructions access the serial port, for example). This is the "build.mcu" field in the boards.txt file.

  • A certain "protocol". The larger boards need a different protocol (stk500v2) because that protocol handles higher memory addresses. This is the "upload.protocol" field in the boards.txt file.

  • A certain baud rate. That is, the rate at which the programming program sends data to the bootloader. This is the "upload.speed" parameter in the boards.txt file.

  • A certain clock speed. This is so that various things like the delay() function, and serial communications, work as intended. This is the "build.f_cpu" field in the boards.txt file.

  • A certain memory size. That is, the bootloader is intended to be loaded at a specific address in memory, not some other address. This is the "upload.maximum_size" field in the boards.txt file. (The bootloader starts at this address).

  • Certain fuses to be set (as mentioned above).

  • Information about the sort of board ... this will affect which pin it thinks D3 is, for example.



If you have the wrong bootloader, all sorts of things could go wrong. It might not work at all, or upload at the wrong speed, or if it uploads, delays will be too slow or too fast.


Choose the right board in the IDE


There is a file "boards.txt" in the Arduino folder. It tells the IDE about the various sorts of boards you might have, and for each one, what protocol, baud rate, and bootloader to use. It is important to choose the correct board in the Tools -> Board menu, otherwise it might attempt to communicate with your (otherwise correct) bootloader at the wrong speed, or with the wrong protocol.



Of all the choices there, only one is likely to work. Also, if you alter the bootloader, the correct one might not be what it appears to be. For example if you put a Duemilanove bootloader on a Uno, you would need to choose the the "Arduino Duemilanove w/ Atmega328" option, even though it is a Uno board. Similarly if you put the Uno Optiboot loader on a Duemilanove you would need to choose "Arduino Uno".


How to find what your fuse settings are


avrdude

If you can get far enough to use avrdude, you can find the fuses with the "verify" option, after connecting up a ICSP programming board, like the ones listed earlier.

For example, using the "command line", type:


avrdude -c usbtiny -p m328p -v


And see (amongst other things):


         Using Port                    : unknown
         Using Programmer              : usbtiny
         AVR Part                      : ATMEGA328P
...
avrdude: Device signature = 0x1e950f
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DE
avrdude: safemode: efuse reads as 5


Board-detector sketch

Or you can use another Uno loaded with the "board detector" sketch I wrote, and described here:

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

(See that page for how to connect the two boards together).

That will show you something like this:


Atmega chip detector.
Entered programming mode OK.
Signature = 1E 95 0F 
Processor = ATmega328P
Flash memory size = 32768
LFuse = FF 
HFuse = DE 
EFuse = FD 
Lock byte = CF 
Bootloader in use: Yes
EEPROM preserved through erase: No
Watchdog timer always on: No
Bootloader is 512 bytes starting at 7E00


AVR Studio

You can also use the AVR Dragon (or similar device) and fire up AVR Studio (available from the Atmel site).

What do the fuses mean, exactly?


Data sheet

The best source of reference is the processor datasheet. Download that from the Atmel web site. For example, the one for the Atmega328 is (currently) at:

http://atmel.com/dyn/resources/prod_documents/8271S.pdf

Fuse calculator

A helpful web-based fuse calculator is here:

http://www.engbedded.com/fusecalc

Select the correct processor, and then you can type in the hex codes for the fuses and see what they mean. Type in hex values:



A "user friendly" explanation is given here:



And the individual bit settings shown below:




What are the default fuse settings?


Located somewhere in your Arduino IDE installation directory is a file "boards.txt" that lists the boards it understands. There may also be additional files in the "hardware" folder inside your sketches folder. This will show things like this:


uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard


So we can see here the the Uno expects the fuses (low) 0xFF, (high) 0xDE and (extended) 0x05.

Or more accurately, if you upload the bootloader file "optiboot_atmega328.hex" then this bootloader will expect those fuse settings.


How to change fuses


You can use AVR Studio if you have that installed. Otherwise you can use avrdude which will be part of the IDE installation. For example, assuming you have connected up your board via the USBtinyISP device:


avrdude -c usbtiny -p m328p -U lfuse:w:0xFF:m


This example changes (w) the lfuse (low fuse) to 0xFF (the "m" means value given right here on the command line). You can modify this example to use hfuse (high fuse) or efuse (extended fuse).

You can also use the "bootloader programmer" sketch I describe here:

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

As part of uploading the bootloader it fixes up the fuses to match.

You can also just use the IDE to "Burn Bootloader" which will upload a new bootloader, and fix up the fuses to match what is in the boards.txt file.

The "board uploader" sketch now also can be used to program fuses:

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

Example session:


--------- 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:

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 


Warning: Hopefully I have made it clear above, that if you set a fuse wrongly, you can "brick" your processor, at least unless you have a high-voltage programming board handy, in order to recover from doing things like turning off ICSP programming.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


31,006 views.

Postings by administrators only.

[Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]