From fa205ce214abe5ee589177d9a1439b014a098581 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Thu, 23 Nov 2006 07:07:06 +0000
Subject: [PATCH] Implement EEPROM access through debugWire.

* jtagmkII.c: Extend the jtagmkII_read_byte() and
jtagmkII_write_byte() methods to handle EEPROM through
debugWire.

* avrpart.h: Implement the "flash instruction" parameter.
* config_gram.y: (Ditto.)
* lexer.l: (Ditto.)
* avrdude.conf.in: (Ditto.)

* avrdude.1: Document the EEPROM access through dW.
* doc/avrdude.texi: (Ditto.)

* tools/get-dw-params.xsl: Extend to extract the flash
instruction field.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@693 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avrdude/ChangeLog               | 15 +++++++++
 avrdude/avrdude.1               |  4 +--
 avrdude/avrdude.conf.in         | 48 +++++++++++++++++++++++++++
 avrdude/avrpart.h               |  2 ++
 avrdude/config_gram.y           | 33 +++++++++++++++++++
 avrdude/doc/avrdude.texi        |  4 +--
 avrdude/jtagmkII.c              | 58 ++++++++++++++++++++-------------
 avrdude/lexer.l                 |  1 +
 avrdude/tools/get-dw-params.xsl | 11 ++++++-
 9 files changed, 148 insertions(+), 28 deletions(-)

diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index 04a271a5..4f1a1558 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,18 @@
+2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
+
+	Implement EEPROM access through debugWire.
+	* jtagmkII.c: Extend the jtagmkII_read_byte() and
+	jtagmkII_write_byte() methods to handle EEPROM through
+	debugWire.
+	* avrpart.h: Implement the "flash instruction" parameter.
+	* config_gram.y: (Ditto.)
+	* lexer.l: (Ditto.)
+	* avrdude.conf.in: (Ditto.)
+	* avrdude.1: Document the EEPROM access through dW.
+	* doc/avrdude.texi: (Ditto.)
+	* tools/get-dw-params.xsl: Extend to extract the flash
+	instruction field.
+
 2006-11-23 Joerg Wunsch <j@uriah.heep.sax.de>
 
 	* avr.c (avr_read, avr_write): if the paged access returns a
diff --git a/avrdude/avrdude.1 b/avrdude/avrdude.1
index f5f8de26..9491ae63 100644
--- a/avrdude/avrdude.1
+++ b/avrdude/avrdude.1
@@ -722,8 +722,8 @@ DebugWire mode is initiated by activating the
 fuse, and then power-cycling the target.
 While this mode is mainly intented for debugging/emulation, it
 also offers limited programming capabilities.
-Effectively, the only memory area that can be read or programmed
-in this mode is the flash ROM.
+Effectively, the only memory areas that can be read or programmed
+in this mode are flash ROM and EEPROM.
 It is also possible to read out the signature.
 All other memory areas cannot be accessed.
 There is no
diff --git a/avrdude/avrdude.conf.in b/avrdude/avrdude.conf.in
index 200ae942..05d6b83f 100644
--- a/avrdude/avrdude.conf.in
+++ b/avrdude/avrdude.conf.in
@@ -965,6 +965,9 @@ part
     desc                = "ATtiny13";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x0E, 0x1E;
+     eeprom_instr  = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
     stk500_devcode      = 0x14;
     signature           = 0x1e 0x90 0x07;
     chip_erase_delay    = 4000;
@@ -5915,6 +5918,9 @@ part
     desc                = "ATTINY261";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x00, 0x10;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 #    stk500_devcode      = 0x21;
 #    avr910_devcode      = 0x5e;
     signature           = 0x1e 0x91 0x0c;
@@ -6101,6 +6107,9 @@ part
     desc                = "ATTINY461";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x00, 0x10;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 #    stk500_devcode      = 0x21;
 #    avr910_devcode      = 0x5e;
     signature           = 0x1e 0x92 0x08;
