0
\$\begingroup\$

I have a circuit using an ATmega32U4 and am using the Arduino Leonardo/Micro Caterina bootloader (the one that comes with arduinoIDE v1.8.13). The problem I am having is on power-up (via USB connection) the AVR enters bootloader mode instead of application mode. I checked the MCUSR register (by replacing the bootloader) and the EXTRF bit is being set on power-up. I tried replacing the capacitor in the reset circuit shown with a 100nF cap, but no change. I then tried simply removing the capacitor, and it then powers up to start the application as it should.

On closer examination of various Arduino schematics show that the UNO (using the Atmega328) has a similar 100nF cap from reset to ground, but the Leonardo and Micro do not have a capacitor from reset to ground. Furthermore, this Atmel app note specifies an optional 100nF cap from reset to ground.

I do not understand why this cap is causing this problem. I suspect its presence is causing enough delay on power-up so that the reset pin fails to reach sufficient voltage before the EXTRF bit gets set due to it being low. However, the spec sheet does not mention such a timing interval. I am not sure, but I suspect it is particular to the AVR chips providing an USB interface.

Any insights or suggestions? I do not believe removing the capacitor is a problem, and seems to be the correct thing to do, but I want to make sure I understand what is happening in order to be sure of the correct solution.

enter image description here

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

The source code for the Leonardo bootloader is available in the Arduino IDE folder, specifically a file called Catrina.c. In this we find the following code:

if (mcusr_state & (1<<EXTRF)) {
    // External reset -  we should continue to self-programming mode.
} else if (mcusr_state == (1<<PORF) && pgm_read_word(0) != 0xFFFF) {        
    // After a power-on reset skip the bootloader and jump straight to sketch 
    // if one exists.   
    StartSketch();
} else if ((mcusr_state == (1<<WDRF)) && (bootKeyPtrVal != bootKey) && (pgm_read_word(0) != 0xFFFF)) {  
    // If it looks like an "accidental" watchdog reset then start the sketch.
    StartSketch();
}

An external reset is used to enter the bootloader, whereas a power-on reset skips the bootloader and jumps straight to the user code.

With a large capacitor on the reset line, the reset signal will take longer to rise, which means that the MCU will have completed power-on reset timeout before the reset line has risen above its threshold. This triggers the EXTRF flag to be set, and so once out of reset, it will enter the bootloader.

By choosing a smaller resistor, or smaller capacitor, such that the rise time of the reset signal is reduced to be less than the power-on reset timeout, then the EXTRF flag will remain clear and the PORF flag will trigger bypassing of the bootloader.


A large capacitor on the reset line is not really necessary. It's purpose could be to avoid triggering spurious resets if the reset signal picks up noise, however a suitably strong pull-up resistor all but negates the need for this. Alternatively in this case it was likely there to "debounce" the push-button used on the reset signal, to avoid repeatedly resetting the processor very quickly.

I've personally never added a 100nF capacitor to the reset signal of an AVR.

\$\endgroup\$
1
\$\begingroup\$

It seems to me that a smaller cap RC time constant is necessary to prevent triggering the watch-dog timer, whatever that duration is vs the < T= 47 us trip duration. But then the clock takes time to startup too. Try RC <~ 10 us.

Also read http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_softreset

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.