From 024ef322d7819f89dfd368101d5319715d969176 Mon Sep 17 00:00:00 2001
From: joerg_wunsch <joerg_wunsch@81a1dc3b-b13d-400b-aceb-764788c761c2>
Date: Thu, 25 May 2006 14:38:08 +0000
Subject: [PATCH] Implement extended addressing needed for the ATmega256x
 devices.

Document ATmega256x support.  Also document Solaris port defaults
in avrdude.texi.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@584 81a1dc3b-b13d-400b-aceb-764788c761c2
---
 ChangeLog        |  8 ++++++++
 avrdude.1        | 18 ++++++++++------
 doc/avrdude.texi | 19 ++++++++++++++++-
 stk500v2.c       | 53 ++++++++++++++++++++++++++++++++++++++----------
 4 files changed, 80 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 525bb17f..ef833f26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-05-25 Joerg Wunsch <j@uriah.heep.sax.de>
+
+	* stk500v2.c: Implement extended addressing needed
+	for the ATmega256x devices.
+	* avrdude.1: Document ATmega256x support.
+	* doc/avrdude.texi: Document ATmega256x support.
+	Also document Solaris port defaults.
+
 2006-05-24 Joerg Wunsch <j@uriah.heep.sax.de>
 
 	* avr.c: Start implementing support for ATmega256x;
diff --git a/avrdude.1 b/avrdude.1
index e631c913..73dd9e10 100644
--- a/avrdude.1
+++ b/avrdude.1
@@ -1,6 +1,6 @@
 .\"
 .\" avrdude - A Downloader/Uploader for AVR device programmers
-.\" Copyright (C) 2001, 2002, 2003, 2005  Joerg Wunsch
+.\" Copyright (C) 2001, 2002, 2003, 2005, 2006  Joerg Wunsch
 .\"
 .\" This program is free software; you can redistribute it and/or modify
 .\" it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
 .\"
 .\" $Id$
 .\"
-.Dd DATE November 29, 2005
+.Dd DATE May 25, 2006
 .Os
 .Dt AVRDUDE 1
 .Sh NAME
@@ -170,21 +170,23 @@ pwm3	AT90PWM3
 8535	AT90S8535
 m103	ATmega103
 m128	ATmega128
-m1280   ATmega1280
-m1281   ATmega1281
+m1280	ATmega1280
+m1281	ATmega1281
 m16	ATmega16
 m161	ATmega161
 m162	ATmega162
 m163	ATmega163
 m164	ATmega164
 m169	ATmega169
+m2560	ATmega2560 (**)
+m2561	ATmega2561 (**)
 m32	ATmega32
 m324	ATmega324
 m329	ATmega329
 m3290	ATmega3290
 m48	ATmega48
 m64	ATmega64
-m640    ATmega640
+m640	ATmega640
 m644	ATmega644
 m649	ATmega649
 m6490	ATmega6490
@@ -201,9 +203,13 @@ t26	ATtiny26
 t45	ATtiny45
 t85	ATtiny85
 .TE
-.Bl -tag -width "(*) "
+.Bl -tag -width "(**) "
 .It "(*)"
 The AT90S2323 and ATtiny22 use the same algorithm.
+.It "(**)"
+Flash addressing above 128 KB is not supported by all
+programming hardware.  Known to work are jtag2, stk500v2,
+and bit-bang programmers.
 .El
 .It Fl b Ar baudrate
 Override the RS-232 connection baud rate specified in the respective
diff --git a/doc/avrdude.texi b/doc/avrdude.texi
index d693de8c..9949af3a 100644
--- a/doc/avrdude.texi
+++ b/doc/avrdude.texi
@@ -28,7 +28,7 @@ This file documents the avrdude program.
 
 For avrdude version @value{VERSION}, @value{UPDATED}.
 
-Copyright @copyright{} 2003, 2005 Brian Dean
+Copyright @copyright{} 2003, 2005, 2006 Brian Dean
 
 Permission is granted to make and distribute verbatim copies of
 this manual provided the copyright notice and this permission notice
@@ -316,6 +316,12 @@ ATmega164
 @itemx m169
 ATmega169
 
+@itemx m2560
+ATmega2560 (**)
+
+@itemx m2561
+ATmega2561 (**)
+
 @itemx m32
 ATmega32
 
@@ -386,6 +392,10 @@ ATtiny85
 
 (*)   The AT90S2323 and ATtiny22 use the same algorithm.
 
+(**)  Flash addressing above 128 KB is not supported by all
+programming hardware.  Known to work are jtag2, stk500v2,
+and bit-bang programmers.
+
 @item -b @var{baudrate}
 Override the RS-232 connection baud rate specified in the respective
 programmer's entry of the configuration file.
@@ -1520,6 +1530,9 @@ The following table lists the default names for a given system.
 @item Linux
   @tab @code{/dev/parport0}
   @tab @code{/dev/ttyS0}
+@item Solaris
+  @tab @code{/dev/printers/0}
+  @tab @code{/dev/term/a}
 @end multitable
 
 On FreeBSD systems, AVRDUDE uses the ppi(4) interface for
