Hi again,

On Saturday 07 December 2013 13:46, I wrote:
> In brief:
> When programming the ATMega2560 using an stk500 (v1) compatible ISP,
> avrdude doesn't set the extended address byte in the target device.  As a
> result it cannot be certain whether it is programming above or below the
> 128K bytes threshold.  One manifestation of this is reports of verify
> errors at 0x1e000 when programming the Mega2560 bootloader using the
> ArduinoISP.  A patch that resolves this is attached - modifying the stk500
> code to set the extended byte when necessary.

<snip>

> This could be fixed in other different ways - and may be better pushed up
> the layers in avrdude into avr.c; I am posting for your comments, awareness
> etc. If there is important info missed, ask and I will try to respond.

Had more chance to study the workings of avrdude (rather than being focused on 
the ISP<->target-SPI interactions) and have re-worked the fix-patch along the 
lines of other code in avrdude that handles the ext_addr_byte, using the 
OPCODE etc.- so here is version 2.

Hopefully this is much closer to a correct solution here - so I would 
appreciate review comments etc and consideration for inclusion.  Then stk500 
could perhaps be added to the list of ISPs that work with the Mega2560?

With this patch applied, programming either half of the Mega2560 256K flash 
works correctly with an stk500 (v1) ISP.

Regards

Alan
--- stk500-orig.c	2011-09-15 15:37:04.000000000 +0100
+++ stk500.c	2013-12-08 20:06:54.000000000 +0000
@@ -45,6 +45,8 @@
 
 #define STK500_XTAL 7372800U
 
+static unsigned char ext_addr_byte; /* Record ext-addr byte set in the target device (if used) */
+
 static int stk500_getparm(PROGRAMMER * pgm, unsigned parm, unsigned * value);
 static int stk500_setparm(PROGRAMMER * pgm, unsigned parm, unsigned value);
 static void stk500_print_parms1(PROGRAMMER * pgm, const char * p);
@@ -427,6 +429,7 @@
     n_extparms = 3;
 
   tries = 0;
+  ext_addr_byte = 0xff; /* Ensures it is programmed before first memory address */
 
  retry:
   tries++;
@@ -689,14 +692,30 @@
 }
 
 
-static int stk500_loadaddr(PROGRAMMER * pgm, unsigned int addr)
+static int stk500_loadaddr(PROGRAMMER * pgm, AVRMEM * mem, unsigned int addr)
 {
   unsigned char buf[16];
   int tries;
+  unsigned char ext_byte;
+  OPCODE * lext;
 
   tries = 0;
  retry:
   tries++;
+
+  /* To support flash > 64K words the correct Extended Address Byte is needed */
+  lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
+  if (lext != NULL) {
+    ext_byte = (addr >> 16) & 0xff;
+    if (ext_byte != ext_addr_byte) {
+      /* Either this is the first addr load, or a 64K word boundary is crossed, so set the ext addr byte */
+      avr_set_bits(lext, buf);
+      avr_set_addr(lext, buf, addr);
+      stk500_cmd(pgm, buf, buf);
+      ext_addr_byte = ext_byte;
+    }
+  }
+
   buf[0] = Cmnd_STK_LOAD_ADDRESS;
   buf[1] = addr & 0xff;
   buf[2] = (addr >> 8) & 0xff;
@@ -822,7 +841,7 @@
     tries = 0;
   retry:
     tries++;
-    stk500_loadaddr(pgm, addr/a_div);
+    stk500_loadaddr(pgm, m, addr/a_div);
 
     /* build command block and avoid multiple send commands as it leads to a crash
         of the silabs usb serial driver on mac os x */
@@ -939,7 +958,7 @@
     tries = 0;
   retry:
     tries++;
-    stk500_loadaddr(pgm, addr/a_div);
+    stk500_loadaddr(pgm, m, addr/a_div);
     buf[0] = Cmnd_STK_READ_PAGE;
     buf[1] = (block_size >> 8) & 0xff;
     buf[2] = block_size & 0xff;
_______________________________________________
avrdude-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avrdude-dev

Reply via email to