From a7e45fd3d3c740359b4b0d01727350c55da33896 Mon Sep 17 00:00:00 2001
From: Joerg Wunsch <j@uriah.heep.sax.de>
Date: Mon, 11 Jan 2010 15:27:44 +0000
Subject: [PATCH] Clean-up the Xmega erase functions. * jtagmkII_private.h: Add
 CMND_XMEGA_ERASE as well as the various XMEGA_ERASE_* definitions (from
 updated appnote AVR067) * jtagmkII.c (jtagmkII_chip_erase): Correctly
 implement Xmega chip erase based on CMND_XMEGA_ERASE. * jtagmkII.c
 (jtagmkII_pre_write): Remove, this turned out to be just a chip erase. *
 jtagmkII.c (jtagmkII_program_disable): Don't try reading "hfuse" for Xmega
 parts; they don't have it. * main.c (main): Re-enable auto-erase.  It's been
 done before (as "jtagmkII_pre_write") in jtagmkII_paged_write() anyway. 
 Xmega boot and application flash areas should be handled separately in the
 future, so auto_erase can only affect the area just being programmed.

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@903 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avrdude/ChangeLog          | 18 ++++++++++
 avrdude/jtagmkII.c         | 67 ++++++++++----------------------------
 avrdude/jtagmkII_private.h | 12 ++++++-
 avrdude/main.c             |  9 -----
 4 files changed, 47 insertions(+), 59 deletions(-)

diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog
index 298beed1..1c5c317b 100644
--- a/avrdude/ChangeLog
+++ b/avrdude/ChangeLog
@@ -1,3 +1,21 @@
+2010-01-11  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
+
+	Clean-up the Xmega erase functions.
+	* jtagmkII_private.h: Add CMND_XMEGA_ERASE as well as
+	the various XMEGA_ERASE_* definitions (from updated
+	appnote AVR067)
+	* jtagmkII.c (jtagmkII_chip_erase): Correctly implement
+	Xmega chip erase based on CMND_XMEGA_ERASE.
+	* jtagmkII.c (jtagmkII_pre_write): Remove, this turned out
+	to be just a chip erase.
+	* jtagmkII.c (jtagmkII_program_disable): Don't try reading
+	"hfuse" for Xmega parts; they don't have it.
+	* main.c (main): Re-enable auto-erase.  It's been done
+	before (as "jtagmkII_pre_write") in jtagmkII_paged_write()
+	anyway.  Xmega boot and application flash areas should be
+	handled separately in the future, so auto_erase can only
+	affect the area just being programmed.
+
 2010-01-11  Joerg Wunsch <j.gnu@uriah.heep.sax.de>
 
 	* main.c (main): disable safemode for Xmega parts.