@@ -6287,6 +6296,9 @@ part
     desc                = "ATTINY861";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x00, 0x10;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 #    stk500_devcode      = 0x21;
 #    avr910_devcode      = 0x5e;
     signature           = 0x1e 0x93 0x0d;
@@ -6472,6 +6484,9 @@ part
     desc             = "ATMEGA48";
      has_debugwire = yes;
      flash_instr   = 0xB6, 0x01, 0x11;
+     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+	             0x99, 0xF9, 0xBB, 0xAF;
     stk500_devcode   = 0x59;
 #    avr910_devcode   = 0x;
     signature        = 0x1e 0x92 0x05;
@@ -6656,6 +6671,9 @@ part
     desc             = "ATMEGA88";
      has_debugwire = yes;
      flash_instr   = 0xB6, 0x01, 0x11;
+     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+	             0x99, 0xF9, 0xBB, 0xAF;
     stk500_devcode   = 0x73;
 #    avr910_devcode   = 0x;
     signature        = 0x1e 0x93 0x0a;
@@ -6839,6 +6857,9 @@ part
     desc            = "ATMEGA168";
      has_debugwire = yes;
      flash_instr   = 0xB6, 0x01, 0x11;
+     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+	             0x99, 0xF9, 0xBB, 0xAF;
     stk500_devcode  = 0x86;
     # avr910_devcode = 0x;
     signature       = 0x1e 0x94 0x06;
@@ -7024,6 +7045,9 @@ part
      desc          = "ATtiny2313";
      has_debugwire = yes;
      flash_instr   = 0xB2, 0x0F, 0x1F;
+     eeprom_instr  = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
      stk500_devcode   = 0x23;
 ##   Use the ATtiny26 devcode:
      avr910_devcode   = 0x5e;
@@ -7208,6 +7232,9 @@ part
      desc          = "AT90PWM2";
      has_debugwire = yes;
      flash_instr   = 0xB6, 0x01, 0x11;
+     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+	             0x99, 0xF9, 0xBB, 0xAF;
      stk500_devcode   = 0x65;
 ##  avr910_devcode   = ?;
      signature        = 0x1e 0x93 0x81;
@@ -7389,6 +7416,9 @@ part
      desc          = "AT90PWM3";
      has_debugwire = yes;
      flash_instr   = 0xB6, 0x01, 0x11;
+     eeprom_instr  = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
+	             0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
+	             0x99, 0xF9, 0xBB, 0xAF;
      stk500_devcode   = 0x65;
 ##  avr910_devcode   = ?;
      signature        = 0x1e 0x93 0x81;
@@ -7568,6 +7598,9 @@ part
      desc          = "ATtiny25";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x02, 0x12;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
@@ -7745,6 +7778,9 @@ part
      desc          = "ATtiny45";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x02, 0x12;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
 ##  Try the AT90S2313 devcode:
@@ -7921,6 +7957,9 @@ part
      desc          = "ATtiny85";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x02, 0x12;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
@@ -9050,6 +9089,9 @@ part
      desc          = "ATtiny24";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x07, 0x17;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
@@ -9229,6 +9271,9 @@ part
      desc          = "ATtiny44";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x07, 0x17;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+                     0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+                     0x99, 0xE1, 0xBB, 0xAC;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
@@ -9408,6 +9453,9 @@ part
      desc          = "ATtiny84";
      has_debugwire = yes;
      flash_instr   = 0xB4, 0x07, 0x17;
+     eeprom_instr  = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
+	             0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
+	             0x99, 0xE1, 0xBB, 0xAC;
 ## no STK500 devcode in XML file, use the ATtiny45 one
      stk500_devcode   = 0x14;
 ##  avr910_devcode   = ?;
