Is a reset needed to program an Atmega328p with an Arduino bootloader?

TL;DR Given a standalone Atmega328p with bootloader, does the FTDI chip need to be wired to the Atmega's reset? If so what connection(s) need to be made?

I will start with a little bit of context for everyone. I have been trying to learn the roles of the components that come together to make the Arduino boards work. I thought that a good way to do with would be to build a standalone arduino.

I am looking into how the USB-to-serial chip (whether it be a dedicated FTDI chip or the Atmega 16u2) on the Arduino boards interacts with the primary microcontroller for programming purposes.

I started with the Arduino to breadboard tutorial and noticed that programming requires the target board to have a reset connection to the programming board. This seems to make sense as the Arduino will reset during normal programming (I am assuming because the bootloader will check for a programming command on startup)

However, in the Arduino Standalone Tutorial I noticed that their FTDI breakout had no connection to the target reset pin. I am assuming this is either an oversight or one is expected to manually reset the target chip right before attempting to program it?

Would I be able to "automatically" reset the target chip by simply connecting the FTDI "CTS" pin to the reset pin on the target chip? Or is it more complicated than that?

Any explanation would be great, I am trying to wrap my head around how the micro controller acts in boot-up and programming. I studied the Arduino Uno schematics so I feel like I have an idea of how the reset signal works (there is a CTS connection to the reset pin) but I am still a little confused.

No, you must connect the dtr pin to reset though a 0.1uf cap to get auto reset. Otherwise you need to push reset button at just the right time (very small window of the bootloader was designed to use auto reset) between compiling and uploading.

The bootloader runs upon reset - if the BOOTRST fuse is set, the BOOTSZ fuses are uses to determine where in memory the bootloader starts, and jump there to run the bootloader. The boot loader then jumps to the reset vector (address 0) to start the user program.

So to enter the bootloader, you need to pulse reset low briefly. How do you do that? The closest you have is aDTR line that goes low when serial communication is initiated... But it stays low, which would hold the chip in reset if connected directly - so you capacitively couple it to the reset pin. Dtr goes low, so the cap pulls reset low too... Then the pullup on reset charges the cap back up, chip leaves reset and the bootloader runs.

Phone sent, hence autocorrect.

Thank you for your reply, it was very helpful and clear! I assumed that the CTS pin was used because I saw so many FTDI breakout boards with that pin specifically brought out.

Out of curiosity, is there a common use for the CTS pin?

Nope (at least not in this context) - the FTDI pinout brings it out, but if you look at all the Arduino boards with that 6-pin FTDI header, CTS is connected to ground.

worth mentioning a 10k external resistor on the mcu side of that cap is helpful. although sometimes it works with only the internal pull-up, for 100% reliable boot on all chips this is highly recommended.

also note that hardware reset is not always required. its possible for user program to monitor an external event and jump to boot code for new program. i use this trick to allow loading a new file over wifi (esp8266) or rf (24l01).

john1993:
worth noting a 10k external resistor on the mcu side of that cap is helpful. although sometimes it works with only the internal pull-up, for 100% reliable boot on all chips this is highly recommended.

also true that hardware reset is not always required. its possible for user program to monitor an external event and jump to boot code for new program. i use this trick to allow loading a new file over wifi (esp8266) or rf (24l01).

Yeah, you could jump to the bootloader code from within application code - but since that doesn't reset the chip, you would need to make sure nothing had been configured such that it would break the bootloader.

afaik its almost impossible to leave traces that break bootloaders. not properly written ones anyway. im always more concerned with the bootloaders leaving crap that interferes with apps. things like failing to put uart pins back to default which has caused more than a few blinkies to fail.

Mellow_Mo:
Out of curiosity, is there a common use for the CTS pin?

RTS and CTS are used for hardware flow control, where they signal in each direction, whether the corresponding device is actually able to receive serial data.

This is relevant to the operation of modems where the voice channel link is the speed-limiting point. As the name implies, the original purpose of the FT232 chip is to implement an RS-232 serial port (requiring a MAX232 or similar lever interface chip) from a USB port, so the FTDI adapter provides the most basic connections. A MAX232 provides two interfaces in each direction, so combined with the FTDI adapter, could provide a minimal RS232 interface.

A USB-to-RS232 cable would commonly consist of an FT232 chip and possibly a MAX232 or preferably the variant of that chip which supplies all six handshake lines (RTS, CTS, DSR, DTR, DCD, RI).

its almost impossible to leave traces that break bootloaders. not properly written ones anyway.

