From 80ca8a644edd01f3dbfe38a3d34da8f726c0fe08 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Sat, 24 Sep 2022 22:48:14 +0200
Subject: [PATCH 1/6] Add support for Flip 2 reset on exit This makes it
 possible for the application to start immedeatly after the program has been
 loaded. Simply use '-E reset' or '-E noreset'. Default is no reset. Closes
 #733

---
 src/flip2.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/flip2.c b/src/flip2.c
index 2925030c..bef5be94 100644
--- a/src/flip2.c
+++ b/src/flip2.c
@@ -131,6 +131,7 @@ static void flip2_disable(const PROGRAMMER *pgm);
 static void flip2_display(const PROGRAMMER *pgm, const char *prefix);
 static int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part);
 static int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part);
+static int flip2_start_app(const PROGRAMMER *pgm);
 static int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value);
 static int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
@@ -140,6 +141,7 @@ static int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AV
 static int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned int page_size, unsigned int addr, unsigned int n_bytes);
 static int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem);
+static int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s);
 static void flip2_setup(PROGRAMMER * pgm);
 static void flip2_teardown(PROGRAMMER * pgm);
 
@@ -187,6 +189,7 @@ void flip2_initpgm(PROGRAMMER *pgm) {
   pgm->read_byte        = flip2_read_byte;
   pgm->write_byte       = flip2_write_byte;
   pgm->read_sig_bytes   = flip2_read_sig_bytes;
+  pgm->parseexitspecs   = flip2_parseexitspecs;
   pgm->setup            = flip2_setup;
   pgm->teardown         = flip2_teardown;
 }
@@ -315,6 +318,9 @@ flip2_initialize_fail:
 void flip2_close(PROGRAMMER* pgm)
 {
   if (FLIP2(pgm)->dfu != NULL) {
+    if (pgm->exit_reset == EXIT_RESET_ENABLED)
+      flip2_start_app(pgm);
+
     dfu_close(FLIP2(pgm)->dfu);
     FLIP2(pgm)->dfu = NULL;
   }
@@ -375,6 +381,22 @@ int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
   return cmd_result;
 }
 
+int flip2_start_app(const PROGRAMMER *pgm) {
+  avrdude_message(MSG_INFO, "%s: Starting application\n", progname);
+
+  struct flip2_cmd cmd = {
+    FLIP2_CMD_GROUP_EXEC, FLIP2_CMD_START_APP, { 0x00, 0, 0, 0 }
+  };
+
+  // queue command
+  int cmd_result = dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
+
+  // repeat dnload to actually execute
+  dfu_dnload(FLIP2(pgm)->dfu, &cmd, sizeof(cmd));
+
+  return cmd_result;
+}
+
 int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
   unsigned long addr, unsigned char *value)
 {
@@ -489,6 +511,20 @@ int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *
   return (result == 0) ? n_bytes : -1;
 }
 
+
+// Parse the -E option flag
+int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s) {
+  if (strcmp(s, "reset") == 0) {
+    pgm->exit_reset = EXIT_RESET_ENABLED;
+  } else if (strcmp(s, "noreset") == 0) {
+    pgm->exit_reset = EXIT_RESET_DISABLED;
+  } else {
+    return -1;
+  }
+
+  return 0;
+}
+
 int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
   if (FLIP2(pgm)->dfu == NULL)
     return -1;

From e1a317c6704f21433329673bf1f6b12397d03ea7 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Tue, 27 Sep 2022 19:21:29 +0200
Subject: [PATCH 2/6] Remove Flip 2 stub functions Used when compiling without
 libusb. Print reasonable error instead

---
 src/flip2.c | 80 ++++++-----------------------------------------------
 1 file changed, 8 insertions(+), 72 deletions(-)

diff --git a/src/flip2.c b/src/flip2.c
index bef5be94..25963661 100644
--- a/src/flip2.c
+++ b/src/flip2.c
@@ -168,10 +168,6 @@ static const char * flip2_status_str(const struct dfu_status *status);
 static const char * flip2_mem_unit_str(enum flip2_mem_unit mem_unit);
 static enum flip2_mem_unit flip2_mem_unit(const char *name);
 
