Hi,

Here is a patch to make reading from the USBtinyISP programmer more
robust. The error recovery of the firmware in the programmer is very
limited, which means that avrdude bails out on the first transmission
error. A failed read request is now retried a number of times, and the
total number of retries is reported at the end. The remaining changes
are cosmetic.

This post is an example of a situation where avrdude bails out:

http://forums.ladyada.net/viewtopic.php?f=20&t=7647&p=37784

-- 
Dick
diff -pu avrdude-5.5/usbtiny.c.orig avrdude-5.5/usbtiny.c
--- avrdude-5.5/usbtiny.c.orig	2007-10-29 16:40:04.000000000 +0100
+++ avrdude-5.5/usbtiny.c	2009-01-16 22:33:09.000000000 +0100
@@ -50,6 +50,7 @@ extern int avr_write_byte_default ( PROG
 static	usb_dev_handle*	usb_handle;
 static	int		sck_period;
 static	int		chunk_size;
+static	int		retries;
 
 
 // ----------------------------------------------------------------------
@@ -65,7 +66,7 @@ static int usb_control (unsigned int req
 			    NULL, 0,              // no data buffer in control messge
 			    USB_TIMEOUT );        // default timeout
   if(nbytes < 0){
-    fprintf(stderr, "%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
+    fprintf(stderr, "\n%s: error: usbtiny_transmit: %s\n", progname, usb_strerror());
     exit(1);
   }
 
@@ -78,24 +79,36 @@ static int usb_in (unsigned int requesti
 {
   int nbytes;
   int timeout;
+  int i;
 
   // calculate the amout of time we expect the process to take by
   // figuring the bit-clock time and buffer size and adding to the standard USB timeout.
   timeout = USB_TIMEOUT + (buflen * bitclk) / 1000;
 
-  nbytes = usb_control_msg( usb_handle,
-			    USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			    requestid,
-			    val, index,
-			    (char *)buffer, buflen,
-			    timeout);
-  if (nbytes != buflen) {
-    fprintf(stderr, "%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
-	    progname, usb_strerror(), buflen, nbytes);
-    exit(1);
+  for (i = 0; i < 10; i++) {
+    nbytes = usb_control_msg( usb_handle,
+			      USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      requestid,
+			      val, index,
+			      (char *)buffer, buflen,
+			      timeout);
+    if (nbytes == buflen) {
+      return nbytes;
+    }
+    retries++;
   }
+  fprintf(stderr, "\n%s: error: usbtiny_receive: %s (expected %d, got %d)\n",
+          progname, usb_strerror(), buflen, nbytes);
+  exit(1);
+}
 
-  return nbytes;
+// Report the number of retries, and reset the counter.
+static void check_retries (char* operation)
+{
+  if (retries > 0 && quell_progress < 2) {
+    printf("%s: %d retries during %s\n", progname, retries, operation);
+    retries = 0;
+  }
 }
 
 // Wrapper for simple usb_control_msg messages to send data to programmer
@@ -116,7 +129,7 @@ static int usb_out (unsigned int request
 			    (char *)buffer, buflen,
 			    timeout);
   if (nbytes != buflen) {
-    fprintf(stderr, "%s: error: usbtiny_send: %s (expected %d, got %d)\n",
+    fprintf(stderr, "\n%s: error: usbtiny_send: %s (expected %d, got %d)\n",
 	    progname, usb_strerror(), buflen, nbytes);
     exit(1);
   }
@@ -223,7 +236,9 @@ static int usbtiny_set_sck_period (PROGR
   if  (sck_period > SCK_MAX)
     sck_period = SCK_MAX;
 
-  printf( "%s: Setting SCK period to %d usec\n", progname, sck_period );
+  if (verbose) {
+    printf( "%s: Setting SCK period to %d usec\n", progname, sck_period );
+  }
 
   // send the command to the usbtiny device.
   usb_control(USBTINY_POWERUP, sck_period, RESET_LOW);  // MEME: for at90's fix resetstate?
@@ -292,6 +307,7 @@ static int usbtiny_cmd(PROGRAMMER * pgm,
 		   (cmd[1] << 8) | cmd[0],  // convert to 16-bit words
 		   (cmd[3] << 8) | cmd[2],  //  "
 			res, sizeof(res), 8 * sck_period );
+  check_retries("SPI command");
   if (verbose > 1) {
     // print out the data we sent and received
     printf( "CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n",
@@ -371,7 +387,7 @@ static int usbtiny_paged_load (PROGRAMME
     // Tell avrdude how we're doing to provide user feedback
     report_progress(i + chunk, n_bytes, NULL );
   }
-
+  check_retries("read");
   return n_bytes;
 }
 
@@ -422,7 +438,7 @@ static int usbtiny_paged_write(PROGRAMME
 	    m->buf + i,     // Pointer to data
 	    chunk,          // Number of bytes to write
 	    32 * sck_period + delay  // each byte gets turned into a
-	                             // 4-byte SPI cmd  usb_in() multiplies
+	                             // 4-byte SPI cmd  usb_out() multiplies
 	                             // this per byte. Then add the cmd-delay
 	    );
 
_______________________________________________
avrdude-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/avrdude-dev

Reply via email to