If you merely jump to the bootloader, all bets are off. You'd have left an unknown number of interrupts still running, referencing memory structures that probably aren't there any more. Most bootloaders rely on the hardware reset; they don't have the space to go and reset every peripheral that might be interfering with their operation.

The 328p bootloaders NEED a reset. that reset does not need to come from the serial port; a manual reset will work fine, if it's timed correctly. The older bootloaders (atmegaboot) have an approx 10 second window, so they're pretty easy to get working with a manual reset. Optiboot (as on Uno) has a 1s timeout, so it's trickier.

IIRC, the AVRDude code has been modified to manipulate both RTS and DTR, so you CAN use auto-reset even with FTDI adapters that do not break out the DTR signal. (CTS is an input to the FTDI, and so is irrelevant.)

yes, thats why i used the phrase "properly written". disable interrupts (1 instruction). hard for non-zero io regs to interfere so absolutely not an issue with any of the several ive implemented. even so rarely more than a dozen or so bytes to take care of that. maybe a problem with opti. at least until its trimmed a bit which was not that hard for me to do (real men use asm :slight_smile: ).

westfw:
IIRC, the AVRDude code has been modified to manipulate both RTS and DTR, so you CAN use auto-reset even with FTDI adapters that do not break out the DTR signal. (CTS is an input to the FTDI, and so is irrelevant.)

The support for using RTS for Arduino auto-reset was added when the "arduino" protoco added to avrdudel.
The arduino prodotocol is basically the same as stk500 other than it toggles RTS up front.

Prior to the arduino protocol being added to avrdude, the IDE opened the serial port and toggled the RTS signal itself before running avrdude.
I'm not sure if the IDE is still doing this even though it would be unnecessary when using the "arduino" protocol - I haven't looked at the IDE code in a long time.

Some additional information:

The biggest difference in RTS vs DTR is that normally DTR is under control of the operating system vs the application.
By contrast while RTS is normally often used for h/w flow control, nearly all operating systems allow applications to manually control the RTS signal.
While some operating systems do allow an application to control the DTR output signal, the normal behavior is that the operating system controls the DTR signal and attempts set it to mimic what DTR should mean. Data Terminal Ready: "someone is capable of listing to the data signal". So the operating system will drop the DTR signal when the first open is done on the serial device by an application.
DTR remains low until the last application closes the serial device.

The original Arduino boards did not have auto reset and required manually pushing the reset button.

It was clear that to make downloading easier it would be great if the reset happened automatically.
Someone got the idea to use the DTR signal to autoreset the AVR.
But since the DTR signal was controlled by the OS and not by application (IDE or avrdude) and the DTR signal was a level signal vs a pulse, it could not be used directly.
To remedy that a capacitor was added in series between the DTR signal and the AVR reset signal.
This converts the DTR level signal to a pulse without any s/w interaction which is how auto-reset works when using the DTR signal. No s/w is involved for auto-reset when using the DTR signal.
Using DTR to auto-reset the Arduino was a h/w only solution to a s/w problem.

While this worked great, the original genuine FTDI cable didn't bring out DTR to the 6 pin connector.
That cable brought out RTS# and CTS# signals. RTS# being pin 6 or the green wire.
So to make auto-reset work on the FTDI cable, s/w had to be modified.
Unfortunately, the "quick fix" was to modify the IDE to toggle the RTS rather than add support for it to avrdude.

Several years later, the "arduino" protocol was added to avrdude. The "arduino" protocol is identical to the stk500 protocol other than it toggles the RTS signal for arduino autoreset.

So you can use either RTS or DTR for auto reset. The inline cap will work with either the level signal from DTR or the pulse signal from RTS.

One of the advantages of using RTS over DTR for auto-reset is that since RTS is not messed with by the operating system at serial port open time and can be controlled by application, the RTS signal does not cause an auto-reset when the serial port is opened by the application.
This can be useful as it can allow an application to open and close the serial port for communication with the Arduino board without causing and auto-reset.
This is not the case when using DTR, as DTR will always cause an auto-reset as soon as the serial port is opened by the application.

I really wish that Arduino would switch from using DTR to using RTS as that would allow some great new capabilities in the IDE.

  • The serial monitor could connect to the arduino without resetting it.
  • The serial monitor or IDE could have a [RESET] button to reset the board without having to close/re-open the serial port which can potentially miss serial output from the arduino board.

--- bill

ides for my stm32 and esp8266 (esplorer) have a button for manual control of dtr. this allows for user choice of auto or manual reset. i normally prefer auto reset on open com and its nice to be able to reset any other time w/o physically pushing buttons. too bad arduino and other environments dont have similar feature.