From 5a6a357c8fc35f77fce5c752b8b482c34b25ca15 Mon Sep 17 00:00:00 2001
From: joerg_wunsch <joerg_wunsch@81a1dc3b-b13d-400b-aceb-764788c761c2>
Date: Tue, 16 Aug 2011 18:15:19 +0000
Subject: [PATCH] bug #29636: AVRDude issues invalid
 CMD_CHECK_TARGET_CONNECTION on the AVRISP-MKII * stk500v2.c
 (stk500v2_program_enable): Rewrite the logic to explain ISP activation
 failures. * stk500v2_private.h: Fix the various STATUS_* constants; AVR069
 and AVR079 disagreed in their values, even though they are apparently
 implementing the same logic behind.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@972 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog          |  10 +++++
 stk500v2.c         | 105 ++++++++++++++++++++++-----------------------
 stk500v2_private.h |   4 +-
 3 files changed, 63 insertions(+), 56 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 237f39a9..c9f41979 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2011-08-16  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	bug #29636: AVRDude issues invalid CMD_CHECK_TARGET_CONNECTION
+	on the AVRISP-MKII
+	* stk500v2.c (stk500v2_program_enable): Rewrite the logic to
+	explain ISP activation failures.
+	* stk500v2_private.h: Fix the various STATUS_* constants;
+	AVR069 and AVR079 disagreed in their values, even though they
+	are apparently implementing the same logic behind.
+
 2011-08-16  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	bug #29650: Programming timeouts in ATmega128RFA1 are too slow
diff --git a/stk500v2.c b/stk500v2.c
index fca8f7aa..5da77e33 100644
--- a/stk500v2.c
+++ b/stk500v2.c
@@ -973,24 +973,46 @@ static struct
   { STATUS_CONN_FAIL_SCK, "SCK fail" },
   { STATUS_TGT_NOT_DETECTED, "Target not detected" },
   { STATUS_TGT_REVERSE_INSERTED, "Target reverse inserted" },
-  { STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_RST,
-    "MOSI and RST fail" },
-  { STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_RST | STATUS_CONN_FAIL_SCK,
-    "MOSI, RST, and SCK fail" },
-  { STATUS_CONN_FAIL_RST | STATUS_CONN_FAIL_SCK,
-    "RST and SCK fail" },
-  { STATUS_CONN_FAIL_MOSI | STATUS_CONN_FAIL_SCK,
-    "MOSI and SCK fail" },
 };
 
+/*
+ * Max length of returned message is the sum of all the description
+ * strings in the table above, plus 2 characters for separation.
+ * Currently, this is 76 chars.
+ */
+static void
+stk500v2_translate_conn_status(unsigned char status, char *msg)
+{
+    size_t i;
+    int need_comma;
+
+    *msg = 0;
+    need_comma = 0;
+
+    for (i = 0;
+         i < sizeof connection_status / sizeof connection_status[0];
+         i++)
+    {
+        if ((status & connection_status[i].state) != 0)
+        {
+            if (need_comma)
+                strcat(msg, ", ");
+            strcat(msg, connection_status[i].description);
+            need_comma = 1;
+        }
+    }
+    if (*msg == 0)
+        sprintf(msg, "Unknown status 0x%02x", status);
+}
+
+
 /*
  * issue the 'program enable' command to the AVR device
  */
 static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
 {
   unsigned char buf[16];
-  size_t i;
-  const char *msg;
+  char msg[100];             /* see remarks above about size needed */
   int rv;
 
   PDATA(pgm)->lastpart = p;
@@ -1006,31 +1028,6 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
       /* Activate AVR-style (low active) RESET */
       stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
 
-  if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
-    buf[0] = CMD_CHECK_TARGET_CONNECTION;
-    if (stk500v2_command(pgm, buf, 1, sizeof(buf)) < 0) {
-      fprintf(stderr, "%s: stk500v2_program_enable(): cannot get connection status\n",
-            progname);
-      return -1;
-    }
-    if (buf[2] != STATUS_ISP_READY) {
-      msg = "Unknown";
-
-      for (i = 0;
-           i < sizeof connection_status / sizeof connection_status[0];
-           i++)
-        if (connection_status[i].state == (unsigned)buf[2]) {
-          msg = connection_status[i].description;
-          break;
-        }
-
-      fprintf(stderr, "%s: stk500v2_program_enable():"
-              " bad STK600 connection status: %s (0x%02x)\n",
-            progname, msg, buf[2]);
-      return -1;
-    }
-  }
-
   buf[0] = CMD_ENTER_PROGMODE_ISP;
   buf[1] = p->timeout;
   buf[2] = p->stabdelay;
@@ -1045,26 +1042,26 @@ static int stk500v2_program_enable(PROGRAMMER * pgm, AVRPART * p)
   rv = stk500v2_command(pgm, buf, 12, sizeof(buf));
 
   if (rv < 0) {
-    buf[0] = CMD_CHECK_TARGET_CONNECTION;
-    if (stk500v2_command(pgm, buf, 1, sizeof(buf)) < 0) {
-      fprintf(stderr, "%s: stk500v2_program_enable(): cannot get connection status\n",
-            progname);
-      return -1;
+    switch (PDATA(pgm)->pgmtype)
+    {
+    case PGMTYPE_STK600:
+    case PGMTYPE_AVRISP_MKII:
+        if (stk500v2_getparm(pgm, PARAM_STATUS_TGT_CONN, &buf[0]) != 0) {
+            fprintf(stderr,
+                    "%s: stk500v2_program_enable(): cannot get connection status\n",
+                    progname);
+        } else {
+            stk500v2_translate_conn_status(buf[0], msg);
+            fprintf(stderr, "%s: stk500v2_program_enable():"
+                    " bad AVRISPmkII connection status: %s\n",
+                    progname, msg);
+        }
+        break;
+
+    default:
+        /* cannot report anything for other pgmtypes */
+        break;
     }
-
-    msg = "Unknown";
-
-    for (i = 0;
-	 i < sizeof connection_status / sizeof connection_status[0];
-	 i++)
-      if (connection_status[i].state == (unsigned)buf[2]) {
-	msg = connection_status[i].description;
-	break;
-      }
-
-    fprintf(stderr, "%s: stk500v2_program_enable():"
-	    " bad STK600 connection status: %s (0x%02x)\n",
-            progname, msg, buf[2]);
   }
 
   return rv;
diff --git a/stk500v2_private.h b/stk500v2_private.h
index d0079801..2f3cd2af 100644
--- a/stk500v2_private.h
+++ b/stk500v2_private.h
@@ -137,11 +137,11 @@
 #define STATUS_CMD_ILLEGAL_PARAMETER        0xCA
 
 // Status
+#define STATUS_ISP_READY                    0x00
 #define STATUS_CONN_FAIL_MOSI               0x01
 #define STATUS_CONN_FAIL_RST                0x02
 #define STATUS_CONN_FAIL_SCK                0x04
-#define STATUS_TGT_NOT_DETECTED             0x00
-#define STATUS_ISP_READY                    0x10
+#define STATUS_TGT_NOT_DETECTED             0x10
 #define STATUS_TGT_REVERSE_INSERTED         0x20
 
 // hw_status