diff --git a/avrdude/jtagmkII.c b/avrdude/jtagmkII.c
index 75cfbf58..95cababc 100644
--- a/avrdude/jtagmkII.c
+++ b/avrdude/jtagmkII.c
@@ -863,14 +863,24 @@ int jtagmkII_getsync(PROGRAMMER * pgm, int mode) {
  */
 static int jtagmkII_chip_erase(PROGRAMMER * pgm, AVRPART * p)
 {
-  int status;
-  unsigned char buf[1], *resp, c;
-  
-  buf[0] = CMND_CHIP_ERASE;
+  int status, len;
+  unsigned char buf[6], *resp, c;
+
+  if (p->flags & AVRPART_HAS_PDI) {
+    buf[0] = CMND_XMEGA_ERASE;
+    buf[1] = XMEGA_ERASE_CHIP;
+    memset(buf + 2, 0, 4);      /* address of area to be erased */
+    len = 6;
+  } else {
+    buf[0] = CMND_CHIP_ERASE;
+    len = 1;
+  }
   if (verbose >= 2)
-    fprintf(stderr, "%s: jtagmkII_chip_erase(): Sending chip erase command: ",
-	    progname);
-  jtagmkII_send(pgm, buf, 1);
+    fprintf(stderr,
+            "%s: jtagmkII_chip_erase(): Sending %schip erase command: ",
+	    progname,
+            (p->flags & AVRPART_HAS_PDI)? "Xmega ": "");
+  jtagmkII_send(pgm, buf, len);
 
   status = jtagmkII_recv(pgm, &resp);
   if (status <= 0) {
@@ -1089,45 +1099,6 @@ static int jtagmkII_program_enable(PROGRAMMER * pgm)
   return 0;
 }
 
-static int jtagmkII_pre_write(PROGRAMMER * pgm)
-{
-  int status;
-  unsigned char *resp, c;
-  unsigned char buf[] = { CMND_0x34, 0x0, 0x0, 0x0, 0x0, 0x0 };
-  if (verbose >= 2)
-    fprintf(stderr, "%s: jtagmkII_pre_write(): Sending pre-write command: ",
-	    progname);
-  jtagmkII_send(pgm, buf, 6);
-
-  status = jtagmkII_recv(pgm, &resp);
-  if (status <= 0) {
-    if (verbose >= 2)
-      putc('\n', stderr);
-    fprintf(stderr,
-	    "%s: jtagmkII_pre_write(): "
-	    "timeout/error communicating with programmer (status %d)\n",
-	    progname, status);
-    return -1;
-  }
-  if (verbose >= 3) {
-    putc('\n', stderr);
-    jtagmkII_prmsg(pgm, resp, status);
-  } else if (verbose == 2)
-    fprintf(stderr, "0x%02x (%d bytes msg)\n", resp[0], status);
-  c = resp[0];
-  free(resp);
-  if (c != RSP_OK) {
-    fprintf(stderr,
-	    "%s: jtagmkII_pre_write(): "
-	    "bad response to pre_write command: %s\n",
-	    progname, jtagmkII_get_rc(c));
-    return -1;
-  }
-
-  return 0;
-}
-
-
 static int jtagmkII_program_disable(PROGRAMMER * pgm)
 {
   int status;
@@ -1284,7 +1255,7 @@ static int jtagmkII_initialize(PROGRAMMER * pgm, AVRPART * p)
   if (jtagmkII_reset(pgm, 0x01) < 0)
     return -1;
 
-  if (!(pgm->flag & PGM_FL_IS_DW)) {
+  if (!(pgm->flag & PGM_FL_IS_DW) && !(p->flags & AVRPART_HAS_PDI)) {
     strcpy(hfuse.desc, "hfuse");
     if (jtagmkII_read_byte(pgm, p, &hfuse, 1, &b) < 0)
       return -1;
@@ -1671,8 +1642,6 @@ static int jtagmkII_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     PDATA(pgm)->eeprom_pageaddr = (unsigned long)-1L;
     page_size = PDATA(pgm)->eeprom_pagesize;
   }
-  if ( cmd[1] == MTYPE_FLASH )  (void)jtagmkII_pre_write(pgm);
-  
   serial_recv_timeout = 100;
   for (addr = 0; addr < n_bytes; addr += page_size) {
     report_progress(addr, n_bytes,NULL);
diff --git a/avrdude/jtagmkII_private.h b/avrdude/jtagmkII_private.h
index 0cd45a75..fa896435 100644
--- a/avrdude/jtagmkII_private.h
+++ b/avrdude/jtagmkII_private.h
@@ -103,7 +103,7 @@
 #define CMND_SPI_CMD 0x1D
 #define CMND_WRITE_MEMORY 0x04
 #define CMND_WRITE_PC 0x06
-#define CMND_0x34 0x34
+#define CMND_XMEGA_ERASE 0x34
 // AVR32 - DFH
 #define CMND_GET_IR 0x24
 #define CMND_GET_xxx 0x25
@@ -252,6 +252,16 @@
 # define PAGEPROG_NOT_ALLOWED 0x00
 # define PAGEPROG_ALLOWED 0x01
 
+/* Xmega erase memory types, for CMND_XMEGA_ERASE */
+#define XMEGA_ERASE_CHIP 0x00
+#define XMEGA_ERASE_APP 0x01
+#define XMEGA_ERASE_BOOT 0x02
+#define XMEGA_ERASE_EEPROM 0x03
+#define XMEGA_ERASE_APP_PAGE 0x04
+#define XMEGA_ERASE_BOOT_PAGE 0x05
+#define XMEGA_ERASE_EEPROM_PAGE 0x06
+#define XMEGA_ERASE_USERSIG 0x07
+
 #if !defined(JTAGMKII_PRIVATE_EXPORTED)
 /*
  * In appnote AVR067, struct device_descriptor is written with
diff --git a/avrdude/main.c b/avrdude/main.c
index f9ee0aaa..a929dae3 100644
--- a/avrdude/main.c
+++ b/avrdude/main.c
@@ -972,15 +972,6 @@ int main(int argc, char * argv [])
     }
   }
 
-
-  if (p->flags & AVRPART_HAS_PDI) {
-    /*
-     * This is an ATxmega which can page erase, so no auto erase is
-     * needed.
-     */
-    auto_erase = 0;
-  }
-
   if ((erase == 0) && (auto_erase == 1)) {
     AVRMEM * m;
     for (ln=lfirst(updates); ln; ln=lnext(ln)) {