File uisp_fastpoll_3712.patch of Package uisp

diff -Nru uisp-cvs-2005-02-01/src/Avr.C uisp-cvs-2005-02-01-patched/src/Avr.C
--- uisp-cvs-2005-02-01/src/Avr.C	2004-12-28 09:54:11.000000000 -0500
+++ uisp-cvs-2005-02-01-patched/src/Avr.C	2005-02-01 02:05:46.000000000 -0500
@@ -44,7 +44,7 @@
 
 /* ATMEL AVR codes */
 TAvr::TPart TAvr::parts [] = {
-  /* device         sig. bytes   flash page EEPROM twdFL twdEE  flags */
+  /* device_name    sig. bytes   flash page EEPROM twdFL twdEE  flags */
   { "AT90S1200",    0x90, 0x01,   1024,   0,   64,  4000, 4000, AVR_1200 },
 
   { "ATtiny12",     0x90, 0x05,   1024,   0,   64,  1700, 3400, AVR_TN12 },
@@ -65,7 +65,7 @@
   { "ATtiny22",     0x91, 0x06,   2048,   0,  128,  4000, 4000, AVR_TN22 },
 
   { "ATtiny26",     0x91, 0x09,   2048,  32,  128,  4500, 9000, AVR_TN26 },
-  { "ATtiny2313",   0x91, 0x0A,   2048,   0,  128,  4000, 4000, AVR_TN2313 },
+  { "ATtiny2313",   0x91, 0x0A,   2048,  32,  128,  4500, 4000, AVR_TN2313 },
 
 #if 0
   /* 12V parallel programming only; here just for the evidence */
@@ -77,7 +77,7 @@
   /* no longer in production? -> use 8515, 8535 instead */
   { "AT90S4414",    0x92, 0x01,   4096,   0,  256,  4000, 4000, AVR_2313 },
   { "AT90S4434",    0x92, 0x02,   4096,   0,  256,  4000, 4000, AVR_8535 },
-  { "ATmega48",     0x92, 0x05,   4096,   0,  256,  4000, 4000, AVR_M163 },
+  { "ATmega48",     0x92, 0x05,   4096,  64,  256,  4500, 4000, AVR_M48 },
 
   { "AT90S8515",    0x93, 0x01,   8192,   0,  512,  4000, 4000, AVR_2313 },
   { "AT90S8535",    0x93, 0x03,   8192,   0,  512,  4000, 4000, AVR_8535 },
@@ -90,7 +90,7 @@
   { "ATmega8515",   0x93, 0x06,   8192,  64,  512,  4500, 9000, AVR_M163 },
   { "ATmega8",      0x93, 0x07,   8192,  64,  512,  4500, 9000, AVR_M163 },
   { "ATmega8535",   0x93, 0x08,   8192,  64,  512,  4500, 9000, AVR_M163 },
-  { "ATmega88",     0x93, 0x0a,   8192,  64,  512,  4000, 4000, AVR_M163 },
+  { "ATmega88",     0x93, 0x0a,   8192,  64,  512,  4500, 4000, AVR_M48 },
 
 #if 0
   /* 12V parallel programming only; here just for the evidence */
diff -Nru uisp-cvs-2005-02-01/src/Avr.h uisp-cvs-2005-02-01-patched/src/Avr.h
--- uisp-cvs-2005-02-01/src/Avr.h	2004-03-30 21:25:44.000000000 -0500
+++ uisp-cvs-2005-02-01-patched/src/Avr.h	2005-02-01 02:10:40.000000000 -0500
@@ -99,6 +99,9 @@
 /* Read Lock Bits at bits 4, 3, 2. */
 #define AT89S_LOCK_RD432	0x1000
 
+/* Some newer devices use Ready/Busy page-polling for Flash/EEPROM */
+#define AVR_RDY_BSY	0x2000
+
 /* Aliases. */
 #define AT89S_BYTE_POLL	AVR_BYTE_POLL
 #define AT89S_PAGE_POLL AVR_PAGE_POLL
@@ -127,9 +130,12 @@
 #define AVR_TN26 (AVR_BYTE_POLL | AVR_PAGE_POLL | AVR_LOCK_BOOT | AVR_FUSE_RD \
 		  | AVR_FUSE_NEWWR | AVR_CAL_RD | AVR_FUSE_HIGH)
 
