Updates avrftdi to use libftdi1

This includes adding libftdi1 to configure.ac and Makefile.am.
avrftdi code is changed to use libftdi1. At the same time device
discovery is moved to libftdi1. Some error and debug messages in
avrftdi are corrected and/or updated. avrftdi_print is updated,
to print all messages whose verbosity level is less or equal to
the global verbosity level, so that messages with level 0 are always
printed.
This change is tested on OS X 10.6.8, Ubuntu 12.04.2 and Win7 x86_64.
The Win7 version was cross-compiled on OS X 10.6.8.


git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1141 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
Hannes Weisbach 2013-04-27 20:52:01 +00:00
parent 81a0c06013
commit 295b6f3711
4 changed files with 63 additions and 92 deletions

View File

@ -1,3 +1,13 @@
2013-04-27 Hannes Weisbach <hannes_weisbach@gmx.net>
* configure.ac: Add libftdi1 library check, remove TYPE_232H DECL check
* Makefile.am: Add @LIBFTDI1@ to avrdude_LDADD
* avrftdi.c: Update from libftdi0 to libftdi1. Use libftdi1's function to
find a device by vid/pid/serial instead of doing it ourself and add/update
error messages. avrftdi_print is changed so that a message is printed when
the verbosity level is greater or equal the message level, to have always-on
messages.
2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de> 2013-04-25 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
* configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER * configure.ac(AC_CONFIG_HEADERS): Replace the old AM_CONFIG_HEADER

View File

@ -63,7 +63,7 @@ avrdude_CFLAGS = @ENABLE_WARNINGS@
libavrdude_a_CFLAGS = @ENABLE_WARNINGS@ libavrdude_a_CFLAGS = @ENABLE_WARNINGS@
avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBUSB_1_0@ @LIBFTDI@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm avrdude_LDADD = $(top_builddir)/$(noinst_LIBRARIES) @LIBUSB@ @LIBUSB_1_0@ @LIBFTDI@ @LIBFTDI1@ @LIBHID@ @LIBELF@ @LIBPTHREAD@ -lm
bin_PROGRAMS = avrdude bin_PROGRAMS = avrdude

125
avrftdi.c
View File