diff --git a/avrdude/avrpart.h b/avrdude/avrpart.h
index 2e5bc48d..747b3495 100644
--- a/avrdude/avrpart.h
+++ b/avrdude/avrpart.h
@@ -95,6 +95,7 @@ typedef struct opcode {
 #define AVR_IDLEN   32
 #define CTL_STACK_SIZE 32
 #define FLASH_INSTR_SIZE 3
+#define EEPROM_INSTR_SIZE 20
 typedef struct avrpart {
   char          desc[AVR_DESCLEN];  /* long part name */
   char          id[AVR_IDLEN];      /* short part name */
@@ -123,6 +124,7 @@ typedef struct avrpart {
   enum ctl_stack_t ctl_stack_type;  /* what to use the ctl stack for */
   unsigned char controlstack[CTL_STACK_SIZE]; /* stk500v2 PP/HVSP ctl stack */
   unsigned char flash_instr[FLASH_INSTR_SIZE]; /* flash instructions (debugWire, JTAG) */
+  unsigned char eeprom_instr[EEPROM_INSTR_SIZE]; /* EEPROM instructions (debugWire, JTAG) */
 
   int           hventerstabdelay;   /* stk500 v2 hv mode parameter */
   int           progmodedelay;      /* stk500 v2 hv mode parameter */
diff --git a/avrdude/config_gram.y b/avrdude/config_gram.y
index 185e4725..b182f200 100644
--- a/avrdude/config_gram.y
+++ b/avrdude/config_gram.y
@@ -202,6 +202,7 @@ static int parse_cmdbits(OPCODE * op);
 %token K_SPMCR			/* address of SPMC[S]R in memory space */
 %token K_EECR    		/* address of EECR in memory space */
 %token K_FLASH_INSTR		/* flash instructions */
+%token K_EEPROM_INSTR		/* EEPROM instructions */
 
 %token TKN_COMMA
 %token TKN_EQUAL
@@ -751,6 +752,38 @@ part_parm :
     }
   } |
 
+  K_EEPROM_INSTR TKN_EQUAL num_list {
+    {
+      TOKEN * t;
+      unsigned nbytes;
+      int ok;
+
+      nbytes = 0;
+      ok = 1;
+
+      while (lsize(number_list)) {
+        t = lrmv_n(number_list, 1);
+	if (nbytes < EEPROM_INSTR_SIZE)
+	  {
+	    current_part->eeprom_instr[nbytes] = t->value.number;
+	    nbytes++;
+	  }
+	else
+	  {
+	    ok = 0;
+	  }
+        free_token(t);
+      }
+      if (!ok)
+	{
+	  fprintf(stderr,
+                  "%s: Warning: line %d of %s: "
+		  "too many bytes in EEPROM instructions\n",
+                  progname, lineno, infile);
+        }
+    }
+  } |
+
   K_CHIP_ERASE_DELAY TKN_EQUAL TKN_NUMBER
     {
       current_part->chip_erase_delay = $3->value.number;
diff --git a/avrdude/doc/avrdude.texi b/avrdude/doc/avrdude.texi
index 472a323f..18c69c15 100644
--- a/avrdude/doc/avrdude.texi
+++ b/avrdude/doc/avrdude.texi
@@ -1944,8 +1944,8 @@ DebugWire mode is initiated by activating the @var{DWEN}
 fuse, and then power-cycling the target.
 While this mode is mainly intented for debugging/emulation, it
 also offers limited programming capabilities.
-Effectively, the only memory area that can be read or programmed
-in this mode is the flash ROM.
+Effectively, the only memory areas that can be read or programmed
+in this mode are flash ROM and EEPROM.
 It is also possible to read out the signature.
 All other memory areas cannot be accessed.
 There is no
diff --git a/avrdude/jtagmkII.c b/avrdude/jtagmkII.c
index f65552d1..8a42174b 100644
--- a/avrdude/jtagmkII.c
+++ b/avrdude/jtagmkII.c
@@ -846,8 +846,10 @@ static void jtagmkII_set_devdescr(PROGRAMMER * pgm, AVRPART * p)
       u32_to_b4(sendbuf.dd.ulFlashSize, m->size);
       u16_to_b2(sendbuf.dd.uiFlashPageSize, flash_pagesize);
       u16_to_b2(sendbuf.dd.uiFlashpages, m->size / flash_pagesize);
-      if (p->flags & AVRPART_HAS_DW)
+      if (p->flags & AVRPART_HAS_DW) {
 	memcpy(sendbuf.dd.ucFlashInst, p->flash_instr, FLASH_INSTR_SIZE);
+	memcpy(sendbuf.dd.ucEepromInst, p->eeprom_instr, EEPROM_INSTR_SIZE);
+      }
     } else if (strcmp(m->desc, "eeprom") == 0) {
       sendbuf.dd.ucEepromPageSize = eeprom_pagesize = m->page_size;
     }
@@ -1660,13 +1662,16 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     paddr_ptr = &flash_pageaddr;
     cache_ptr = flash_pagecache;
   } else if (strcmp(mem->desc, "eeprom") == 0) {
-    cmd[1] = MTYPE_EEPROM_PAGE;
-    pagesize = mem->page_size;
-    paddr = addr & ~(pagesize - 1);
-    paddr_ptr = &eeprom_pageaddr;
-    cache_ptr = eeprom_pagecache;
-    if (pgm->flag & PGM_FL_IS_DW)
-      unsupp = 1;
+    if (pgm->flag & PGM_FL_IS_DW) {
+      /* debugWire cannot use page access for EEPROM */
+      cmd[1] = MTYPE_EEPROM;
+    } else {
+      cmd[1] = MTYPE_EEPROM_PAGE;
+      pagesize = mem->page_size;
+      paddr = addr & ~(pagesize - 1);
+      paddr_ptr = &eeprom_pageaddr;
+      cache_ptr = eeprom_pagecache;
+    }
   } else if (strcmp(mem->desc, "lfuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 0;
@@ -1716,7 +1721,6 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
       default:
 	fprintf(stderr, "%s: illegal address %lu for signature memory\n",
 		progname, addr);
-	*value = 42;
 	return -1;
       }
       return 0;
@@ -1776,6 +1780,8 @@ static int jtagmkII_read_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 	    "%s: jtagmkII_read_byte(): "
 	    "fatal timeout/error communicating with programmer (status %d)\n",
 	    progname, status);
