Skip to content

Commit

Permalink
Reduce DTR/RTS-low time for reset generation to 100 us
Browse files Browse the repository at this point in the history
Standard AVR reset circuits deploy a connection from the DTR/RTS line of a
USB-to-serial chip to the AVR via a small capacitor, see

  https://onlinedocs.microchip.com/pr/GUID-F626284A-58F0-4C25-A6F3-0EA5054F3E2B-en-US-6/index.html?GUID-B80B25FF-E9D7-4766-B562-DA197B8B938C

Setting DTR/RTS low once will issue a reset. Setting this signal high
again after a short time ensures that a direct connection DTR/RTS to reset
also works. The duration of pulling DTR/RTS low must be relatively short,
say RC/10, in order to avoid a reset spike above Vcc. If Vcc exceeds 5.5 V
then a full 2 Vcc reset spike can potentially trigger HV programming.

See also
 - avrdudes#1504 (comment)
 - avrdudes#1505 (comment)
  • Loading branch information
stefanrueger committed Sep 27, 2023
1 parent 35dcf68 commit aa2f451
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 16 deletions.
8 changes: 5 additions & 3 deletions src/arduino.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ static int arduino_open(PROGRAMMER *pgm, const char *port) {
usleep(250 * 1000);
// Pull the RTS/DTR line low to reset AVR
serial_set_dtr_rts(&pgm->fd, 1);
usleep(50 * 1000);
// Set the RTS/DTR line back to high
// Max 100 us: charging a cap longer creates a high reset spike above Vcc
usleep(100);
// Set the RTS/DTR line back to high, so direct connection to reset works
serial_set_dtr_rts(&pgm->fd, 0);
usleep(50 * 1000);

usleep(100 * 1000);

/*
* drain any extraneous input
Expand Down
4 changes: 2 additions & 2 deletions src/avrdude.1
Original file line number Diff line number Diff line change
Expand Up @@ -1666,7 +1666,7 @@ query on flash prepared with -xnometadata yields useful results.
.It Ar delay=<n>
Add a <n> ms delay after reset. This can be useful if a board takes a
particularly long time to exit from external reset. <n> can be negative,
in which case the default 100 ms delay after issuing reset will be
in which case the default 120 ms delay after issuing reset will be
shortened accordingly.
.It Ar strict
Urclock has a faster, but slightly different strategy than -c arduino to
Expand Down Expand Up @@ -1795,7 +1795,7 @@ is greater than 0.
Add a <n> milliseconds delay after resetting the part through toggling the
DTR/RTS lines. This can be useful if a board takes a particularly long
time to exit from external reset. <n> can be negative, in which case the
default 80 ms delay after issuing reset will be shortened accordingly.
default 100 ms delay after issuing reset will be shortened accordingly.
.It Ar help
Show help menu and exit.
.El
Expand Down
4 changes: 2 additions & 2 deletions src/doc/avrdude.texi
Original file line number Diff line number Diff line change
Expand Up @@ -1304,7 +1304,7 @@ yields useful results.
@item @samp{delay=<n>}
Add a <n> ms delay after reset. This can be useful if a board takes a
particularly long time to exit from external reset. <n> can be negative,
in which case the default 100 ms delay after issuing reset will be
in which case the default 120 ms delay after issuing reset will be
shortened accordingly.
@item @samp{strict}
Urclock has a faster, but slightly different strategy than -c arduino to
Expand Down Expand Up @@ -1447,7 +1447,7 @@ No toggling of DTR/RTS is performed if @var{snooze} > 0.
@item @samp{delay=<n>}
Add a <n> milliseconds delay after reset. This can be useful if a board
takes a particularly long time to exit from external reset. <n> can be
negative, in which case the default 80 ms delay after issuing reset will
negative, in which case the default 100 ms delay after issuing reset will
be shortened accordingly.
@item @samp{help}
Show help menu and exit.
Expand Down
6 changes: 4 additions & 2 deletions src/stk500.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ int stk500_getsync(const PROGRAMMER *pgm) {
// This code assumes a negative-logic USB to TTL serial adapter
// Pull the RTS/DTR line low to reset AVR: it is still high from open()/last attempt
serial_set_dtr_rts(&pgm->fd, 1);
usleep(20*1000);
// Set the RTS/DTR line back to high
// Max 100 us: charging a cap longer creates a high reset spike above Vcc
usleep(100);
// Set the RTS/DTR line back to high, so direct connection to reset works
serial_set_dtr_rts(&pgm->fd, 0);
usleep(20*1000);
stk500_drain(pgm, 0);
}

Expand Down
9 changes: 5 additions & 4 deletions src/urclock.c
Original file line number Diff line number Diff line change
Expand Up @@ -2220,12 +2220,13 @@ static int urclock_open(PROGRAMMER *pgm, const char *port) {
usleep(20*1000);
// Pull the RTS/DTR line low to reset AVR
serial_set_dtr_rts(&pgm->fd, 1);
usleep(20*1000);
// Set the RTS/DTR line back to high
// Max 100 us: charging a cap longer creates a high reset spike above Vcc
usleep(100);
// Set the RTS/DTR line back to high, so direct connection to reset works
serial_set_dtr_rts(&pgm->fd, 0);

if((100+ur.delay) > 0)
usleep((100+ur.delay)*1000); // Wait until board comes out of reset
if((120+ur.delay) > 0)
usleep((120+ur.delay)*1000); // Wait until board comes out of reset

pmsg_debug("%4ld ms: enter urclock_getsync()\n", avr_mstimestamp());
if(urclock_getsync(pgm) < 0)
Expand Down
7 changes: 4 additions & 3 deletions src/wiring.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,15 @@ static int wiring_open(PROGRAMMER *pgm, const char *port) {
// Pull the RTS/DTR line low to reset AVR
pmsg_notice2("wiring_open(): asserting DTR/RTS\n");
serial_set_dtr_rts(&pgm->fd, 1);
usleep(20*1000);

// Max 100 us: charging a cap longer creates a high reset spike above Vcc
usleep(100);
// Set the RTS/DTR line back to high, so direct connection to reset works
serial_set_dtr_rts(&pgm->fd, 0);

int delay = WIRINGPDATA(pgm)->delay;
if((80+delay) > 0)
usleep((80+delay)*1000); // Wait until board comes out of reset
if((100+delay) > 0)
usleep((100+delay)*1000); // Wait until board comes out of reset
}

// Drain any extraneous input
Expand Down

0 comments on commit aa2f451

Please sign in to comment.