@@ -1530,6 +1543,10 @@ On Linux systems, AVRDUDE uses the ppdev interface for
 accessing the parallel port and the tty driver for serial port
 access.
 
+On Solaris systems, AVRDUDE uses the ecpp(7D) driver for
+accessing the parallel port and the asy(7D) driver for serial port
+access.
+
 @c
 @c Node
 @c
diff --git a/stk500v2.c b/stk500v2.c
index f42f897c..a7ed9268 100644
--- a/stk500v2.c
+++ b/stk500v2.c
@@ -41,6 +41,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <unistd.h>
 #include <sys/time.h>
 #include <time.h>
@@ -554,8 +555,7 @@ 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, last_addr;
-  int a_div=1;
+  unsigned int addr, block_size, last_addr, hiaddr, addrshift, use_ext_addr;
   unsigned char commandbuf[10];
   unsigned char buf[266];
   unsigned char cmds[4];
@@ -565,17 +565,29 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   DEBUG("STK500V2: stk500v2_paged_write(..,%s,%d,%d)\n",m->desc,page_size,n_bytes);
 
   if (page_size == 0) page_size = 256;
+  hiaddr = UINT_MAX;
+  addrshift = 0;
+  use_ext_addr = 0;
 
   // determine which command is to be used
   if (strcmp(m->desc, "flash") == 0) {
-    a_div=2;
+    addrshift = 1;
     commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
+    /*
+     * If bit 31 is set, this indicates that the following read/write
+     * operation will be performed on a memory that is larger than
+     * 64KBytes. This is an indication to STK500 that a load extended
+     * address must be executed.
+     */
+    if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+      use_ext_addr = (1U << 31);
+    }
   } else if (strcmp(m->desc, "eeprom") == 0) {
     commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
   }
   commandbuf[4] = m->delay;
 
-  if (a_div == 1) {
+  if (addrshift == 0) {
     wop = m->op[AVR_OP_WRITE];
     rop = m->op[AVR_OP_READ];
   }
@@ -631,7 +643,7 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   commandbuf[8] = m->readback[0];
   commandbuf[9] = m->readback[1];
 
-  last_addr=-1;
+  last_addr=UINT_MAX;		/* impossible address */
 
   for (addr=0; addr < n_bytes; addr += page_size) {
     report_progress(addr,n_bytes,NULL);
@@ -654,8 +666,8 @@ static int stk500v2_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     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);
+    if((last_addr==UINT_MAX)||(last_addr+block_size != addr)){
+      stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift));
     }
     last_addr=addr;
 
@@ -690,7 +702,7 @@ static int stk500v2_is_page_empty(unsigned int address, int page_size,
 static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
                              int page_size, int n_bytes)
 {
-  int addr, block_size;
+  unsigned int addr, block_size, hiaddr, addrshift, use_ext_addr;
   unsigned char commandbuf[4];
   unsigned char buf[275];	// max buffer size for stk500v2 at this point
   unsigned char cmds[4];
@@ -703,11 +715,25 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
 
   rop = m->op[AVR_OP_READ];
 
+  hiaddr = UINT_MAX;
+  addrshift = 0;
+  use_ext_addr = 0;
+
   // determine which command is to be used
   if (strcmp(m->desc, "flash") == 0) {
     commandbuf[0] = CMD_READ_FLASH_ISP;
     rop = m->op[AVR_OP_READ_LO];
-  } 
+    addrshift = 1;
+    /*
+     * If bit 31 is set, this indicates that the following read/write
+     * operation will be performed on a memory that is larger than
+     * 64KBytes. This is an indication to STK500 that a load extended
+     * address must be executed.
+     */
+    if (m->op[AVR_OP_LOAD_EXT_ADDR] != NULL) {
+      use_ext_addr = (1U << 31);
+    }
+  }
   else if (strcmp(m->desc, "eeprom") == 0) {
     commandbuf[0] = CMD_READ_EEPROM_ISP;
   }
@@ -721,8 +747,6 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
   avr_set_bits(rop, cmds);
   commandbuf[3] = cmds[0];
 
-  stk500v2_loadaddr(pgm, 0);
-
   for (addr=0; addr < n_bytes; addr += page_size) {
     report_progress(addr, n_bytes,NULL);
 
@@ -737,6 +761,13 @@ static int stk500v2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m,
     buf[1] = block_size >> 8;
     buf[2] = block_size & 0xff;
 
+    // Ensure a new "load extended address" will be issued
+    // when crossing a 64 KB boundary in flash.
+    if (hiaddr != (addr & ~0xFFFF)) {
+      hiaddr = addr & ~0xFFFF;
+      stk500v2_loadaddr(pgm, use_ext_addr | (addr >> addrshift));
+    }
+
     result = stk500v2_command(pgm,buf,4,sizeof(buf));
     if (buf[1] != STATUS_CMD_OK) {
       fprintf(stderr,"%s: stk500v2_paged_load: read command failed with %d\n",