From ee73e2e873e3eb279df71f890bcfe095ad85d2f8 Mon Sep 17 00:00:00 2001
From: dhoerl <dhoerl@81a1dc3b-b13d-400b-aceb-764788c761c2>
Date: Mon, 12 Oct 2009 16:44:30 +0000
Subject: [PATCH] avr32 cleanup, now does flash read and verify

git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@870 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog       |  10 +-
 avrdude.conf.in | 118 +--------------------
 avrpart.h       |   3 +-
 jtagmkII.c      | 275 ++++++++++++++++++++++--------------------------
 lexer.l         |   1 +
 main.c          |   1 -
 6 files changed, 141 insertions(+), 267 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 549975e6..3610dcd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,15 @@
+2009-10-12  David Hoerl <dhoerl@mac.com>
+
+	*  main.c: removed some avr32 code that was pushed into jtagmkII.c
+	*  jtagmkII.c: consolodated the avr32 reset code and avr32_chipreset
+	*  avrpart.h: modified AVRPART flags for avr32
+	*  lexer.l: added is_avr32 flag - only way to get yacc code to set flag
+	*  avrdude.conf.in: updated avr32 section to include "is_avr32" flag
+
 2009-10-12  David Hoerl <dhoerl@mac.com>
 
 	*  config_gram.y: Restored inadvertantly removed buspirate entry
-	*  lexer.l.y: Restored inadvertantly removed buspirate entry
+	*  lexer.l: Restored inadvertantly removed buspirate entry
 
 2009-10-12  Michal Ludvig  <mludvig@logix.net.nz>
 
diff --git a/avrdude.conf.in b/avrdude.conf.in
index 822b58f7..f0bf109c 100644
--- a/avrdude.conf.in
+++ b/avrdude.conf.in
@@ -15051,119 +15051,11 @@ part
 
     memory "flash"
         paged           = yes;
-        page_size       = 512;               # bytes
-        num_pages       = 1024 ;             # numeric
-        size		= 0x00080000;
-        offset		= 0x80000000;
-        readsize	= 512;
+        page_size		= 512;               # bytes
+        readsize		= 512;				 # bytes
+        num_pages       = 1024;              # could be set dynamicly
+        size			= 0x00080000;		 # could be set dynamicly
+        offset			= 0x80000000;
     ;
 ;
 