@ -41,17 +41,11 @@
#include "tpi.h" #include "tpi.h"
#include "usbasp.h" #include "usbasp.h"
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB_1_0
#ifdef HAVE_LIBFTDI #ifdef HAVE_LIBFTDI1
#include <ftdi.h> #include <libusb-1.0/libusb.h>
#if defined(HAVE_USB_H) #include <libftdi1/ftdi.h>
# include <usb.h>
#elif defined(HAVE_LUSB0_USB_H)
# include <lusb0_usb.h>
#else
# error "libusb needs either <usb.h> or <lusb0_usb.h>"
#endif
enum { FTDI_SCK = 1, FTDI_MOSI, FTDI_MISO, FTDI_RESET }; enum { FTDI_SCK = 1, FTDI_MOSI, FTDI_MISO, FTDI_RESET };
#define FTDI_DEFAULT_MASK ( (1 << (FTDI_SCK - 1)) | (1 << (FTDI_MOSI - 1)) ) #define FTDI_DEFAULT_MASK ( (1 << (FTDI_SCK - 1)) | (1 << (FTDI_MOSI - 1)) )
@ -147,7 +141,7 @@ static void
avrftdi_print(int level, const char * fmt, ...) avrftdi_print(int level, const char * fmt, ...)
{ {
va_list ap; va_list ap;
if(verbose > level) if(verbose >= level)
{ {
fprintf(stderr, "avrftdi: "); fprintf(stderr, "avrftdi: ");
va_start(ap, fmt); va_start(ap, fmt);
@ -612,11 +606,8 @@ static int write_flush(avrftdi_t* pdata)
static int avrftdi_open(PROGRAMMER * pgm, char *port) static int avrftdi_open(PROGRAMMER * pgm, char *port)
{ {
int vid, pid, interface, snfound; int vid, pid, interface, index, err;
char serial[255], *foundsn; char * serial, *desc;
struct ftdi_device_list* devlist;
struct ftdi_device_list* devlist_ptr;
struct usb_device *found_dev;
avrftdi_t* pdata = to_pdata(pgm); avrftdi_t* pdata = to_pdata(pgm);
@ -626,10 +617,7 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
/* use vid/pid in following priority: config, /* use vid/pid in following priority: config,
* defaults. cmd-line is currently not supported */ * defaults. cmd-line is currently not supported */
snfound = 0;
foundsn = NULL;
memset(serial, 0, sizeof(serial));
if (pgm->usbvid) if (pgm->usbvid)
vid = pgm->usbvid; vid = pgm->usbvid;
else else
@ -641,7 +629,15 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
pid = 0x6010; pid = 0x6010;
if (0 == pgm->usbsn[0]) /* we don't care about SN. Use first avail. */ if (0 == pgm->usbsn[0]) /* we don't care about SN. Use first avail. */
snfound = 1; serial = NULL;
else
serial = pgm->usbsn;
/* not used yet, but i put them here, just in case someone does needs or
* wants to implement this.
*/
desc = NULL;
index = 0;
if (pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A') if (pgm->usbdev[0] == 'a' || pgm->usbdev[0] == 'A')
interface = INTERFACE_A; interface = INTERFACE_A;
@ -654,76 +650,33 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
interface = INTERFACE_A; interface = INTERFACE_A;
} }
/**************
* USB lookup *
**************/
#ifndef DRYRUN
found_dev = NULL;
if (ftdi_usb_find_all(pdata->ftdic, &devlist, vid, pid)) {
devlist_ptr = devlist;
do {
ftdi_usb_get_strings(pdata->ftdic, devlist_ptr->dev,
NULL, 0, NULL, 0, serial, sizeof(serial));
avrftdi_print(1, "%s: device: %s, serial number: %s type 0x%04x found\n",
progname, devlist_ptr->dev->filename, serial,
devlist_ptr->dev->descriptor.bcdDevice);
if (!snfound) {
if (strcmp(pgm->usbsn, serial) == 0){
foundsn = strdup(serial);
snfound = 1;
found_dev = devlist_ptr->dev;
}
}else {
if (NULL == found_dev)
found_dev = devlist_ptr->dev;
if (NULL == foundsn)
foundsn = strdup(serial);
}
memset(serial, 0, 255);
devlist_ptr = devlist_ptr->next;
} while (devlist_ptr);
ftdi_list_free(&devlist);
} else {
fprintf(stderr,
"%s: No devices with Vendor-ID:Product-ID %04x:%04x found.\n",
progname, vid, pid);
ftdi_list_free(&devlist);
return -1;
}
if (!snfound) {
fprintf(stderr,
"%s: No devices with VID:PID %04x:%04x and SN '%s' found.\n",
progname, vid, pid, pgm->usbsn);
return -1;
}
avrftdi_print(1,
"%s: Using device VID:PID %04x:%04x and SN '%s' on interface %c.\n",
progname, vid, pid, foundsn, INTERFACE_A == interface? 'A': 'B');
free(foundsn);
#endif
/**************** /****************
* Device setup * * Device setup *
****************/ ****************/
E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic); E(ftdi_set_interface(pdata->ftdic, interface) < 0, pdata->ftdic);
E(ftdi_usb_open_dev(pdata->ftdic,found_dev) <0, pdata->ftdic);
E(ftdi_usb_reset(pdata->ftdic) < 0, pdata->ftdic); err = ftdi_usb_open_desc_index(pdata->ftdic, vid, pid, desc, serial, index);
if(err) {
avrftdi_print(0, "Error %d occured: %s\n", err, ftdi_get_error_string(pdata->ftdic));
//stupid hack, because avrdude calls pgm->close() even when pgm->open() fails
//and usb_dev is intialized to the last usb device from probing
pdata->ftdic->usb_dev = NULL;
return err;
} else {
avrftdi_print(1,
"Using device VID:PID %04x:%04x and SN '%s' on interface %c.\n",
vid, pid, serial, INTERFACE_A == interface? 'A': 'B');
}
//E(ftdi_usb_open_dev(pdata->ftdic, found_dev) <0, pdata->ftdic);
ftdi_set_latency_timer(pdata->ftdic, 1); ftdi_set_latency_timer(pdata->ftdic, 1);
#ifndef DRYRUN
/* set SPI mode */ /* set SPI mode */
E(ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET) < 0, pdata->ftdic); E(ftdi_set_bitmode(pdata->ftdic, 0, BITMODE_RESET) < 0, pdata->ftdic);
E(ftdi_set_bitmode(pdata->ftdic, pdata->pin_direction & 0xff, BITMODE_MPSSE) < 0, pdata->ftdic); E(ftdi_set_bitmode(pdata->ftdic, pdata->pin_direction & 0xff, BITMODE_MPSSE) < 0, pdata->ftdic);
E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic); E(ftdi_usb_purge_buffers(pdata->ftdic), pdata->ftdic);
#endif
if (pgm->baudrate) { if (pgm->baudrate) {
set_frequency(pdata, pgm->baudrate); set_frequency(pdata, pgm->baudrate);
} else if(pgm->bitclock) { } else if(pgm->bitclock) {
@ -778,9 +731,7 @@ static int avrftdi_open(PROGRAMMER * pgm, char *port)
pdata->pin_limit = 11; pdata->pin_limit = 11;
break; break;
case TYPE_2232H: case TYPE_2232H:
#ifdef HAVE_LIBFTDI_TYPE_232H
case TYPE_232H: case TYPE_232H:
#endif
pdata->pin_limit = 15; pdata->pin_limit = 15;
break; break;
case TYPE_4232H: case TYPE_4232H:
@ -1322,12 +1273,12 @@ void avrftdi_initpgm(PROGRAMMER * pgm)
pgm->vfy_led = set_led_vfy; pgm->vfy_led = set_led_vfy;
} }
#else /*HAVE_LIBFTDI*/ #else /*HAVE_LIBFTDI1*/
static int avrftdi_noftdi_open (struct programmer_t *pgm, char * name) static int avrftdi_noftdi_open (struct programmer_t *pgm, char * name)
{ {
fprintf(stderr, fprintf(stderr,
"%s: error: no libftdi support. please compile again with libftdi installed.\n", "%s: Error: no libftdi1 support. Install libftdi1 and run configure/make again.\n",
progname); progname);
exit(1); exit(1);
@ -1339,14 +1290,14 @@ void avrftdi_initpgm(PROGRAMMER * pgm)
pgm->open = avrftdi_noftdi_open; pgm->open = avrftdi_noftdi_open;
} }
#endif /* HAVE_LIBFTDI */ #endif /* HAVE_LIBFTDI1 */
#else /*HAVE_LIBUSB*/ #else /*HAVE_LIBUSB_1_0*/
static int avrftdi_nousb_open (struct programmer_t *pgm, char * name) static int avrftdi_nousb_open (struct programmer_t *pgm, char * name)
{ {
fprintf(stderr, fprintf(stderr,
"%s: error: no usb support. please compile again with libusb installed.\n", "%s: Error: no USB support. Install libusb-1.0 and run configure/make again.\n",
progname); progname);
exit(1); exit(1);
@ -1358,7 +1309,7 @@ void avrftdi_initpgm(PROGRAMMER * pgm)
pgm->open = avrftdi_nousb_open; pgm->open = avrftdi_nousb_open;
} }
#endif /*HAVE_LIBUSB*/ #endif /*HAVE_LIBUSB_1_0*/
const char avrftdi_desc[] = "Interface to the MPSSE Engine of FTDI Chips using libftdi."; const char avrftdi_desc[] = "Interface to the MPSSE Engine of FTDI Chips using libftdi.";

View File

@ -152,12 +152,16 @@ AC_CHECK_LIB([ftdi], [ftdi_usb_get_strings], [have_libftdi=yes], [], [-lusb])
if test x$have_libftdi = xyes; then if test x$have_libftdi = xyes; then
LIBFTDI="-lftdi -lusb" LIBFTDI="-lftdi -lusb"
AC_DEFINE([HAVE_LIBFTDI]) AC_DEFINE([HAVE_LIBFTDI])
AC_CHECK_DECL(TYPE_232H,[have_libftdi_FT232H=yes], [], [[#include <ftdi.h>]])
if test x$have_libftdi_FT232H = xyes; then
AC_DEFINE([HAVE_LIBFTDI_TYPE_232H])
fi
fi fi
AC_SUBST(LIBFTDI, $LIBFTDI) AC_SUBST(LIBFTDI, $LIBFTDI)
AH_TEMPLATE([HAVE_LIBFTDI1],
[Define if FTDI support is enabled via libftdi1])
AC_CHECK_LIB([ftdi1], [ftdi_new], [have_libftdi1=yes], [], [-lusb-1.0])
if test x$have_libftdi1 = xyes; then
LIBFTDI1="-lftdi1"
AC_DEFINE([HAVE_LIBFTDI1])
fi
AC_SUBST(LIBFTDI1, $LIBFTDI1)
AC_CHECK_HEADERS([pthread.h]) AC_CHECK_HEADERS([pthread.h])
# as there exits header file only pthread implementations for Windows, check if we have a library # as there exits header file only pthread implementations for Windows, check if we have a library
AC_CHECK_LIB([pthread], [pthread_create], [have_pthread=yes]) AC_CHECK_LIB([pthread], [pthread_create], [have_pthread=yes])
@ -488,6 +492,12 @@ else
echo "DON'T HAVE libftdi" echo "DON'T HAVE libftdi"
fi fi
if test x$have_libftdi1 = xyes; then
echo "DO HAVE libftdi1"
else
echo "DON'T HAVE libftdi1"
fi
if test x$have_libhid = xyes; then if test x$have_libhid = xyes; then
echo "DO HAVE libhid" echo "DO HAVE libhid"
else else