From b1da0b09222d107f569238db387a51cc72b9f8ef Mon Sep 17 00:00:00 2001 From: Marius Greuel Date: Fri, 6 Jan 2023 19:38:48 +0100 Subject: [PATCH 1/3] Change Arduino auto-reset via RTS to allow direct RTS-reset connection --- src/arduino.c | 14 ++++++++------ src/stk500.c | 14 ++++++++++---- src/urclock.c | 16 ++++++++++------ 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/arduino.c b/src/arduino.c index 3f468294..f3e7f8d1 100644 --- a/src/arduino.c +++ b/src/arduino.c @@ -85,13 +85,16 @@ static int arduino_open(PROGRAMMER *pgm, const char *port) { return -1; } - /* Clear DTR and RTS to unload the RESET capacitor - * (for example in Arduino) */ + // This code assumes a negative-logic USB to TTL serial adapter + // Set RTS/DTR high to discharge the series-capacitor, if present serial_set_dtr_rts(&pgm->fd, 0); - usleep(250*1000); - /* Set DTR and RTS back to high */ + usleep(50 * 1000); + // Pull the RTS/DTR line low to reset AVR serial_set_dtr_rts(&pgm->fd, 1); - usleep(50*1000); + usleep(50 * 1000); + // Set the RTS/DTR line back to high + serial_set_dtr_rts(&pgm->fd, 0); + usleep(50 * 1000); /* * drain any extraneous input @@ -106,7 +109,6 @@ static int arduino_open(PROGRAMMER *pgm, const char *port) { static void arduino_close(PROGRAMMER * pgm) { - serial_set_dtr_rts(&pgm->fd, 0); serial_close(&pgm->fd); pgm->fd.ifd = -1; } diff --git a/src/stk500.c b/src/stk500.c index b7788a59..f6bf70e9 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -97,10 +97,16 @@ int stk500_getsync(const PROGRAMMER *pgm) { for (attempt = 0; attempt < max_sync_attempts; attempt++) { // Restart Arduino bootloader for every sync attempt if (strcmp(pgm->type, "Arduino") == 0 && attempt > 0) { - serial_set_dtr_rts(&pgm->fd, 0); // Set DTR and RTS low - usleep(250*1000); - serial_set_dtr_rts(&pgm->fd, 1); // Set DTR and RTS back to high - usleep(50*1000); + // This code assumes a negative-logic USB to TTL serial adapter + // Set RTS/DTR high to discharge the series-capacitor, if present + serial_set_dtr_rts(&pgm->fd, 0); + usleep(50 * 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 + serial_set_dtr_rts(&pgm->fd, 0); + usleep(50 * 1000); stk500_drain(pgm, 0); } diff --git a/src/urclock.c b/src/urclock.c index 1d613e6a..a15a37e7 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -2237,14 +2237,19 @@ static int urclock_open(PROGRAMMER *pgm, const char *port) { if(serial_open(port, pinfo, &pgm->fd) == -1) return -1; - // Clear DTR and RTS to unload the RESET capacitor + // This code assumes a negative-logic USB to TTL serial adapter + // Set RTS/DTR high to discharge the series-capacitor, if present serial_set_dtr_rts(&pgm->fd, 0); - usleep(20*1000); // 20 ms is ample for dis/charging the cap from reset to DTR/RTS - // Set DTR and RTS back to high + usleep(50 * 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 + serial_set_dtr_rts(&pgm->fd, 0); + usleep(50 * 1000); - if((120+ur.delay) > 0) - usleep((120+ur.delay)*1000); // Wait until board comes out of reset + if((70+ur.delay) > 0) + usleep((70+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) @@ -2256,7 +2261,6 @@ static int urclock_open(PROGRAMMER *pgm, const char *port) { static void urclock_close(PROGRAMMER *pgm) { - serial_set_dtr_rts(&pgm->fd, 0); serial_close(&pgm->fd); pgm->fd.ifd = -1; if(ur.bloptiversion) // Optiboot needs a pause between two successive avrdude calls From 2b04a2e4a79a2ed162dd951cfb30dfed496fae5f Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Wed, 15 Mar 2023 19:42:54 +0000 Subject: [PATCH 2/3] Update urclock/stk500 reset times and streamline DTR/RTS twiddling --- src/arduino.c | 8 +++++++- src/stk500.c | 8 ++------ src/urclock.c | 9 ++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/arduino.c b/src/arduino.c index f3e7f8d1..3ca83615 100644 --- a/src/arduino.c +++ b/src/arduino.c @@ -88,7 +88,13 @@ static int arduino_open(PROGRAMMER *pgm, const char *port) { // This code assumes a negative-logic USB to TTL serial adapter // Set RTS/DTR high to discharge the series-capacitor, if present serial_set_dtr_rts(&pgm->fd, 0); - usleep(50 * 1000); + /* + * Long wait needed for optiboot: otherwise the second of two bootloader + * calls in quick succession fails: + * + * avrdude -c arduino -qqp m328p -U x.hex; avrdude -c arduino -qqp m328p -U x.hex + */ + usleep(250 * 1000); // Pull the RTS/DTR line low to reset AVR serial_set_dtr_rts(&pgm->fd, 1); usleep(50 * 1000); diff --git a/src/stk500.c b/src/stk500.c index f6bf70e9..71c35069 100644 --- a/src/stk500.c +++ b/src/stk500.c @@ -98,15 +98,11 @@ int stk500_getsync(const PROGRAMMER *pgm) { // Restart Arduino bootloader for every sync attempt if (strcmp(pgm->type, "Arduino") == 0 && attempt > 0) { // This code assumes a negative-logic USB to TTL serial adapter - // Set RTS/DTR high to discharge the series-capacitor, if present - serial_set_dtr_rts(&pgm->fd, 0); - usleep(50 * 1000); - // Pull the RTS/DTR line low to reset AVR + // 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(50 * 1000); + usleep(20*1000); // Set the RTS/DTR line back to high serial_set_dtr_rts(&pgm->fd, 0); - usleep(50 * 1000); stk500_drain(pgm, 0); } diff --git a/src/urclock.c b/src/urclock.c index a15a37e7..b728be7f 100644 --- a/src/urclock.c +++ b/src/urclock.c @@ -2240,16 +2240,15 @@ static int urclock_open(PROGRAMMER *pgm, const char *port) { // This code assumes a negative-logic USB to TTL serial adapter // Set RTS/DTR high to discharge the series-capacitor, if present serial_set_dtr_rts(&pgm->fd, 0); - usleep(50 * 1000); + usleep(20*1000); // Pull the RTS/DTR line low to reset AVR serial_set_dtr_rts(&pgm->fd, 1); - usleep(50 * 1000); + usleep(20*1000); // Set the RTS/DTR line back to high serial_set_dtr_rts(&pgm->fd, 0); - usleep(50 * 1000); - if((70+ur.delay) > 0) - usleep((70+ur.delay)*1000); // Wait until board comes out of reset + if((100+ur.delay) > 0) + usleep((100+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) From 7e94ed4442b35e7dadf176f729459c8205bc0d62 Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Sun, 19 Mar 2023 19:25:55 +0000 Subject: [PATCH 3/3] Change wiring auto-reset to allow direct DTR/RTS-reset connection --- src/wiring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wiring.c b/src/wiring.c index a0d3cf66..78309c18 100644 --- a/src/wiring.c +++ b/src/wiring.c @@ -175,6 +175,9 @@ static int wiring_open(PROGRAMMER *pgm, const char *port) { serial_set_dtr_rts(&pgm->fd, 1); usleep(50*1000); + + /* Set high, so a direct connection to reset works. */ + serial_set_dtr_rts(&pgm->fd, 0); } /* drain any extraneous input */ @@ -188,7 +191,6 @@ static int wiring_open(PROGRAMMER *pgm, const char *port) { static void wiring_close(PROGRAMMER * pgm) { - serial_set_dtr_rts(&pgm->fd, 0); serial_close(&pgm->fd); pgm->fd.ifd = -1; }