From d1c90c4ce2ff36a378ada2c3c4a32ee15fcbbf18 Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Wed, 18 Feb 2009 20:10:32 +0000 Subject: [PATCH] Submitted by Dick Streefland: patch #6749: make reading from the USBtinyISP programmer more robust Add code to retry failed communication attempts. git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk@799 81a1dc3b-b13d-400b-aceb-764788c761c2 --- avrdude/ChangeLog | 6 ++++++ avrdude/usbtiny.c | 49 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/avrdude/ChangeLog b/avrdude/ChangeLog index 67263374..7752d0ad 100644 --- a/avrdude/ChangeLog +++ b/avrdude/ChangeLog @@ -1,3 +1,9 @@ +2009-02-18 Joerg Wunsch + + Submitted by Dick Streefland: + patch #6749: make reading from the USBtinyISP programmer more robust + * usbtiny.c: Add code to retry failed communication attempts. + 2009-02-17 Joerg Wunsch Submitted by Nick Hibma: diff --git a/avrdude/usbtiny.c b/avrdude/usbtiny.c index 88ffcbfa..cfe0f0de 100644 --- a/avrdude/usbtiny.c +++ b/avrdude/usbtiny.c @@ -55,6 +55,7 @@ struct pdata usb_dev_handle *usb_handle; int sck_period; int chunk_size; + int retries; }; #define PDATA(pgm) ((struct pdata *)(pgm->cookie)) @@ -89,7 +90,7 @@ static int usb_control (PROGRAMMER * pgm, 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); } @@ -103,24 +104,37 @@ static int usb_in (PROGRAMMER * pgm, { 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( PDATA(pgm)->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( PDATA(pgm)->usb_handle, + USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + requestid, + val, index, + (char *)buffer, buflen, + timeout); + if (nbytes == buflen) { + return nbytes; + } + PDATA(pgm)->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 (PROGRAMMER * pgm, const char* operation) +{ + if (PDATA(pgm)->retries > 0 && quell_progress < 2) { + printf("%s: %d retries during %s\n", progname, + PDATA(pgm)->retries, operation); + } + PDATA(pgm)->retries = 0; } // Wrapper for simple usb_control_msg messages to send data to programmer @@ -142,7 +156,7 @@ static int usb_out (PROGRAMMER * pgm, (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); } @@ -249,7 +263,10 @@ static int usbtiny_set_sck_period (PROGRAMMER *pgm, double v) if (PDATA(pgm)->sck_period > SCK_MAX) PDATA(pgm)->sck_period = SCK_MAX; - printf( "%s: Setting SCK period to %d usec\n", progname, PDATA(pgm)->sck_period ); + if (verbose) { + printf( "%s: Setting SCK period to %d usec\n", progname, + PDATA(pgm)->sck_period ); + } // send the command to the usbtiny device. usb_control(pgm, USBTINY_POWERUP, PDATA(pgm)->sck_period, RESET_LOW); // MEME: for at90's fix resetstate? @@ -318,6 +335,7 @@ static int usbtiny_cmd(PROGRAMMER * pgm, unsigned char cmd[4], unsigned char res (cmd[1] << 8) | cmd[0], // convert to 16-bit words (cmd[3] << 8) | cmd[2], // " res, 4, 8 * PDATA(pgm)->sck_period ); + check_retries(pgm, "SPI command"); if (verbose > 1) { // print out the data we sent and received printf( "CMD: [%02x %02x %02x %02x] [%02x %02x %02x %02x]\n", @@ -399,6 +417,7 @@ static int usbtiny_paged_load (PROGRAMMER * pgm, AVRPART * p, AVRMEM* m, report_progress(i + chunk, n_bytes, NULL ); } + check_retries(pgm, "read"); return n_bytes; } @@ -450,7 +469,7 @@ static int usbtiny_paged_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, m->buf + i, // Pointer to data chunk, // Number of bytes to write 32 * PDATA(pgm)->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 );