From c0d9de9b67356d08ff106f8549b1807171da0401 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Sun, 8 Sep 2013 19:57:58 +0000
Subject: [PATCH] Fix byte-wise EEPROM and flash writes on Xmega *
 jtagmkII_private.h (MTYPE_EEPROM_XMEGA): New memory type. * jtagmkII.c
 (jtagmkII_write_byte): For Xmega EEPROM, use memory type MTYPE_EEPROM_XMEGA;
 for flash writes, always write 2 bytes starting on an even address.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1212 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog          |  8 ++++++++
 jtagmkII.c         | 20 ++++++++++++++------
 jtagmkII_private.h |  1 +
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fbd0c810..d074eb9d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2013-09-08  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Fix byte-wise EEPROM and flash writes on Xmega
+	* jtagmkII_private.h (MTYPE_EEPROM_XMEGA): New memory type.
+	* jtagmkII.c (jtagmkII_write_byte): For Xmega EEPROM, use
+	memory type MTYPE_EEPROM_XMEGA; for flash writes, always
+	write 2 bytes starting on an even address.
+
 2013-09-08  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* term.c: Implement the "verbose" terminal mode command.
diff --git a/jtagmkII.c b/jtagmkII.c
index d84c3c39..a5337167 100644
--- a/jtagmkII.c
+++ b/jtagmkII.c
@@ -2465,9 +2465,9 @@ fail:
 static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
 			       unsigned long addr, unsigned char data)
 {
-  unsigned char cmd[11];
-  unsigned char *resp = NULL, writedata;
-  int status, tries, need_progmode = 1, unsupp = 0;
+  unsigned char cmd[12];
+  unsigned char *resp = NULL, writedata, writedata2 = 0xFF;
+  int status, tries, need_progmode = 1, unsupp = 0, writesize = 1;
 
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkII_write_byte(.., %s, 0x%lx, ...)\n",
@@ -2479,12 +2479,19 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
   cmd[0] = CMND_WRITE_MEMORY;
   cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_FLASH : MTYPE_SPM;
   if (strcmp(mem->desc, "flash") == 0) {
+     if ((addr & 1) == 1) {
+       /* odd address = high byte */
+       writedata = 0xFF;	/* don't modify the low byte */
+       writedata2 = data;
+       addr &= ~1L;
+     }
+     writesize = 2;
      need_progmode = 0;
      PDATA(pgm)->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;
+    cmd[1] = ( p->flags & AVRPART_HAS_PDI ) ? MTYPE_EEPROM_XMEGA: MTYPE_EEPROM;
     need_progmode = 0;
     PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
   } else if (strcmp(mem->desc, "lfuse") == 0) {
@@ -2533,16 +2540,17 @@ static int jtagmkII_write_byte(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
       return -1;
   }
 
-  u32_to_b4(cmd + 2, 1);
+  u32_to_b4(cmd + 2, writesize);
   u32_to_b4(cmd + 6, addr);
   cmd[10] = writedata;
+  cmd[11] = writedata2;
 
   tries = 0;
   retry:
   if (verbose >= 2)
     fprintf(stderr, "%s: jtagmkII_write_byte(): Sending write memory command: ",
 	    progname);
-  jtagmkII_send(pgm, cmd, 11);
+  jtagmkII_send(pgm, cmd, 10 + writesize);
 
   status = jtagmkII_recv(pgm, &resp);
   if (status <= 0) {
diff --git a/jtagmkII_private.h b/jtagmkII_private.h
index e542ffcd..6df8f6f2 100644
--- a/jtagmkII_private.h
+++ b/jtagmkII_private.h
@@ -181,6 +181,7 @@
 #define MTYPE_CAN         0xB6	/* CAN mailbox */
 #define MTYPE_FLASH       0xc0	/* xmega (app.) flash - undocumented in AVR067 */
 #define MTYPE_BOOT_FLASH  0xc1	/* xmega boot flash - undocumented in AVR067 */
+#define MTYPE_EEPROM_XMEGA 0xc4	/* xmega EEPROM in debug mode - undocumented in AVR067 */
 #define MTYPE_USERSIG     0xc5	/* xmega user signature - undocumented in AVR067 */
 #define MTYPE_PRODSIG     0xc6	/* xmega production signature - undocumented in AVR067 */