-
-
-#   part
-#       id               = <id> ;                 # quoted string
-#       desc             = <description> ;        # quoted string
-#       has_jtag         = <yes/no> ;             # part has JTAG i/f
-#       has_debugwire    = <yes/no> ;             # part has debugWire i/f
-#       devicecode       = <num> ;            # deprecated, use stk500_devcode
-#       stk500_devcode   = <num> ;                # numeric
-#       avr910_devcode   = <num> ;                # numeric
-#       signature        = <num> <num> <num> ;    # signature bytes
-#       chip_erase_delay = <num> ;                # micro-seconds
-#       reset            = dedicated | io;
-#       retry_pulse      = reset | sck;
-#       pgm_enable       = <instruction format> ;
-#       chip_erase       = <instruction format> ;
-#       chip_erase_delay = <num> ;                # chip erase delay (us)
-#       # STK500 parameters (parallel programming IO lines)
-#       pagel            = <num> ;                # pin name in hex, i.e., 0xD7
-#       bs2              = <num> ;                # pin name in hex, i.e., 0xA0
-#       serial           = <yes/no> ;             # can use serial downloading
-#       parallel         = <yes/no/pseudo>;       # can use par. programming
-#       # STK500v2 parameters, to be taken from Atmel's XML files
-#       timeout          = <num> ;
-#       stabdelay        = <num> ;
-#       cmdexedelay      = <num> ;
-#       synchloops       = <num> ;
-#       bytedelay        = <num> ;
-#       pollvalue        = <num> ;
-#       pollindex        = <num> ;
-#       predelay         = <num> ;
-#       postdelay        = <num> ;
-#       pollmethod       = <num> ;
-#       mode             = <num> ;
-#       delay            = <num> ;
-#       blocksize        = <num> ;
-#       readsize         = <num> ;
-#       hvspcmdexedelay  = <num> ;
-#       # STK500v2 HV programming parameters, from XML
-#       pp_controlstack  = <num>, <num>, ...;   # PP only
-#       hvsp_controlstack = <num>, <num>, ...;  # HVSP only
-#       hventerstabdelay = <num>;
-#       progmodedelay    = <num>;               # PP only
-#       latchcycles      = <num>;
-#       togglevtg        = <num>;
-#       poweroffdelay    = <num>;
-#       resetdelayms     = <num>;
-#       resetdelayus     = <num>;
-#       hvleavestabdelay = <num>;
-#       resetdelay       = <num>;
-#       synchcycles      = <num>;               # HVSP only
-#       chiperasepulsewidth = <num>;            # PP only
-#       chiperasepolltimeout = <num>;
-#       chiperasetime    = <num>;               # HVSP only
-#       programfusepulsewidth = <num>;          # PP only
-#       programfusepolltimeout = <num>;
-#       programlockpulsewidth = <num>;          # PP only
-#       programlockpolltimeout = <num>;
-#       # JTAG ICE mkII parameters, also from XML files
-#       allowfullpagebitstream = <yes/no> ;
-#       enablepageprogramming = <yes/no> ;
-#       idr              = <num> ;                # IO addr of IDR (OCD) reg.
-#       rampz            = <num> ;                # IO addr of RAMPZ reg.
-#       spmcr            = <num> ;                # mem addr of SPMC[S]R reg.
-#       eecr             = <num> ;                # mem addr of EECR reg.
-#                                                 # (only when != 0x3c)
-#
-#       memory <memtype>
-#           paged           = <yes/no> ;          # yes / no
-#           size            = <num> ;             # bytes
-#           page_size       = <num> ;             # bytes
-#           num_pages       = <num> ;             # numeric
-#           min_write_delay = <num> ;             # micro-seconds
-#           max_write_delay = <num> ;             # micro-seconds
-#           readback_p1     = <num> ;             # byte value
-#           readback_p2     = <num> ;             # byte value
-#           pwroff_after_write = <yes/no> ;       # yes / no
-#           read            = <instruction format> ;
-#           write           = <instruction format> ;
-#           read_lo         = <instruction format> ;
-#           read_hi         = <instruction format> ;
-#           write_lo        = <instruction format> ;
-#           write_hi        = <instruction format> ;
-#           loadpage_lo     = <instruction format> ;
-#           loadpage_hi     = <instruction format> ;
-#           writepage       = <instruction format> ;
-#         ;
-#     ;
-
-
-#   <flash_read_delay time="1000" to_rev="8"/>
-#   <avr_reset domains="5"/>
-#   <core_name>STILETTO</core_name>
-#   <flashc id="I7503" name="FLASHC" revision="2.0.0" address="0xFFFE1400" page_size="512" pages_pr_region="64" flash_size="524288">
-#       <fuses gp_hi_offset="0xC" gp_lo_offset="0x10"/>
-#   </flashc>
-#   <pm address="0xFFFF0C00"/>
-#   <memory>
-#       <block name="EBI_CS0" type="EXT_SRAM" address="0xC0000000" size="0x01000000"/>
-#       <block name="EBI_CS1" type="EXT_SRAM" address="0xD0000000" size="0x08000000"/>
-#       <block name="EBI_CS2" type="EXT_SRAM" address="0xC8000000" size="0x01000000"/>
-#       <block name="EBI_CS3" type="EXT_SRAM" address="0xCC000000" size="0x01000000"/>
-#       <block name="FLASH" type="FLASH" address="0x80000000" size="0x00080000"/>
-#       <block name="SRAM" type="INT_SRAM" address="0x00000000" size="0x00010000"/>
-#       <block name="USBB_SLAVE" type="INT_SRAM" address="0xE0000000" size="0x00800000"/>
-#   </memory>
-
-
diff --git a/avrpart.h b/avrpart.h
index 6d67bc59..dc6250d1 100644
--- a/avrpart.h
+++ b/avrpart.h
@@ -90,7 +90,8 @@ typedef struct opcode {
 #define AVRPART_HAS_DW         0x0040  /* part has a debugWire i/f */
 #define AVRPART_HAS_PDI        0x0080  /* part has PDI i/f rather than ISP (ATxmega) */
 #define AVRPART_AVR32          0x0100  /* part is in AVR32 family */
-#define AVRPART_CHIP_ERASE     0x0200  /* part will undergo chip erase */
+#define AVRPART_INIT_SMC       0x0200  /* part will undergo chip erase */
+#define AVRPART_WRITE          0x0400  /* at least one write operation specified */
 
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
diff --git a/jtagmkII.c b/jtagmkII.c
index b4cdcfa0..4e1e4969 100644
--- a/jtagmkII.c
+++ b/jtagmkII.c
@@ -2563,6 +2563,10 @@ static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val, unsigned ch
   int status;
   unsigned char buf[3], *resp;
 
+  if(verbose) fprintf(stderr,
+          "%s: jtagmkII_avr32_reset(%2.2x)\n",
+          progname, val);
+
   buf[0] = CMND_GET_IR;
   buf[1] = 0x0C;
   status = jtagmkII_send(pgm, buf, 2);
@@ -2596,9 +2600,11 @@ static int jtagmkII_avr32_reset(PROGRAMMER * pgm, unsigned char val, unsigned ch
   return 0;
 }
 
-#define AVR32_RESET_READ_IR             0x0001
-#define AVR32_RESET_READ_READ_CHIPINFO  0x0002
-#define AVR32_SET4RUNNING               0x0004
+#define AVR32_RESET_READ             0x0001
+#define AVR32_RESET_WRITE            0x0002
+#define AVR32_RESET_CHIP_ERASE       0x0004
+#define AVR32_SET4RUNNING            0x0008
+//#define AVR32_RESET_COMMON           (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE )
 
 // At init: AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO
 static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
@@ -2608,8 +2614,12 @@ static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
   unsigned long val=0;
   unsigned long config0, config1;
 
+  if(verbose) fprintf(stderr,
+          "%s: jtagmkII_reset32(%2.2x)\n",
+          progname, flags);
+
   // Happens at the start of a programming operation
-  if(flags & AVR32_RESET_READ_IR) {
+  if(flags & AVR32_RESET_READ) {
     buf[0] = CMND_GET_IR;
     buf[1] = 0x11;
     status = jtagmkII_send(pgm, buf, 2);
@@ -2620,48 +2630,63 @@ static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
       {lineno = __LINE__; goto eRR;};
   }
   
-  // AVR_RESET(0x1F), AVR_RESET(0x07)
-  status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
-  if(val != 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
-  if(val != 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR);
-  if(status < 0) return -1;
-
-  // Read OCD Register a bunch of times...
-  for(j=0; j<21; ++j) {
-    val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+  if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
+    // AVR_RESET(0x1F)
+    status = jtagmkII_avr32_reset(pgm, 0x1F, 0x01, 0x00);
+    if(status < 0) {lineno = __LINE__; goto eRR;}
+    // AVR_RESET(0x07)
+    status = jtagmkII_avr32_reset(pgm, 0x07, 0x11, 0x1F);
+    if(status < 0) {lineno = __LINE__; goto eRR;}
   }
-  if(val != 0x04000000) {lineno = __LINE__; goto eRR;}
-  
-  
-  // AVR_RESET(0x00)
-  status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
 
-  for(j=0; j<2; ++j) {
+  //if(flags & AVR32_RESET_COMMON)
+  {
     val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
-    if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
-    if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+    if(val != 0) {lineno = __LINE__; goto eRR;}
+    val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
+    if(val != 0) {lineno = __LINE__; goto eRR;}
   }
   
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
-  if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+  if(flags & (AVR32_RESET_READ | AVR32_RESET_CHIP_ERASE)) {
+    status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, AVR32_DC_DBE | AVR32_DC_DBR);
+    if(status < 0) return -1;
+  }
   
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
-  if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+  if(flags & (AVR32_RESET_WRITE | AVR32_SET4RUNNING)) {
+    status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, AVR32_DC_ABORT | AVR32_DC_RESET | AVR32_DC_DBE | AVR32_DC_DBR);
+    if(status < 0) return -1;
+    for(j=0; j<21; ++j) {
+      val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+    }
+    if(val != 0x04000000) {lineno = __LINE__; goto eRR;}
+    
+    // AVR_RESET(0x00)
+    status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x07);
+    if(status < 0) {lineno = __LINE__; goto eRR;}
+  }
+//  if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE))
+  {
+    for(j=0; j<2; ++j) {
+      val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
+      if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
+      if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
+    }
+  }
 
+  //if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE))
+  {
+    status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
+    if(status < 0) {lineno = __LINE__; goto eRR;}
 
+    val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
+    if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
+    
+    val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
+    if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
+  }
 
-  if(flags & AVR32_RESET_READ_READ_CHIPINFO) {
+  // Read chip configuration - common for all
+  if(flags & (AVR32_RESET_READ | AVR32_RESET_WRITE | AVR32_RESET_CHIP_ERASE)) {
     for(j=0; j<2; ++j) {
       val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
       if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
@@ -2725,9 +2750,17 @@ static int jtagmkII_reset32(PROGRAMMER * pgm, unsigned short flags)
     status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045);  // mtdr R0, 276
     if(status < 0) {lineno = __LINE__; goto eRR;}
 
-    val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
+    val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06); // need to recheck who does this...
     if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
   }
+  
+  if(flags & AVR32_RESET_CHIP_ERASE) {
+    status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00);
+    if(status < 0) {lineno = __LINE__; goto eRR;}
+    status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f);
+    if(status < 0) {lineno = __LINE__; goto eRR;}
+  }
+
   if(flags & AVR32_SET4RUNNING) {
     status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00014);  // mfsr R0, 80
     if(status < 0) {lineno = __LINE__; goto eRR;}