-#define AVR_TN2313 (AVR_BYTE_POLL | AVR_PAGE_POLL | AVR_LOCK_BOOT \
-                    | AVR_FUSE_RD | AVR_FUSE_NEWWR | AVR_CAL_RD \
-                    | AVR_FUSE_HIGH | AVR_FUSE_EXT) 
+#define AVR_TN2313 (AVR_RDY_BSY | AVR_LOCK_BOOT | AVR_FUSE_RD \
+		| AVR_FUSE_NEWWR | AVR_CAL_RD | AVR_FUSE_HIGH | AVR_FUSE_EXT)
+
+#define AVR_M48 (AVR_RDY_BSY | AVR_LOCK_BOOT | AVR_FUSE_RD \
+		| AVR_FUSE_NEWWR | AVR_CAL_RD | AVR_FUSE_HIGH | AVR_FUSE_EXT)
+ 
 
 #define AT89S51 (AT89S | AT89S_BYTE_POLL | AT89S_LOCK_RD432)
 #define AT89S52 (AT89S | AT89S_BYTE_POLL | AT89S_LOCK_RD432)
diff -Nru uisp-cvs-2005-02-01/src/AvrDummy.C uisp-cvs-2005-02-01-patched/src/AvrDummy.C
--- uisp-cvs-2005-02-01/src/AvrDummy.C	2004-02-07 14:19:46.000000000 -0500
+++ uisp-cvs-2005-02-01-patched/src/AvrDummy.C	2005-02-02 00:19:12.000000000 -0500
@@ -99,6 +99,11 @@
   bool poll_data = use_data_polling && TestFeatures(AVR_PAGE_POLL)
 		   && (page_poll_byte != 0xFF);
 