+    if (status < 0)
+      resp = 0;
     goto fail;
   }
   if (verbose >= 3) {
@@ -1811,7 +1817,7 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 {
   unsigned char cmd[11];
   unsigned char *resp = NULL, writedata;
-  int status, tries, need_progmode = 1;
+  int status, tries, need_progmode = 1, unsupp = 0;
 
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n",
@@ -1823,6 +1829,8 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
     cmd[1] = MTYPE_SPM;
     need_progmode = 0;
     flash_pageaddr = (unsigned long)-1L;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "eeprom") == 0) {
     cmd[1] = MTYPE_EEPROM;
     need_progmode = 0;
@@ -1830,20 +1838,35 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   } else if (strcmp(mem->desc, "lfuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 0;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "hfuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 1;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "efuse") == 0) {
     cmd[1] = MTYPE_FUSE_BITS;
     addr = 2;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "lock") == 0) {
     cmd[1] = MTYPE_LOCK_BITS;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "calibration") == 0) {
     cmd[1] = MTYPE_OSCCAL_BYTE;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   } else if (strcmp(mem->desc, "signature") == 0) {
     cmd[1] = MTYPE_SIGN_JTAG;
+    if (pgm->flag & PGM_FL_IS_DW)
+      unsupp = 1;
   }
 
+  if (unsupp)
+    return -1;
+
   if (need_progmode) {
     if (jtagmkII_program_enable(pgm) < 0)
       return -1;
@@ -1902,17 +1925,6 @@ fail:
 }
 
 
