diff --git a/jtag/ChangeLog b/jtag/ChangeLog index 72ec4c60..d3cb74a6 100644 --- a/jtag/ChangeLog +++ b/jtag/ChangeLog @@ -1,5 +1,10 @@ 2008-12-23 Kolja Waschk + * src/tap/parport/direct.c, configure.ac, doc/UrJTAG.txt: + Dynamically load the InpOut32.dll for parallel port access. Tested + in MinGW environment (Cygwin GCC with -mno-cygwin flag), and + documented how to compile it. Could build a distributable EXE now. + * src/cmd/usleep.c, sysdep.h: usleep() is declared in unistd.h, also present in modern MinGW environments. Defining it in sysdep.h collides with unistd.h. diff --git a/jtag/configure.ac b/jtag/configure.ac index 2e5f31ed..c3bbcdf5 100644 --- a/jtag/configure.ac +++ b/jtag/configure.ac @@ -246,40 +246,22 @@ AC_SUBST(FTD2XXLIB) dnl Use InpOut I/O library? dnl http://www.highrez.co.uk/Downloads/InpOut32/default.htm -AC_ARG_WITH([inpout], - [AS_HELP_STRING([--with-inpout], - [use InpOutXX for parallel port access on Windows])], - [], [with_inpout=check]) - -INPOUTXX= -AS_IF([test "x$with_inpout" = xyes -o "x$with_inpout" = xcheck], [ - AC_CHECK_LIB([inpout32], [Out32], [ - HAVEINPOUTXX=yes - LIBS="-linpout32 $LIBS" - ],[ - AC_MSG_WARN([*** InpOutXX libray not found]) - ]) -],[ - AS_IF([test "x$with_inpout" != xno], [ - HAVEINPOUTXX=yes - AS_IF([test -d "$with_inpout/Win32"], [ - INPOUTXX="$with_inpout/Win32/inpout32.lib" - CFLAGS="$CFLAGS -I$with_inpout/Win32" - ],[ - INPOUTXX="$with_inpout/inpout32.lib" - CFLAGS="$CFLAGS -I$with_inpout" - ]) - ],) -]) -AS_IF([test "x$HAVEINPOUTXX" = xyes], [ +AC_ARG_WITH([inpout32], + [AS_HELP_STRING([--with-inpout32], + [use InpOut32.dll for parallel port access on Windows])], + [], [with_inpout32=no]) + +case $host in + *cygwin*|*mingw*) ;; + *) with_inpout32=no ;; +esac + +AS_IF([test "x$with_inpout32" = xyes], [ AM_CONDITIONAL(HAVE_INPOUTXX, true) - AC_DEFINE(HAVE_INPOUTXX, 1, [define if you have libinpout]) + AC_DEFINE(HAVE_INPOUTXX, 1, [define if you have inpout32.dll]) ],[ AM_CONDITIONAL(HAVE_INPOUTXX, false) ]) -AC_SUBST(INPOUTXX) - - CFLAGS="$CFLAGS -Wall" @@ -560,7 +542,7 @@ AS_IF([test "x$HAVE_LINUX_PPDEV_H" != "xyes"], [ AS_IF([test "x$HAVE_DEV_PPBUS_PPI_H" != "xyes"], [ lowleveldrivers=`echo ${lowleveldrivers} | $SED -e "s/ppi//"` ]) -AS_IF([test "x$HAVE_IOPERM" != "xyes" -a "x$HAVE_I386_SET_IOPERM" != "xyes"], [ +AS_IF([test "x$HAVE_IOPERM" != "xyes" -a "x$HAVE_I386_SET_IOPERM" != "xyes" -a "x$HAVE_INPOUTXX" != "xyes" ], [ lowleveldrivers=`echo ${lowleveldrivers} | $SED -e "s/direct//"` ]) # diff --git a/jtag/doc/UrJTAG.txt b/jtag/doc/UrJTAG.txt index e33fa62a..0653b70b 100644 --- a/jtag/doc/UrJTAG.txt +++ b/jtag/doc/UrJTAG.txt @@ -294,10 +294,10 @@ To run autogen.sh, you need autoconf and automake, bison, and a recent flex. The distributed source tarball contains source pregenerated with a current flex version; flex therefore is only needed if you want to compile code checked out from our Subversion repository. Flex 2.5.4a as it comes with -Cygwin cannot build the scanners for BSDL and SVF. Building these files -requires Flex 2.5.33 or newer. The configure script will compare the available -Flex version against these preconditions and enables or disables the related -features. +most but the very latest Cygwin release cannot build the scanners for BSDL and +SVF. Building these files requires Flex 2.5.33 or newer. The configure script +will compare the available Flex version against these preconditions and enables +or disables the related features. Furthermore, libtool should be available, and "devel" versions of the following packages: @@ -390,17 +390,35 @@ might give problems if the path contains spaces, as "Program Files" does!): ==== Compiling with MinGW ==== UrJTAG may be compiled into a Windows executable using the MinGW compiler -(http://www.mingw.org). This has the advantage over running in a Cygwin -environment that you don't need to install anything else but the jtag.exe. +(http://www.mingw.org), or Cygwin GCC with the "-mno-cygwin" compiler flag. + +This has the advantage over running in a Cygwin environment that you don't need +to install anything else but the jtag.exe (plus libraries like FTD2XX.dll or +InpOut32.DLL that are required for device access under Windows in any case). + However, because support for MinGW is quite new in UrJTAG, it may lack some features (e.g. readline support) or run a little slower. +Because it seems to be easier to set up a Cygwin environment, we recommend +using the Cygwin GCC with "-mno-cygwin" flag instead of using a MinGW setup: + + CFLAGS="-mno-cygwin -O2" ./configure --with-ftd2xx=/tmp/cdm-drivers --with-inpout32 + + It is even possible to cross-compile and build the executable on a Linux host: - ./configure --host=i586-mingw32msvc --with-ftd2xx=/tmp/cdm-drivers + ./configure --host=i586-mingw32msvc --with-ftd2xx=/tmp/cdm-drivers --with-inpout32 make + +The "--with-inpout32" switch tells UrJTAG to use the InpOut32.DLL for access to +parallel ports, because the Cygwin ioperm isn't available for MinGW. The InpOut32 +library is available from logix4u.net: + + http://logix4u.net/Legacy_Ports/Parallel_Port/Inpout32.dll_for_Windows_98/2000/NT/XP.html + + ==== Driver tailoring ==== The configure script enables all default bus, cable and lowlevel drivers. You diff --git a/jtag/src/tap/parport/direct.c b/jtag/src/tap/parport/direct.c index 92bdae69..4d598dfe 100644 --- a/jtag/src/tap/parport/direct.c +++ b/jtag/src/tap/parport/direct.c @@ -26,30 +26,37 @@ #include "sysdep.h" +#ifdef ENABLE_LOWLEVEL_DIRECT + #include #include #include "parport.h" #include "cable.h" -#if defined(WIN32) && defined(HAVE_INPOUTXX) -void _stdcall Out32(short PortAddress, short data); -short _stdcall Inp32(short PortAddress); +#if defined(HAVE_INPOUTXX) + +HINSTANCE inpout32_dll_handle = NULL; + +typedef short _stdcall (*inpfuncPtr)(short p); +typedef void _stdcall (*outfuncPtr)(short p, short d); -#define inb(p) Inp32(p) -#define outb(d,p) Out32(p,d) +inpfuncPtr Inp32; +outfuncPtr Out32; -#elif defined(HAVE_IOPERM) || defined(HAVE_I386_SET_IOPERM) +#define inb(p) (Inp32)(p) +#define outb(d,p) (Out32)(p,d) + +#elif defined(HAVE_IOPERM) -#if defined(HAVE_IOPERM) #include + #elif defined(HAVE_I386_SET_IOPERM) + #include #include #include -#endif -#ifdef HAVE_I386_SET_IOPERM static __inline int ioperm( unsigned long from, unsigned long num, int permit ) { @@ -122,7 +129,27 @@ direct_parport_alloc( unsigned int port ) parport_t *parport = malloc( sizeof *parport ); port_node_t *node = malloc( sizeof *node ); - if (!node || !parport || !params) { +#if defined(HAVE_INPOUTXX) + if (inpout32_dll_handle == NULL) + { + inpout32_dll_handle = LoadLibrary("inpout32.dll"); + } + if (inpout32_dll_handle == NULL) + { + fprintf(stderr, _("Couldn't load InpOut32.dll; maybe not installed?\n")); + } + else + { + Inp32 = (inpfuncPtr) GetProcAddress(inpout32_dll_handle, "Inp32"); + Out32 = (outfuncPtr) GetProcAddress(inpout32_dll_handle, "Out32"); + } + + if (!node || !parport || !params || !inpout32_dll_handle) +#else + if (!node || !parport || !params) +#endif + { + free( node ); free( parport ); free( params ); @@ -160,6 +187,11 @@ direct_parport_free( parport_t *port ) free( port->params ); free( port ); + +#if defined(HAVE_INPOUTXX) + if (inpout32_dll_handle != NULL) + FreeLibrary(inpout32_dll_handle); +#endif } parport_t * @@ -210,15 +242,23 @@ direct_connect( const char **par, int parnum ) static int direct_open( parport_t *parport ) { +#ifdef HAVE_INPOUTXX + return 0; +#else unsigned int port = ((direct_params_t *) parport->params)->port; return ((port + 3 <= 0x400) && ioperm( port, 3, 1 )) || ((port + 3 > 0x400) && iopl( 3 )); +#endif } static int direct_close( parport_t *parport ) { +#if defined(HAVE_INPOUTXX) + return 0; +#else unsigned int port = ((direct_params_t *) parport->params)->port; return (port + 3 <= 0x400) ? ioperm( port, 3, 0 ) : iopl( 0 ); +#endif } static int @@ -263,4 +303,4 @@ parport_driver_t direct_parport_driver = { direct_set_control }; -#endif /* defined(HAVE_IOPERM) || defined(HAVE_I386_SET_IOPERM) */ +#endif /* ENABLE_LOWLEVEL_DIRECT */