mirror of
https://github.com/mariusgreuel/avrdude.git
synced 2025-09-27 14:35:27 +00:00
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:
174
usb_libusb.c
174
usb_libusb.c
@@ -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 */
|
||||
|
Reference in New Issue
Block a user