@@ -2857,7 +2890,7 @@ static int jtagmkII_smc_init32(PROGRAMMER * pgm)
  */
 static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
 {
-  int status, ret, j;
+  int status, j;
   unsigned char buf[6], *resp;
 
   if (jtagmkII_setparm(pgm, PAR_DAISY_CHAIN_INFO, PDATA(pgm)->jtagchain) < 0) {
@@ -2931,89 +2964,32 @@ static int jtagmkII_initialize32(PROGRAMMER * pgm, AVRPART * p)
     }
     free(resp);
   }
-  if(!(p->flags & AVRPART_CHIP_ERASE))
-    ret = jtagmkII_reset32(pgm, AVR32_RESET_READ_IR | AVR32_RESET_READ_READ_CHIPINFO);
-  else
-    ret = 0;
 
-  return ret;
+  return 0;
 }
 
 static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
 {
-  int status=0, j;
-  unsigned char *resp, buf[3], x;
+  int status=0, loops;
+  unsigned char *resp, buf[3], x, ret[4], *retP;
   unsigned long val;
   unsigned int lineno;
 
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
-  if(val != 0) {lineno = __LINE__; goto eRR;}
+  if(verbose) fprintf(stderr,
+          "%s: jtagmkII_chip_erase32()\n",
+          progname);
 
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DC, 0x01);
-  if(val != 0) {lineno = __LINE__; goto eRR;}
+  status = jtagmkII_reset32(pgm, AVR32_RESET_CHIP_ERASE);
+  if(status != 0) goto eRR;
+
+  // sequence of IR transitions
+  ret[0] = 0x01;
+  ret[1] = 0x05;
+  ret[2] = 0x01;
+  ret[3] = 0x00;
   
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DC, 0x01, AVR32_DC_DBE | AVR32_DC_DBR);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
-  if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
-  if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
-
-  for(j=0; j<2; ++j) {
-    status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
-    if(status < 0) {lineno = __LINE__; goto eRR;}
-    val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
-    if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
-    val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
-    if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
-  }
-
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00040);  // mfsr R0, 256
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
-  if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
-  if(val != 0x0204098b) {lineno = __LINE__; goto eRR;}
-
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045);  // mtdr R0, 276
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DS, 0x01);
-  if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
-  if((val&0x05000020) != 0x05000020) {lineno = __LINE__; goto eRR;}
-  
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
-  if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
-  if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
-
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe1b00041);  // mfsr R0, 260
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe7b00044);  // mtdr 272, R0
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCSR, 0x01);
-  if(val != 0x00000001) {lineno = __LINE__; goto eRR;}
-  val = jtagmkII_read_SABaddr(pgm, AVR32_DCCPU, 0x01);
-  if(val != 0x00800000) {lineno = __LINE__; goto eRR;}
-  
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DCEMU, 0x01, 0x00000000);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_write_SABaddr(pgm, AVR32_DINST, 0x01, 0xe5b00045);  // mtdr R0, 276
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-
-  val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
-  if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
-
-  status = jtagmkII_avr32_reset(pgm, 0x1f, 0x01, 0x00);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-  status = jtagmkII_avr32_reset(pgm, 0x01, 0x11, 0x1f);
-  if(status < 0) {lineno = __LINE__; goto eRR;}
-
-  for(;;) {
+  retP = ret;
+  for(loops=0; loops<1000; ++loops) {
     buf[0] = CMND_GET_IR;
     buf[1] = 0x0F;
     status = jtagmkII_send(pgm, buf, 2);
@@ -3025,36 +3001,10 @@ static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
     }
     x = resp[1];
     free(resp);
-    if(x == 0x01) break;
-  }
-  for(;;) {
-    buf[0] = CMND_GET_IR;
-    buf[1] = 0x0F;
-    status = jtagmkII_send(pgm, buf, 2);
-    if(status < 0) {lineno = __LINE__; goto eRR;}
-
-    status = jtagmkII_recv(pgm, &resp);
-    if (status != 2 || resp[0] != 0x87) {
-      {lineno = __LINE__; goto eRR;}
-    }
-    x = resp[1];
-    free(resp);
-    if(x == 0x05) break;
-  }
-  for(;;) {
-    buf[0] = CMND_GET_IR;
-    buf[1] = 0x0F;
-    status = jtagmkII_send(pgm, buf, 2);
-    if(status < 0) {lineno = __LINE__; goto eRR;}
-
-    status = jtagmkII_recv(pgm, &resp);
-    if (status != 2 || resp[0] != 0x87) {
-      {lineno = __LINE__; goto eRR;}
-    }
-    x = resp[1];
-    free(resp);
-    if(x== 0x01) break;
+    if(x == *retP) ++retP;
+    if(*retP == 0x00) break;
   }
