From da0f0105bbc4bec415b62e1dce06da657cb39f54 Mon Sep 17 00:00:00 2001
From: joerg_wunsch <joerg_wunsch@81a1dc3b-b13d-400b-aceb-764788c761c2>
Date: Mon, 24 Mar 2008 21:22:04 +0000
Subject: [PATCH] Add support for the -x devcode option, and document it.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@769 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog        |   6 +++
 NEWS             |   4 ++
 avr910.c         | 103 ++++++++++++++++++++++++++++++++++-------------
 avrdude.1        |  20 ++++++++-
 doc/avrdude.texi |  25 +++++++++---
 5 files changed, 123 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 14122db3..aaa33d80 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-03-24  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	* avr910.c: Add support for the -x devcode option.
+	* avrdude.1: Document -x devcode for avr910.
+	* doc/avrdude.texi: (Ditto.)
+
 2008-03-14  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	Add initial support for the Atmel STK600, for
diff --git a/NEWS b/NEWS
index 7367baee..d30be3a5 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@ Current:
   * Add support for the Atmel STK600 for "classic" AVRs (AT90, ATtiny,
     ATmega), using either ISP or high-voltage programming modes.
 
+  * Add support for the -x devcode extended parameter to the avr910
+    programmer, to allow overriding the device code sent to the
+    programmer.
+
 Version 5.5:
 
   * Add support for the USBtinyISP programmer (patch #6233)
diff --git a/avr910.c b/avr910.c
index 1c15895c..d7bcec33 100644
--- a/avr910.c
+++ b/avr910.c
@@ -47,6 +47,7 @@
 struct pdata
 {
   char has_auto_incr_addr;
+  unsigned char devcode;
 };
 
 #define PDATA(pgm) ((struct pdata *)(pgm->cookie))
@@ -193,42 +194,48 @@ static int avr910_initialize(PROGRAMMER * pgm, AVRPART * p)
   if (PDATA(pgm)->has_auto_incr_addr == 'Y')
       fprintf(stderr, "Programmer supports auto addr increment.\n");
 
-  /* Get list of devices that the programmer supports. */
+  if (PDATA(pgm)->devcode == 0) {
 
-  avr910_send(pgm, "t", 1);
-  fprintf(stderr, "\nProgrammer supports the following devices:\n");
-  devtype_1st = 0;
-  while (1) {
-    avr910_recv(pgm, &c, 1);
-    if (devtype_1st == 0)
-      devtype_1st = c;
-    if (c == 0)
-      break;
-    part = locate_part_by_avr910_devcode(part_list, c);
+    /* Get list of devices that the programmer supports. */
 
-    fprintf(stderr, "    Device code: 0x%02x = %s\n", c, part ?  part->desc : "(unknown)");
+    avr910_send(pgm, "t", 1);
+    fprintf(stderr, "\nProgrammer supports the following devices:\n");
+    devtype_1st = 0;
+    while (1) {
+      avr910_recv(pgm, &c, 1);
+      if (devtype_1st == 0)
+	devtype_1st = c;
+      if (c == 0)
+	break;
+      part = locate_part_by_avr910_devcode(part_list, c);
 
-    /* FIXME: Need to lookup devcode and report the device. */
+      fprintf(stderr, "    Device code: 0x%02x = %s\n", c, part ?  part->desc : "(unknown)");
 
-    if (p->avr910_devcode == c)
-      dev_supported = 1;
-  };
-  fprintf(stderr,"\n");
+      /* FIXME: Need to lookup devcode and report the device. */
 
-  if (!dev_supported) {
-    fprintf(stderr,
-            "%s: %s: selected device is not supported by programmer: %s\n",
-            progname, ovsigck? "warning": "error", p->id);
-    if (!ovsigck)
-      exit(1);
+      if (p->avr910_devcode == c)
+	dev_supported = 1;
+    };
+    fprintf(stderr,"\n");
+
+    if (!dev_supported) {
+      fprintf(stderr,
+	      "%s: %s: selected device is not supported by programmer: %s\n",
+	      progname, ovsigck? "warning": "error", p->id);
+      if (!ovsigck)
+	exit(1);
+    }
+    /* If the user forced the selection, use the first device
+       type that is supported by the programmer. */
+    buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
+  } else {
+    /* devcode overridden by -x devcode= option */
+    buf[1] = (char)(PDATA(pgm)->devcode);
   }
 
-  /* Tell the programmer which part we selected.
-     If the user forced the selection, use the first device
-     type that is supported by the programmer. */
-
+  /* Tell the programmer which part we selected. */
   buf[0] = 'T';
-  buf[1] = ovsigck? devtype_1st: p->avr910_devcode;
+  /* buf[1] has been set up above */
 
   avr910_send(pgm, buf, 2);
   avr910_vfy_cmd_sent(pgm, "select device");
@@ -284,6 +291,45 @@ static int avr910_cmd(PROGRAMMER * pgm, unsigned char cmd[4],
 }
 
 
+static int avr910_parseextparms(PROGRAMMER * pgm, LISTID extparms)
+{
+  LNODEID ln;
+  const char *extended_param;
+  int rv = 0;
+
+  for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
+    extended_param = ldata(ln);
+
+    if (strncmp(extended_param, "devcode=", strlen("devcode=")) == 0) {
+      int devcode;
+      if (sscanf(extended_param, "devcode=%i", &devcode) != 1 ||
+	  devcode <= 0 || devcode > 255) {
+        fprintf(stderr,
+                "%s: avr910_parseextparms(): invalid devcode '%s'\n",
+                progname, extended_param);
+        rv = -1;
+        continue;
+      }
+      if (verbose >= 2) {
+        fprintf(stderr,
+                "%s: avr910_parseextparms(): devcode overwritten as 0x%02x\n",
+                progname, devcode);
+      }
+      PDATA(pgm)->devcode = devcode;
+
+      continue;
+    }
+
+    fprintf(stderr,
+            "%s: avr910_parseextparms(): invalid extended parameter '%s'\n",
+            progname, extended_param);
+    rv = -1;
+  }
+
+  return rv;
+}
+
+
 static int avr910_open(PROGRAMMER * pgm, char * port)
 {
   /*
@@ -634,6 +680,7 @@ void avr910_initpgm(PROGRAMMER * pgm)
 
   pgm->read_sig_bytes = avr910_read_sig_bytes;
 
+  pgm->parseextparams = avr910_parseextparms;
   pgm->setup          = avr910_setup;
   pgm->teardown       = avr910_teardown;
 }
diff --git a/avrdude.1 b/avrdude.1
index 0ecad037..9db8b896 100644
--- a/avrdude.1
+++ b/avrdude.1
@@ -19,7 +19,7 @@
 .\"
 .\" $Id$
 .\"
-.Dd DATE March 14, 2008
+.Dd DATE March 24, 2008
 .Os
 .Dt AVRDUDE 1
 .Sh NAME
@@ -666,7 +666,7 @@ Set the target's supply voltage to
 .Ar voltage
 Volts.
 .Em Only supported on the STK500 and STK600 programmer.
-.It Ar varef Op channel Ar voltage
+.It Ar varef Oo Ar channel Oc Ar voltage
 Set the adjustable voltage source to
 .Ar voltage
 Volts.
@@ -780,6 +780,22 @@ bits after the target AVR, respectively.
 Each AVR unit within the chain shifts by 4 bits.
 Other JTAG units might require a different bit shift count.
 .El
+.It Ar AVR910
+.Bl -tag -offset indent -width indent
+.It Ar devcode=VALUE
+Override the device code selection by using
+.Ar VALUE
+as the device code.
+The programmer is not queried for the list of supported
+device codes, and the specified
+.Ar VALUE
+is not verified but used directly within the
+.Ql T
+command sent to the programmer.
+.Ar VALUE
+can be specified using the conventional number notation of the
+C programming language.
+.El
 .El
 .Sh FILES
 .Bl -tag -offset indent -width /dev/ppi0XXX
diff --git a/doc/avrdude.texi b/doc/avrdude.texi
index 2b8de588..026d98c4 100644
--- a/doc/avrdude.texi
+++ b/doc/avrdude.texi
@@ -802,7 +802,7 @@ should not be used.
 When using the JTAG ICE mkII or AVR Dragon in JTAG mode, the
 following extended parameter is accepted:
 @table @code
-@item @var{jtagchain=UB,UA,BB,BA}
+@item @samp{jtagchain=UB,UA,BB,BA}
 Setup the JTAG scan chain for @var{UB} units before, @var{UA} units
 after, @var{BB} bits before, and @var{BA} bits after the target AVR,
 respectively.
@@ -810,6 +810,21 @@ Each AVR unit within the chain shifts by 4 bits.
 Other JTAG units might require a different bit shift count.
 @end table
 
+@item AVR910
+
+The AVR910 programmer type accepts the following extended parameter:
+@table @code
+@item @samp{devcode=VALUE}
+Override the device code selection by using @var{VALUE}
+as the device code.
+The programmer is not queried for the list of supported
+device codes, and the specified @var{VALUE}
+is not verified but used directly within the
+@code{T} command sent to the programmer.
+@var{VALUE} can be specified using the conventional number notation of the
+C programming language.
+@end table
+
 @end table
 
 @page
@@ -1060,7 +1075,7 @@ and STK600 programmer:
 @item vtarg @var{voltage}
 Set the target's supply voltage to @var{voltage} Volts.
 
-@item varef @var{[channel]} @var{voltage}
+@item varef [@var{channel}] @var{voltage}
 Set the adjustable voltage source to @var{voltage} Volts.
 This voltage is normally used to drive the target's
 @emph{Aref} input on the STK500 and STK600.
@@ -1068,10 +1083,10 @@ The STK600 offers two reference voltages, which can be
 selected by the optional parameter @var{channel} (either
 0 or 1).
 
-@item fosc @var{freq}[@var{M}|@var{k}]
+@item fosc @var{freq}[@code{M}|@code{k}]
 Set the master oscillator to @var{freq} Hz.
-An optional trailing letter @var{M}
-multiplies by 1E6, a trailing letter @var{k} by 1E3.
+An optional trailing letter @code{M}
+multiplies by 1E6, a trailing letter @code{k} by 1E3.
 
 @item fosc off
 Turn the master oscillator off.