-#endif /* HAVE_LIBUSB */
-
-/* THE INITPGM FUNCTION DEFINITIONS */
-
 void flip2_initpgm(PROGRAMMER *pgm) {
   strcpy(pgm->type, "flip2");
 
@@ -194,7 +190,6 @@ void flip2_initpgm(PROGRAMMER *pgm) {
   pgm->teardown         = flip2_teardown;
 }
 
-#ifdef HAVE_LIBUSB
 /* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
 
 int flip2_open(PROGRAMMER *pgm, const char *port_spec) {
@@ -941,76 +936,17 @@ enum flip2_mem_unit flip2_mem_unit(const char *name) {
   return FLIP2_MEM_UNIT_UNKNOWN;
 }
 
-#else /* HAVE_LIBUSB */
+#else /* !HAVE_LIBUSB */
 
-/* EXPORTED PROGRAMMER FUNCTION DEFINITIONS */
-
-int flip2_open(PROGRAMMER *pgm, const char *port_spec) {
-  fprintf(stderr, "%s: Error: No USB support in this compile of avrdude\n",
-    progname);
-  return -1;
+ // Give a proper error if we were not compiled with libusb
+static int flip2_nousb_open(PROGRAMMER* pgm, const char* name) {
+    avrdude_message(MSG_INFO, "%s: error: No usb support. Please compile again with libusb installed.\n", progname);
+    return -1;
 }
 
-int flip2_initialize(const PROGRAMMER *pgm, const AVRPART *part) {
-  return -1;
+void flip2_initpgm(PROGRAMMER *pgm) {
+    strcpy(pgm->type, "flip2");
+    pgm->open = flip2_nousb_open;
 }
 
-void flip2_close(PROGRAMMER* pgm)
-{
-}
-
-void flip2_enable(PROGRAMMER *pgm, const AVRPART *p) {
-}
-
-void flip2_disable(const PROGRAMMER *pgm) {
-}
-
-void flip2_display(const PROGRAMMER *pgm, const char *prefix) {
-}
-
-int flip2_program_enable(const PROGRAMMER *pgm, const AVRPART *part) {
-  return -1;
-}
-
-int flip2_chip_erase(const PROGRAMMER *pgm, const AVRPART *part) {
-  return -1;
-}
-
-int flip2_read_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
-  unsigned long addr, unsigned char *value)
-{
-  return -1;
-}
-
-int flip2_write_byte(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
-  unsigned long addr, unsigned char value)
-{
-  return -1;
-}
-
-int flip2_paged_load(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
-  unsigned int page_size, unsigned int addr, unsigned int n_bytes)
-{
-  return -1;
-}
-
-int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem,
-  unsigned int page_size, unsigned int addr, unsigned int n_bytes)
-{
-  return -1;
-}
-
-int flip2_read_sig_bytes(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *mem) {
-  return -1;
-}
-
-void flip2_setup(PROGRAMMER * pgm)
-{
-}
-
-void flip2_teardown(PROGRAMMER * pgm)
-{
-}
-
-
 #endif /* HAVE_LIBUSB */

From 521155c1c2eaa37eddf2a956b26aeebf2c258af8 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Fri, 30 Sep 2022 20:03:04 +0200
Subject: [PATCH 3/6] Improve punctuation in error message

---
 src/flip2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/flip2.c b/src/flip2.c
index 25963661..5e74dfe9 100644
--- a/src/flip2.c
+++ b/src/flip2.c
@@ -940,7 +940,7 @@ enum flip2_mem_unit flip2_mem_unit(const char *name) {
 
  // Give a proper error if we were not compiled with libusb
 static int flip2_nousb_open(PROGRAMMER* pgm, const char* name) {
-    avrdude_message(MSG_INFO, "%s: error: No usb support. Please compile again with libusb installed.\n", progname);
+    avrdude_message(MSG_INFO, "%s: error, no USB support; please compile with libusb installed\n", progname);
     return -1;
 }
 

From 01ccab08b4ae8eafe9ee96990b5a2e69c1e394e6 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Fri, 30 Sep 2022 20:16:16 +0200
Subject: [PATCH 4/6] Improve exitspecs (-E) parsing Use the same
 implementation as linuxspi does, instead of the one suggested in #733

---
 src/flip2.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/flip2.c b/src/flip2.c
index 5e74dfe9..40c4cc54 100644
--- a/src/flip2.c
+++ b/src/flip2.c
@@ -506,17 +506,26 @@ int flip2_paged_write(const PROGRAMMER *pgm, const AVRPART *part, const AVRMEM *
   return (result == 0) ? n_bytes : -1;
 }
 
-
 // Parse the -E option flag
-int flip2_parseexitspecs(PROGRAMMER* pgm, const char *s) {
-  if (strcmp(s, "reset") == 0) {
-    pgm->exit_reset = EXIT_RESET_ENABLED;
-  } else if (strcmp(s, "noreset") == 0) {
-    pgm->exit_reset = EXIT_RESET_DISABLED;
-  } else {
+int flip2_parseexitspecs(PROGRAMMER *pgm, const char *sp) {
+  char *cp, *s, *str = cfg_strdup("flip2_parseextitspecs()", sp);
+
+  s = str;
+  while ((cp = strtok(s, ","))) {
+    s = NULL;
+    if (!strcmp(cp, "reset")) {
+      pgm->exit_reset = EXIT_RESET_ENABLED;
+      continue;
+    }
+    if (!strcmp(cp, "noreset")) {
+      pgm->exit_reset = EXIT_RESET_DISABLED;
+      continue;
+    }
+    free(str);
     return -1;
   }
 
+  free(str);
   return 0;
 }
 

From ef209fe44e8f02cf74db33a455436cd0d2eed5ea Mon Sep 17 00:00:00 2001
From: Marius Greuel <greuelm@mgtek.com>
Date: Thu, 29 Sep 2022 22:02:04 +0200
Subject: [PATCH 5/6] GitHub Actions: Update apt index before installing
 packages

---
 .github/workflows/build.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index dbb7a0cf..916b7f1a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -37,6 +37,8 @@ jobs:
       - uses: actions/checkout@v2
       - name: Install prerequisites
         run: >-
+          sudo apt-get update
+
           sudo apt-get install -y
           build-essential
           cmake
@@ -95,6 +97,8 @@ jobs:
           apt-get update
       - name: Install prerequisites
         run: >-
+          apt-get update
+
           apt-get install -y
           git
           cmake
@@ -145,6 +149,8 @@ jobs:
       - uses: actions/checkout@v2
       - name: Install prerequisites
         run: >-
+          brew update
+
           brew install
           cmake
           flex

From 419fd35b7244ab72cd536aaeaedd67d62e3d89c0 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Sat, 1 Oct 2022 22:11:46 +0200
Subject: [PATCH 6/6] Mention linuxspi and flip2 programmers  in the -E
 exitspecs section. linuxspi and flip2 supports "-E reset" and "-E noreset".

---
 src/avrdude.1        | 6 ++++++
 src/doc/avrdude.texi | 8 ++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/avrdude.1 b/src/avrdude.1
index a9b5b812..deb50a1a 100644
--- a/src/avrdude.1
+++ b/src/avrdude.1
@@ -462,11 +462,17 @@ MCU type, a previous invocation of
 .Nm
 with this option specified is one of the possible ways to guarantee this
 condition.
+.Em reset
+is supported by the linuxspi and flip2 programmer options, as well as all
+parallel port based programmers.
 .It Ar noreset
 The
 .Ql /RESET
 line will be deactivated at program exit, thus allowing the MCU target
 program to run while the programming hardware remains connected.
+.Em noreset
+is supported by the linuxspi and flip2 programmer options, as well as all
+parallel port based programmers.
 .It Ar vcc
 This option will leave those parallel port pins active
 .Pq \&i. \&e. Em high
diff --git a/src/doc/avrdude.texi b/src/doc/avrdude.texi
index 8644768c..bcf03cd0 100644
--- a/src/doc/avrdude.texi
+++ b/src/doc/avrdude.texi
@@ -556,12 +556,16 @@ Note in particular that the programming algorithm for the AT90S1200
 device mandates that the `/RESET' signal is active before powering up
 the MCU, so in case an external power supply is used for this MCU type,
 a previous invocation of AVRDUDE with this option specified is one of
-the possible ways to guarantee this condition.
+the possible ways to guarantee this condition. @code{reset} is supported
+by the @code{linuxspi} and @code{flip2} programmer options, as well as
+all parallel port based programmers.
 
 @item noreset
 The `/RESET' line will be deactivated at program exit, thus allowing the
 MCU target program to run while the programming hardware remains
-connected.
+connected. @code{noreset} is supported by the @code{linuxspi} and
+@code{flip2} programmer options, as well as all parallel port based
+programmers.
 
 @item vcc
 This option will leave those parallel port pins active (i. e. high) that