Contributed by dcm@mit.edu: add support for the

AVRISP mkII device. (Savannah patch #4789.)
* serial.h: Declare usb_serdev_frame device descriptor.
* stk500v2.c: Implementation of the AVRISP mkII handling.
* usb_libusb.c: Add USB handling for short-frame delimited
AVRISP mkII USB protocol; add distinction of different
devices in usbdev_open().
* jtagmkII.c: Tell usbdev_open() to search for the JTAG ICE mkII.
* usbdevs.h: (New file.)
* Makefile.am: Add usbdevs.h, as well as some other forgotten
files "make distcheck" complained about.
* avrdude.conf.in: Add more aliases for the AVRISP mkII.
* avrdude.1: Document how to use the AVRISP mkII.
* doc/avrdude.texi: (Ditto.)


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@564 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch
2006-01-12 23:13:50 +00:00
parent 655094b681
commit 108793bc7a
10 changed files with 368 additions and 43 deletions

View File

@@ -1,6 +1,7 @@
/*
* avrdude - A Downloader/Uploader for AVR device programmers
* Copyright (C) 2005 Joerg Wunsch
* Copyright (C) 2005,2006 Joerg Wunsch
* Copyright (C) 2006 dcm@mit.edu
*
* 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
@@ -38,28 +39,24 @@
#include <usb.h>
#include "serial.h"
#include "usbdevs.h"
extern char *progname;
extern int verbose;
#define USB_VENDOR_ATMEL 1003
#define USB_DEVICE_JTAGICEMKII 0x2103
/*
* Should we query the endpoint number and max transfer size from USB?
* After all, the JTAG ICE mkII docs document these values.
*/
#define JTAGICE_BULK_EP_WRITE 0x02
#define JTAGICE_BULK_EP_READ 0x82
#define JTAGICE_MAX_XFER 64
static char usbbuf[JTAGICE_MAX_XFER];
static char usbbuf[USBDEV_MAX_XFER];
static int buflen = -1, bufptr;
static int usb_interface;
/*
* The "baud" parameter is meaningless for USB devices, so we reuse it
* to pass the desired USB device ID.
*/
static int usbdev_open(char * port, long baud)
{
char string[256];
char product[256];
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *udev;
@@ -110,7 +107,7 @@ static int usbdev_open(char * port, long baud)
if (udev)
{
if (dev->descriptor.idVendor == USB_VENDOR_ATMEL &&
dev->descriptor.idProduct == USB_DEVICE_JTAGICEMKII)
dev->descriptor.idProduct == (unsigned short)baud)
{
/* yeah, we found something */
if (usb_get_string_simple(udev,
@@ -133,10 +130,20 @@ static int usbdev_open(char * port, long baud)
strcpy(string, "[unknown]");
}
if (usb_get_string_simple(udev,
dev->descriptor.iProduct,
product, sizeof(product)) < 0)
{
fprintf(stderr,
"%s: usb_open(): cannot read product name \"%s\"\n",
progname, usb_strerror());
strcpy(product, "[unnamed product]");
}
if (verbose)
fprintf(stderr,
"%s: usbdev_open(): Found JTAG ICE, serno: %s\n",
progname, string);
"%s: usbdev_open(): Found %s, serno: %s\n",
progname, product, string);
if (serno != NULL)
{
/*
@@ -205,6 +212,13 @@ static void usbdev_close(int fd)
usb_dev_handle *udev = (usb_dev_handle *)fd;
(void)usb_release_interface(udev, usb_interface);
/*
* Without this reset, the AVRISP mkII seems to stall the second
* time we try to connect to it.
*/
usb_reset(udev);
usb_close(udev);
}
@@ -213,13 +227,48 @@ static int usbdev_send(int fd, unsigned char *bp, size_t mlen)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
size_t rv;
int i = mlen;
unsigned char * p = bp;
int tx_size;
rv = usb_bulk_write(udev, JTAGICE_BULK_EP_WRITE, (char *)bp, mlen, 5000);
if (rv != mlen)
/*
* Split the frame into multiple packets. It's important to make
* sure we finish with a short packet, or else the device won't know
* the frame is finished. For example, if we need to send 64 bytes,
* we must send a packet of length 64 followed by a packet of length
* 0.
*/
do {
tx_size = (mlen < USBDEV_MAX_XFER)? mlen: USBDEV_MAX_XFER;
rv = usb_bulk_write(udev, USBDEV_BULK_EP_WRITE, (char *)bp, tx_size, 5000);
if (rv != tx_size)
{
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
progname, rv, tx_size, usb_strerror());
return -1;
}
bp += tx_size;
mlen -= tx_size;
} while (tx_size == USBDEV_MAX_XFER);
if (verbose > 3)
{
fprintf(stderr, "%s: usbdev_send(): wrote %d out of %d bytes, err = %s\n",
progname, rv, mlen, usb_strerror());
return -1;
fprintf(stderr, "%s: Sent: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
i--;
}
fprintf(stderr, "\n");
}
return 0;
}
@@ -237,7 +286,7 @@ usb_fill_buf(usb_dev_handle *udev)
{
int rv;
rv = usb_bulk_read(udev, JTAGICE_BULK_EP_READ, usbbuf, JTAGICE_MAX_XFER, 5000);
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 5000);
if (rv < 0)
{
if (verbose > 1)
@@ -295,6 +344,71 @@ static int usbdev_recv(int fd, unsigned char *buf, size_t nbytes)
return 0;
}
/*
* This version of recv keeps reading packets until we receive a short
* packet. Then, the entire frame is assembled and returned to the
* user. The length will be unknown in advance, so we return the
* length as the return value of this function, or -1 in case of an
* error.
*
* This is used for the AVRISP mkII device.
*/
static int usbdev_recv_frame(int fd, unsigned char *buf, size_t nbytes)
{
usb_dev_handle *udev = (usb_dev_handle *)fd;
int rv, n;
int i;
unsigned char * p = buf;
n = 0;
do
{
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf,
USBDEV_MAX_XFER, 10000);
if (rv < 0)
{
if (verbose > 1)
fprintf(stderr, "%s: usbdev_recv_frame(): usb_bulk_read(): %s\n",
progname, usb_strerror());
return -1;
}
if (rv <= nbytes)
{
memcpy (buf, usbbuf, rv);
buf += rv;
}
n += rv;
nbytes -= rv;
}
while (rv == USBDEV_MAX_XFER);
if (nbytes < 0)
return -1;
if (verbose > 3)
{
i = n;
fprintf(stderr, "%s: Recv: ", progname);
while (i) {
unsigned char c = *p;
if (isprint(c)) {
fprintf(stderr, "%c ", c);
}
else {
fprintf(stderr, ". ");
}
fprintf(stderr, "[%02x] ", c);
p++;
i--;
}
fprintf(stderr, "\n");
}
return n;
}
static int usbdev_drain(int fd, int display)
{
@@ -302,7 +416,7 @@ static int usbdev_drain(int fd, int display)
int rv;
do {
rv = usb_bulk_read(udev, JTAGICE_BULK_EP_READ, usbbuf, JTAGICE_MAX_XFER, 100);
rv = usb_bulk_read(udev, USBDEV_BULK_EP_READ, usbbuf, USBDEV_MAX_XFER, 100);
if (rv > 0 && verbose >= 4)
fprintf(stderr, "%s: usbdev_drain(): flushed %d characters\n",
progname, rv);
@@ -311,6 +425,9 @@ static int usbdev_drain(int fd, int display)
return 0;
}
/*
* Device descriptor for the JTAG ICE mkII.
*/
struct serial_device usb_serdev =
{
.open = usbdev_open,
@@ -321,4 +438,17 @@ struct serial_device usb_serdev =
.drain = usbdev_drain,
};
/*
* Device descriptor for the AVRISP mkII.
*/
struct serial_device usb_serdev_frame =
{
.open = usbdev_open,
.setspeed = usbdev_setspeed,
.close = usbdev_close,
.send = usbdev_send,
.recv = usbdev_recv_frame,
.drain = usbdev_drain,
};
#endif /* HAVE_LIBUSB */