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