+  if(loops == 1000) {lineno = __LINE__; goto eRR;}
 
   status = jtagmkII_avr32_reset(pgm, 0x00, 0x01, 0x01);
   if(status < 0) {lineno = __LINE__; goto eRR;}
@@ -3062,7 +3012,6 @@ static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
   val = jtagmkII_read_SABaddr(pgm, 0x00000010, 0x06);
   if(val != 0x00000000) {lineno = __LINE__; goto eRR;}
   
- 
   // AVR32 "special"
   buf[0] = CMND_SET_PARAMETER;  
   buf[1] = 0x03;
@@ -3071,8 +3020,6 @@ static int jtagmkII_chip_erase32(PROGRAMMER * pgm, AVRPART * p)
   status = jtagmkII_recv(pgm, &resp);
   if(status < 0 || resp[0] != RSP_OK) {lineno = __LINE__; goto eRR;}
   free(resp);
-    
-  // pgm->initialize(pgm, p);
 
   return 0;
   
@@ -3369,6 +3316,25 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   serial_recv_timeout = 256;
 
+  if(!(p->flags & AVRPART_WRITE)) {
+    status = jtagmkII_reset32(pgm, AVR32_RESET_READ);
+    if(status != 0) goto eRR;
+  }
+  
+  // Init SMC and set clocks
+  if(!(p->flags & AVRPART_INIT_SMC)) {
+    status = jtagmkII_smc_init32(pgm);
+    if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+    p->flags |= AVRPART_INIT_SMC;
+  }
+  
+  // Init SMC and set clocks
+  if(!(p->flags & AVRPART_INIT_SMC)) {
+    status = jtagmkII_smc_init32(pgm);
+    if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+    p->flags |= AVRPART_INIT_SMC;
+  }
+
   //fprintf(stderr, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", page_size, n_bytes, pages, m->offset, pgm->page_size);
 
   cmd[0] = CMND_READ_MEMORY32;
