From b7810ccb403ed613280734882de42a6f2b101f0e Mon Sep 17 00:00:00 2001
From: "Brian S. Dean" <bsd@bsdhome.com>
Date: Sun, 28 Aug 2005 22:23:35 +0000
Subject: [PATCH] This is patch # 4338, obsoletes patch #4327, provides fixes
 for bugs #13693, #13871, and #14212.

This provides bug fixes to the STK500V2 programmer type.  From the
patch information:

    - incorrect token used from avrdude.conf.in

    - wrong command sent to programmer, hence no write to eeprom.

    - programmer was said to start writing at 0x0000 and continue page
      by page and was not repositionned when a gap was found in the
      hex file, or when the hex file start address was not
      0x0000. Hence the verify procedure was correct, not the write
      procedure.

    - speed up of flash write to skip empty pages (full of 0xFF) by
      re-enabling a dedicated function for that task.

    - stk500v2_paged_load() was not returning the number of byte read,
      so empty hex files were generated when reading memory.

Submitted by:  Bernard Fouch <bernard.fouche@kuantic.com>


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@490 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 avrdude/avrdude.conf.in |  9 +++++----
 avrdude/stk500v2.c      | 29 ++++++++++++++++++++++-------
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/avrdude/avrdude.conf.in b/avrdude/avrdude.conf.in
index 7b2fae76..4e229bba 100644
--- a/avrdude/avrdude.conf.in
+++ b/avrdude/avrdude.conf.in
@@ -1782,12 +1782,12 @@ part
         max_write_delay = 9000;
         readback_p1     = 0xff;
         readback_p2     = 0xff;
-	read            = "  1   0   1   0      0   0   0   0",
+	read_lo           = "  1   0   1   0      0   0   0   0",
                           "  x   x   x   x    a11 a10  a9  a8",
                           " a7  a6  a5  a4     a3  a2  a1  a0",
                           "  o   o   o   o      o   o   o   o";
 
-	write           = "  1   1   0   0      0   0   0   0",
+	write_lo           = "  1   1   0   0      0   0   0   0",
                           "  x   x   x   x    a11 a10  a9  a8",
                           " a7  a6  a5  a4     a3  a2  a1  a0", 
                           "  i   i   i   i      i   i   i   i";
@@ -1817,6 +1817,7 @@ part
                           " a7  a6  a5  a4     a3  a2  a1  a0",
                           "  o   o   o   o      o   o   o   o";
 
+
         loadpage_lo     = "  0   1   0   0      0   0   0   0",
                           "  x   x   x   x      x   x   x   x",
                           "  x  a6  a5  a4     a3  a2  a1  a0",
@@ -1934,12 +1935,12 @@ part
         max_write_delay = 9000;
         readback_p1     = 0xff;
         readback_p2     = 0xff;
-	read            = "  1   0   1   0      0   0   0   0",
+	read_lo            = "  1   0   1   0      0   0   0   0",
                           "  x   x   x   x    a11 a10  a9  a8",
                           " a7  a6  a5  a4     a3  a2  a1  a0",
                           "  o   o   o   o      o   o   o   o";
 
-	write           = "  1   1   0   0      0   0   0   0",
+	write_lo           = "  1   1   0   0      0   0   0   0",
                           "  x   x   x   x    a11 a10  a9  a8",
                           " a7  a6  a5  a4     a3  a2  a1  a0", 
                           "  i   i   i   i      i   i   i   i";
diff --git a/avrdude/stk500v2.c b/avrdude/stk500v2.c
index b6361b98..eaf54095 100644
--- a/avrdude/stk500v2.c
+++ b/avrdude/stk500v2.c
@@ -495,7 +495,8 @@ static int stk500v2_loadaddr(PROGRAMMER * pgm, unsigned int addr)
 static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, 
                               int page_size, int n_bytes)
 {
-  int addr, block_size;
+  int addr, block_size, last_addr;
+  int a_div=1;
   unsigned char commandbuf[10];
   unsigned char buf[266];
   unsigned char cmds[4];
@@ -507,6 +508,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   // determine which command is to be used
   if (strcmp(m->desc, "flash") == 0) {
+    a_div=2;
     commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
   } else if (strcmp(m->desc, "eeprom") == 0) {
     commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
@@ -543,7 +545,8 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       return -1;
     }
     avr_set_bits(m->op[AVR_OP_WRITE_LO], cmds);
-    commandbuf[6] = cmds[0];
+    commandbuf[5] = cmds[0];
+    commandbuf[6] = 0;
   }
 
   // the read command is common to both methods
@@ -558,7 +561,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   commandbuf[8] = m->readback[0];
   commandbuf[9] = m->readback[1];
 
-  stk500v2_loadaddr(pgm, 0);
+  last_addr=-1;
 
   for (addr=0; addr < n_bytes; addr += page_size) {
     report_progress(addr,n_bytes,NULL);
@@ -567,13 +570,25 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
       block_size = n_bytes - addr;
     else
       block_size = page_size;
+
     DEBUG("block_size at addr %d is %d\n",addr,block_size);
 
+    if(commandbuf[0] == CMD_PROGRAM_FLASH_ISP){
+      if (stk500v2_is_page_empty(addr, block_size, m->buf)) {
+          continue;
+      }
+    }
+
     memcpy(buf,commandbuf,sizeof(commandbuf));
 
     buf[1] = block_size >> 8;
     buf[2] = block_size & 0xff;
 
+    if((last_addr==-1)||(last_addr+block_size != addr)){
+      stk500v2_loadaddr(pgm, addr/a_div);
+    }
+    last_addr=addr;
+
     memcpy(buf+10,m->buf+addr, block_size);
 
     result = stk500v2_command(pgm,buf,block_size+10, sizeof(buf));
@@ -609,7 +624,7 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   unsigned char commandbuf[4];
   unsigned char buf[275];	// max buffer size for stk500v2 at this point
   unsigned char cmds[4];
-  int result, i;
+  int result;
 
   DEBUG("STK500V2: stk500v2_paged_load(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
 
@@ -624,7 +639,7 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   // the read command is common to both methods
   if (m->op[AVR_OP_READ_LO] == NULL) {
-    fprintf(stderr, "%s: stk500v2_paged_write: read instruction not defined for part \"%s\"\n",
+    fprintf(stderr, "%s: stk500v2_paged_load: read instruction not defined for part \"%s\"\n",
             progname, p->desc);
     return -1;
   }
@@ -649,7 +664,7 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
     result = stk500v2_command(pgm,buf,4,sizeof(buf));
     if (buf[1] != STATUS_CMD_OK) {
-      fprintf(stderr,"%s: stk500v2_paged_write: read command failed with %d\n",
+      fprintf(stderr,"%s: stk500v2_paged_load: read command failed with %d\n",
               progname,buf[1]);
       return -1;
     }
@@ -663,7 +678,7 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     memcpy(&m->buf[addr], &buf[2], block_size);
   }
 
-  return 0;
+  return n_bytes;
 }