+  bool poll_rdybsy = use_data_polling && TestFeatures(AVR_RDY_BSY);
+
+  TByte rbyte = 0xFF;
+
+  /* "Write Program Memory Page" serial instruction: */
   TByte prg_page [4] = { 0x4C,
 			(TByte)((page_addr >> 9) & 0xff),
 			(TByte)((page_addr >> 1) & 0xff),
@@ -115,11 +120,15 @@
   gettimeofday(&t_start_poll, NULL);
   timeradd(&t_start_poll, &t_wait, &t_timeout);
 
-  /* Wait */
+  /* Wait in a busy loop upto t_wd_flash usecs, unless polling returns */
   do {
     gettimeofday(&t_end, NULL);
-    if (poll_data) {
-      TByte rbyte = ReadByte(page_poll_addr);
+    if (poll_rdybsy) {
+      rbyte = ReadReadyBusy();
+      if ((rbyte & 0x01) == 0x0)
+        break;
+    } else if (poll_data) {
+      rbyte = ReadByte(page_poll_addr);
       if (rbyte == page_poll_byte)
 	break;
     }
@@ -127,7 +136,7 @@
 
   /* Write Statistics */
   timersub(&t_end, &t_start_wr, &t_write);  /* t_write = t_end - t_start_wr */
-  if (poll_data) {
+  if (poll_data || poll_rdybsy) {
     float write_time = 1.0e-6 * t_write.tv_usec + t_write.tv_sec;
     total_poll_time += write_time;
     if (max_poll_time < write_time)
@@ -204,6 +213,18 @@
 }
 
 /*
+ Read/Poll Ready/Busy:    7     6     5     4     3     2     1     0
+ tn2313,m48,m88,m168:     x     x     x     x     x     x     x   1=BUSY
+ */
+TByte
+TAvrDummy::ReadReadyBusy()
+{
+  TByte rdybsy[4] = { 0xF0, 0x00, 0x00, 0x01};
+  Send(rdybsy, 4);
+  return rdybsy[3];
+}
+
+/*
  Read Lock/Fuse Bits:           7     6     5     4     3     2     1     0
  2333,4433,m103,m603,tn12,tn15: x     x     x     x     x     LB2   LB1   x
  2323,8535:                     LB1   LB2   SPIEN x     x     x     x     FSTRT
@@ -350,6 +371,8 @@
   bool poll_data = ((segment==SEG_FLASH && !page_size) || segment==SEG_EEPROM)
 		   && use_data_polling && TestFeatures(AVR_BYTE_POLL);
 
+  bool poll_rdybsy = use_data_polling && TestFeatures(AVR_RDY_BSY);
+
   CheckMemoryRange(addr);
   
   /* For speed, don't program a byte that is already there
@@ -389,6 +412,7 @@
     if (at89)
       addr <<= 1;
 
+    /* Load program memory page */
     TByte hl = (addr & 1) ? 0x48 : 0x40;
     TByte flash [4] = { hl,
 			(TByte)((addr >> 9) & 0xff),
@@ -460,9 +484,14 @@
        so it has much better (microsecond) resolution.  
     */
     gettimeofday(&t_end, NULL);
-    if (poll_data){
+
+    if (poll_rdybsy) {
+      rbyte = ReadReadyBusy();
+      if ((rbyte & 0x01) == 0x0)
+        break;
+    } else if (poll_data) {
       if ((byte == (rbyte = ReadByte(addr))) &&
-          (byte != 0) && (byte != 0x7F) && (byte != 0x80) && (byte != 0xFF)){
+          (byte != 0) && (byte != 0x7F) && (byte != 0x80) && (byte != 0xFF)) {
 	break;
       }
     }
@@ -470,7 +499,7 @@
   
   /* Write Statistics */
   timersub(&t_end, &t_start_wr, &t_write);  /* t_write = t_end - t_start_wr */
-  if (poll_data) {
+  if (poll_data || poll_rdybsy) {
     float write_time = 1.0e-6 * t_write.tv_usec + t_write.tv_sec;
     total_poll_time += write_time;
     if (max_poll_time < write_time)
diff -Nru uisp-cvs-2005-02-01/src/AvrDummy.h uisp-cvs-2005-02-01-patched/src/AvrDummy.h
--- uisp-cvs-2005-02-01/src/AvrDummy.h	2002-05-25 13:59:46.000000000 -0400
+++ uisp-cvs-2005-02-01-patched/src/AvrDummy.h	2005-02-01 23:43:27.000000000 -0500
@@ -41,6 +41,7 @@
   void EnableAvr();
   TByte GetPartInfo(TAddr addr);
   void WriteProgramMemoryPage();
+  TByte ReadReadyBusy();
   TByte ReadLockFuseBits();
   TByte ReadFuseLowBits();
   TByte ReadFuseHighBits();
diff -Nru uisp-cvs-2005-02-01/src/Main.C uisp-cvs-2005-02-01-patched/src/Main.C
--- uisp-cvs-2005-02-01/src/Main.C	2004-11-16 22:18:33.000000000 -0500
+++ uisp-cvs-2005-02-01-patched/src/Main.C	2005-02-01 23:59:34.000000000 -0500
@@ -66,7 +66,7 @@
 "Syntax: uisp [-v{=level}] [-h] [--help] [--version] [--hash=perbytes]\n"
 "             [-dprog=avr910|pavr|stk500]"
 #ifndef NO_DAPA
-" [-dprog=type]\n"
+"             [-dprog=type]\n"
 "             [-dlpt=address|/dev/parportX] [-dno-poll] [-dno-retry]\n"
 "             [-dvoltage=...] [-dt_sck=time] [-dt_wd_{flash|eeprom}=time]\n"
 "             [-dt_reset=time] [-dinvert=sck,mosi,miso,reset]"
@@ -79,7 +79,8 @@
 "             [--download] [--size=bytes] [of=output_file]\n"
 "             [--segment=flash|eeprom|fuse] [--terminal]\n"
 "             [--rd_fuses] [--wr_fuse_l=byte] [--wr_fuse_h=byte]\n"
-"             [--wr_fuse_e=byte] [--wr_lock=byte]\n\n"
+"             [--wr_fuse_e=byte] [--wr_lock=byte]\n"
+"\n"
 "Programming Methods:\n"
 "  -dprog=avr910    Standard Atmel Serial Programmer/Atmel Low Cost Programmer\n"
 "         pavr      http://www.avr1.org/pavr/pavr.html\n"
@@ -266,6 +267,7 @@
   try{
     const char* val;
 
+    device = NULL;
     val = GetCmdParam("-dprog");
     /* backwards compatibility, -datmel is now -dprog=avr910 */
     if (GetCmdParam("-datmel", false))
@@ -298,7 +300,8 @@
       if (argv_ok[i]==0 && strncmp(argv[i], "-d", 2)==0){
         Info(0,"Invalid parameter: %s\n", argv[i]); exit(1);
       }
-    }    
+    }
+
     if (device()==NULL){
       throw Error_Device("Programming method is not selected.");
     }
@@ -429,13 +432,13 @@
     /* Check bad command line parameters */
     for (int i=1; i<argc; i++){
       if (argv_ok[i]==0){Info(0,"Invalid parameter: %s\n", argv[i]);}
-    }  
-  } 
+    }
+  }
   catch(Error_C& errC){perror("Error"); errC.print(); return_val=1;}
   catch(Error_Device& errDev){errDev.print(); return_val=2;}
   catch(Error_MemoryRange& x){
     Info(0, "Address out of memory range.\n"); return_val=3;
-  }    
+  }
   // free(argv_ok);
   return return_val;
 }