@@ -3377,6 +3343,8 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   addr = 0;
   for (addr = 0; addr < n_bytes; addr += block_size) {
+    report_progress(addr, n_bytes, NULL);
+
     block_size = ((n_bytes-addr) < pgm->page_size) ? (n_bytes - addr) : pgm->page_size;
     if (verbose >= 3)
       fprintf(stderr, "%s: jtagmkII_paged_load32(): "
@@ -3404,7 +3372,6 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     memcpy(m->buf + addr, resp + 1, block_size);
     free(resp);
 
-    report_progress(addr, n_bytes, NULL);
   }
 
   serial_recv_timeout = otimeout;
@@ -3416,7 +3383,6 @@ static int jtagmkII_paged_load32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   
   eRR:
     serial_recv_timeout = otimeout;
-    free(cmd);
     fprintf(stderr,
 	    "%s: jtagmkII_paged_load32(): "
 	    "failed at line %d (status=%x val=%lx)\n",
@@ -3438,6 +3404,10 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   
   if(n_bytes == 0) return -1;
 
+  status = jtagmkII_reset32(pgm, AVR32_RESET_WRITE);
+  if(status != 0) goto eRR;
+  p->flags |= AVRPART_WRITE;
+
   pages = (n_bytes-1)/page_size + 1;
   //fprintf(stderr, "\n pageSize=%d bytes=%d pages=%d m->offset=0x%x pgm->page_size %d\n", page_size, n_bytes, pages, m->offset, pgm->page_size);
 
@@ -3448,8 +3418,11 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   }
 
   // Init SMC and set clocks
-  status = jtagmkII_smc_init32(pgm);
-  if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+  if(!(p->flags & AVRPART_INIT_SMC)) {
+    status = jtagmkII_smc_init32(pgm);
+    if(status != 0) {lineno = __LINE__; goto eRR;} // PLL 0
+    p->flags |= AVRPART_INIT_SMC;
+  }
 
   // First unlock the pages
   for(pageNum=0; pageNum < pages; ++pageNum) {
@@ -3469,6 +3442,9 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   addr = 0;
   for(pageNum=0; pageNum < pages; ++pageNum) {
+  
+    report_progress(addr, n_bytes, NULL);
+
 #if 0
     val = jtagmkII_read_SABaddr(pgm, AVR32_FLASHC_FSR, 0x05);
     if(val == ERROR_SAB) {lineno = __LINE__; goto eRR;}
@@ -3512,10 +3488,7 @@ static int jtagmkII_paged_write32(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     }
     status = jtagmkII_flash_write_page32(pgm, pageNum);
     if(status < 0) {lineno = __LINE__; goto eRR;}
-
-    report_progress(addr, n_bytes, NULL);
   }
-
   free(cmd);
   serial_recv_timeout = otimeout;
 
diff --git a/lexer.l b/lexer.l
index 5e84ab00..0447d97a 100644
--- a/lexer.l
+++ b/lexer.l
@@ -150,6 +150,7 @@ has_debugwire    { yylval=NULL; return K_HAS_DW; }
 has_pdi          { yylval=NULL; return K_HAS_PDI; }
 id               { yylval=NULL; return K_ID; }
 idr              { yylval=NULL; return K_IDR; }
+is_avr32         { yylval=NULL; return K_IS_AVR32; }
 jtagmki          { yylval=NULL; return K_JTAG_MKI; }
 jtagmkii         { yylval=NULL; return K_JTAG_MKII; }
 jtagmkii_avr32   { yylval=NULL; return K_JTAG_MKII_AVR32; }
diff --git a/main.c b/main.c
index 2424d8ba..f9bd5477 100644
--- a/main.c
+++ b/main.c
@@ -723,7 +723,6 @@ int main(int argc, char * argv [])
   }
 
   if(p->flags & AVRPART_AVR32) {
-    if(erase) p->flags |= AVRPART_CHIP_ERASE;
     safemode = 0;
     auto_erase = 0;
   }