-static int jtagmkII_write_byte_dw(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
-				  unsigned long addr, unsigned char data)
-{
-
-  fprintf(stderr,
-	  "%s: jtagmkII_write_byte_dw(): no single-byte writes supported in debugWire\n",
-	  progname);
-
-  return -1;
-}
-
 /*
  * Set the JTAG clock.  The actual frequency is quite a bit of
  * guesswork, based on the values claimed by AVR Studio.  Inside the
@@ -2172,7 +2184,7 @@ void jtagmkII_dw_initpgm(PROGRAMMER * pgm)
   pgm->open           = jtagmkII_open_dw;
   pgm->close          = jtagmkII_close;
   pgm->read_byte      = jtagmkII_read_byte;
-  pgm->write_byte     = jtagmkII_write_byte_dw;
+  pgm->write_byte     = jtagmkII_write_byte;
 
   /*
    * optional functions
@@ -2230,7 +2242,7 @@ void jtagmkII_dragon_dw_initpgm(PROGRAMMER * pgm)
   pgm->open           = jtagmkII_dragon_open_dw;
   pgm->close          = jtagmkII_close;
   pgm->read_byte      = jtagmkII_read_byte;
-  pgm->write_byte     = jtagmkII_write_byte_dw;
+  pgm->write_byte     = jtagmkII_write_byte;
 
   /*
    * optional functions
diff --git a/avrdude/lexer.l b/avrdude/lexer.l
index 22a35dda..94e6c7ac 100644
--- a/avrdude/lexer.l
+++ b/avrdude/lexer.l
@@ -224,6 +224,7 @@ programfusepolltimeout { yylval=NULL; return K_PROGRAMFUSEPOLLTIMEOUT; }
 programlockpulsewidth { yylval=NULL; return K_PROGRAMLOCKPULSEWIDTH; }
 programlockpolltimeout { yylval=NULL; return K_PROGRAMLOCKPOLLTIMEOUT; }
 flash_instr      { yylval=NULL; return K_FLASH_INSTR; }
+eeprom_instr     { yylval=NULL; return K_EEPROM_INSTR; }
 
 dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
 io               { yylval=new_token(K_IO); return K_IO; }
diff --git a/avrdude/tools/get-dw-params.xsl b/avrdude/tools/get-dw-params.xsl
index e5cb7987..3561db91 100644
--- a/avrdude/tools/get-dw-params.xsl
+++ b/avrdude/tools/get-dw-params.xsl
@@ -40,6 +40,8 @@
                     select="translate(/AVRPART/ADMIN/PART_NAME,
                                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                       'abcdefghijklmnopqrstuvwxyz')" />
+      <xsl:variable name="ucEepromInst"
+                    select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucEepromInst" />
       <xsl:variable name="ucFlashInst"
                     select="//AVRPART/ICE_SETTINGS/JTAGICEmkII/ucFlashInst" />
 
@@ -63,6 +65,13 @@
       </xsl:call-template>
       <xsl:text>;&#010;</xsl:text>
 
+      <xsl:text>     eeprom_instr  = </xsl:text>
+      <xsl:call-template name="format-hex">
+        <xsl:with-param name="arg" select="$ucEepromInst" />
+        <xsl:with-param name="count" select="0" />
+      </xsl:call-template>
+      <xsl:text>;&#010;</xsl:text>
+
       </xsl:if> <!-- JTAGICEmkII uses debugWire -->
 
     </xsl:template>
@@ -118,7 +127,7 @@
           <xsl:value-of select="substring($arg, 1, 4)" />
           <xsl:choose>
             <xsl:when test="$count mod 8 = 7">
-              <xsl:text>,&#010;&#009;      </xsl:text>
+              <xsl:text>,&#010;&#009;             </xsl:text>
             </xsl:when>
             <xsl:otherwise>
               <xsl:text>, </xsl:text>