From 1f7b134420893097cb294c8814f1baab92574457 Mon Sep 17 00:00:00 2001
From: joerg_wunsch <joerg_wunsch@81a1dc3b-b13d-400b-aceb-764788c761c2>
Date: Mon, 3 Dec 2012 21:03:06 +0000
Subject: [PATCH] * jtag3.c: Make jtag3_command() public * jtag3.h: (Dito.) *
 jtag3_private.h: Add two new commands * stk500v2.c: Implement the "MonCon
 disable" hack that allows temporarily falling back to ISP when trying to talk
 to a part that has debugWIRE enabled

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1123 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog       |  9 +++++++++
 jtag3.c         |  7 ++-----
 jtag3.h         |  2 ++
 jtag3_private.h |  2 ++
 stk500v2.c      | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index dfaa1c5f..21b1fce6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-12-03  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* jtag3.c: Make jtag3_command() public
+	* jtag3.h: (Dito.)
+	* jtag3_private.h: Add two new commands
+	* stk500v2.c: Implement the "MonCon disable" hack that
+	allows temporarily falling back to ISP when trying to
+	talk to a part that has debugWIRE enabled
+
 2012-12-03  Rene Liebscher <R.Liebscher@gmx.de>
 
 	* pickit2.c: reordered #includes for non-usb configuration
diff --git a/jtag3.c b/jtag3.c
index 8a8ead86..21c313a7 100644
--- a/jtag3.c
+++ b/jtag3.c
@@ -98,9 +98,6 @@ struct pdata
 
 static int jtag3_open(PROGRAMMER * pgm, char * port);
 
-static int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
-			 unsigned char **resp, const char *descr);
-
 static int jtag3_initialize(PROGRAMMER * pgm, AVRPART * p);
 static int jtag3_chip_erase(PROGRAMMER * pgm, AVRPART * p);
 static int jtag3_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
@@ -530,8 +527,8 @@ int jtag3_recv(PROGRAMMER * pgm, unsigned char **msg) {
   }
 }
 
-static int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
-			 unsigned char **resp, const char *descr)
+ int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+		   unsigned char **resp, const char *descr)
 {
   int status;
   unsigned char c;
diff --git a/jtag3.h b/jtag3.h
index c7ba1656..fba0d81e 100644
--- a/jtag3.h
+++ b/jtag3.h
@@ -35,6 +35,8 @@ int  jtag3_getparm(PROGRAMMER * pgm, unsigned char scope,
 int jtag3_setparm(PROGRAMMER * pgm, unsigned char scope,
 		  unsigned char section, unsigned char parm,
 		  unsigned char *value, unsigned char length);
+int jtag3_command(PROGRAMMER *pgm, unsigned char *cmd, unsigned int cmdlen,
+		  unsigned char **resp, const char *descr);
 extern const char jtag3_desc[];
 extern const char jtag3_dw_desc[];
 extern const char jtag3_pdi_desc[];
diff --git a/jtag3_private.h b/jtag3_private.h
index bd094688..27e8681a 100644
--- a/jtag3_private.h
+++ b/jtag3_private.h
@@ -109,6 +109,8 @@
 #define CMD3_GET_PARAMETER         0x02
 #define CMD3_SIGN_ON               0x10
 #define CMD3_SIGN_OFF              0x11 /* takes one parameter? */
+#define CMD3_START_DW_DEBUG        0x13
+#define CMD3_MONCON_DISABLE        0x17
 
 /* AVR ISP scope: no commands of its own */
 
diff --git a/stk500v2.c b/stk500v2.c
index 3ff84079..0edf8c9a 100644
--- a/stk500v2.c
+++ b/stk500v2.c
@@ -1150,6 +1150,52 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
         }
         break;
 
+    case PGMTYPE_JTAGICE3:
+        if (buf[1] == STATUS_CMD_FAILED &&
+            (p->flags & AVRPART_HAS_DW) != 0) {
+            void *mycookie;
+            unsigned char cmd[4], *resp;
+
+            /* Try debugWIRE, and MONCON_DISABLE */
+            if (verbose >= 2)
+                fprintf(stderr,
+                        "%s: No response in ISP mode, trying debugWIRE\n",
+                        progname);
+
+            mycookie = pgm->cookie;
+            pgm->cookie = PDATA(pgm)->chained_pdata;
+
+            cmd[0] = PARM3_CONN_DW;
+            if (jtag3_setparm(pgm, SCOPE_AVR, 1, PARM3_CONNECTION, cmd, 1) < 0) {
+                pgm->cookie = mycookie;
+                break;
+            }
+
+            cmd[0] = SCOPE_AVR;
+
+            cmd[1] = CMD3_SIGN_ON;
+            cmd[2] = cmd[3] = 0;
+            if (jtag3_command(pgm, cmd, 4, &resp, "AVR sign-on") >= 0) {
+                free(resp);
+
+                cmd[1] = CMD3_START_DW_DEBUG;
+                if (jtag3_command(pgm, cmd, 4, &resp, "start DW debug") >= 0) {
+                    free(resp);
+
+                    cmd[1] = CMD3_MONCON_DISABLE;
+                    if (jtag3_command(pgm, cmd, 3, &resp, "MonCon disable") >= 0)
+                        free(resp);
+
+                    fprintf(stderr,
+                            "%s: Target prepared for ISP, signed off.\n"
+                            "%s: Please restart %s without power-cycling the target.\n",
+                            progname, progname, progname);
+                }
+            }
+            pgm->cookie = mycookie;
+        }
+        break;
+
     default:
         /* cannot report anything for other pgmtypes */
         break;