From 104dcf60527422ab3323fb77780376e872e03bee Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Tue, 26 Jul 2022 11:30:53 +0200
Subject: [PATCH 1/2] Add new jtagmkii_updi programmer type option in order to
 resolve issue #1037

---
 src/avrdude.conf.in |  2 +-
 src/jtagmkII.c      | 37 +++++++++++++++++++++++++++++++++++--
 src/jtagmkII.h      |  2 ++
 src/pgm_type.c      |  1 +
 4 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index 1728497f..92c578e8 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -1734,7 +1734,7 @@ programmer
 programmer
   id    = "jtag2updi";
   desc  = "JTAGv2 to UPDI bridge";
-  type  = "jtagmkii_pdi";
+  type  = "jtagmkii_updi";
   connection_type = serial;
   baudrate = 115200;
 ;
diff --git a/src/jtagmkII.c b/src/jtagmkII.c
index b1024b53..675c9540 100644
--- a/src/jtagmkII.c
+++ b/src/jtagmkII.c
@@ -1306,9 +1306,9 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
   const char *ifname;
 
   /* Abort and print error if programmer does not support the target microcontroller */
-  if ((strncmp(ldata(lfirst(pgm->id)), "jtag2updi", strlen("jtag2updi")) == 0 && p->flags & AVRPART_HAS_PDI) ||
+  if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && p->flags & AVRPART_HAS_PDI) ||
       (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && p->flags & AVRPART_HAS_UPDI)) {
-    avrdude_message(MSG_INFO, "Error: programmer %s does not support target %s\n\n",
+    avrdude_message(MSG_INFO, "ERROR: programmer %s does not support target %s\n\n",
 	  ldata(lfirst(pgm->id)), p->desc);
     return -1;
   }
@@ -3929,6 +3929,39 @@ void jtagmkII_pdi_initpgm(PROGRAMMER * pgm)
   pgm->flag           = PGM_FL_IS_PDI;
 }
 
+const char jtagmkII_updi_desc[] = "Atmel JTAG ICE mkII in UPDI mode";
+
+void jtagmkII_updi_initpgm(PROGRAMMER * pgm)
+{
+  strcpy(pgm->type, "JTAGMKII_UPDI");
+
+  /*
+   * mandatory functions
+   */
+  pgm->initialize     = jtagmkII_initialize;
+  pgm->display        = jtagmkII_display;
+  pgm->enable         = jtagmkII_enable;
+  pgm->disable        = jtagmkII_disable;
+  pgm->program_enable = jtagmkII_program_enable_INFO;
+  pgm->chip_erase     = jtagmkII_chip_erase;
+  pgm->open           = jtagmkII_open_pdi;
+  pgm->close          = jtagmkII_close;
+  pgm->read_byte      = jtagmkII_read_byte;
+  pgm->write_byte     = jtagmkII_write_byte;
+
+  /*
+   * optional functions
+   */
+  pgm->paged_write    = jtagmkII_paged_write;
+  pgm->paged_load     = jtagmkII_paged_load;
+  pgm->page_erase     = jtagmkII_page_erase;
+  pgm->print_parms    = jtagmkII_print_parms;
+  pgm->setup          = jtagmkII_setup;
+  pgm->teardown       = jtagmkII_teardown;
+  pgm->page_size      = 256;
+  pgm->flag           = PGM_FL_IS_PDI;
+}
+
 const char jtagmkII_dragon_desc[] = "Atmel AVR Dragon in JTAG mode";
 
 void jtagmkII_dragon_initpgm(PROGRAMMER * pgm)
diff --git a/src/jtagmkII.h b/src/jtagmkII.h
index aa79c18d..34004d6d 100644
--- a/src/jtagmkII.h
+++ b/src/jtagmkII.h
@@ -36,6 +36,7 @@ extern const char jtagmkII_desc[];
 extern const char jtagmkII_avr32_desc[];
 extern const char jtagmkII_dw_desc[];
 extern const char jtagmkII_pdi_desc[];
+extern const char jtagmkII_updi_desc[];
 extern const char jtagmkII_dragon_desc[];
 extern const char jtagmkII_dragon_dw_desc[];
 extern const char jtagmkII_dragon_pdi_desc[];
@@ -43,6 +44,7 @@ void jtagmkII_initpgm (PROGRAMMER * pgm);
 void jtagmkII_avr32_initpgm (PROGRAMMER * pgm);
 void jtagmkII_dw_initpgm (PROGRAMMER * pgm);
 void jtagmkII_pdi_initpgm (PROGRAMMER * pgm);
+void jtagmkII_updi_initpgm (PROGRAMMER * pgm);
 void jtagmkII_dragon_initpgm (PROGRAMMER * pgm);
 void jtagmkII_dragon_dw_initpgm (PROGRAMMER * pgm);
 void jtagmkII_dragon_pdi_initpgm (PROGRAMMER * pgm);
diff --git a/src/pgm_type.c b/src/pgm_type.c
index 8afb50bd..82320fab 100644
--- a/src/pgm_type.c
+++ b/src/pgm_type.c
@@ -80,6 +80,7 @@ const PROGRAMMER_TYPE programmers_types[] = {
         {"jtagmkii_dw", jtagmkII_dw_initpgm, jtagmkII_dw_desc},
         {"jtagmkii_isp", stk500v2_jtagmkII_initpgm, stk500v2_jtagmkII_desc},
         {"jtagmkii_pdi", jtagmkII_pdi_initpgm, jtagmkII_pdi_desc},
+        {"jtagmkii_updi", jtagmkII_updi_initpgm, jtagmkII_updi_desc},
         {"jtagice3", jtag3_initpgm, jtag3_desc},
         {"jtagice3_pdi", jtag3_pdi_initpgm, jtag3_pdi_desc},
         {"jtagice3_updi", jtag3_updi_initpgm, jtag3_updi_desc},

From de124bfd9b3b4a002b71bf73574d412c0c9bb573 Mon Sep 17 00:00:00 2001
From: MCUdude <hansibull@gmail.com>
Date: Fri, 29 Jul 2022 12:48:53 +0200
Subject: [PATCH 2/2] Improve error detection logic

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

diff --git a/src/jtagmkII.c b/src/jtagmkII.c
index 675c9540..7181d186 100644
--- a/src/jtagmkII.c
+++ b/src/jtagmkII.c
@@ -1306,7 +1306,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
   const char *ifname;
 
   /* Abort and print error if programmer does not support the target microcontroller */
-  if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && p->flags & AVRPART_HAS_PDI) ||
+  if ((strncmp(pgm->type, "JTAGMKII_UPDI", strlen("JTAGMKII_UPDI")) == 0 && !(p->flags & AVRPART_HAS_UPDI)) ||
       (strncmp(ldata(lfirst(pgm->id)), "jtagmkII", strlen("jtagmkII")) == 0 && p->flags & AVRPART_HAS_UPDI)) {
     avrdude_message(MSG_INFO, "ERROR: programmer %s does not support target %s\n\n",
 	  ldata(lfirst(pgm->id)), p->desc);