From 2bf9eca380070af531c045521958fe031dd0006b Mon Sep 17 00:00:00 2001 From: Marius Greuel Date: Tue, 10 Mar 2020 21:41:51 +0200 Subject: [PATCH] Add support for FTDI devices via D2XX API --- avrdude.sln | 10 + avrdude.vcxproj | 17 +- avrdude.vcxproj.filters | 18 + avrftdi.c | 39 +- avrftdi_private.h | 2 +- avrftdi_tpi.c | 5 + clean.bat | 4 + external/libftdi1/AUTHORS | 91 +++ external/libftdi1/COPYING.LIB | 481 ++++++++++++++++ external/libftdi1/ChangeLog | 280 +++++++++ external/libftdi1/LICENSE | 25 + external/libftdi1/README | 67 +++ external/libftdi1/README.build | 96 ++++ external/libftdi1/include/ftdi.h | 638 +++++++++++++++++++++ external/libftdi1/libftdi1.vcxproj | 153 +++++ external/libftdi1/libftdi1.vcxproj.filters | 10 + external/libftdi1/src/ftdi.cpp | 320 +++++++++++ external/libftdi1/src/libwinftdi.h | 380 ++++++++++++ ft245r.c | 2 +- msvc/IntegerHandleMap.h | 68 +++ msvc/ReaderWriterLock.h | 80 +++ msvc/generated/ac_cfg.h | 6 +- msvc/pthread.cpp | 184 ++++++ msvc/pthread.h | 43 ++ msvc/semaphore.cpp | 68 +++ msvc/semaphore.h | 40 ++ 26 files changed, 3110 insertions(+), 17 deletions(-) create mode 100644 external/libftdi1/AUTHORS create mode 100644 external/libftdi1/COPYING.LIB create mode 100644 external/libftdi1/ChangeLog create mode 100644 external/libftdi1/LICENSE create mode 100644 external/libftdi1/README create mode 100644 external/libftdi1/README.build create mode 100644 external/libftdi1/include/ftdi.h create mode 100644 external/libftdi1/libftdi1.vcxproj create mode 100644 external/libftdi1/libftdi1.vcxproj.filters create mode 100644 external/libftdi1/src/ftdi.cpp create mode 100644 external/libftdi1/src/libwinftdi.h create mode 100644 msvc/IntegerHandleMap.h create mode 100644 msvc/ReaderWriterLock.h create mode 100644 msvc/pthread.cpp create mode 100644 msvc/pthread.h create mode 100644 msvc/semaphore.cpp create mode 100644 msvc/semaphore.h diff --git a/avrdude.sln b/avrdude.sln index ff19192b..a2835dd4 100644 --- a/avrdude.sln +++ b/avrdude.sln @@ -11,6 +11,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libhidapi", "external\libhi EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libusb", "external\libusb\libusb.vcxproj", "{22615EC5-9DBC-4538-9C01-2CD535B3810B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libftdi1", "external\libftdi1\libftdi1.vcxproj", "{632649AB-A351-46D4-A81F-1D6E9A819A5C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -51,6 +53,14 @@ Global {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x64.Build.0 = Release|x64 {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x86.ActiveCfg = Release|Win32 {22615EC5-9DBC-4538-9C01-2CD535B3810B}.Release|x86.Build.0 = Release|Win32 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Debug|x64.ActiveCfg = Debug|x64 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Debug|x64.Build.0 = Debug|x64 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Debug|x86.ActiveCfg = Debug|Win32 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Debug|x86.Build.0 = Debug|Win32 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Release|x64.ActiveCfg = Release|x64 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Release|x64.Build.0 = Release|x64 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Release|x86.ActiveCfg = Release|Win32 + {632649AB-A351-46D4-A81F-1D6E9A819A5C}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/avrdude.vcxproj b/avrdude.vcxproj index 97dbae71..d88fd3d4 100644 --- a/avrdude.vcxproj +++ b/avrdude.vcxproj @@ -84,7 +84,7 @@ WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + msvc;msvc\generated;.;external\libelf\include;external\libusb\include;external\libhidapi\include;external\libftdi1\include;%(AdditionalIncludeDirectories) Level3 true @@ -96,7 +96,7 @@ WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + msvc;msvc\generated;.;external\libelf\include;external\libusb\include;external\libhidapi\include;external\libftdi1\include;%(AdditionalIncludeDirectories) Level3 true @@ -108,7 +108,7 @@ WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + msvc;msvc\generated;.;external\libelf\include;external\libusb\include;external\libhidapi\include;external\libftdi1\include;%(AdditionalIncludeDirectories) Level3 true true @@ -125,7 +125,7 @@ WIN32NATIVE;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;LOG_APPNAME="avrdude";NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - msvc;msvc\generated;.;external\libelf\include;external\libhidapi\include;external\libusb\include;%(AdditionalIncludeDirectories) + msvc;msvc\generated;.;external\libelf\include;external\libusb\include;external\libhidapi\include;external\libftdi1\include;%(AdditionalIncludeDirectories) Level3 true true @@ -164,6 +164,8 @@ + + @@ -226,6 +228,10 @@ + + + + @@ -257,6 +263,9 @@ {a2d07885-a0d1-473b-83b2-209cd008ee8f} + + {632649ab-a351-46d4-a81f-1d6e9a819a5c} + {17054837-6ae6-44d7-914d-9625edef4657} diff --git a/avrdude.vcxproj.filters b/avrdude.vcxproj.filters index 12e01d78..cddf0460 100644 --- a/avrdude.vcxproj.filters +++ b/avrdude.vcxproj.filters @@ -179,6 +179,12 @@ 4 msvc + + 4 msvc + + + 4 msvc + @@ -337,5 +343,17 @@ 4 msvc + + 4 msvc + + + 4 msvc + + + 4 msvc + + + 4 msvc + \ No newline at end of file diff --git a/avrftdi.c b/avrftdi.c index 29d10332..02b7956c 100644 --- a/avrftdi.c +++ b/avrftdi.c @@ -364,7 +364,11 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig // (8*2) outputs per data byte, 6 transmit bytes per output (SET_BITS_LOW/HIGH), // (8*1) inputs per data byte, 2 transmit bytes per input (GET_BITS_LOW/HIGH), // 1x SEND_IMMEDIATE +#ifdef _MSC_VER + unsigned char* send_buffer = _alloca((8 * 2 * 6) * transfer_size + (8 * 1 * 2) * transfer_size + 7); +#else unsigned char send_buffer[(8*2*6)*transfer_size+(8*1*2)*transfer_size+7]; +#endif int len = 0; int i; @@ -384,7 +388,11 @@ static int avrftdi_transmit_bb(PROGRAMMER * pgm, unsigned char mode, const unsig E(ftdi_write_data(pdata->ftdic, send_buffer, len) != len, pdata->ftdic); if (mode & MPSSE_DO_READ) { +#ifdef _MSC_VER + unsigned char* recv_buffer = _alloca(2 * 16 * transfer_size); +#else unsigned char recv_buffer[2*16*transfer_size]; +#endif int n; int k = 0; do { @@ -949,10 +957,16 @@ static int avrftdi_eeprom_read(PROGRAMMER *pgm, AVRPART *p, AVRMEM *m, unsigned int page_size, unsigned int addr, unsigned int len) { unsigned char cmd[4]; - unsigned char buffer[len], *bufptr = buffer; unsigned int add; +#ifdef _MSC_VER + unsigned char* buffer = _alloca(len); + unsigned char* bufptr = buffer; +#else + unsigned char buffer[len], *bufptr = buffer; +#endif + + memset(buffer, 0, len); - memset(buffer, 0, sizeof(buffer)); for (add = addr; add < addr + len; add++) { memset(cmd, 0, sizeof(cmd)); @@ -980,9 +994,14 @@ static int avrftdi_flash_write(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, unsigned char poll_byte; unsigned char *buffer = &m->buf[addr]; +#ifdef _MSC_VER + unsigned char* buf = _alloca(4 * len + 4); + unsigned char* bufptr = buf; +#else unsigned char buf[4*len+4], *bufptr = buf; +#endif - memset(buf, 0, sizeof(buf)); + memset(buf, 0, 4 * len + 4); /* pre-check opcodes */ if (m->op[AVR_OP_LOADPAGE_LO] == NULL) { @@ -1098,14 +1117,18 @@ static int avrftdi_flash_read(PROGRAMMER * pgm, AVRPART * p, AVRMEM * m, int byte, word; int use_lext_address = m->op[AVR_OP_LOAD_EXT_ADDR] != NULL; unsigned int address = addr/2; - - unsigned char o_buf[4*len+4]; - unsigned char i_buf[4*len+4]; unsigned int index; +#ifdef _MSC_VER + unsigned char* o_buf = _alloca(4 * len + 4); + unsigned char* i_buf = _alloca(4 * len + 4); +#else + unsigned char o_buf[4*len+4]; + unsigned char i_buf[4*len+4]; +#endif - memset(o_buf, 0, sizeof(o_buf)); - memset(i_buf, 0, sizeof(i_buf)); + memset(o_buf, 0, 4 * len + 4); + memset(i_buf, 0, 4 * len + 4); /* pre-check opcodes */ if (m->op[AVR_OP_READ_LO] == NULL) { diff --git a/avrftdi_private.h b/avrftdi_private.h index 177f8ca6..21853d3b 100644 --- a/avrftdi_private.h +++ b/avrftdi_private.h @@ -12,7 +12,7 @@ # include # undef HAVE_LIBFTDI_TYPE_232H # define HAVE_LIBFTDI_TYPE_232H 1 -#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H) +#elif defined(HAVE_LIBFTDI) && (defined(HAVE_USB_H) || defined(_MSC_VER)) /* ftdi.h includes usb.h */ #include #else diff --git a/avrftdi_tpi.c b/avrftdi_tpi.c index d82444e8..9ac343f7 100644 --- a/avrftdi_tpi.c +++ b/avrftdi_tpi.c @@ -13,6 +13,11 @@ #include "avrftdi_tpi.h" #include "avrftdi_private.h" +#ifdef _MSC_VER +#include +#define __builtin_popcount __popcnt +#endif + #ifndef DO_NOT_BUILD_AVRFTDI static void avrftdi_tpi_disable(PROGRAMMER *); diff --git a/clean.bat b/clean.bat index 2386ebfd..ebe0cc51 100644 --- a/clean.bat +++ b/clean.bat @@ -9,6 +9,10 @@ rmdir /s /q "external\libelf\Debug" >nul 2>nul rmdir /s /q "external\libelf\Release" >nul 2>nul rmdir /s /q "external\libelf\x64" >nul 2>nul +rmdir /s /q "external\libftdi1\Debug" >nul 2>nul +rmdir /s /q "external\libftdi1\Release" >nul 2>nul +rmdir /s /q "external\libftdi1\x64" >nul 2>nul + rmdir /s /q "external\libhidapi\Debug" >nul 2>nul rmdir /s /q "external\libhidapi\Release" >nul 2>nul rmdir /s /q "external\libhidapi\x64" >nul 2>nul diff --git a/external/libftdi1/AUTHORS b/external/libftdi1/AUTHORS new file mode 100644 index 00000000..e8f5a69d --- /dev/null +++ b/external/libftdi1/AUTHORS @@ -0,0 +1,91 @@ +Main developers: + + Intra2net AG + +Contributors in alphabetical order, +see Changelog for full details: + + Adam Malinowski + Alain Abbas + Alex Harford + Alexander Lehmann + Anders Larsen + Andrei Errapart + Andrew John Rogers + Arnim Läuger + Aurelien Jarno + Benjamin Vanheuverzwijn + Chris Morgan + Chris Zeh + Claudio Lanconelli + Clifford Wolf + Dan Dedrick + Daniel Kirkham + David Challis + Davide Michelizza + Denis Sirotkin + Diego Elio Pettenò + Emil + Eneas U de Queiroz + Eric Schott + Eugene Hutorny + Evan Nemerson + Evgeny Sinelnikov + Fabrice Fontaine + Fahrzin Hemmati + Flynn Marquardt + Forest Crossman + Frank Dana + Holger Mößinger + Ian Abbott + Jared Boone + Jarkko Sonninen + Jean-Daniel Merkli + Jochen Sprickerhof + Joe Zbiciak + Jon Beniston + Jordan Rupprecht + Juergen Beisert + Lorenz Moesenlechner + Marek Vavruša + Marius Kintel + Mark Hämmerling + Matthias Janke + Matthias Kranz + Matthias Richter + Matthijs ten Berge + Max + Maxwell Dreytser + Michel Zou + Mike Frysinger + Nathael Pajani + Nathan Fraser + Oleg Seiljus + Paul Fertser + Pawel Jewstafjew + Peter Holik + Raphael Assenat + Richard Shaw + Robby McKilliam + Robert Cox + Robin Haberkorn + Rodney Sinclair + Rogier Wolff + Rolf Fiedler + Roman Lapin + Salvador Eduardo Tropea + Stephan Linz + Steven Turner + Tarek Heiland + Thilo Schulz + Thimo Eichstaedt + Thomas Fischl + Thomas Klose + Tim Ansell + Tom Saunders + Uwe Bonnes + Vladimir Yakovlev + Wilfried Holzke + Xiaofan Chen + Yegor Yefremov + Yi-Shin Li diff --git a/external/libftdi1/COPYING.LIB b/external/libftdi1/COPYING.LIB new file mode 100644 index 00000000..5bc8fb2c --- /dev/null +++ b/external/libftdi1/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/external/libftdi1/ChangeLog b/external/libftdi1/ChangeLog new file mode 100644 index 00000000..8e2b2138 --- /dev/null +++ b/external/libftdi1/ChangeLog @@ -0,0 +1,280 @@ +New in 1.5 - 2020-07-07 +----------------------- +* Implement tc[io]flush methods & deprecate broken purge_buffers methods + + Please check your code for ftdi_usb_purge_rx_buffer(), + ftdi_usb_purge_tx_buffer() and ftdi_usb_purge_buffers() + and migrate to the new ftdi_tc[io]flush() methods. + + Old code will continue to function, but you'll get + a deprecation warning during compilation. + +* Add program to test buffer flush (purge) functionality +* Add kernel driver auto attach/detach. + See new AUTO_DETACH_REATACH_SIO_MODULE option +* Add ftdi_setflowctrl_xonxoff() +* ftdi_eeprom / eeprom handling: + * Unify handling of all boolean eeprom flags + * Add device release number support + * Add channel_a_driver support for type xxR chips + * Add support for group0 drive levels on x232H chips + * Fix handling of high_current_drive parameter + * Fix inverted handling of VCP driver field for TYPE_R chips + * New --verbose option for eeprom decode operation +* Add example code for async mode +* Add SPDX license identifiers to the core library & ftdi_eeprom +* Various python SWIG wrapper improvements +* Various cmake file improvements +* Fix small bugs in error code paths + +New in 1.4 - 2017-08-07 +----------------------- +* New ftdi_usb_open_bus_addr() open function +* Use BM/R series baud rate computation for FT230X +* ftdi_get_error_string() now returns const char* +* C++ API: Ability to open devices with empty descriptor strings +* C++ API: Fix enumerations for buffer purge and modem controls +* small build fixes and improvements in the python examples +* ftdi_eeprom / eeprom handling: + * New API function: ftdi_eeprom_get_strings() + * Fix USE_SERIAL handling for 230X type chips + * Make ftdi_read_eeprom_location() endianness independent + * Fix flashing of FT245R + +New in 1.3 - 2016-05-20 +----------------------- +* Added ftdi_usb_get_strings2() to prevent automatic device close (Fahrzin Hemmati) +* Added ftdi_transfer_data_cancel() for cancellation of a submitted transfer, + avoided resubmittion of a canceled transfer in the callbacks, + replaced calls to libusb_handle_events with + libusb_handle_events_timeout_completed (Eugene Hutorny) +* ftdi_eeprom / eeprom handling: + * Add support for arbitrary user data (Salvador Eduardo Tropea) + * Add --build-eeprom support (Salvador Eduardo Tropea) + * Fix use_usb_version config file option (Thilo Schulz) + * Ability to include other config files in EEPROM config file (Thilo Schulz) + * Add external oscillator enable bit (Raphael Assenat) + * Support channel configuration (Stephan Linz) + * Added --device option to ftdi_eeprom to specify FTDI device (Robin Haberkorn) + * Fixed EEPROM user-area space checks for FT232R and FT245R chips (Robin Haberkorn) +* Various improvements to CBUS handling, including the EEPROM (Robin Haberkorn) +* swig wrapper: Fix handling of binary strings in ftdi_write_data() + for python 3 (xantares09) +* cbus python example code (Rodney Sinclair) +* ftdi_stream: fix timeout setting (Ларионов Даниил) +* Fixed typo in CBUS defines: CBUSG_DRIVE1 -> CBUSH_DRIVE1 + +New in 1.2 - 2014-11-21 +----------------------- +* Support for FT230X devices (Uwe Bonnes) +* ftdi_usb_get_strings(): Don't try to open an already open device (Denis Sirotkin) +* Support for finding devices bricked by the Windows driver (Forest Crossman) +* cmake build system: New LibFTDI1ConfigVersion.cmake file (xantares09) +* Fix a typo in the MPSSE command CLK_BYTES_OR_LOW (Benjamin Vanheuverzwijn) +* Minor fixes for MSVC++ (Andrei Errapart) +* Various small code improvements (Florian Preinstorfer, Jochen Sprickerhof, xantares09) + +New in 1.1 - 2014-02-05 +----------------------- +* Fix FT232H eeprom suspend pulldown setting (Davide Michelizza) +* Fix FT232H eeprom user area size (Davide Michelizza) +* Improved mingw build (Paul Fertser and Michel Zou) +* C++ wrapper: Get/set functions for USB timeouts (Jochen Sprickerhof) +* Partial support for FT230X (Nathael Pajani) +* New API function: ftdi_eeprom_set_strings() (Nathael Pajani) +* Prevent possible segfault in ftdi_eeprom_decode() (Nathael Pajani) +* Save device release number in eeprom (Jarkko Sonninen) +* Fix "self powered" eeprom flag (Jarkko Sonninen) +* Improved python wrapper (Michel Zou) +* Many buildsystem improvements (Michel Zou and Mike Frysinger) +* See the git history for more changes and fixes + +New in 1.0 - 2013-01-29 +----------------------- +* Ported to libusb 1.x (initial work by Jie Zhang) +* Many eeprom handling improvements (Uwe Bonnes, Anders Larsen) +* Renamed pkconfig, library .so etc. files to "libftdi1" (Intra2net) +* ftdi_eeprom is part of libftdi now (Intra2net) + +* New baudrate calculation code + unit tests (Uwe Bonnes and Intra2net) +* Improved python bindings including python3 support (Michel Zou) +* Switched completely to cmake build system (Intra2net) +* cmake: Easy libftdi discovery via find_package() (Michel Zou) +* eeprom handling now done via get()/set() functions (Uwe Bonnes) +* C++ wrapper: Fixed use-after-free in List::find_all() (Intra2net) +* Documentation updates (Xiaofan Chen) +* See the git history for more changes and fixes + +New in 0.20 - 2012-03-19 +------------------------ +* Support for FT232H (Uwe Bonnes) +* Fixed install location of header files (Uwe Bonnes and Intra2net) +* Backported serial_test tool from libftdi 1.x (Uwe Bonnes) + +New in 0.19 - 2011-05-23 +------------------------ +* Make kernel driver detach configurable (Thomas Klose) +* Correct ftdi_poll_modem_status() result code (Tom Saunders) +* cmake build system improvements (Evgeny Sinelnikov) +* Fix uninitialized memory access in async mode (Intra2net) +* Support for FT232R eeprom features (Hermann Kraus) +* Fix size returned by ftdi_read_data (Hermann Kraus) +* C++ wrapper: Fix infinite recursion in set_bitmode (Intra2net) +* Improvements to the python wrapper (Flynn Marquardt and Chris Zeh) + +New in 0.18 - 2010-06-25 +------------------------ +* Add ftdi_eeprom_free() to free allocated memory in eeprom (Wilfried Holzke) +* More generic error message for the FTDI kernel driver (Intra2net) +* Honor CPPFLAGS in python wrapper build (Alexander Lehmann) +* cmake: Fix package creation on 32-bit machines (Uwe Bonnes) +* Fix swig argument constraints (Intra2net) +* Don't segfault if device is closed or ftdi context is invalid (Intra2net) +* Ability to disable build of examples / documentation (Mike Frysinger and Intra2net) +* Fix typo in python wrapper build (Mike Frysinger) +* Autoconf build system improvements (Mike Frysinger) + +New in 0.17 - 2009-12-19 +------------------------ +* C++ wrapper: Reduced code duplication and small other changes (Intra2net) +* Deprecated old ftdi_enable_bitbang() function (Intra2net) +* New ftdi_usb_open_desc_index() function (Intra2net) +* Added baud rate test example code (Intra2net) +* New serial input example code (Jim Paris) +* Fix modem status byte filtering for USB high speed chips (Intra2net and Jim Paris) +* Add bitmode for synchronous fifo in FT2232H (Uwe Bonnes) +* Fix usb_set_configuration() call on Windows 64 (NIL) +* Fix usb index in ftdi_convert_baudrate() for FT2232H/FT4232H chips (Thimo Eichstaedt) +* Set initial baudrate on correct interface instead of always the first one (Thimo Eichstaedt) +* Call usb_set_configuration() on Windows only (Uwe Bonnes) +* 64 bit and other buildsystem fixes (Uwe Bonnes) +* Don't build --with-async-mode w/ libusb-compat-0.1 (Clifford Wolf) +* Functions for read/write of a single eeprom location (Oleg Seiljus) +* Protect against double close of usb device (Nathan Fraser) +* Fix out-of-tree-build in python wrapper (Aurelien Jarno) +* Autoconf and doxygen cleanup (Jim Paris) + +New in 0.16 - 2009-05-08 +------------------------ +* C++ wrapper: Reopen the device after calling get_strings() in Context::open() (Marek Vavruša and Intra2net) +* C++ wrapper: Fixed an inheritance problem (Marek Vavruša and Intra2net) +* C++ wrapper: Relicensed under GPLv2 + linking exception (Marek Vavruša and Intra2net) +* Support for FT2232H and FT4232H (David Challis, Alex Harford and Intra2net) +* Support for mingw cross compile (Uwe Bonnes) +* Python bindings and minor autoconf cleanup (Tarek Heiland) +* Code cleanup in various places (Intra2net) +* Fixed ftdi_read_chipid in some cases (Matthias Richter) +* eeprom decode function and small cleanups (Marius Kintel) +* cmake system improvements (Marius Kintel and Intra2net) +* Fix compilation in -ansi -pedantic mode (Matthias Janke) + +New in 0.15 - 2008-12-19 +------------------------ +* Full C++ wrapper. Needs boost (Marek Vavruša and Intra2net) +* cmake rules (Marek Vavruša) + +New in 0.14 - 2008-09-09 +------------------------ +* Fixed flow control code for second FT2232 interface (Marek Vavruša) +* Ability to set flow control via one USB call (Marek Vavruša) +* 64 bit build support in the RPM spec file (Uwe Bonnes) +* Small fix to the RPM spec file (Uwe Bonnes) +* Ability to set RS232 break type (Intra2net) +* Grouped flow control and modem status code together (Intra2net) + +New in 0.13 - 2008-06-13 +------------------------ +* Build .spec file via configure.in (Intra2net) +* Fixed "libusb-config --cflags" call (Mike Frysinger and Intra2net) +* Always set usb configuration (Mike Frysinger and Intra2net) +* Improved libusb-win32 support (Mike Frysinger) + +New in 0.12 - 2008-04-16 +------------------------ +* Fix build of documentation for "out of tree" builds +* Fix USB config descriptor in the eeprom (Juergen Beisert) +* Ability to purge RX/TX buffers separately (Arnim Läuger) +* Setting of event and error character (Arnim Läuger) +* Poll modem status function (Arnim Läuger and Intra2net) +* Updated documentation and created AUTHORS file + +New in 0.11 - 2008-03-01 +------------------------ +* Vala bindings helper functions (ftdi_new, ftdi_free, ftdi_list_free2) (Even Nermerson) +* Support for different EEPROM sizes (Andrew John Rogers, andrew@rogerstech.co.uk) +* Async write support. Linux only and no error handling. + You have to enable it via --with-async-mode. +* Detection of R-type chips +* FTDIChip-ID read support (Peter Holik) + +New in 0.10 - 2007-05-08 +------------------------ +* Examples for libftdi_usb_find_all and CBUS mode +* Fixed ftdi_list_free +* Small cosmetic changes + +New in 0.9 - 2007-02-09 +----------------------- +* Fixed build without doxygen +* Correct .so file library version + +New in 0.8 - 2007-02-08 +----------------------- +* Complete doxygen documentation and examples +* Extended FT2232C bitbang mode example code (Max) +* ftdi_usb_get_strings function to get device ID strings (Matthijs ten Berge) +* Fix ftdi_read_pins on PowerPC systems (Thomas Fischl) +* Automatically detach ftdi_sio kernel driver (Uwe Bonnes and Intra2net) +* Configurable flow control (Lorenz Moesenlechner and Matthias Kranz) + +New in 0.7 - 2005-10-11 +----------------------- +* Baudrate calculation fix for FT2232C (Steven Turner/FTDI) +* Find all devices by vendor/product id (Tim Ansell and Intra2net) +* Documentation updates (Tim Ansell) + +New in 0.6 - 2005-04-24 +----------------------- +* Set library version on .so file again +* Configurable serial line parameters (Alain Abbas) +* Improved filtering of status bytes (Evgeny Sinelnikov) +* Extended FT2232C support (Uwe Bonnes) +* Small improvement to the baudrate calculation code (Emil) +* Error handling cleanup (Rogier Wolff and Intra2net) + +New in 0.5 - 2004-09-24 +----------------------- +* New autoconf suite +* pkgconfig support +* Status byte filtering now works for "big" readbuffer sizes (Thanks Evgeny!) +* Open device by description and/or serial (Evgeny Sinelnikov) +* Improved error handling (Evgeny Sinelnikov) + +New in 0.4 - 2004-06-15 +----------------------- +* Fixed filtering of status bytes (Readbuffer size is now 64 bytes) +* FT2232C support (Steven Turner/FTDI) +* New baudrate calculation code (Ian Abbott) +* Automatic detection of chip type +* Important: ftdi_write_data now returns the bytes written +* Fixed defaults values in ftdi_eeprom_initdefaults (Jean-Daniel Merkli) +* Reset internal readbuffer offsets for reset()/purge_buffers() +* Small typo fixes (Mark Haemmerling) + +New in 0.3 - 2004-03-25 +----------------------- +* Improved read function which takes arbitrary input buffer sizes + Attention: Call ftdi_deinit() on exit to free used memory +* Vastly increased read/write performance (configurable chunksize, default is 4096) +* Set/get latency timer function working (Thanks Steven Turner/FTDI) +* Increased library version because the changes require recompilation + +New in 0.2 - 2004-01-03 +----------------------- +* EEPROM build fix by Daniel Kirkham (Melbourne, Australia) +* Implemented basic ftdi_read_data() function +* EEPROM write fixes + +New in 0.1 - 2003-06-10 +----------------------- +* First public release diff --git a/external/libftdi1/LICENSE b/external/libftdi1/LICENSE new file mode 100644 index 00000000..f1831c0f --- /dev/null +++ b/external/libftdi1/LICENSE @@ -0,0 +1,25 @@ +The C library "libftdi1" is distributed under the +GNU Library General Public License version 2. + +A copy of the GNU Library General Public License (LGPL) is included +in this distribution, in the file COPYING.LIB. + +---------------------------------------------------------------------- + +The C++ wrapper "ftdipp1" is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of the GNU General Public License (GPL) is included +in this distribution, in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. diff --git a/external/libftdi1/README b/external/libftdi1/README new file mode 100644 index 00000000..c64f8843 --- /dev/null +++ b/external/libftdi1/README @@ -0,0 +1,67 @@ +-------------------------------------------------------------------- +libftdi version 1.5 +-------------------------------------------------------------------- + +libftdi - A library (using libusb) to talk to FTDI's UART/FIFO chips +including the popular bitbang mode. + +The following chips are supported: +* FT230X +- FT4232H / FT2232H +- FT232R / FT245R +- FT2232L / FT2232D / FT2232C +- FT232BM / FT245BM (and the BL/BQ variants) +- FT8U232AM / FT8U245AM + +libftdi requires libusb 1.x. + +The AUTHORS file contains a list of all the people +that made libftdi possible what it is today. + +Changes +------- +* Implement tc[io]flush methods & deprecate broken purge_buffers methods + + Please check your code for ftdi_usb_purge_rx_buffer(), + ftdi_usb_purge_tx_buffer() and ftdi_usb_purge_buffers() + and migrate to the new ftdi_tc[io]flush() methods. + + Old code will continue to function, but you'll get + a deprecation warning during compilation. + +* Add program to test buffer flush (purge) functionality +* Add kernel driver auto attach/detach. + See new AUTO_DETACH_REATACH_SIO_MODULE option +* Add ftdi_setflowctrl_xonxoff() +* ftdi_eeprom / eeprom handling: + * Unify handling of all boolean eeprom flags + * Add device release number support + * Add channel_a_driver support for type xxR chips + * Add support for group0 drive levels on x232H chips + * Fix handling of high_current_drive parameter + * Fix inverted handling of VCP driver field for TYPE_R chips + * New --verbose option for eeprom decode operation +* Add example code for async mode +* Add SPDX license identifiers to the core library & ftdi_eeprom +* Various python SWIG wrapper improvements +* Various cmake file improvements +* Fix small bugs in error code paths + +You'll find the newest version of libftdi at: +https://www.intra2net.com/en/developer/libftdi + + +Quick start +----------- +mkdir build +cd build + +cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ +make +make install + +More verbose build instructions are in "README.build" + +-------------------------------------------------------------------- +www.intra2net.com 2003-2020 Intra2net AG +-------------------------------------------------------------------- diff --git a/external/libftdi1/README.build b/external/libftdi1/README.build new file mode 100644 index 00000000..e130ca09 --- /dev/null +++ b/external/libftdi1/README.build @@ -0,0 +1,96 @@ +Here is a short tutorial on how to build libftdi git under +Ubuntu 12.10, But it is similar on other Linux distros. + +1) Install the build tools +sudo apt-get install build-essential (yum install make automake gcc gcc-c++ kernel-devel) +sudo apt-get install git-core (yum install git) +sudo apt-get install cmake (yum install cmake) +sudo apt-get install doxygen (for building documentations) (yum install doxygen) + +2) Install dependencies +sudo apt-get install libusb-1.0-devel (yum install libusb-devel) +(if the system comes with older version like 1.0.8 or +earlier, it is recommended you build libusbx-1.0.14 or later). + +sudo apt-get install libconfuse-dev (for ftdi-eeprom) (yum install libconfuse-devel) +sudo apt-get install swig python-dev (for python bindings) (yum install swig python-devel) +sudo apt-get install libboost-all-dev (for C++ binding and unit test) (yum install boost-devel) + +3) Clone the git repository +mkdir libftdi +cd libftdi +git clone git://developer.intra2net.com/libftdi + +If you are building the release tar ball, just extract the source +tar ball. + +4) Build the git source and install +cd libftdi +mkdir build +cd build +cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ +make +sudo make install + +5) carry out some tests +cd examples + +mcuee@Ubuntu1210VM:~/Desktop/build/libftdi/libftdi/build/examples$ +./find_all_pp -v 0x0403 -p 0x6001 +Found devices ( VID: 0x403, PID: 0x6001 ) +------------------------------------------------ +FTDI (0x8730800): ftdi, usb serial converter, ftDEH51S (Open OK) +FTDI (0x8730918): FTDI, FT232R USB UART, A8007Ub5 (Open OK) + +mcuee@Ubuntu1210VM:~/Desktop/build/libftdi/libftdi/build/examples$ ./eeprom +2 FTDI devices found: Only Readout on EEPROM done. Use +VID/PID/desc/serial to select device +Decoded values of device 1: +Chip type 1 ftdi_eeprom_size: 128 +0x000: 00 00 03 04 01 60 00 04 a0 16 08 00 10 01 94 0a .....`.. ........ +0x010: 9e 2a c8 12 0a 03 66 00 74 00 64 00 69 00 2a 03 .*....f. t.d.i.*. +0x020: 75 00 73 00 62 00 20 00 73 00 65 00 72 00 69 00 u.s.b. . s.e.r.i. +0x030: 61 00 6c 00 20 00 63 00 6f 00 6e 00 76 00 65 00 a.l. .c. o.n.v.e. +0x040: 72 00 74 00 65 00 72 00 12 03 66 00 74 00 44 00 r.t.e.r. ..f.t.D. +0x050: 45 00 48 00 35 00 31 00 53 00 02 03 00 00 00 00 E.H.5.1. S....... +0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ +0x070: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 16 02 ........ ........ +VID: 0x0403 +PID: 0x6001 +Release: 0x0400 +Bus Powered: 44 mA USB Remote Wake Up +Manufacturer: ftdi +Product: usb serial converter +Serial: ftDEH51S +Checksum : 0216 +Enable Remote Wake Up +PNP: 1 +Decoded values of device 2: +Chip type 3 ftdi_eeprom_size: 128 +0x000: 00 40 03 04 01 60 00 00 a0 2d 08 00 00 00 98 0a .@...`.. .-...... +0x010: a2 20 c2 12 23 10 05 00 0a 03 46 00 54 00 44 00 . ..#... ..F.T.D. +0x020: 49 00 20 03 46 00 54 00 32 00 33 00 32 00 52 00 I. .F.T. 2.3.2.R. +0x030: 20 00 55 00 53 00 42 00 20 00 55 00 41 00 52 00 .U.S.B. .U.A.R. +0x040: 54 00 12 03 41 00 38 00 30 00 30 00 37 00 55 00 T...A.8. 0.0.7.U. +0x050: 62 00 35 00 c9 bf 1c 80 00 00 00 00 00 00 00 00 b.5..... ........ +0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ +0x070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 23 ........ .......# +0x080: 2c 04 d3 fb 00 00 c9 bf 1c 80 42 00 00 00 00 00 ,....... ..B..... +0x090: 00 00 00 00 00 00 00 00 38 41 32 52 4a 33 47 4f ........ 8A2RJ3GO +VID: 0x0403 +PID: 0x6001 +Release: 0x0000 +Bus Powered: 90 mA USB Remote Wake Up +Manufacturer: FTDI +Product: FT232R USB UART +Serial: A8007Ub5 +Checksum : 230f +Internal EEPROM +Enable Remote Wake Up +PNP: 1 +Channel A has Mode UART VCP +C0 Function: TXLED +C1 Function: RXLED +C2 Function: TXDEN +C3 Function: PWREN +C4 Function: SLEEP diff --git a/external/libftdi1/include/ftdi.h b/external/libftdi1/include/ftdi.h new file mode 100644 index 00000000..ea8ba050 --- /dev/null +++ b/external/libftdi1/include/ftdi.h @@ -0,0 +1,638 @@ +/*************************************************************************** + ftdi.h - description + ------------------- + begin : Fri Apr 4 2003 + copyright : (C) 2003-2020 by Intra2net AG and the libftdi developers + email : opensource@intra2net.com + SPDX-License-Identifier: LGPL-2.1-only + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License * + * version 2.1 as published by the Free Software Foundation; * + * * + ***************************************************************************/ + +#ifndef __libftdi_h__ +#define __libftdi_h__ + +#include +#ifndef _WIN32 +#include +#endif + +/* Define _FTDI_DISABLE_DEPRECATED to disable deprecated messages. */ +#ifdef _FTDI_DISABLE_DEPRECATED +#define _Ftdi_Pragma(_msg) +#else +#define _Ftdi_Pragma(_msg) _Pragma(_msg) +#endif + +/* 'interface' might be defined as a macro on Windows, so we need to + * undefine it so as not to break the current libftdi API, because + * struct ftdi_context has an 'interface' member + * As this can be problematic if you include windows.h after ftdi.h + * in your sources, we force windows.h to be included first. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#include +#if defined(interface) +#undef interface +#endif +#endif + +/** FTDI chip type */ +enum ftdi_chip_type +{ + TYPE_AM=0, + TYPE_BM=1, + TYPE_2232C=2, + TYPE_R=3, + TYPE_2232H=4, + TYPE_4232H=5, + TYPE_232H=6, + TYPE_230X=7, +}; +/** Parity mode for ftdi_set_line_property() */ +enum ftdi_parity_type { NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4 }; +/** Number of stop bits for ftdi_set_line_property() */ +enum ftdi_stopbits_type { STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2 }; +/** Number of bits for ftdi_set_line_property() */ +enum ftdi_bits_type { BITS_7=7, BITS_8=8 }; +/** Break type for ftdi_set_line_property2() */ +enum ftdi_break_type { BREAK_OFF=0, BREAK_ON=1 }; + +/** MPSSE bitbang modes */ +enum ftdi_mpsse_mode +{ + BITMODE_RESET = 0x00, /**< switch off bitbang mode, back to regular serial/FIFO */ + BITMODE_BITBANG= 0x01, /**< classical asynchronous bitbang mode, introduced with B-type chips */ + BITMODE_MPSSE = 0x02, /**< MPSSE mode, available on 2232x chips */ + BITMODE_SYNCBB = 0x04, /**< synchronous bitbang mode, available on 2232x and R-type chips */ + BITMODE_MCU = 0x08, /**< MCU Host Bus Emulation mode, available on 2232x chips */ + /* CPU-style fifo mode gets set via EEPROM */ + BITMODE_OPTO = 0x10, /**< Fast Opto-Isolated Serial Interface Mode, available on 2232x chips */ + BITMODE_CBUS = 0x20, /**< Bitbang on CBUS pins of R-type chips, configure in EEPROM before */ + BITMODE_SYNCFF = 0x40, /**< Single Channel Synchronous FIFO mode, available on 2232H chips */ + BITMODE_FT1284 = 0x80, /**< FT1284 mode, available on 232H chips */ +}; + +/** Port interface for chips with multiple interfaces */ +enum ftdi_interface +{ + INTERFACE_ANY = 0, + INTERFACE_A = 1, + INTERFACE_B = 2, + INTERFACE_C = 3, + INTERFACE_D = 4 +}; + +/** Automatic loading / unloading of kernel modules */ +enum ftdi_module_detach_mode +{ + AUTO_DETACH_SIO_MODULE = 0, + DONT_DETACH_SIO_MODULE = 1, + AUTO_DETACH_REATACH_SIO_MODULE = 2 +}; + +/* Shifting commands IN MPSSE Mode*/ +#define MPSSE_WRITE_NEG 0x01 /* Write TDI/DO on negative TCK/SK edge*/ +#define MPSSE_BITMODE 0x02 /* Write bits, not bytes */ +#define MPSSE_READ_NEG 0x04 /* Sample TDO/DI on negative TCK/SK edge */ +#define MPSSE_LSB 0x08 /* LSB first */ +#define MPSSE_DO_WRITE 0x10 /* Write TDI/DO */ +#define MPSSE_DO_READ 0x20 /* Read TDO/DI */ +#define MPSSE_WRITE_TMS 0x40 /* Write TMS/CS */ + +/* FTDI MPSSE commands */ +#define SET_BITS_LOW 0x80 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define SET_BITS_HIGH 0x82 +/*BYTE DATA*/ +/*BYTE Direction*/ +#define GET_BITS_LOW 0x81 +#define GET_BITS_HIGH 0x83 +#define LOOPBACK_START 0x84 +#define LOOPBACK_END 0x85 +#define TCK_DIVISOR 0x86 +/* H Type specific commands */ +#define DIS_DIV_5 0x8a +#define EN_DIV_5 0x8b +#define EN_3_PHASE 0x8c +#define DIS_3_PHASE 0x8d +#define CLK_BITS 0x8e +#define CLK_BYTES 0x8f +#define CLK_WAIT_HIGH 0x94 +#define CLK_WAIT_LOW 0x95 +#define EN_ADAPTIVE 0x96 +#define DIS_ADAPTIVE 0x97 +#define CLK_BYTES_OR_HIGH 0x9c +#define CLK_BYTES_OR_LOW 0x9d +/*FT232H specific commands */ +#define DRIVE_OPEN_COLLECTOR 0x9e +/* Value Low */ +/* Value HIGH */ /*rate is 12000000/((1+value)*2) */ +#define DIV_VALUE(rate) (rate > 6000000)?0:((6000000/rate -1) > 0xffff)? 0xffff: (6000000/rate -1) + +/* Commands in MPSSE and Host Emulation Mode */ +#define SEND_IMMEDIATE 0x87 +#define WAIT_ON_HIGH 0x88 +#define WAIT_ON_LOW 0x89 + +/* Commands in Host Emulation Mode */ +#define READ_SHORT 0x90 +/* Address_Low */ +#define READ_EXTENDED 0x91 +/* Address High */ +/* Address Low */ +#define WRITE_SHORT 0x92 +/* Address_Low */ +#define WRITE_EXTENDED 0x93 +/* Address High */ +/* Address Low */ + +/* Definitions for flow control */ +#define SIO_RESET 0 /* Reset the port */ +#define SIO_MODEM_CTRL 1 /* Set the modem control register */ +#define SIO_SET_FLOW_CTRL 2 /* Set flow control register */ +#define SIO_SET_BAUD_RATE 3 /* Set baud rate */ +#define SIO_SET_DATA 4 /* Set the data characteristics of the port */ + +#define FTDI_DEVICE_OUT_REQTYPE (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT) +#define FTDI_DEVICE_IN_REQTYPE (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN) + +/* Requests */ +#define SIO_RESET_REQUEST SIO_RESET +#define SIO_SET_BAUDRATE_REQUEST SIO_SET_BAUD_RATE +#define SIO_SET_DATA_REQUEST SIO_SET_DATA +#define SIO_SET_FLOW_CTRL_REQUEST SIO_SET_FLOW_CTRL +#define SIO_SET_MODEM_CTRL_REQUEST SIO_MODEM_CTRL +#define SIO_POLL_MODEM_STATUS_REQUEST 0x05 +#define SIO_SET_EVENT_CHAR_REQUEST 0x06 +#define SIO_SET_ERROR_CHAR_REQUEST 0x07 +#define SIO_SET_LATENCY_TIMER_REQUEST 0x09 +#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A +#define SIO_SET_BITMODE_REQUEST 0x0B +#define SIO_READ_PINS_REQUEST 0x0C +#define SIO_READ_EEPROM_REQUEST 0x90 +#define SIO_WRITE_EEPROM_REQUEST 0x91 +#define SIO_ERASE_EEPROM_REQUEST 0x92 + + +#define SIO_RESET_SIO 0 + +/* ** WARNING ** SIO_RESET_PURGE_RX or SIO_RESET_PURGE_TX are values used + * internally by libftdi to purge the RX and/or TX FIFOs (buffers). + * APPLICATION PROGRAMS SHOULD NOT BE USING THESE VALUES. Application + * programs should use one of the ftdi_tciflush, ftdi_tcoflush, or + * ftdi_tcioflush functions which emulate the Linux serial port tcflush(3) + * function. + * + * History: + * + * The definitions for these values are with respect to the FTDI chip, not the + * CPU. That is, when the FTDI chip receives a USB control transfer request + * with the command SIO_RESET_PURGE_RX, the FTDI chip empties the FIFO + * containing data received from the CPU awaiting transfer out the serial + * port to the connected serial device (e.g., a modem). Likewise, upon + * reception of the SIO_RESET_PURGE_TX command, the FTDI chip empties the + * FIFO of data received from the attached serial device destined to be + * transmitted to the CPU. + * + * Unfortunately the coding of the previous releases of libfti assumed these + * commands had the opposite effect. This resulted in the function + * ftdi_usb_purge_tx_buffer clearing data received from the attached serial + * device. Similarly, the function ftdi_usb_purge_rx_buffer cleared the + * FTDI FIFO containing data to be transmitted to the attached serial + * device. More seriously, this latter function clear the libftid's + * internal buffer of data received from the serial device, destined + * to the application program. + */ +#ifdef __GNUC__ +#define SIO_RESET_PURGE_RX _Ftdi_Pragma("GCC warning \"SIO_RESET_PURGE_RX\" deprecated: - use tciflush() method") 1 +#define SIO_RESET_PURGE_TX _Ftdi_Pragma("GCC warning \"SIO_RESET_PURGE_RX\" deprecated: - use tcoflush() method") 2 +#else +#define SIO_RESET_PURGE_RX 1 +#define SIO_RESET_PURGE_TX 2 +#endif +/* New names for the values used internally to flush (purge). */ +#define SIO_TCIFLUSH 2 +#define SIO_TCOFLUSH 1 + +#define SIO_DISABLE_FLOW_CTRL 0x0 +#define SIO_RTS_CTS_HS (0x1 << 8) +#define SIO_DTR_DSR_HS (0x2 << 8) +#define SIO_XON_XOFF_HS (0x4 << 8) + +#define SIO_SET_DTR_MASK 0x1 +#define SIO_SET_DTR_HIGH ( 1 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_DTR_LOW ( 0 | ( SIO_SET_DTR_MASK << 8)) +#define SIO_SET_RTS_MASK 0x2 +#define SIO_SET_RTS_HIGH ( 2 | ( SIO_SET_RTS_MASK << 8 )) +#define SIO_SET_RTS_LOW ( 0 | ( SIO_SET_RTS_MASK << 8 )) + +#define SIO_RTS_CTS_HS (0x1 << 8) + +/* marker for unused usb urb structures + (taken from libusb) */ +#define FTDI_URB_USERCONTEXT_COOKIE ((void *)0x1) + +#ifdef _FTDI_DISABLE_DEPRECATED +#define DEPRECATED(func) func +#else +#ifdef __GNUC__ +#define DEPRECATED(func) __attribute__ ((deprecated)) func +#elif defined(_MSC_VER) +#define DEPRECATED(func) __declspec(deprecated) func +#else +#pragma message("WARNING: You need to implement DEPRECATED for this compiler") +#define DEPRECATED(func) func +#endif +#endif + +struct ftdi_transfer_control +{ + int completed; + unsigned char *buf; + int size; + int offset; + struct ftdi_context *ftdi; + struct libusb_transfer *transfer; +}; + +/** + \brief Main context structure for all libftdi functions. + + Do not access directly if possible. +*/ +struct ftdi_context +{ + /* USB specific */ + /** libusb's context */ + struct libusb_context *usb_ctx; + /** libusb's usb_dev_handle */ + struct libusb_device_handle *usb_dev; + /** usb read timeout */ + int usb_read_timeout; + /** usb write timeout */ + int usb_write_timeout; + + /* FTDI specific */ + /** FTDI chip type */ + enum ftdi_chip_type type; + /** baudrate */ + int baudrate; + /** bitbang mode state */ + unsigned char bitbang_enabled; + /** pointer to read buffer for ftdi_read_data */ + unsigned char *readbuffer; + /** read buffer offset */ + unsigned int readbuffer_offset; + /** number of remaining data in internal read buffer */ + unsigned int readbuffer_remaining; + /** read buffer chunk size */ + unsigned int readbuffer_chunksize; + /** write buffer chunk size */ + unsigned int writebuffer_chunksize; + /** maximum packet size. Needed for filtering modem status bytes every n packets. */ + unsigned int max_packet_size; + + /* FTDI FT2232C requirecments */ + /** FT2232C interface number: 0 or 1 */ + int interface; /* 0 or 1 */ + /** FT2232C index number: 1 or 2 */ + int index; /* 1 or 2 */ + /* Endpoints */ + /** FT2232C end points: 1 or 2 */ + int in_ep; + int out_ep; /* 1 or 2 */ + + /** Bitbang mode. 1: (default) Normal bitbang mode, 2: FT2232C SPI bitbang mode */ + unsigned char bitbang_mode; + + /** Decoded eeprom structure */ + struct ftdi_eeprom *eeprom; + + /** String representation of last error */ + const char *error_str; + + /** Defines behavior in case a kernel module is already attached to the device */ + enum ftdi_module_detach_mode module_detach_mode; +}; + +/** + List all handled EEPROM values. + Append future new values only at the end to provide API/ABI stability*/ +enum ftdi_eeprom_value +{ + VENDOR_ID = 0, + PRODUCT_ID = 1, + SELF_POWERED = 2, + REMOTE_WAKEUP = 3, + IS_NOT_PNP = 4, + SUSPEND_DBUS7 = 5, + IN_IS_ISOCHRONOUS = 6, + OUT_IS_ISOCHRONOUS = 7, + SUSPEND_PULL_DOWNS = 8, + USE_SERIAL = 9, + USB_VERSION = 10, + USE_USB_VERSION = 11, + MAX_POWER = 12, + CHANNEL_A_TYPE = 13, + CHANNEL_B_TYPE = 14, + CHANNEL_A_DRIVER = 15, + CHANNEL_B_DRIVER = 16, + CBUS_FUNCTION_0 = 17, + CBUS_FUNCTION_1 = 18, + CBUS_FUNCTION_2 = 19, + CBUS_FUNCTION_3 = 20, + CBUS_FUNCTION_4 = 21, + CBUS_FUNCTION_5 = 22, + CBUS_FUNCTION_6 = 23, + CBUS_FUNCTION_7 = 24, + CBUS_FUNCTION_8 = 25, + CBUS_FUNCTION_9 = 26, + HIGH_CURRENT = 27, + HIGH_CURRENT_A = 28, + HIGH_CURRENT_B = 29, + INVERT = 30, + GROUP0_DRIVE = 31, + GROUP0_SCHMITT = 32, + GROUP0_SLEW = 33, + GROUP1_DRIVE = 34, + GROUP1_SCHMITT = 35, + GROUP1_SLEW = 36, + GROUP2_DRIVE = 37, + GROUP2_SCHMITT = 38, + GROUP2_SLEW = 39, + GROUP3_DRIVE = 40, + GROUP3_SCHMITT = 41, + GROUP3_SLEW = 42, + CHIP_SIZE = 43, + CHIP_TYPE = 44, + POWER_SAVE = 45, + CLOCK_POLARITY = 46, + DATA_ORDER = 47, + FLOW_CONTROL = 48, + CHANNEL_C_DRIVER = 49, + CHANNEL_D_DRIVER = 50, + CHANNEL_A_RS485 = 51, + CHANNEL_B_RS485 = 52, + CHANNEL_C_RS485 = 53, + CHANNEL_D_RS485 = 54, + RELEASE_NUMBER = 55, + EXTERNAL_OSCILLATOR= 56, + USER_DATA_ADDR = 57, +}; + +/** + \brief list of usb devices created by ftdi_usb_find_all() +*/ +struct ftdi_device_list +{ + /** pointer to next entry */ + struct ftdi_device_list *next; + /** pointer to libusb's usb_device */ + struct libusb_device *dev; +}; +#define FT1284_CLK_IDLE_STATE 0x01 +#define FT1284_DATA_LSB 0x02 /* DS_FT232H 1.3 amd ftd2xx.h 1.0.4 disagree here*/ +#define FT1284_FLOW_CONTROL 0x04 +#define POWER_SAVE_DISABLE_H 0x80 + +#define USE_SERIAL_NUM 0x08 +enum ftdi_cbus_func +{ + CBUS_TXDEN = 0, CBUS_PWREN = 1, CBUS_RXLED = 2, CBUS_TXLED = 3, CBUS_TXRXLED = 4, + CBUS_SLEEP = 5, CBUS_CLK48 = 6, CBUS_CLK24 = 7, CBUS_CLK12 = 8, CBUS_CLK6 = 9, + CBUS_IOMODE = 0xa, CBUS_BB_WR = 0xb, CBUS_BB_RD = 0xc +}; + +enum ftdi_cbush_func +{ + CBUSH_TRISTATE = 0, CBUSH_TXLED = 1, CBUSH_RXLED = 2, CBUSH_TXRXLED = 3, CBUSH_PWREN = 4, + CBUSH_SLEEP = 5, CBUSH_DRIVE_0 = 6, CBUSH_DRIVE1 = 7, CBUSH_IOMODE = 8, CBUSH_TXDEN = 9, + CBUSH_CLK30 = 10, CBUSH_CLK15 = 11, CBUSH_CLK7_5 = 12 +}; + +enum ftdi_cbusx_func +{ + CBUSX_TRISTATE = 0, CBUSX_TXLED = 1, CBUSX_RXLED = 2, CBUSX_TXRXLED = 3, CBUSX_PWREN = 4, + CBUSX_SLEEP = 5, CBUSX_DRIVE_0 = 6, CBUSX_DRIVE1 = 7, CBUSX_IOMODE = 8, CBUSX_TXDEN = 9, + CBUSX_CLK24 = 10, CBUSX_CLK12 = 11, CBUSX_CLK6 = 12, CBUSX_BAT_DETECT = 13, + CBUSX_BAT_DETECT_NEG = 14, CBUSX_I2C_TXE = 15, CBUSX_I2C_RXF = 16, CBUSX_VBUS_SENSE = 17, + CBUSX_BB_WR = 18, CBUSX_BB_RD = 19, CBUSX_TIME_STAMP = 20, CBUSX_AWAKE = 21 +}; + +/** Invert TXD# */ +#define INVERT_TXD 0x01 +/** Invert RXD# */ +#define INVERT_RXD 0x02 +/** Invert RTS# */ +#define INVERT_RTS 0x04 +/** Invert CTS# */ +#define INVERT_CTS 0x08 +/** Invert DTR# */ +#define INVERT_DTR 0x10 +/** Invert DSR# */ +#define INVERT_DSR 0x20 +/** Invert DCD# */ +#define INVERT_DCD 0x40 +/** Invert RI# */ +#define INVERT_RI 0x80 + +/** Interface Mode. */ +#define CHANNEL_IS_UART 0x0 +#define CHANNEL_IS_FIFO 0x1 +#define CHANNEL_IS_OPTO 0x2 +#define CHANNEL_IS_CPU 0x4 +#define CHANNEL_IS_FT1284 0x8 + +#define CHANNEL_IS_RS485 0x10 + +#define DRIVE_4MA 0 +#define DRIVE_8MA 1 +#define DRIVE_12MA 2 +#define DRIVE_16MA 3 +#define SLOW_SLEW 4 +#define IS_SCHMITT 8 + +/** Driver Type. */ +#define DRIVER_VCP 0x08 +#define DRIVER_VCPH 0x10 /* FT232H has moved the VCP bit */ + +#define USE_USB_VERSION_BIT 0x10 + +#define SUSPEND_DBUS7_BIT 0x80 + +/** High current drive. */ +#define HIGH_CURRENT_DRIVE 0x10 +#define HIGH_CURRENT_DRIVE_R 0x04 + +/** + \brief Progress Info for streaming read +*/ +struct size_and_time +{ + uint64_t totalBytes; + struct timeval time; +}; + +typedef struct +{ + struct size_and_time first; + struct size_and_time prev; + struct size_and_time current; + double totalTime; + double totalRate; + double currentRate; +} FTDIProgressInfo; + +typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, + FTDIProgressInfo *progress, void *userdata); + +/** + * Provide libftdi version information + * major: Library major version + * minor: Library minor version + * micro: Currently unused, ight get used for hotfixes. + * version_str: Version as (static) string + * snapshot_str: Git snapshot version if known. Otherwise "unknown" or empty string. +*/ +struct ftdi_version_info +{ + int major; + int minor; + int micro; + const char *version_str; + const char *snapshot_str; +}; + + +#ifdef __cplusplus +extern "C" +{ +#endif + + int ftdi_init(struct ftdi_context *ftdi); + struct ftdi_context *ftdi_new(void); + int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface); + + void ftdi_deinit(struct ftdi_context *ftdi); + void ftdi_free(struct ftdi_context *ftdi); + void ftdi_set_usbdev (struct ftdi_context *ftdi, struct libusb_device_handle *usbdev); + + struct ftdi_version_info ftdi_get_library_version(void); + + int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, + int vendor, int product); + void ftdi_list_free(struct ftdi_device_list **devlist); + void ftdi_list_free2(struct ftdi_device_list *devlist); + int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len); + int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, + char *manufacturer, int mnf_len, + char *description, int desc_len, + char *serial, int serial_len); + + int ftdi_eeprom_get_strings(struct ftdi_context *ftdi, + char *manufacturer, int mnf_len, + char *product, int prod_len, + char *serial, int serial_len); + int ftdi_eeprom_set_strings(struct ftdi_context *ftdi, const char * manufacturer, + const char * product, const char * serial); + + int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product); + int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial); + int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product, + const char* description, const char* serial, unsigned int index); + int ftdi_usb_open_bus_addr(struct ftdi_context *ftdi, uint8_t bus, uint8_t addr); + int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct libusb_device *dev); + int ftdi_usb_open_string(struct ftdi_context *ftdi, const char* description); + + int ftdi_usb_close(struct ftdi_context *ftdi); + int ftdi_usb_reset(struct ftdi_context *ftdi); + int ftdi_tciflush(struct ftdi_context *ftdi); + int ftdi_tcoflush(struct ftdi_context *ftdi); + int ftdi_tcioflush(struct ftdi_context *ftdi); + int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi); + int ftdi_usb_purge_buffers(struct ftdi_context *ftdi); + + int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate); + int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity); + int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits, + enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, + enum ftdi_break_type break_type); + + int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_write_data(struct ftdi_context *ftdi, const unsigned char *buf, int size); + int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); + int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); + + int ftdi_readstream(struct ftdi_context *ftdi, FTDIStreamCallback *callback, + void *userdata, int packetsPerTransfer, int numTransfers); + struct ftdi_transfer_control *ftdi_write_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size); + + struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size); + int ftdi_transfer_data_done(struct ftdi_transfer_control *tc); + void ftdi_transfer_data_cancel(struct ftdi_transfer_control *tc, struct timeval * to); + + int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode); + int ftdi_disable_bitbang(struct ftdi_context *ftdi); + int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins); + + int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency); + int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency); + + int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status); + + /* flow control */ + int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl); + int ftdi_setflowctrl_xonxoff(struct ftdi_context *ftdi, unsigned char xon, unsigned char xoff); + int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, int rts); + int ftdi_setdtr(struct ftdi_context *ftdi, int state); + int ftdi_setrts(struct ftdi_context *ftdi, int state); + + int ftdi_set_event_char(struct ftdi_context *ftdi, unsigned char eventch, unsigned char enable); + int ftdi_set_error_char(struct ftdi_context *ftdi, unsigned char errorch, unsigned char enable); + + /* init eeprom for the given FTDI type */ + int ftdi_eeprom_initdefaults(struct ftdi_context *ftdi, + char * manufacturer, char *product, + char * serial); + int ftdi_eeprom_build(struct ftdi_context *ftdi); + int ftdi_eeprom_decode(struct ftdi_context *ftdi, int verbose); + + int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value value_name, int* value); + int ftdi_set_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value value_name, int value); + + int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, int size); + int ftdi_set_eeprom_buf(struct ftdi_context *ftdi, const unsigned char * buf, int size); + + int ftdi_set_eeprom_user_data(struct ftdi_context *ftdi, const char * buf, int size); + + int ftdi_read_eeprom(struct ftdi_context *ftdi); + int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); + int ftdi_write_eeprom(struct ftdi_context *ftdi); + int ftdi_erase_eeprom(struct ftdi_context *ftdi); + + int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val); + int ftdi_write_eeprom_location(struct ftdi_context *ftdi, int eeprom_addr, unsigned short eeprom_val); + + const char *ftdi_get_error_string(struct ftdi_context *ftdi); + +#ifdef __cplusplus +} +#endif + +#endif /* __libftdi_h__ */ diff --git a/external/libftdi1/libftdi1.vcxproj b/external/libftdi1/libftdi1.vcxproj new file mode 100644 index 00000000..f1f580bf --- /dev/null +++ b/external/libftdi1/libftdi1.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + 16.0 + Win32Proj + {632649ab-a351-46d4-a81f-1d6e9a819a5c} + libftdi1 + 10.0 + + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + StaticLibrary + true + v142 + MultiByte + + + StaticLibrary + false + v142 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + include + + + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include + + + true + true + true + + + + + Level3 + true + _DEBUG;_LIB;%(PreprocessorDefinitions) + true + include + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreaded + include + + + true + true + true + + + + + + \ No newline at end of file diff --git a/external/libftdi1/libftdi1.vcxproj.filters b/external/libftdi1/libftdi1.vcxproj.filters new file mode 100644 index 00000000..74a430a5 --- /dev/null +++ b/external/libftdi1/libftdi1.vcxproj.filters @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/external/libftdi1/src/ftdi.cpp b/external/libftdi1/src/ftdi.cpp new file mode 100644 index 00000000..5739ba17 --- /dev/null +++ b/external/libftdi1/src/ftdi.cpp @@ -0,0 +1,320 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2019 Marius Greuel + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "libwinftdi.h" +#include +#include + +using namespace LibWinFtdi; + +static ftdi_chip_type MapChipType(ULONG type) +{ + switch (type) + { + case FT_DEVICE_BM: + return TYPE_BM; + case FT_DEVICE_AM: + return TYPE_AM; + case FT_DEVICE_100AX: + return TYPE_AM; + case FT_DEVICE_2232C: + return TYPE_2232C; + case FT_DEVICE_232R: + return TYPE_R; + case FT_DEVICE_2232H: + return TYPE_2232H; + case FT_DEVICE_4232H: + return TYPE_4232H; + case FT_DEVICE_232H: + return TYPE_232H; + default: + return TYPE_AM; + } +} +static int SetError(struct ftdi_context* ftdi, int result, const char* error_str) +{ + if (ftdi != nullptr) + { + ftdi->error_str = error_str; + } + + return result; +} + +const char* ftdi_get_error_string(struct ftdi_context* ftdi) +{ + return ftdi != nullptr && ftdi->error_str != nullptr ? ftdi->error_str : "unknown error"; +} + +struct ftdi_context* ftdi_new(void) +{ + struct ftdi_context* ftdi = new struct ftdi_context(); + + if (ftdi_init(ftdi) != 0) + { + delete ftdi; + return nullptr; + } + + return ftdi; +} + +void ftdi_free(struct ftdi_context* ftdi) +{ + ftdi_deinit(ftdi); + delete ftdi; +} + +int ftdi_set_interface(struct ftdi_context* ftdi, enum ftdi_interface interface) +{ + return 0; +} + +int ftdi_init(struct ftdi_context* ftdi) +{ + std::memset(ftdi, 0, sizeof(struct ftdi_context)); + return 0; +} + +void ftdi_deinit(struct ftdi_context* ftdi) +{ + if (ftdi->usb_dev != nullptr) + { + std::unique_ptr device(reinterpret_cast(ftdi->usb_dev)); + ftdi->usb_dev = nullptr; + } +} + +int ftdi_usb_open_desc_index(struct ftdi_context* ftdi, int vendor, int product, + const char* description, const char* serial, unsigned int index) +{ + if (ftdi == nullptr) + { + return SetError(ftdi, -3, "invalid ftdi context"); + } + + FtdiEnumerator enumerator; + auto status = enumerator.EnumerateDevices(); + if (status != FT_OK) + { + return SetError(ftdi, -3, "failed to enumerate devices"); + } + + for (auto const& info : enumerator.GetDevices()) + { + if ((info.Flags & FT_FLAGS_OPENED) != 0) + continue; + + if (vendor != static_cast(info.ID >> 16)) + continue; + + if (product != static_cast(info.ID >> 0)) + continue; + + if (description != nullptr && strcmp(description, info.Description) != 0) + continue; + + if (serial != nullptr && strcmp(serial, info.SerialNumber) != 0) + continue; + + if (index > 0) + { + index--; + continue; + } + + auto device = std::make_unique(); + auto status = device->OpenBySerialNumber(info.SerialNumber); + if (status != FT_OK) + { + return SetError(ftdi, -3, "failed to open device"); + } + + device->SetEventNotification(FT_EVENT_RXCHAR); + + ftdi->type = MapChipType(info.Type); + ftdi->usb_dev = reinterpret_cast(device.release()); + return 0; + } + + return SetError(ftdi, -3, "device not found"); +} + +int ftdi_usb_close(struct ftdi_context* ftdi) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -3, "invalid device"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + auto status = device->Close(); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to close device"); + } + + return 0; +} + +int ftdi_usb_purge_buffers(struct ftdi_context* ftdi) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -3, "invalid device"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + auto status = device->Purge(); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to purge buffers"); + } + + return 0; +} + +int ftdi_set_baudrate(struct ftdi_context* ftdi, int baudrate) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -3, "invalid device"); + } + + if (ftdi->bitbang_enabled) + { + baudrate /= 16; + } + + if (baudrate <= 0) + { + return SetError(ftdi, -1, "invalid baudrate"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + auto status = device->SetBaudRate(baudrate); + if (status != FT_OK) + { + return SetError(ftdi, -2, "Failed to set baudrate"); + } + + ftdi->baudrate = baudrate; + return 0; +} + +int ftdi_set_bitmode(struct ftdi_context* ftdi, unsigned char bitmask, unsigned char mode) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -2, "invalid device"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + auto status = device->SetBitMode(bitmask, mode); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to set bitmode"); + } + + ftdi->bitbang_mode = mode; + ftdi->bitbang_enabled = mode == BITMODE_RESET ? 0 : 1; + return 0; +} + +int ftdi_set_latency_timer(struct ftdi_context* ftdi, unsigned char latency) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -3, "invalid device"); + } + + if (latency < 1) + { + return SetError(ftdi, -1, "invalid latency"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + auto status = device->SetLatencyTimer(latency); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to set latency timer"); + } + + return 0; +} + +int ftdi_read_data(struct ftdi_context* ftdi, unsigned char* buf, int size) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -666, "invalid device"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + + auto handle = device->GetNotificationEvent(); + if (handle != nullptr) + { + DWORD dwStatus = WaitForSingleObject(handle, 1000); + if (dwStatus != WAIT_OBJECT_0) + { + return 0; + } + } + + DWORD bytesInQueue = 0; + auto status = device->GetQueueStatus(&bytesInQueue); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to get queue status"); + } + + DWORD bytesRead = 0; + if (bytesInQueue > 0) + { + if (size > static_cast(bytesInQueue)) + size = static_cast(bytesInQueue); + + status = device->Read(buf, size, &bytesRead); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to read data"); + } + } + + return bytesRead; +} + +int ftdi_write_data(struct ftdi_context* ftdi, const unsigned char* buf, int size) +{ + if (ftdi == nullptr || ftdi->usb_dev == nullptr) + { + return SetError(ftdi, -666, "invalid device"); + } + + auto device = reinterpret_cast(ftdi->usb_dev); + + DWORD bytesWritten = 0; + auto status = device->Write(const_cast(buf), size, &bytesWritten); + if (status != FT_OK) + { + return SetError(ftdi, -1, "Failed to write data"); + } + + return bytesWritten; +} diff --git a/external/libftdi1/src/libwinftdi.h b/external/libftdi1/src/libwinftdi.h new file mode 100644 index 00000000..4e998ab9 --- /dev/null +++ b/external/libftdi1/src/libwinftdi.h @@ -0,0 +1,380 @@ +// +// libwinftdi.h +// Copyright (C) 2019 Marius Greuel. All rights reserved. +// + +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace LibWinFtdi +{ + enum + { + FT_OK, + FT_INVALID_HANDLE, + FT_DEVICE_NOT_FOUND, + FT_DEVICE_NOT_OPENED, + FT_IO_ERROR, + FT_INSUFFICIENT_RESOURCES, + FT_INVALID_PARAMETER, + FT_INVALID_BAUD_RATE, + FT_DEVICE_NOT_OPENED_FOR_ERASE, + FT_DEVICE_NOT_OPENED_FOR_WRITE, + FT_FAILED_TO_WRITE_DEVICE, + FT_EEPROM_READ_FAILED, + FT_EEPROM_WRITE_FAILED, + FT_EEPROM_ERASE_FAILED, + FT_EEPROM_NOT_PRESENT, + FT_EEPROM_NOT_PROGRAMMED, + FT_INVALID_ARGS, + FT_NOT_SUPPORTED, + FT_OTHER_ERROR, + FT_DEVICE_LIST_NOT_READY, + }; + + enum + { + FT_DEVICE_BM, + FT_DEVICE_AM, + FT_DEVICE_100AX, + FT_DEVICE_UNKNOWN, + FT_DEVICE_2232C, + FT_DEVICE_232R, + FT_DEVICE_2232H, + FT_DEVICE_4232H, + FT_DEVICE_232H, + }; + + enum + { + FT_FLAGS_OPENED = 1, + FT_FLAGS_HISPEED = 2, + }; + + enum + { + FT_OPEN_BY_SERIAL_NUMBER = 1, + FT_OPEN_BY_DESCRIPTION = 2, + FT_OPEN_BY_LOCATION = 4, + }; + + enum + { + FT_PURGE_RX = 1, + FT_PURGE_TX = 2, + }; + + enum + { + FT_EVENT_RXCHAR = 1, + FT_EVENT_MODEM_STATUS = 2, + FT_EVENT_LINE_STATUS = 4, + }; + + typedef PVOID FT_HANDLE; + typedef ULONG FT_STATUS; + + struct DeviceInfo + { + ULONG Flags; + ULONG Type; + ULONG ID; + DWORD LocId; + char SerialNumber[16]; + char Description[64]; + FT_HANDLE ftHandle; + }; + + class FtdiApi + { + public: + FtdiApi() = default; + FtdiApi(const FtdiApi&) = delete; + FtdiApi& operator=(const FtdiApi&) = delete; + FtdiApi(FtdiApi&&) = delete; + FtdiApi& operator=(FtdiApi&&) = delete; + + ~FtdiApi() + { + Unload(); + } + + HRESULT Load() + { + if (m_module != nullptr) + return S_FALSE; + + m_module = LoadLibraryExW(L"ftd2xx.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (m_module == nullptr) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + HRESULT hr = S_OK; + if (FAILED(hr = LoadImport("FT_CreateDeviceInfoList", &FT_CreateDeviceInfoList)) || + FAILED(hr = LoadImport("FT_GetDeviceInfoList", &FT_GetDeviceInfoList)) || + FAILED(hr = LoadImport("FT_OpenEx", &FT_OpenEx)) || + FAILED(hr = LoadImport("FT_Close", &FT_Close)) || + FAILED(hr = LoadImport("FT_Purge", &FT_Purge)) || + FAILED(hr = LoadImport("FT_SetTimeouts", &FT_SetTimeouts)) || + FAILED(hr = LoadImport("FT_SetBaudRate", &FT_SetBaudRate)) || + FAILED(hr = LoadImport("FT_SetBitMode", &FT_SetBitMode)) || + FAILED(hr = LoadImport("FT_SetLatencyTimer", &FT_SetLatencyTimer)) || + FAILED(hr = LoadImport("FT_GetQueueStatus", &FT_GetQueueStatus)) || + FAILED(hr = LoadImport("FT_SetEventNotification", &FT_SetEventNotification)) || + FAILED(hr = LoadImport("FT_Read", &FT_Read)) || + FAILED(hr = LoadImport("FT_Write", &FT_Write))) + { + return hr; + } + + return S_OK; + } + + HRESULT Unload() + { + if (m_module == nullptr) + return S_FALSE; + + FreeLibrary(m_module); + m_module = nullptr; + + return S_OK; + } + + private: + template + HRESULT LoadImport(LPCSTR lpProcName, T** ptr) + { + auto proc = GetProcAddress(m_module, lpProcName); + if (proc == nullptr) + { + return HRESULT_FROM_WIN32(GetLastError()); + } + + *ptr = reinterpret_cast(proc); + return S_OK; + } + + private: + HMODULE m_module = nullptr; + + public: + FT_STATUS(WINAPI* FT_CreateDeviceInfoList)(LPDWORD lpdwNumDevs) = nullptr; + FT_STATUS(WINAPI* FT_GetDeviceInfoList)(DeviceInfo* pDest, LPDWORD lpdwNumDevs) = nullptr; + FT_STATUS(WINAPI* FT_OpenEx)(PVOID pArg1, DWORD Flags, FT_HANDLE* pHandle) = nullptr; + FT_STATUS(WINAPI* FT_Close)(FT_HANDLE ftHandle) = nullptr; + FT_STATUS(WINAPI* FT_Purge)(FT_HANDLE ftHandle, ULONG Mask) = nullptr; + FT_STATUS(WINAPI* FT_SetTimeouts)(FT_HANDLE ftHandle, ULONG ReadTimeout, ULONG WriteTimeout) = nullptr; + FT_STATUS(WINAPI* FT_SetBaudRate)(FT_HANDLE ftHandle, ULONG BaudRate) = nullptr; + FT_STATUS(WINAPI* FT_SetBitMode)(FT_HANDLE ftHandle, UCHAR ucMask, UCHAR ucEnable) = nullptr; + FT_STATUS(WINAPI* FT_SetLatencyTimer)(FT_HANDLE ftHandle, UCHAR ucLatency) = nullptr; + FT_STATUS(WINAPI* FT_GetQueueStatus)(FT_HANDLE ftHandle, DWORD* dwRxBytes) = nullptr; + FT_STATUS(WINAPI* FT_SetEventNotification)(FT_HANDLE ftHandle, DWORD Mask, PVOID Param) = nullptr; + FT_STATUS(WINAPI* FT_Read)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned) = nullptr; + FT_STATUS(WINAPI* FT_Write)(FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten) = nullptr; + }; + + class FtdiEnumerator : public FtdiApi + { + public: + FtdiEnumerator() = default; + FtdiEnumerator(const FtdiEnumerator&) = delete; + FtdiEnumerator& operator=(const FtdiEnumerator&) = delete; + FtdiEnumerator(FtdiEnumerator&&) = delete; + FtdiEnumerator& operator=(FtdiEnumerator&&) = delete; + + public: + FT_STATUS EnumerateDevices() + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + DWORD lpdwNumDevs = 0; + FT_STATUS status = FT_CreateDeviceInfoList(&lpdwNumDevs); + if (status != FT_OK) + return status; + + m_devices.resize(lpdwNumDevs); + + status = FT_GetDeviceInfoList(m_devices.data(), &lpdwNumDevs); + if (status != FT_OK) + return status; + + return FT_OK; + } + + const std::vector& GetDevices() const + { + return m_devices; + } + + private: + std::vector m_devices; + }; + + class FtdiDevice : public FtdiApi + { + public: + FtdiDevice() = default; + FtdiDevice(const FtdiDevice&) = delete; + FtdiDevice& operator=(const FtdiDevice&) = delete; + FtdiDevice(FtdiDevice&&) = delete; + FtdiDevice& operator=(FtdiDevice&&) = delete; + + ~FtdiDevice() + { + if (m_event != nullptr) + { + CloseHandle(m_event); + } + } + + HANDLE GetNotificationEvent() const + { + return m_event; + } + + public: + FT_STATUS OpenBySerialNumber(const char* serialNumber) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_OpenEx(const_cast(serialNumber), FT_OPEN_BY_SERIAL_NUMBER, &m_handle); + } + + FT_STATUS OpenByLocation(uint32_t location) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_OpenEx(&location, FT_OPEN_BY_LOCATION, &m_handle); + } + + FT_STATUS Close() + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_Close(m_handle); + } + + FT_STATUS Purge(ULONG Mask = FT_PURGE_RX | FT_PURGE_TX) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_Purge(m_handle, Mask); + } + + FT_STATUS SetTimeouts(ULONG ReadTimeout, ULONG WriteTimeout) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_SetTimeouts(m_handle, ReadTimeout, WriteTimeout); + } + + FT_STATUS SetBaudRate(ULONG BaudRate) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_SetBaudRate(m_handle, BaudRate); + } + + FT_STATUS SetBitMode(UCHAR ucMask, UCHAR ucEnable) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_SetBitMode(m_handle, ucMask, ucEnable); + } + + FT_STATUS SetLatencyTimer(UCHAR ucLatency) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_SetLatencyTimer(m_handle, ucLatency); + } + + FT_STATUS GetQueueStatus(DWORD* dwRxBytes) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_GetQueueStatus(m_handle, dwRxBytes); + } + + FT_STATUS SetEventNotification(DWORD Mask) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + if (m_event == nullptr) + { + m_event = CreateEventW(nullptr, FALSE, FALSE, nullptr); + } + + return FT_SetEventNotification(m_handle, Mask, m_event); + } + + FT_STATUS Read(LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpBytesReturned) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_Read(m_handle, lpBuffer, dwBytesToRead, lpBytesReturned); + } + + FT_STATUS Write(LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpBytesWritten) + { + if (FAILED(Load())) + { + return FT_INVALID_HANDLE; + } + + return FT_Write(m_handle, lpBuffer, dwBytesToWrite, lpBytesWritten); + } + + private: + FT_HANDLE m_handle = nullptr; + HANDLE m_event = nullptr; + }; +} diff --git a/ft245r.c b/ft245r.c index 80aed028..2c0ef259 100644 --- a/ft245r.c +++ b/ft245r.c @@ -78,7 +78,7 @@ # include # endif # include -#elif defined(HAVE_LIBFTDI) && defined(HAVE_USB_H) +#elif defined(HAVE_LIBFTDI) && (defined(HAVE_USB_H) || defined(_MSC_VER)) /* ftdi.h includes usb.h */ #include #else diff --git a/msvc/IntegerHandleMap.h b/msvc/IntegerHandleMap.h new file mode 100644 index 00000000..51cfd423 --- /dev/null +++ b/msvc/IntegerHandleMap.h @@ -0,0 +1,68 @@ +// +// HandleMap.h +// Copyright (C) 2019 Marius Greuel. All rights reserved. +// + +#pragma once +#include +#include +#include "ReaderWriterLock.h" + +#pragma push_macro("max") +#undef max + +template +class IntegerHandleMap +{ +public: + TKey Add(TValue value) + { + TKey key = GetNextId(); + + ReaderWriterLock::WriterLock lock(m_lock); + m_map.emplace(key, value); + return key; + } + + void Remove(TKey key) noexcept + { + ReaderWriterLock::WriterLock lock(m_lock); + m_map.erase(key); + } + + TValue Lookup(TKey key) noexcept + { + ReaderWriterLock::ReaderLock lock(m_lock); + + TValue value; + auto result = m_map.find(key); + return result != m_map.end() ? result->second : nullptr; + } + +private: + TKey GetNextId() noexcept + { + ReaderWriterLock::ReaderLock lock(m_lock); + + TKey key = m_next; + while (m_map.find(key) != m_map.end()) + { + key = GetNextId(key); + } + + m_next = GetNextId(key); + return key; + } + + static TKey GetNextId(TKey key) noexcept + { + return key < std::numeric_limits::max() ? key + 1 : 1; + } + +private: + ReaderWriterLock m_lock; + std::unordered_map m_map; + TKey m_next = 1; +}; + +#pragma pop_macro("max") diff --git a/msvc/ReaderWriterLock.h b/msvc/ReaderWriterLock.h new file mode 100644 index 00000000..512e6072 --- /dev/null +++ b/msvc/ReaderWriterLock.h @@ -0,0 +1,80 @@ +// +// ReaderWriterLock.h +// Copyright (C) 2019 Marius Greuel. All rights reserved. +// + +#pragma once + +class ReaderWriterLock +{ +public: + class ReaderLock + { + public: + ReaderLock(ReaderWriterLock& lock) noexcept : m_lock(lock) + { + Acquire(); + } + + ~ReaderLock() + { + Release(); + } + + private: + void Acquire() noexcept + { + AcquireSRWLockShared(&m_lock.m_srwlock); + } + + void Release() noexcept + { + ReleaseSRWLockShared(&m_lock.m_srwlock); + } + + private: + ReaderWriterLock& m_lock; + }; + + class WriterLock + { + public: + WriterLock(ReaderWriterLock& lock) noexcept : m_lock(lock) + { + Acquire(); + } + + ~WriterLock() + { + Release(); + } + + private: + void Acquire() noexcept + { + AcquireSRWLockExclusive(&m_lock.m_srwlock); + } + + void Release() noexcept + { + ReleaseSRWLockExclusive(&m_lock.m_srwlock); + } + + private: + ReaderWriterLock& m_lock; + }; + +public: + ReaderWriterLock() noexcept + { + InitializeSRWLock(&m_srwlock); + } + + ReaderWriterLock(const ReaderWriterLock&) = delete; + ReaderWriterLock& operator=(const ReaderWriterLock&) = delete; + ReaderWriterLock(ReaderWriterLock&&) = delete; + ReaderWriterLock& operator=(ReaderWriterLock&&) = delete; + +private: + SRWLOCK m_srwlock{}; +}; diff --git a/msvc/generated/ac_cfg.h b/msvc/generated/ac_cfg.h index 366e64ee..00018603 100644 --- a/msvc/generated/ac_cfg.h +++ b/msvc/generated/ac_cfg.h @@ -32,13 +32,13 @@ /* #undef HAVE_LIBELF_LIBELF_H */ /* Define if FTDI support is enabled via libftdi */ -/* #undef HAVE_LIBFTDI */ +#define HAVE_LIBFTDI 1 /* Define if FTDI support is enabled via libftdi1 */ /* #undef HAVE_LIBFTDI1 */ /* Define if libftdi supports FT232H, libftdi version >= 0.20 */ -/* #undef HAVE_LIBFTDI_TYPE_232H */ +#define HAVE_LIBFTDI_TYPE_232H 1 /* Define if HID support is enabled via the Win32 DDK */ #define HAVE_LIBHID 1 @@ -92,7 +92,7 @@ /* #undef HAVE_PARPORT */ /* Define to 1 if you have the header file. */ -/* #undef HAVE_PTHREAD_H */ +#define HAVE_PTHREAD_H 1 /* Define to 1 if you have the `select' function. */ /* #undef HAVE_SELECT */ diff --git a/msvc/pthread.cpp b/msvc/pthread.cpp new file mode 100644 index 00000000..f1cd06e6 --- /dev/null +++ b/msvc/pthread.cpp @@ -0,0 +1,184 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "pthread.h" +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include "IntegerHandleMap.h" + +struct ThreadContext +{ + ~ThreadContext() + { + if (hCancel != nullptr) + { + CloseHandle(hCancel); + hCancel = nullptr; + } + + if (hThread != nullptr) + { + CloseHandle(hThread); + hThread = nullptr; + } + } + + using start_routine_t = void* (*)(void*); + HANDLE hThread = nullptr; + HANDLE hCancel = nullptr; + start_routine_t start_routine = nullptr; + void* arguments = nullptr; + int canceltype = 0; +}; + +static IntegerHandleMap> contextMap; +static thread_local pthread_t currentThread; + +static unsigned __stdcall pthread_start_routine_wrapper(void* arguments) +{ + pthread_t id = reinterpret_cast(arguments); + auto context = contextMap.Lookup(id); + if (context == nullptr) + { + return ESRCH; + } + + currentThread = id; + context->start_routine(context->arguments); + return 0; +} + +int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine) (void*), void* arg) +{ + try + { + auto context = std::make_shared(); + context->start_routine = start_routine; + context->arguments = arg; + + auto id = contextMap.Add(context); + context->hThread = reinterpret_cast(_beginthreadex(nullptr, 0, pthread_start_routine_wrapper, reinterpret_cast(id), 0, nullptr)); + if (context->hThread == nullptr) + { + return ENOMEM; + } + + *thread = id; + return 0; + } + catch (std::exception&) + { + return ENOMEM; + } +} + +void pthread_exit(void* retval) +{ + _endthreadex(static_cast(reinterpret_cast(retval))); +} + +int pthread_cancel(pthread_t thread) +{ + auto context = contextMap.Lookup(thread); + if (context == nullptr) + { + return ESRCH; + } + + if (context->hCancel == nullptr) + { + context->hCancel = CreateEventW(nullptr, TRUE, FALSE, nullptr); + if (context->hCancel == nullptr) + { + return ENOMEM; + } + } + + if (!SetEvent(context->hCancel)) + { + return 1; + } + + return 0; +} + +int pthread_join(pthread_t thread, void** retval) +{ + auto context = contextMap.Lookup(thread); + if (context == nullptr) + return ESRCH; + + DWORD dwStatus = WaitForSingleObject(context->hThread, INFINITE); + if (dwStatus == WAIT_OBJECT_0) + { + if (retval != nullptr) + { + DWORD dwExitCode = 0; + if (GetExitCodeThread(context->hThread, &dwExitCode)) + { + *retval = reinterpret_cast(static_cast(dwExitCode)); + } + else + { + *retval = nullptr; + } + } + + contextMap.Remove(thread); + return 0; + } + else + { + return EINVAL; + } +} + +int pthread_setcanceltype(int type, int* oldtype) +{ + auto context = contextMap.Lookup(currentThread); + if (context == nullptr) + return ESRCH; + + if (oldtype != nullptr) + { + *oldtype = context->canceltype; + } + + context->canceltype = type; + return 0; +} + +void pthread_testcancel(void) +{ + auto context = contextMap.Lookup(currentThread); + if (context == nullptr) + return; + + if (context->hCancel != nullptr) + { + DWORD dwStatus = WaitForSingleObject(context->hCancel, 0); + if (dwStatus == WAIT_OBJECT_0) + { + pthread_exit(nullptr); + } + } +} diff --git a/msvc/pthread.h b/msvc/pthread.h new file mode 100644 index 00000000..24890737 --- /dev/null +++ b/msvc/pthread.h @@ -0,0 +1,43 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _PTHREAD_H +#define _PTHREAD_H + +#include + +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 + +typedef uintptr_t pthread_t; +typedef int pthread_attr_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*start_routine) (void*), void* arg); +int pthread_cancel(pthread_t thread); +int pthread_join(pthread_t thread, void** retval); +int pthread_setcanceltype(int type, int* oldtype); +void pthread_testcancel(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/msvc/semaphore.cpp b/msvc/semaphore.cpp new file mode 100644 index 00000000..aec9f4c9 --- /dev/null +++ b/msvc/semaphore.cpp @@ -0,0 +1,68 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "semaphore.h" +#define WIN32_LEAN_AND_MEAN +#include + +int sem_init(sem_t* sem, int pshared, unsigned int value) +{ + if (sem == nullptr) + return -1; + + sem->handle = nullptr; + + auto handle = CreateSemaphoreW(nullptr, value, MAXLONG32, nullptr); + if (handle == nullptr) + return -1; + + sem->handle = handle; + return 0; +} + +int sem_destroy(sem_t* sem) +{ + if (sem == nullptr) + return -1; + + if (sem->handle != nullptr) + { + CloseHandle(sem->handle); + sem->handle = nullptr; + } + + return 0; +} + +int sem_post(sem_t* sem) +{ + if (sem == nullptr) + return -1; + + BOOL bStatus = ReleaseSemaphore(sem->handle, 1, nullptr); + return bStatus ? 0 : -1; +} + +int sem_wait(sem_t* sem) +{ + if (sem == nullptr) + return -1; + + DWORD dwStatus = WaitForSingleObject(sem->handle, INFINITE); + return dwStatus == WAIT_OBJECT_0 ? 0 : -1; +} diff --git a/msvc/semaphore.h b/msvc/semaphore.h new file mode 100644 index 00000000..4a446a93 --- /dev/null +++ b/msvc/semaphore.h @@ -0,0 +1,40 @@ +/* + * avrdude - A Downloader/Uploader for AVR device programmers + * Copyright (C) 2018 Marius Greuel + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _SEMAPHORE_H +#define _SEMAPHORE_H + +typedef struct sem +{ + void* handle; +} sem_t; + +#ifdef __cplusplus +extern "C" { +#endif + +int sem_init(sem_t* sem, int pshared, unsigned int value); +int sem_destroy(sem_t* sem); +int sem_post(sem_t* sem); +int sem_wait(sem_t* sem); + +#ifdef __cplusplus +} +#endif + +#endif