├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── CMakeOptions.txt ├── COPYING-CMAKE-SCRIPTS ├── COPYING.GPL ├── COPYING.LIB ├── ChangeLog ├── LICENSE ├── README ├── README.build ├── README.mingw ├── TODO ├── cmake ├── FindConfuse.cmake ├── FindLibUSB1.cmake ├── FindLibintl.cmake ├── LibFTDI1Config.cmake.in ├── LibFTDI1ConfigVersion.cmake.in ├── Toolchain-Crossbuild32.cmake ├── Toolchain-i686-w64-mingw32.cmake ├── Toolchain-mingw32.cmake ├── Toolchain-x86_64-w64-mingw32.cmake └── UseLibFTDI1.cmake ├── doc ├── Doxyfile.in ├── Doxyfile.xml.in ├── EEPROM-structure ├── astyle_reformat.sh └── release-checklist.txt ├── examples ├── CMakeLists.txt ├── async.c ├── baud_test.c ├── bitbang.c ├── bitbang2.c ├── bitbang_cbus.c ├── bitbang_cbus_eeprom_for_windows.ept ├── bitbang_ft2232.c ├── cmake_example │ ├── CMakeLists.txt │ └── main.c ├── eeprom.c ├── find_all.c ├── find_all_pp.cpp ├── serial_test.c ├── simple.c └── stream_test.c ├── ftdi_eeprom ├── CMakeLists.txt ├── example.conf ├── ftdi_eeprom_version.h.in └── main.c ├── ftdipp ├── CMakeLists.txt ├── ftdi.cpp └── ftdi.hpp ├── libftdi-1.0.kdev4 ├── libftdi.lnt ├── libftdi1-config.in ├── libftdi1.pc.in ├── libftdi1.spec.in ├── libftdipp1.pc.in ├── packages ├── 99-libftdi.rules └── CMakeLists.txt ├── python ├── CMakeLists.txt ├── doxy2swig.py ├── examples │ ├── CMakeLists.txt │ ├── cbus.py │ ├── complete.py │ └── simple.py └── ftdi1.i ├── src ├── CMakeLists.txt ├── ftdi.c ├── ftdi.h ├── ftdi_i.h ├── ftdi_stream.c └── ftdi_version_i.h.in └── test ├── CMakeLists.txt ├── basic.cpp └── baudrate.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Normal stuff 2 | *.o 3 | *.a 4 | *.so 5 | *.lo 6 | *.la 7 | *.pc 8 | .deps/ 9 | .libs/ 10 | .kdev4/ 11 | build/ 12 | 13 | # kdevelop 14 | *.kdevelop.pcs 15 | *.kdevses 16 | 17 | # Doxygen documentation 18 | Doxyfile 19 | Doxyfile.xml 20 | doc/Doxyfile 21 | doc/html 22 | doc/man 23 | doc/xml 24 | 25 | # examples 26 | examples/baud_test 27 | examples/bitbang 28 | examples/bitbang2 29 | examples/bitbang_cbus 30 | examples/bitbang_ft2232 31 | examples/find_all 32 | examples/find_all_pp 33 | examples/serial_test 34 | examples/simple 35 | 36 | # Backup files and stuff from patches 37 | *.orig 38 | *.rej 39 | *~ 40 | .*.swp 41 | 42 | # libftdi specific 43 | libftdi1-config 44 | libftdi1.spec 45 | 46 | # CMake 47 | CMakeCache.txt 48 | cmake_install.cmake 49 | CMakeFiles 50 | 51 | # Misc. binaries 52 | *.dylib 53 | opt 54 | 55 | LibFTDI1Config.cmake 56 | LibFTDI1ConfigVersion.cmake 57 | src/ftdi_version_i.h 58 | src/libftdi1.so.* 59 | Makefile 60 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Main developers: 2 | 3 | Intra2net AG 4 | 5 | Contributors in alphabetical order, 6 | see Changelog for full details: 7 | 8 | Adam Malinowski 9 | Alain Abbas 10 | Alexander Lehmann 11 | Alex Harford 12 | Anders Larsen 13 | Andrei Errapart 14 | Andrew John Rogers 15 | Arnim Läuger 16 | Aurelien Jarno 17 | Benjamin Vanheuverzwijn 18 | Chris Morgan 19 | Chris Zeh 20 | Clifford Wolf 21 | Daniel Kirkham 22 | David Challis 23 | Davide Michelizza 24 | Denis Sirotkin 25 | Emil 26 | Eric Schott 27 | Eugene Hutorny 28 | Evan Nemerson 29 | Evgeny Sinelnikov 30 | Fahrzin Hemmati 31 | Flynn Marquardt 32 | Forest Crossman 33 | Ian Abbott 34 | Jared Boone 35 | Jarkko Sonninen 36 | Jean-Daniel Merkli 37 | Jochen Sprickerhof 38 | Joe Zbiciak 39 | Jon Beniston 40 | Juergen Beisert 41 | Lorenz Moesenlechner 42 | Marek Vavruša 43 | Marius Kintel 44 | Mark Hämmerling 45 | Matthias Janke 46 | Matthias Kranz 47 | Matthias Richter 48 | Matthijs ten Berge 49 | Max 50 | Maxwell Dreytser 51 | Michel Zou 52 | Mike Frysinger 53 | Nathael Pajani 54 | Nathan Fraser 55 | Oleg Seiljus 56 | Paul Fertser 57 | Pawel Jewstafjew 58 | Peter Holik 59 | Raphael Assenat 60 | Robby McKilliam 61 | Robert Cox 62 | Robin Haberkorn 63 | Rodney Sinclair 64 | Rogier Wolff 65 | Rolf Fiedler 66 | Salvador Eduardo Tropea 67 | Stephan Linz 68 | Steven Turner 69 | Tarek Heiland 70 | Thilo Schulz 71 | Thimo Eichstaedt 72 | Thomas Fischl 73 | Thomas Klose 74 | Tim Ansell 75 | Tom Saunders 76 | Uwe Bonnes 77 | Vladimir Yakovlev 78 | Wilfried Holzke 79 | Xiaofan Chen 80 | Yegor Yefremov 81 | Yi-Shin Li 82 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project 2 | project(libftdi1) 3 | set(MAJOR_VERSION 1) 4 | set(MINOR_VERSION 4) 5 | set(PACKAGE libftdi1) 6 | set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}) 7 | set(VERSION ${VERSION_STRING}) 8 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 9 | 10 | # CMake 11 | if("${CMAKE_BUILD_TYPE}" STREQUAL "") 12 | set(CMAKE_BUILD_TYPE RelWithDebInfo) 13 | endif("${CMAKE_BUILD_TYPE}" STREQUAL "") 14 | set(CMAKE_COLOR_MAKEFILE ON) 15 | cmake_minimum_required(VERSION 2.6 FATAL_ERROR) 16 | 17 | add_definitions(-Wall) 18 | 19 | include(CMakeOptions.txt) 20 | 21 | # Debug build 22 | message("-- Build type: ${CMAKE_BUILD_TYPE}") 23 | if(${CMAKE_BUILD_TYPE} STREQUAL Debug) 24 | add_definitions(-DDEBUG) 25 | endif(${CMAKE_BUILD_TYPE} STREQUAL Debug) 26 | 27 | # find libusb 28 | 29 | list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 30 | find_package ( LibUSB1 REQUIRED ) 31 | include_directories ( ${LIBUSB1_INCLUDE_DIR} ) 32 | 33 | # Find Boost 34 | if (FTDIPP OR BUILD_TESTS) 35 | find_package( Boost REQUIRED ) 36 | endif() 37 | 38 | # Set components 39 | set(CPACK_COMPONENTS_ALL sharedlibs staticlibs headers) 40 | set(CPACK_COMPONENT_SHAREDLIBS_DISPLAY_NAME "Shared libraries") 41 | set(CPACK_COMPONENT_STATICLIBS_DISPLAY_NAME "Static libraries") 42 | set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers") 43 | 44 | set(CPACK_COMPONENT_SHAREDLIBS_DESCRIPTION 45 | "Shared library for general use.") 46 | set(CPACK_COMPONENT_STATICLIBS_DESCRIPTION 47 | "Static library, good if you want to embed libftdi1 in your application.") 48 | set(CPACK_COMPONENT_HEADERS_DESCRIPTION 49 | "C/C++ header files.") 50 | 51 | set(CPACK_COMPONENT_SHAREDLIBS_GROUP "Development") 52 | set(CPACK_COMPONENT_STATICLIBS_GROUP "Development") 53 | set(CPACK_COMPONENT_HEADERS_GROUP "Development") 54 | 55 | # guess LIB_SUFFIX, don't take debian multiarch into account 56 | if ( NOT DEFINED LIB_SUFFIX ) 57 | if( CMAKE_SYSTEM_NAME MATCHES "Linux" 58 | AND NOT CMAKE_CROSSCOMPILING 59 | AND NOT EXISTS "/etc/debian_version" 60 | AND NOT EXISTS "/etc/arch-release" ) 61 | if ( "${CMAKE_SIZEOF_VOID_P}" EQUAL "8" ) 62 | set ( LIB_SUFFIX 64 ) 63 | endif () 64 | endif () 65 | endif () 66 | 67 | if(NOT APPLE) 68 | if(CMAKE_SIZEOF_VOID_P EQUAL 4) 69 | SET(PACK_ARCH "") 70 | else(CMAKE_SIZEOF_VOID_P EQUAL 8) 71 | SET(PACK_ARCH .x86_64) 72 | endif(CMAKE_SIZEOF_VOID_P EQUAL 4) 73 | else(NOT APPLE) 74 | SET(PACK_ARCH "") 75 | endif(NOT APPLE) 76 | 77 | # Package information 78 | set(CPACK_PACKAGE_VERSION ${VERSION_STRING}) 79 | set(CPACK_PACKAGE_CONTACT "Intra2net AG ") 80 | set(CPACK_PACKAGE_DESCRIPTION "libftdi1 library.") 81 | set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${CPACK_PACKAGE_DESCRIPTION} 82 | ) 83 | # Package settings 84 | if ( UNIX ) 85 | set(CPACK_GENERATOR "DEB;RPM") 86 | set(CPACK_CMAKE_GENERATOR "Unix Makefiles") 87 | set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) 88 | set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}${PACK_ARCH}) 89 | endif () 90 | 91 | if ( WIN32 ) 92 | set ( CPACK_GENERATOR "NSIS" ) 93 | set ( CPACK_CMAKE_GENERATOR "MinGW Makefiles" ) 94 | set ( CPACK_PACKAGE_NAME "${PROJECT_NAME}" ) 95 | set ( CPACK_PACKAGE_VENDOR "" ) 96 | set ( CPACK_PACKAGE_INSTALL_DIRECTORY "libftdi1" ) 97 | set ( CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32") 98 | set ( CPACK_NSIS_DISPLAY_NAME "libftdi1" ) 99 | set ( CPACK_NSIS_MODIFY_PATH ON ) 100 | endif () 101 | 102 | set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) 103 | 104 | set(CPACK_SOURCE_GENERATOR TGZ) 105 | set(CPACK_SOURCE_IGNORE_FILES "\\\\.git;~$;build/") 106 | set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}) 107 | 108 | # Subdirectories 109 | if ( UNIX ) 110 | set ( CPACK_SET_DESTDIR ON ) 111 | endif () 112 | 113 | # "make dist" target 114 | set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${VERSION_STRING}) 115 | add_custom_target(dist 116 | COMMAND git archive --prefix=${ARCHIVE_NAME}/ HEAD 117 | | bzip2 > ${CMAKE_CURRENT_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2 118 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 119 | 120 | if ( DOCUMENTATION ) 121 | find_package ( Doxygen REQUIRED) 122 | 123 | # Copy doxy.config.in 124 | set(top_srcdir ${CMAKE_CURRENT_SOURCE_DIR}) 125 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ) 126 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.xml.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.xml ) 127 | 128 | # Run doxygen 129 | add_custom_command( 130 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html 131 | COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/doc 132 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 133 | DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers} 134 | ) 135 | 136 | add_custom_target(docs ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html) 137 | endif () 138 | 139 | add_subdirectory(src) 140 | if ( FTDIPP ) 141 | add_subdirectory(ftdipp) 142 | endif () 143 | if ( PYTHON_BINDINGS ) 144 | add_subdirectory(python) 145 | endif () 146 | if ( FTDI_EEPROM ) 147 | add_subdirectory(ftdi_eeprom) 148 | endif () 149 | if ( EXAMPLES ) 150 | add_subdirectory(examples) 151 | endif () 152 | add_subdirectory(packages) 153 | if ( BUILD_TESTS ) 154 | add_subdirectory(test) 155 | endif () 156 | 157 | # PkgConfig 158 | set(prefix ${CMAKE_INSTALL_PREFIX}) 159 | set(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin) 160 | set(includedir ${CMAKE_INSTALL_PREFIX}/include/${PROJECT_NAME}) 161 | 162 | if(${UNIX}) 163 | set(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}) 164 | endif(${UNIX}) 165 | if(${WIN32}) 166 | set(libdir ${CMAKE_INSTALL_PREFIX}/bin) 167 | endif(${WIN32}) 168 | 169 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libftdi1.spec.in ${CMAKE_CURRENT_BINARY_DIR}/libftdi1.spec @ONLY) 170 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libftdi1.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libftdi1.pc @ONLY) 171 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libftdipp1.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libftdipp1.pc @ONLY) 172 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libftdi1.pc ${CMAKE_CURRENT_BINARY_DIR}/libftdipp1.pc 173 | DESTINATION lib${LIB_SUFFIX}/pkgconfig) 174 | 175 | if (UNIX OR MINGW) 176 | configure_file ( libftdi1-config.in ${CMAKE_CURRENT_BINARY_DIR}/libftdi1-config @ONLY ) 177 | install ( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libftdi1-config 178 | DESTINATION bin ) 179 | endif () 180 | 181 | # config script install path 182 | if ( NOT DEFINED LIBFTDI_CMAKE_CONFIG_DIR ) 183 | set ( LIBFTDI_CMAKE_CONFIG_DIR lib${LIB_SUFFIX}/cmake/libftdi1 ) 184 | endif () 185 | 186 | set ( LIBFTDI_INCLUDE_DIR ${includedir} ) 187 | set ( LIBFTDI_INCLUDE_DIRS ${LIBFTDI_INCLUDE_DIR} ) 188 | set ( LIBFTDI_LIBRARY ftdi1 ) 189 | set ( LIBFTDI_LIBRARIES ${LIBFTDI_LIBRARY} ) 190 | list ( APPEND LIBFTDI_LIBRARIES ${LIBUSB1_LIBRARIES} ) 191 | set ( LIBFTDI_STATIC_LIBRARY ftdi1.a ) 192 | set ( LIBFTDI_STATIC_LIBRARIES ${LIBFTDI_STATIC_LIBRARY} ) 193 | list ( APPEND LIBFTDI_STATIC_LIBRARIES ${LIBUSB1_LIBRARIES} ) 194 | if ( FTDIPP ) 195 | set ( LIBFTDIPP_LIBRARY ftdipp1 ) 196 | set ( LIBFTDIPP_LIBRARIES ${LIBFTDIPP_LIBRARY} ) 197 | list ( APPEND LIBFTDIPP_LIBRARIES ${LIBUSB1_LIBRARIES} ) 198 | endif () 199 | set ( LIBFTDI_LIBRARY_DIRS ${libdir} ) 200 | set ( LIBFTDI_ROOT_DIR ${prefix} ) 201 | set ( LIBFTDI_VERSION_STRING ${VERSION_STRING} ) 202 | set ( LIBFTDI_VERSION_MAJOR ${MAJOR_VERSION} ) 203 | set ( LIBFTDI_VERSION_MINOR ${MINOR_VERSION} ) 204 | 205 | set ( LIBFTDI_USE_FILE ${CMAKE_INSTALL_PREFIX}/${LIBFTDI_CMAKE_CONFIG_DIR}/UseLibFTDI1.cmake ) 206 | 207 | if(CMAKE_VERSION VERSION_LESS 2.8.8) 208 | configure_file ( cmake/LibFTDI1Config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LibFTDI1Config.cmake @ONLY ) 209 | configure_file ( cmake/LibFTDI1ConfigVersion.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/LibFTDI1ConfigVersion.cmake @ONLY ) 210 | else () 211 | include(CMakePackageConfigHelpers) 212 | 213 | configure_package_config_file ( 214 | ${CMAKE_CURRENT_SOURCE_DIR}/cmake/LibFTDI1Config.cmake.in 215 | ${CMAKE_CURRENT_BINARY_DIR}/LibFTDI1Config.cmake 216 | INSTALL_DESTINATION ${LIBFTDI_CMAKE_CONFIG_DIR} 217 | PATH_VARS 218 | LIBFTDI_USE_FILE 219 | LIBFTDI_ROOT_DIR 220 | LIBFTDI_INCLUDE_DIR 221 | LIBFTDI_INCLUDE_DIRS 222 | LIBFTDI_LIBRARY_DIRS 223 | NO_CHECK_REQUIRED_COMPONENTS_MACRO 224 | ) 225 | write_basic_package_version_file ( 226 | LibFTDI1ConfigVersion.cmake 227 | VERSION ${LIBFTDI_VERSION_STRING} 228 | COMPATIBILITY AnyNewerVersion 229 | ) 230 | endif () 231 | 232 | 233 | install ( FILES 234 | ${CMAKE_CURRENT_BINARY_DIR}/LibFTDI1Config.cmake 235 | ${CMAKE_CURRENT_BINARY_DIR}/LibFTDI1ConfigVersion.cmake 236 | cmake/UseLibFTDI1.cmake 237 | 238 | DESTINATION ${LIBFTDI_CMAKE_CONFIG_DIR} 239 | ) 240 | 241 | include(CPack) 242 | 243 | #message (STATUS "Summary of build options: 244 | # 245 | # Build static libs: ${STATICLIBS} 246 | # Build C++ bindings: ${FTDIPP} 247 | # Build Python bindings: ${PYTHON_BINDINGS} 248 | # Build ftdi_eeprom: ${FTDI_EEPROM} 249 | # Build examples: ${EXAMPLES} 250 | # Build tests: ${BUILD_TESTS} 251 | # Build API documentation: ${DOCUMENTATION} 252 | #") 253 | -------------------------------------------------------------------------------- /CMakeOptions.txt: -------------------------------------------------------------------------------- 1 | option ( STATICLIBS "Build static libraries" ON ) 2 | option ( BUILD_TESTS "Build unit tests with Boost Unit Test framework" OFF ) 3 | option ( DOCUMENTATION "Generate API documentation with Doxygen" OFF ) 4 | option ( EXAMPLES "Build example programs" OFF ) 5 | option ( FTDIPP "Build C++ binding library libftdi1++" OFF ) 6 | option ( FTDI_EEPROM "Build ftdi_eeprom" OFF ) 7 | option ( PYTHON_BINDINGS "Build python bindings via swig" OFF ) 8 | option ( LINK_PYTHON_LIBRARY "Link against python libraries" OFF ) 9 | -------------------------------------------------------------------------------- /COPYING-CMAKE-SCRIPTS: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions 3 | are met: 4 | 5 | 1. Redistributions of source code must retain the copyright 6 | notice, this list of conditions and the following disclaimer. 7 | 2. Redistributions in binary form must reproduce the copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | 3. The name of the author may not be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 14 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | New in 1.x - 2018-xx-xx 2 | ----------------------- 3 | * Added ftdi_setflowctrl_xonxoff() 4 | 5 | New in 1.4 - 2017-08-07 6 | ----------------------- 7 | * New ftdi_usb_open_bus_addr() open function 8 | * Use BM/R series baud rate computation for FT230X 9 | * ftdi_get_error_string() now returns const char* 10 | * C++ API: Ability to open devices with empty descriptor strings 11 | * C++ API: Fix enumerations for buffer purge and modem controls 12 | * small build fixes and improvements in the python examples 13 | * ftdi_eeprom / eeprom handling: 14 | * New API function: ftdi_eeprom_get_strings() 15 | * Fix USE_SERIAL handling for 230X type chips 16 | * Make ftdi_read_eeprom_location() endianness independent 17 | * Fix flashing of FT245R 18 | 19 | New in 1.3 - 2016-05-20 20 | ----------------------- 21 | * Added ftdi_usb_get_strings2() to prevent automatic device close (Fahrzin Hemmati) 22 | * Added ftdi_transfer_data_cancel() for cancellation of a submitted transfer, 23 | avoided resubmittion of a canceled transfer in the callbacks, 24 | replaced calls to libusb_handle_events with 25 | libusb_handle_events_timeout_completed (Eugene Hutorny) 26 | * ftdi_eeprom / eeprom handling: 27 | * Add support for arbitrary user data (Salvador Eduardo Tropea) 28 | * Add --build-eeprom support (Salvador Eduardo Tropea) 29 | * Fix use_usb_version config file option (Thilo Schulz) 30 | * Ability to include other config files in EEPROM config file (Thilo Schulz) 31 | * Add external oscillator enable bit (Raphael Assenat) 32 | * Support channel configuration (Stephan Linz) 33 | * Added --device option to ftdi_eeprom to specify FTDI device (Robin Haberkorn) 34 | * Fixed EEPROM user-area space checks for FT232R and FT245R chips (Robin Haberkorn) 35 | * Various improvements to CBUS handling, including the EEPROM (Robin Haberkorn) 36 | * swig wrapper: Fix handling of binary strings in ftdi_write_data() 37 | for python 3 (xantares09) 38 | * cbus python example code (Rodney Sinclair) 39 | * ftdi_stream: fix timeout setting (Ларионов Даниил) 40 | * Fixed typo in CBUS defines: CBUSG_DRIVE1 -> CBUSH_DRIVE1 41 | 42 | New in 1.2 - 2014-11-21 43 | ----------------------- 44 | * Support for FT230X devices (Uwe Bonnes) 45 | * ftdi_usb_get_strings(): Don't try to open an already open device (Denis Sirotkin) 46 | * Support for finding devices bricked by the Windows driver (Forest Crossman) 47 | * cmake build system: New LibFTDI1ConfigVersion.cmake file (xantares09) 48 | * Fix a typo in the MPSSE command CLK_BYTES_OR_LOW (Benjamin Vanheuverzwijn) 49 | * Minor fixes for MSVC++ (Andrei Errapart) 50 | * Various small code improvements (Florian Preinstorfer, Jochen Sprickerhof, xantares09) 51 | 52 | New in 1.1 - 2014-02-05 53 | ----------------------- 54 | * Fix FT232H eeprom suspend pulldown setting (Davide Michelizza) 55 | * Fix FT232H eeprom user area size (Davide Michelizza) 56 | * Improved mingw build (Paul Fertser and Michel Zou) 57 | * C++ wrapper: Get/set functions for USB timeouts (Jochen Sprickerhof) 58 | * Partial support for FT230X (Nathael Pajani) 59 | * New API function: ftdi_eeprom_set_strings() (Nathael Pajani) 60 | * Prevent possible segfault in ftdi_eeprom_decode() (Nathael Pajani) 61 | * Save device release number in eeprom (Jarkko Sonninen) 62 | * Fix "self powered" eeprom flag (Jarkko Sonninen) 63 | * Improved python wrapper (Michel Zou) 64 | * Many buildsystem improvements (Michel Zou and Mike Frysinger) 65 | * See the git history for more changes and fixes 66 | 67 | New in 1.0 - 2013-01-29 68 | ----------------------- 69 | * Ported to libusb 1.x (initial work by Jie Zhang) 70 | * Many eeprom handling improvements (Uwe Bonnes, Anders Larsen) 71 | * Renamed pkconfig, library .so etc. files to "libftdi1" (Intra2net) 72 | * ftdi_eeprom is part of libftdi now (Intra2net) 73 | 74 | * New baudrate calculation code + unit tests (Uwe Bonnes and Intra2net) 75 | * Improved python bindings including python3 support (Michel Zou) 76 | * Switched completely to cmake build system (Intra2net) 77 | * cmake: Easy libftdi discovery via find_package() (Michel Zou) 78 | * eeprom handling now done via get()/set() functions (Uwe Bonnes) 79 | * C++ wrapper: Fixed use-after-free in List::find_all() (Intra2net) 80 | * Documentation updates (Xiaofan Chen) 81 | * See the git history for more changes and fixes 82 | 83 | New in 0.20 - 2012-03-19 84 | ------------------------ 85 | * Support for FT232H (Uwe Bonnes) 86 | * Fixed install location of header files (Uwe Bonnes and Intra2net) 87 | * Backported serial_test tool from libftdi 1.x (Uwe Bonnes) 88 | 89 | New in 0.19 - 2011-05-23 90 | ------------------------ 91 | * Make kernel driver detach configurable (Thomas Klose) 92 | * Correct ftdi_poll_modem_status() result code (Tom Saunders) 93 | * cmake build system improvements (Evgeny Sinelnikov) 94 | * Fix uninitialized memory access in async mode (Intra2net) 95 | * Support for FT232R eeprom features (Hermann Kraus) 96 | * Fix size returned by ftdi_read_data (Hermann Kraus) 97 | * C++ wrapper: Fix infinite recursion in set_bitmode (Intra2net) 98 | * Improvements to the python wrapper (Flynn Marquardt and Chris Zeh) 99 | 100 | New in 0.18 - 2010-06-25 101 | ------------------------ 102 | * Add ftdi_eeprom_free() to free allocated memory in eeprom (Wilfried Holzke) 103 | * More generic error message for the FTDI kernel driver (Intra2net) 104 | * Honor CPPFLAGS in python wrapper build (Alexander Lehmann) 105 | * cmake: Fix package creation on 32-bit machines (Uwe Bonnes) 106 | * Fix swig argument constraints (Intra2net) 107 | * Don't segfault if device is closed or ftdi context is invalid (Intra2net) 108 | * Ability to disable build of examples / documentation (Mike Frysinger and Intra2net) 109 | * Fix typo in python wrapper build (Mike Frysinger) 110 | * Autoconf build system improvements (Mike Frysinger) 111 | 112 | New in 0.17 - 2009-12-19 113 | ------------------------ 114 | * C++ wrapper: Reduced code duplication and small other changes (Intra2net) 115 | * Deprecated old ftdi_enable_bitbang() function (Intra2net) 116 | * New ftdi_usb_open_desc_index() function (Intra2net) 117 | * Added baud rate test example code (Intra2net) 118 | * New serial input example code (Jim Paris) 119 | * Fix modem status byte filtering for USB high speed chips (Intra2net and Jim Paris) 120 | * Add bitmode for synchronous fifo in FT2232H (Uwe Bonnes) 121 | * Fix usb_set_configuration() call on Windows 64 (NIL) 122 | * Fix usb index in ftdi_convert_baudrate() for FT2232H/FT4232H chips (Thimo Eichstaedt) 123 | * Set initial baudrate on correct interface instead of always the first one (Thimo Eichstaedt) 124 | * Call usb_set_configuration() on Windows only (Uwe Bonnes) 125 | * 64 bit and other buildsystem fixes (Uwe Bonnes) 126 | * Don't build --with-async-mode w/ libusb-compat-0.1 (Clifford Wolf) 127 | * Functions for read/write of a single eeprom location (Oleg Seiljus) 128 | * Protect against double close of usb device (Nathan Fraser) 129 | * Fix out-of-tree-build in python wrapper (Aurelien Jarno) 130 | * Autoconf and doxygen cleanup (Jim Paris) 131 | 132 | New in 0.16 - 2009-05-08 133 | ------------------------ 134 | * C++ wrapper: Reopen the device after calling get_strings() in Context::open() (Marek Vavruša and Intra2net) 135 | * C++ wrapper: Fixed an inheritance problem (Marek Vavruša and Intra2net) 136 | * C++ wrapper: Relicensed under GPLv2 + linking exception (Marek Vavruša and Intra2net) 137 | * Support for FT2232H and FT4232H (David Challis, Alex Harford and Intra2net) 138 | * Support for mingw cross compile (Uwe Bonnes) 139 | * Python bindings and minor autoconf cleanup (Tarek Heiland) 140 | * Code cleanup in various places (Intra2net) 141 | * Fixed ftdi_read_chipid in some cases (Matthias Richter) 142 | * eeprom decode function and small cleanups (Marius Kintel) 143 | * cmake system improvements (Marius Kintel and Intra2net) 144 | * Fix compilation in -ansi -pedantic mode (Matthias Janke) 145 | 146 | New in 0.15 - 2008-12-19 147 | ------------------------ 148 | * Full C++ wrapper. Needs boost (Marek Vavruša and Intra2net) 149 | * cmake rules (Marek Vavruša) 150 | 151 | New in 0.14 - 2008-09-09 152 | ------------------------ 153 | * Fixed flow control code for second FT2232 interface (Marek Vavruša) 154 | * Ability to set flow control via one USB call (Marek Vavruša) 155 | * 64 bit build support in the RPM spec file (Uwe Bonnes) 156 | * Small fix to the RPM spec file (Uwe Bonnes) 157 | * Ability to set RS232 break type (Intra2net) 158 | * Grouped flow control and modem status code together (Intra2net) 159 | 160 | New in 0.13 - 2008-06-13 161 | ------------------------ 162 | * Build .spec file via configure.in (Intra2net) 163 | * Fixed "libusb-config --cflags" call (Mike Frysinger and Intra2net) 164 | * Always set usb configuration (Mike Frysinger and Intra2net) 165 | * Improved libusb-win32 support (Mike Frysinger) 166 | 167 | New in 0.12 - 2008-04-16 168 | ------------------------ 169 | * Fix build of documentation for "out of tree" builds 170 | * Fix USB config descriptor in the eeprom (Juergen Beisert) 171 | * Ability to purge RX/TX buffers separately (Arnim Läuger) 172 | * Setting of event and error character (Arnim Läuger) 173 | * Poll modem status function (Arnim Läuger and Intra2net) 174 | * Updated documentation and created AUTHORS file 175 | 176 | New in 0.11 - 2008-03-01 177 | ------------------------ 178 | * Vala bindings helper functions (ftdi_new, ftdi_free, ftdi_list_free2) (Even Nermerson) 179 | * Support for different EEPROM sizes (Andrew John Rogers, andrew@rogerstech.co.uk) 180 | * Async write support. Linux only and no error handling. 181 | You have to enable it via --with-async-mode. 182 | * Detection of R-type chips 183 | * FTDIChip-ID read support (Peter Holik) 184 | 185 | New in 0.10 - 2007-05-08 186 | ------------------------ 187 | * Examples for libftdi_usb_find_all and CBUS mode 188 | * Fixed ftdi_list_free 189 | * Small cosmetic changes 190 | 191 | New in 0.9 - 2007-02-09 192 | ----------------------- 193 | * Fixed build without doxygen 194 | * Correct .so file library version 195 | 196 | New in 0.8 - 2007-02-08 197 | ----------------------- 198 | * Complete doxygen documentation and examples 199 | * Extended FT2232C bitbang mode example code (Max) 200 | * ftdi_usb_get_strings function to get device ID strings (Matthijs ten Berge) 201 | * Fix ftdi_read_pins on PowerPC systems (Thomas Fischl) 202 | * Automatically detach ftdi_sio kernel driver (Uwe Bonnes and Intra2net) 203 | * Configurable flow control (Lorenz Moesenlechner and Matthias Kranz) 204 | 205 | New in 0.7 - 2005-10-11 206 | ----------------------- 207 | * Baudrate calculation fix for FT2232C (Steven Turner/FTDI) 208 | * Find all devices by vendor/product id (Tim Ansell and Intra2net) 209 | * Documentation updates (Tim Ansell) 210 | 211 | New in 0.6 - 2005-04-24 212 | ----------------------- 213 | * Set library version on .so file again 214 | * Configurable serial line parameters (Alain Abbas) 215 | * Improved filtering of status bytes (Evgeny Sinelnikov) 216 | * Extended FT2232C support (Uwe Bonnes) 217 | * Small improvement to the baudrate calculation code (Emil) 218 | * Error handling cleanup (Rogier Wolff and Intra2net) 219 | 220 | New in 0.5 - 2004-09-24 221 | ----------------------- 222 | * New autoconf suite 223 | * pkgconfig support 224 | * Status byte filtering now works for "big" readbuffer sizes (Thanks Evgeny!) 225 | * Open device by description and/or serial (Evgeny Sinelnikov) 226 | * Improved error handling (Evgeny Sinelnikov) 227 | 228 | New in 0.4 - 2004-06-15 229 | ----------------------- 230 | * Fixed filtering of status bytes (Readbuffer size is now 64 bytes) 231 | * FT2232C support (Steven Turner/FTDI) 232 | * New baudrate calculation code (Ian Abbott) 233 | * Automatic detection of chip type 234 | * Important: ftdi_write_data now returns the bytes written 235 | * Fixed defaults values in ftdi_eeprom_initdefaults (Jean-Daniel Merkli) 236 | * Reset internal readbuffer offsets for reset()/purge_buffers() 237 | * Small typo fixes (Mark Haemmerling) 238 | 239 | New in 0.3 - 2004-03-25 240 | ----------------------- 241 | * Improved read function which takes arbitrary input buffer sizes 242 | Attention: Call ftdi_deinit() on exit to free used memory 243 | * Vastly increased read/write performance (configurable chunksize, default is 4096) 244 | * Set/get latency timer function working (Thanks Steven Turner/FTDI) 245 | * Increased library version because the changes require recompilation 246 | 247 | New in 0.2 - 2004-01-03 248 | ----------------------- 249 | * EEPROM build fix by Daniel Kirkham (Melbourne, Australia) 250 | * Implemented basic ftdi_read_data() function 251 | * EEPROM write fixes 252 | 253 | New in 0.1 - 2003-06-10 254 | ----------------------- 255 | * First public release 256 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The C library "libftdi1" is distributed under the 2 | GNU Library General Public License version 2. 3 | 4 | A copy of the GNU Library General Public License (LGPL) is included 5 | in this distribution, in the file COPYING.LIB. 6 | 7 | ---------------------------------------------------------------------- 8 | 9 | The C++ wrapper "ftdipp1" is distributed under the GNU General 10 | Public License version 2 (with a special exception described below). 11 | 12 | A copy of the GNU General Public License (GPL) is included 13 | in this distribution, in the file COPYING.GPL. 14 | 15 | As a special exception, if other files instantiate templates or use macros 16 | or inline functions from this file, or you compile this file and link it 17 | with other works to produce a work based on this file, this file 18 | does not by itself cause the resulting work to be covered 19 | by the GNU General Public License. 20 | 21 | However the source code for this file must still be made available 22 | in accordance with section (3) of the GNU General Public License. 23 | 24 | This exception does not invalidate any other reasons why a work based 25 | on this file might be covered by the GNU General Public License. 26 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | libftdi version 1.4 3 | -------------------------------------------------------------------- 4 | 5 | libftdi - A library (using libusb) to talk to FTDI's UART/FIFO chips 6 | including the popular bitbang mode. 7 | 8 | The following chips are supported: 9 | * FT230X 10 | - FT4232H / FT2232H 11 | - FT232R / FT245R 12 | - FT2232L / FT2232D / FT2232C 13 | - FT232BM / FT245BM (and the BL/BQ variants) 14 | - FT8U232AM / FT8U245AM 15 | 16 | libftdi requires libusb 1.x. 17 | 18 | The AUTHORS file contains a list of all the people 19 | that made libftdi possible what it is today. 20 | 21 | Changes 22 | ------- 23 | * New ftdi_usb_open_bus_addr() open function 24 | * Use BM/R series baud rate computation for FT230X 25 | * ftdi_get_error_string() now returns const char* 26 | * C++ API: Ability to open devices with empty descriptor strings 27 | * C++ API: Fix enumerations for buffer purge and modem controls 28 | * small build fixes and improvements in the python examples 29 | * ftdi_eeprom / eeprom handling: 30 | * New API function: ftdi_eeprom_get_strings() 31 | * Fix USE_SERIAL handling for 230X type chips 32 | * Make ftdi_read_eeprom_location() endianness independent 33 | * Fix flashing of FT245R 34 | 35 | You'll find the newest version of libftdi at: 36 | https://www.intra2net.com/en/developer/libftdi 37 | 38 | 39 | Quick start 40 | ----------- 41 | mkdir build 42 | cd build 43 | 44 | cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ 45 | make 46 | make install 47 | 48 | More verbose build instructions are in "README.build" 49 | 50 | -------------------------------------------------------------------- 51 | www.intra2net.com 2003-2017 Intra2net AG 52 | -------------------------------------------------------------------- 53 | -------------------------------------------------------------------------------- /README.build: -------------------------------------------------------------------------------- 1 | Here is a short tutorial on how to build libftdi git under 2 | Ubuntu 12.10, But it is similar on other Linux distros. 3 | 4 | 1) Install the build tools 5 | sudo apt-get install build-essential (yum install make automake gcc gcc-c++ kernel-devel) 6 | sudo apt-get install git-core (yum install git) 7 | sudo apt-get install cmake (yum install cmake) 8 | sudo apt-get install doxygen (for building documentations) (yum install doxygen) 9 | 10 | 2) Install dependencies 11 | sudo apt-get install libusb-1.0-devel (yum install libusb-devel) 12 | (if the system comes with older version like 1.0.8 or 13 | earlier, it is recommended you build libusbx-1.0.14 or later). 14 | 15 | sudo apt-get install libconfuse-dev (for ftdi-eeprom) (yum install libconfuse-devel) 16 | sudo apt-get install swig python-dev (for python bindings) (yum install swig python-devel) 17 | sudo apt-get install libboost-all-dev (for C++ binding and unit test) (yum install boost-devel) 18 | 19 | 3) Clone the git repository 20 | mkdir libftdi 21 | cd libftdi 22 | git clone git://developer.intra2net.com/libftdi 23 | 24 | If you are building the release tar ball, just extract the source 25 | tar ball. 26 | 27 | 4) Build the git source and install 28 | cd libftdi 29 | mkdir build 30 | cd build 31 | cmake -DCMAKE_INSTALL_PREFIX="/usr" ../ 32 | make 33 | sudo make install 34 | 35 | 5) carry out some tests 36 | cd examples 37 | 38 | mcuee@Ubuntu1210VM:~/Desktop/build/libftdi/libftdi/build/examples$ 39 | ./find_all_pp -v 0x0403 -p 0x6001 40 | Found devices ( VID: 0x403, PID: 0x6001 ) 41 | ------------------------------------------------ 42 | FTDI (0x8730800): ftdi, usb serial converter, ftDEH51S (Open OK) 43 | FTDI (0x8730918): FTDI, FT232R USB UART, A8007Ub5 (Open OK) 44 | 45 | mcuee@Ubuntu1210VM:~/Desktop/build/libftdi/libftdi/build/examples$ ./eeprom 46 | 2 FTDI devices found: Only Readout on EEPROM done. Use 47 | VID/PID/desc/serial to select device 48 | Decoded values of device 1: 49 | Chip type 1 ftdi_eeprom_size: 128 50 | 0x000: 00 00 03 04 01 60 00 04 a0 16 08 00 10 01 94 0a .....`.. ........ 51 | 0x010: 9e 2a c8 12 0a 03 66 00 74 00 64 00 69 00 2a 03 .*....f. t.d.i.*. 52 | 0x020: 75 00 73 00 62 00 20 00 73 00 65 00 72 00 69 00 u.s.b. . s.e.r.i. 53 | 0x030: 61 00 6c 00 20 00 63 00 6f 00 6e 00 76 00 65 00 a.l. .c. o.n.v.e. 54 | 0x040: 72 00 74 00 65 00 72 00 12 03 66 00 74 00 44 00 r.t.e.r. ..f.t.D. 55 | 0x050: 45 00 48 00 35 00 31 00 53 00 02 03 00 00 00 00 E.H.5.1. S....... 56 | 0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 57 | 0x070: 00 00 00 00 00 00 00 00 00 00 00 00 01 00 16 02 ........ ........ 58 | VID: 0x0403 59 | PID: 0x6001 60 | Release: 0x0400 61 | Bus Powered: 44 mA USB Remote Wake Up 62 | Manufacturer: ftdi 63 | Product: usb serial converter 64 | Serial: ftDEH51S 65 | Checksum : 0216 66 | Enable Remote Wake Up 67 | PNP: 1 68 | Decoded values of device 2: 69 | Chip type 3 ftdi_eeprom_size: 128 70 | 0x000: 00 40 03 04 01 60 00 00 a0 2d 08 00 00 00 98 0a .@...`.. .-...... 71 | 0x010: a2 20 c2 12 23 10 05 00 0a 03 46 00 54 00 44 00 . ..#... ..F.T.D. 72 | 0x020: 49 00 20 03 46 00 54 00 32 00 33 00 32 00 52 00 I. .F.T. 2.3.2.R. 73 | 0x030: 20 00 55 00 53 00 42 00 20 00 55 00 41 00 52 00 .U.S.B. .U.A.R. 74 | 0x040: 54 00 12 03 41 00 38 00 30 00 30 00 37 00 55 00 T...A.8. 0.0.7.U. 75 | 0x050: 62 00 35 00 c9 bf 1c 80 00 00 00 00 00 00 00 00 b.5..... ........ 76 | 0x060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ........ 77 | 0x070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 23 ........ .......# 78 | 0x080: 2c 04 d3 fb 00 00 c9 bf 1c 80 42 00 00 00 00 00 ,....... ..B..... 79 | 0x090: 00 00 00 00 00 00 00 00 38 41 32 52 4a 33 47 4f ........ 8A2RJ3GO 80 | VID: 0x0403 81 | PID: 0x6001 82 | Release: 0x0000 83 | Bus Powered: 90 mA USB Remote Wake Up 84 | Manufacturer: FTDI 85 | Product: FT232R USB UART 86 | Serial: A8007Ub5 87 | Checksum : 230f 88 | Internal EEPROM 89 | Enable Remote Wake Up 90 | PNP: 1 91 | Channel A has Mode UART VCP 92 | C0 Function: TXLED 93 | C1 Function: RXLED 94 | C2 Function: TXDEN 95 | C3 Function: PWREN 96 | C4 Function: SLEEP 97 | -------------------------------------------------------------------------------- /README.mingw: -------------------------------------------------------------------------------- 1 | * How to cross compile libftdi-1.x for Windows? * 2 | 1 - Prepare a pkg-config wrapper according to 3 | https://www.flameeyes.eu/autotools-mythbuster/pkgconfig/cross-compiling.html , 4 | additionally export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS and 5 | PKG_CONFIG_ALLOW_SYSTEM_LIBS. 6 | 2 - Write a CMake toolchain file according to 7 | http://www.vtk.org/Wiki/CmakeMingw . Change the path to your future sysroot. 8 | 3 - Get libusb sources (either by cloning the git repo or by downloading a 9 | tarball). Unpack, autogen.sh (when building from git), and configure like this: 10 | ./configure --build=`./config.guess` --host=i686-w64-mingw32 \ 11 | --prefix=/usr --with-sysroot=$HOME/i686-w64-mingw32-root/ 12 | 4 - run 13 | make install DESTDIR=$HOME/i686-w64-mingw32-root/ 14 | 5 - go to libftdi-1.x source directory and run 15 | cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-mingw.cmake \ 16 | -DCMAKE_INSTALL_PREFIX="/usr" \ 17 | -DPKG_CONFIG_EXECUTABLE=`which i686-w64-mingw32-pkg-config` 18 | 6 - run 19 | make install DESTDIR=$HOME/i686-w64-mingw32-root/ 20 | 21 | * How to run libftdi 1.x under Windows * 22 | 23 | On 26-Jan-2014, libusbx and libusb project were merged with the release 24 | of libusb-1.0.18 and now the project is called libusb. 25 | 26 | libusb Windows backend will need to rely on a proper driver to run. 27 | Please refer to the following wiki page for proper driver installation. 28 | https://github.com/libusb/libusb/wiki/Windows#wiki-How_to_use_libusb_on_Windows 29 | 30 | As of 26-Jan-2014, libusb Windows backend supports WinUSB, 31 | libusb0.sys and libusbk.sys driver. However, libusb's support of 32 | libusb0.sys and libusbk.sys is considered to be less mature than 33 | WinUSB. Therefore, WinUSB driver installation using Zadig 34 | is recommended. 35 | 36 | Take note once you replace the original FTDI driver with WinUSB driver, 37 | you can no longer use the functionality the original FTDI driver provides 38 | (eg. Virtual Serial Port or D2XX). 39 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | *** TODO for 1.0 release *** 2 | Documentation: 3 | - Document the new EEPROM function 4 | -------------------------------------------------------------------------------- /cmake/FindConfuse.cmake: -------------------------------------------------------------------------------- 1 | # libConfuse is a configuration file parser library 2 | # available at http://www.nongnu.org/confuse/ 3 | # 4 | # The module defines the following variables: 5 | # CONFUSE_FOUND - the system has Confuse 6 | # CONFUSE_INCLUDE_DIR - where to find confuse.h 7 | # CONFUSE_INCLUDE_DIRS - confuse includes 8 | # CONFUSE_LIBRARY - where to find the Confuse library 9 | # CONFUSE_LIBRARIES - aditional libraries 10 | # CONFUSE_ROOT_DIR - root dir (ex. /usr/local) 11 | 12 | #============================================================================= 13 | # Copyright 2010-2013, Julien Schueller 14 | # All rights reserved. 15 | # 16 | # Redistribution and use in source and binary forms, with or without 17 | # modification, are permitted provided that the following conditions are met: 18 | # 19 | # 1. Redistributions of source code must retain the above copyright notice, this 20 | # list of conditions and the following disclaimer. 21 | # 2. Redistributions in binary form must reproduce the above copyright notice, 22 | # this list of conditions and the following disclaimer in the documentation 23 | # and/or other materials provided with the distribution. 24 | # 25 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 26 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 27 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 29 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 32 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | # The views and conclusions contained in the software and documentation are those 37 | # of the authors and should not be interpreted as representing official policies, 38 | # either expressed or implied, of the FreeBSD Project. 39 | #============================================================================= 40 | 41 | 42 | find_path ( CONFUSE_INCLUDE_DIR 43 | NAMES confuse.h 44 | ) 45 | 46 | set ( CONFUSE_INCLUDE_DIRS ${CONFUSE_INCLUDE_DIR} ) 47 | 48 | find_library ( CONFUSE_LIBRARY 49 | NAMES confuse 50 | ) 51 | 52 | set ( CONFUSE_LIBRARIES ${CONFUSE_LIBRARY} ) 53 | 54 | 55 | # try to guess root dir from include dir 56 | if ( CONFUSE_INCLUDE_DIR ) 57 | string ( REGEX REPLACE "(.*)/include.*" "\\1" CONFUSE_ROOT_DIR ${CONFUSE_INCLUDE_DIR} ) 58 | # try to guess root dir from library dir 59 | elseif ( CONFUSE_LIBRARY ) 60 | string ( REGEX REPLACE "(.*)/lib[/|32|64].*" "\\1" CONFUSE_ROOT_DIR ${CONFUSE_LIBRARY} ) 61 | endif () 62 | 63 | 64 | # handle the QUIETLY and REQUIRED arguments 65 | include ( FindPackageHandleStandardArgs ) 66 | find_package_handle_standard_args( Confuse DEFAULT_MSG CONFUSE_LIBRARY CONFUSE_INCLUDE_DIR ) 67 | 68 | mark_as_advanced ( 69 | CONFUSE_LIBRARY 70 | CONFUSE_LIBRARIES 71 | CONFUSE_INCLUDE_DIR 72 | CONFUSE_INCLUDE_DIRS 73 | CONFUSE_ROOT_DIR 74 | ) 75 | -------------------------------------------------------------------------------- /cmake/FindLibUSB1.cmake: -------------------------------------------------------------------------------- 1 | # - Try to find the libusb library (v1.0+) 2 | # 3 | # LIBUSB1_FOUND - system has libusb 4 | # LIBUSB1_INCLUDE_DIR - the libusb include directory 5 | # LIBUSB1_LIBRARIES - Link these to use libusb 6 | 7 | # Copyright (c) 2006, 2008 Laurent Montel, 8 | # 9 | # Redistribution and use is allowed according to the terms of the BSD license. 10 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 11 | 12 | 13 | if (LIBUSB1_INCLUDE_DIR AND LIBUSB1_LIBRARIES) 14 | 15 | # in cache already 16 | set(LIBUSB1_FOUND TRUE) 17 | 18 | else (LIBUSB1_INCLUDE_DIR AND LIBUSB1_LIBRARIES) 19 | # use pkg-config to get the directories and then use these values 20 | # in the FIND_PATH() and FIND_LIBRARY() calls 21 | find_package(PkgConfig) 22 | pkg_check_modules(PC_LIBUSB1 libusb-1.0) 23 | 24 | FIND_PATH(LIBUSB1_INCLUDE_DIR libusb.h 25 | PATH_SUFFIXES libusb-1.0 26 | PATHS ${PC_LIBUSB1_INCLUDEDIR} ${PC_LIBUSB1_INCLUDE_DIRS}) 27 | 28 | FIND_LIBRARY(LIBUSB1_LIBRARIES NAMES usb-1.0 29 | PATHS ${PC_LIBUSB1_LIBDIR} ${PC_LIBUSB1_LIBRARY_DIRS}) 30 | 31 | include(FindPackageHandleStandardArgs) 32 | FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB1 DEFAULT_MSG LIBUSB1_LIBRARIES LIBUSB1_INCLUDE_DIR) 33 | 34 | MARK_AS_ADVANCED(LIBUSB1_INCLUDE_DIR LIBUSB1_LIBRARIES) 35 | 36 | endif (LIBUSB1_INCLUDE_DIR AND LIBUSB1_LIBRARIES) 37 | -------------------------------------------------------------------------------- /cmake/FindLibintl.cmake: -------------------------------------------------------------------------------- 1 | # Try to find Libintl functionality 2 | # Once done this will define 3 | # 4 | # LIBINTL_FOUND - system has Libintl 5 | # LIBINTL_INCLUDE_DIR - Libintl include directory 6 | # LIBINTL_LIBRARIES - Libraries needed to use Libintl 7 | # 8 | # TODO: This will enable translations only if Gettext functionality is 9 | # present in libc. Must have more robust system for release, where Gettext 10 | # functionality can also reside in standalone Gettext library, or the one 11 | # embedded within kdelibs (cf. gettext.m4 from Gettext source). 12 | 13 | # Copyright (c) 2006, Chusslove Illich, 14 | # Copyright (c) 2007, Alexander Neundorf, 15 | # 16 | # Redistribution and use is allowed according to the terms of the BSD license. 17 | # For details see the accompanying COPYING-CMAKE-SCRIPTS file. 18 | 19 | if(LIBINTL_INCLUDE_DIR AND LIBINTL_LIB_FOUND) 20 | set(Libintl_FIND_QUIETLY TRUE) 21 | endif(LIBINTL_INCLUDE_DIR AND LIBINTL_LIB_FOUND) 22 | 23 | find_path(LIBINTL_INCLUDE_DIR libintl.h) 24 | 25 | set(LIBINTL_LIB_FOUND FALSE) 26 | 27 | if(LIBINTL_INCLUDE_DIR) 28 | include(CheckFunctionExists) 29 | check_function_exists(dgettext LIBINTL_LIBC_HAS_DGETTEXT) 30 | 31 | if (LIBINTL_LIBC_HAS_DGETTEXT) 32 | set(LIBINTL_LIBRARIES) 33 | set(LIBINTL_LIB_FOUND TRUE) 34 | else (LIBINTL_LIBC_HAS_DGETTEXT) 35 | find_library(LIBINTL_LIBRARIES NAMES intl libintl ) 36 | if(LIBINTL_LIBRARIES) 37 | set(LIBINTL_LIB_FOUND TRUE) 38 | endif(LIBINTL_LIBRARIES) 39 | endif (LIBINTL_LIBC_HAS_DGETTEXT) 40 | 41 | endif(LIBINTL_INCLUDE_DIR) 42 | 43 | include(FindPackageHandleStandardArgs) 44 | find_package_handle_standard_args(Libintl DEFAULT_MSG LIBINTL_INCLUDE_DIR LIBINTL_LIB_FOUND) 45 | 46 | mark_as_advanced(LIBINTL_INCLUDE_DIR LIBINTL_LIBRARIES LIBINTL_LIBC_HAS_DGETTEXT LIBINTL_LIB_FOUND) 47 | 48 | -------------------------------------------------------------------------------- /cmake/LibFTDI1Config.cmake.in: -------------------------------------------------------------------------------- 1 | # -*- cmake -*- 2 | # 3 | # LibFTDI1Config.cmake(.in) 4 | # 5 | # Copyright (C) 2013 Intra2net AG and the libftdi developers 6 | # 7 | # This file is part of LibFTDI. 8 | # 9 | # LibFTDI is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU Lesser General Public License 11 | # version 2.1 as published by the Free Software Foundation; 12 | # 13 | 14 | # Use the following variables to compile and link against LibFTDI: 15 | # LIBFTDI_FOUND - True if LibFTDI was found on your system 16 | # LIBFTDI_USE_FILE - The file making LibFTDI usable 17 | # LIBFTDI_DEFINITIONS - Definitions needed to build with LibFTDI 18 | # LIBFTDI_INCLUDE_DIRS - Directory where ftdi.h can be found 19 | # LIBFTDI_INCLUDE_DIRS - List of directories of LibFTDI and it's dependencies 20 | # LIBFTDI_LIBRARY - LibFTDI library location 21 | # LIBFTDI_LIBRARIES - List of libraries to link against LibFTDI library 22 | # LIBFTDIPP_LIBRARY - LibFTDI C++ wrapper library location 23 | # LIBFTDIPP_LIBRARIES - List of libraries to link against LibFTDI C++ wrapper 24 | # LIBFTDI_LIBRARY_DIRS - List of directories containing LibFTDI' libraries 25 | # LIBFTDI_ROOT_DIR - The base directory of LibFTDI 26 | # LIBFTDI_VERSION_STRING - A human-readable string containing the version 27 | # LIBFTDI_VERSION_MAJOR - The major version of LibFTDI 28 | # LIBFTDI_VERSION_MINOR - The minor version of LibFTDI 29 | # LIBFTDI_VERSION_PATCH - The patch version of LibFTDI 30 | # LIBFTDI_PYTHON_MODULE_PATH - Path to the python module 31 | 32 | set ( LIBFTDI_FOUND 1 ) 33 | set ( LIBFTDI_USE_FILE "@LIBFTDI_USE_FILE@" ) 34 | 35 | set ( LIBFTDI_DEFINITIONS "@LIBFTDI_DEFINITIONS@" ) 36 | set ( LIBFTDI_INCLUDE_DIR "@LIBFTDI_INCLUDE_DIR@" ) 37 | set ( LIBFTDI_INCLUDE_DIRS "@LIBFTDI_INCLUDE_DIRS@" ) 38 | set ( LIBFTDI_LIBRARY "@LIBFTDI_LIBRARY@" ) 39 | set ( LIBFTDI_LIBRARIES "@LIBFTDI_LIBRARIES@" ) 40 | set ( LIBFTDI_STATIC_LIBRARY "@LIBFTDI_STATIC_LIBRARY@" ) 41 | set ( LIBFTDI_STATIC_LIBRARIES "@LIBFTDI_STATIC_LIBRARIES@" ) 42 | set ( LIBFTDIPP_LIBRARY "@LIBFTDIPP_LIBRARY@" ) 43 | set ( LIBFTDIPP_LIBRARIES "@LIBFTDIPP_LIBRARIES@" ) 44 | set ( LIBFTDI_LIBRARY_DIRS "@LIBFTDI_LIBRARY_DIRS@" ) 45 | set ( LIBFTDI_ROOT_DIR "@LIBFTDI_ROOT_DIR@" ) 46 | 47 | set ( LIBFTDI_VERSION_STRING "@LIBFTDI_VERSION_STRING@" ) 48 | set ( LIBFTDI_VERSION_MAJOR "@LIBFTDI_VERSION_MAJOR@" ) 49 | set ( LIBFTDI_VERSION_MINOR "@LIBFTDI_VERSION_MINOR@" ) 50 | set ( LIBFTDI_VERSION_PATCH "@LIBFTDI_VERSION_PATCH@" ) 51 | 52 | set ( LIBFTDI_PYTHON_MODULE_PATH "@LIBFTDI_PYTHON_MODULE_PATH@" ) 53 | 54 | -------------------------------------------------------------------------------- /cmake/LibFTDI1ConfigVersion.cmake.in: -------------------------------------------------------------------------------- 1 | # This is a basic version file for the Config-mode of find_package(). 2 | # It is used by write_basic_package_version_file() as input file for configure_file() 3 | # to create a version-file which can be installed along a config.cmake file. 4 | # 5 | # The created file sets PACKAGE_VERSION_EXACT if the current version string and 6 | # the requested version string are exactly the same and it sets 7 | # PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version. 8 | # The variable CVF_VERSION must be set before calling configure_file(). 9 | 10 | set(PACKAGE_VERSION "@LIBFTDI_VERSION_STRING@") 11 | 12 | if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) 13 | set(PACKAGE_VERSION_COMPATIBLE FALSE) 14 | else() 15 | set(PACKAGE_VERSION_COMPATIBLE TRUE) 16 | if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") 17 | set(PACKAGE_VERSION_EXACT TRUE) 18 | endif() 19 | endif() 20 | 21 | # if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: 22 | if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") 23 | return() 24 | endif() 25 | 26 | # check that the installed version has the same 32/64bit-ness as the one which is currently searching: 27 | if(NOT "${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") 28 | math(EXPR installedBits "8 * 8") 29 | set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") 30 | set(PACKAGE_VERSION_UNSUITABLE TRUE) 31 | endif() 32 | -------------------------------------------------------------------------------- /cmake/Toolchain-Crossbuild32.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_C_COMPILER gcc -m32) 3 | set(CMAKE_CXX_COMPILER g++ -m32) 4 | set(CMAKE_FIND_ROOT_PATH /usr/lib) 5 | -------------------------------------------------------------------------------- /cmake/Toolchain-i686-w64-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # the name of the target operating system 2 | SET(CMAKE_SYSTEM_NAME Windows) 3 | 4 | # which compilers to use for C and C++ 5 | SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) 6 | SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) 7 | 8 | # here is the target environment located 9 | SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 ) 10 | 11 | # adjust the default behaviour of the FIND_XXX() commands: 12 | # search headers and libraries in the target environment, search 13 | # programs in the host environment 14 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 15 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 17 | set (CMAKE_RC_COMPILER i686-w64-mingw32-windres) 18 | -------------------------------------------------------------------------------- /cmake/Toolchain-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # the name of the target operating system 2 | SET(CMAKE_SYSTEM_NAME Windows) 3 | 4 | # which compilers to use for C and C++ 5 | SET(CMAKE_C_COMPILER i386-mingw32msvc-gcc) 6 | SET(CMAKE_CXX_COMPILER i386-mingw32msvc-g++) 7 | 8 | # here is the target environment located 9 | SET(CMAKE_FIND_ROOT_PATH /opt/cross/i386-mingw32msvc ) 10 | 11 | # adjust the default behaviour of the FIND_XXX() commands: 12 | # search headers and libraries in the target environment, search 13 | # programs in the host environment 14 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 15 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 17 | -------------------------------------------------------------------------------- /cmake/Toolchain-x86_64-w64-mingw32.cmake: -------------------------------------------------------------------------------- 1 | # the name of the target operating system 2 | SET(CMAKE_SYSTEM_NAME Windows) 3 | 4 | # which compilers to use for C and C++ 5 | SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) 6 | SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) 7 | 8 | # here is the target environment located 9 | SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32 ) 10 | 11 | # adjust the default behaviour of the FIND_XXX() commands: 12 | # search headers and libraries in the target environment, search 13 | # programs in the host environment 14 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 15 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 16 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 17 | set (CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) 18 | -------------------------------------------------------------------------------- /cmake/UseLibFTDI1.cmake: -------------------------------------------------------------------------------- 1 | # -*- cmake -*- 2 | # 3 | # UseLibFTDI.cmake 4 | # 5 | # Copyright (C) 2013 Intra2net AG and the libftdi developers 6 | # 7 | # This file is part of LibFTDI. 8 | # 9 | # LibFTDI is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU Lesser General Public License 11 | # version 2.1 as published by the Free Software Foundation; 12 | # 13 | 14 | 15 | add_definitions ( ${LIBFTDI_DEFINITIONS} ) 16 | include_directories ( ${LIBFTDI_INCLUDE_DIRS} ) 17 | link_directories ( ${LIBFTDI_LIBRARY_DIRS} ) 18 | 19 | -------------------------------------------------------------------------------- /doc/Doxyfile.xml.in: -------------------------------------------------------------------------------- 1 | # Doxyfile 1.7.4 2 | 3 | # xml generation only 4 | # keep settings but shut off all other generation 5 | @INCLUDE = Doxyfile 6 | 7 | GENERATE_TODOLIST = NO 8 | GENERATE_TESTLIST = NO 9 | GENERATE_BUGLIST = NO 10 | GENERATE_DEPRECATEDLIST= NO 11 | GENERATE_HTML = NO 12 | GENERATE_DOCSET = NO 13 | GENERATE_HTMLHELP = NO 14 | GENERATE_CHI = NO 15 | GENERATE_QHP = NO 16 | GENERATE_ECLIPSEHELP = NO 17 | GENERATE_TREEVIEW = NO 18 | GENERATE_LATEX = NO 19 | GENERATE_RTF = NO 20 | GENERATE_MAN = NO 21 | GENERATE_AUTOGEN_DEF = NO 22 | GENERATE_PERLMOD = NO 23 | GENERATE_TAGFILE = 24 | GENERATE_LEGEND = NO 25 | 26 | GENERATE_XML = YES 27 | -------------------------------------------------------------------------------- /doc/EEPROM-structure: -------------------------------------------------------------------------------- 1 | Here we try to document what we know about the EEPROM Structure. 2 | 3 | Even with a 93xx66 EEPROM, at maximum 256 Bytes are used 4 | 5 | All important things happen in the first 6 | 0x14(FT232/245), 0x16(FT2232CD), 0x18(FT232/245R) or 0x1a (FT2232H/4432H) bytes 7 | 8 | Type | Use extra EEPROM space 9 | FT2XXB | No 10 | 11 | Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H TYPE_4232H 12 | 00.0 | 0 0 channel_a_type 232R/245R channel_a_type 0 13 | 00.1 | 0 0 channel_a_type channel_a_type 0 14 | 00.2 | 0 0 channel_a_type high_current channel_a_type 0 15 | 00.3 | 0 0 channel_a_driver channel_a_driver channel_a_driver channel_a_driver 16 | 00.4 | 0 0 high_current_a 0 0 0 17 | 00.5 | 0 0 0 0 0 0 18 | 00.6 | 0 0 0 0 0 0 19 | 00.7 | 0 0 0 0 SUSPEND_DBUS7 channel_c_driver 20 | 21 | On TYPE_R 00.0 is set for the FT245R and cleared for the FT232R 22 | On TYPE_R 00.3 set mean D2XX, on other devices VCP 23 | 24 | 01.0 | 0 0 channel_b_type channel_b_type 0 25 | 01.1 | 0 0 channel_b_type channel_b_type 0 26 | 01.2 | 0 0 channel_b_type 0 channel_b_type 0 27 | 01.3 | 0 0 channel_b_driver 0 channel_b_driver channel_b_driver 28 | 01.4 | 0 0 high_current_b 0 0 0 29 | 01.5 | 0 0 0 0 0 0 30 | 01.6 | 0 0 0 0 0 31 | 01.7 | 0 0 0 0 0 channel_d_driver 32 | 33 | Fixme: Missing 4232H validation 34 | 35 | 02 | Vendor ID (VID) LSB (all) 36 | 03 | Vendor ID (VID) MSB (all) 37 | 04 | Product ID (PID) LSB (all) 38 | 05 | Product ID (PID) MSB (all) 39 | 06 | Device release number LSB (not tested on TYPE_4232H) 40 | 07 | Device release number MSB (not tested on TYPE_4232H) 41 | | 42 | 08.4 | Battery powered 43 | 08.5 | Remote wakeup 44 | 08.6 | Self powered: 1, bus powered: 0 45 | 08.7 | Always 1 46 | | 47 | 09 | Max power (mA/2) 48 | | 49 | Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H TYPE_4232H 50 | 0a.0 | 0 IsoIn IsoIn part A 0 0 0 51 | 0a.1 | 0 IsoOut IsoOut part A 0 0 0 52 | 0a.2 | 0 suspend_pull_down suspend_pull_down suspend_pull_down suspend_pull_down 53 | 0a.3 | 0 use_serial use_serial use_serial 54 | 0a.4 | 0 change_usb_version change_usb_version 55 | 0a.5 | 0 0 IsoIn part B 0 0 0 56 | 0a.6 | 0 0 IsoOut part B 0 0 0 57 | 0a.7 | 0 - reserved 58 | 59 | 0b | TYPE_R Bitmask Invert, 0 else 60 | Byte.BIT| TYPE_4232H 61 | 0b.4 | channel_a_rs485enable 62 | 0b.5 | channel_b_rs485enable 63 | 0b.6 | channel_c_rs485enable 64 | 0b.7 | channel_d_rs485enable 65 | 66 | Byte | TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H TYPE_4232H 67 | 0c | 0 USB-VER-LSB USB-VER-LSB 0 ? ? 68 | 0d | 0 USB-VER-MSB USB-VER-MSB 0 ? ? 69 | (On several FT2232H different values were observed -> The value is unused 70 | if change USB version is not set, so it might contain garbage) 71 | 72 | 0e | OFFSET Vendor 73 | 0f | Len VENDOR 74 | 75 | 10 | Offset Product 76 | 11 | Length Product 77 | 78 | 12 | Offset Serial 79 | 13 | Length Serial 80 | 81 | Byte.BIT| TYPE_AM TYPE_BM TYPE_2232C TYPE_R TYPE_2232H TYPE_4232H 82 | 14.3:0 | UA UA CHIP CBUS[0] AL A 83 | 14.7:0 | UA UA CHIP CBUS[1] AH B 84 | 15.3:0 | UA UA 0 CBUS[2] BL C 85 | 15.7:0 | UA UA 0 CBUS[3] BH D 86 | 16.3:0 | UA UA UA CBUS[4] 0 0 87 | 16.7:0 | UA UA UA 0 0 0 88 | 89 | CHIP values: 90 | 0x46: EEPROM is a 93xx46 91 | 0x56: EEPROM is a 93xx56 92 | 0x66: EEPROM is a 93xx66 93 | 94 | 17 UA UA UA 0 0 0 95 | 18 UA UA UA VENDOR CHIP CHIP 96 | 19 UA UA UA VENDOR 0 0 97 | 98 | 1a UA (all) 99 | 100 | 101 | Additional fields after the serial string: 102 | 0x00, 0x00 - reserved for "legacy port name prefix" 103 | 0x00, 0x00 - reserved for plug and play options 104 | (Observed values with PnP == 0: 105 | 0x02 0x03 0x01 0x00) 106 | 107 | Note: The additional fields after the serial number string 108 | collide with the official FTDI formula from AN_121 regarding 109 | the start of the user area: 110 | "Start Address = the address following the last byte of SerialNumber string." 111 | -------------------------------------------------------------------------------- /doc/astyle_reformat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Astyle settings used to format our source code 3 | /usr/bin/astyle --indent=spaces=4 --indent-switches --brackets=break \ 4 | --convert-tabs --keep-one-line-statements --keep-one-line-blocks \ 5 | $* 6 | -------------------------------------------------------------------------------- /doc/release-checklist.txt: -------------------------------------------------------------------------------- 1 | *** Checklist for a new libftdi release *** 2 | - Update ChangeLog and AUTHORS via git history 3 | (git log --oneline latest_release..HEAD) 4 | 5 | - Update version number in the following files: 6 | - CMakeLists.txt 7 | - README 8 | 9 | - Run "make dist" 10 | 11 | - Diff tarball to previous version, check if all 12 | important changes are in the ChangeLog 13 | 14 | - Ensure all modifications are checked in 15 | 16 | - Sign tarball, build .src.rpm and sign it, too 17 | 18 | - Create git tag: 19 | - git tag -s -u 24F006F5 v1.XX 20 | - git tag -d latest_release ; git tag latest_release 21 | - git push --tags 22 | 23 | - Website 24 | - Upload tarball and .src.rpm 25 | - Add ChangeLog to main page 26 | - Update URLs in download section 27 | - Generate API documentation and upload it 28 | 29 | - Announce on mailinglist 30 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Includes 2 | include_directories( ${CMAKE_CURRENT_SOURCE_DIR} 3 | ${CMAKE_CURRENT_BINARY_DIR} 4 | ) 5 | 6 | # Targets 7 | add_executable(simple simple.c) 8 | add_executable(bitbang bitbang.c) 9 | add_executable(bitbang2 bitbang2.c) 10 | add_executable(bitbang_cbus bitbang_cbus.c) 11 | add_executable(bitbang_ft2232 bitbang_ft2232.c) 12 | add_executable(find_all find_all.c) 13 | add_executable(serial_test serial_test.c) 14 | add_executable(baud_test baud_test.c) 15 | add_executable(stream_test stream_test.c) 16 | add_executable(eeprom eeprom.c) 17 | add_executable(async async.c) 18 | 19 | # Linkage 20 | target_link_libraries(simple ftdi1) 21 | target_link_libraries(bitbang ftdi1) 22 | target_link_libraries(bitbang2 ftdi1) 23 | target_link_libraries(bitbang_cbus ftdi1) 24 | target_link_libraries(bitbang_ft2232 ftdi1) 25 | target_link_libraries(find_all ftdi1) 26 | target_link_libraries(serial_test ftdi1) 27 | target_link_libraries(baud_test ftdi1) 28 | target_link_libraries(stream_test ftdi1) 29 | target_link_libraries(eeprom ftdi1) 30 | target_link_libraries(async ftdi1) 31 | 32 | # libftdi++ examples 33 | if( FTDIPP ) 34 | include_directories(BEFORE ${CMAKE_SOURCE_DIR}/ftdipp 35 | ${Boost_INCLUDE_DIRS}) 36 | 37 | # Target 38 | add_executable(find_all_pp find_all_pp.cpp) 39 | 40 | # Linkage 41 | target_link_libraries(find_all_pp ftdipp1) 42 | endif( FTDIPP ) 43 | 44 | # Source includes 45 | include_directories(BEFORE ${CMAKE_SOURCE_DIR}/src) 46 | -------------------------------------------------------------------------------- /examples/async.c: -------------------------------------------------------------------------------- 1 | /* Libftdi example for asynchronous read/write. 2 | 3 | This program is distributed under the GPL, version 2 4 | */ 5 | 6 | /* This programm switches to MPSSE mode, and sets and then reads back 7 | * the high byte 3 times with three different values. 8 | * The expected read values are hard coded in ftdi_init 9 | * with 0x00, 0x55 and 0xaa 10 | * 11 | * Make sure that that nothing else drives some bit of the high byte 12 | * or expect a collision for a very short time and some differences 13 | * in the data read back. 14 | * 15 | * Result should be the same without any option or with either 16 | * -r or -w or -b. 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | int main(int argc, char **argv) 29 | { 30 | struct ftdi_context *ftdi; 31 | int do_read = 0; 32 | int do_write = 0; 33 | int i, f, retval; 34 | 35 | if ((ftdi = ftdi_new()) == 0) 36 | { 37 | fprintf(stderr, "Failed to allocate ftdi structure :%s \n", 38 | ftdi_get_error_string(ftdi)); 39 | return EXIT_FAILURE; 40 | } 41 | 42 | while ((i = getopt(argc, argv, "brw")) != -1) 43 | { 44 | switch (i) 45 | { 46 | case 'b': 47 | do_read = 1; 48 | do_write = 1; 49 | break; 50 | case 'r': 51 | do_read = 1; 52 | break; 53 | case 'w': 54 | do_write = 1; 55 | break; 56 | default: 57 | fprintf(stderr, "usage: %s [options]\n", *argv); 58 | fprintf(stderr, "\t-b do synchronous read and write\n"); 59 | fprintf(stderr, "\t-r do synchronous read\n"); 60 | fprintf(stderr, "\t-w do synchronous write\n"); 61 | retval = -1; 62 | goto done; 63 | } 64 | } 65 | 66 | /* Select first free interface */ 67 | ftdi_set_interface(ftdi, INTERFACE_ANY); 68 | 69 | struct ftdi_device_list *devlist; 70 | int res; 71 | if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0) 72 | { 73 | fprintf(stderr, "No FTDI with default VID/PID found\n"); 74 | retval = EXIT_FAILURE; 75 | goto do_deinit; 76 | } 77 | if (res > 0) 78 | { 79 | int i = 1; 80 | f = ftdi_usb_open_dev(ftdi, devlist[0].dev); 81 | if (f < 0) 82 | { 83 | fprintf(stderr, "Unable to open device %d: (%s)", 84 | i, ftdi_get_error_string(ftdi)); 85 | retval = -1; 86 | goto do_deinit; 87 | } 88 | } 89 | else 90 | { 91 | fprintf(stderr, "No devices found\n"); 92 | retval = -1; 93 | goto do_deinit; 94 | } 95 | ftdi_list_free(&devlist); 96 | int err = ftdi_usb_purge_buffers(ftdi); 97 | if (err != 0) { 98 | fprintf(stderr, "ftdi_usb_purge_buffer: %d: %s\n", 99 | err, ftdi_get_error_string(ftdi)); 100 | retval = -1; 101 | goto do_deinit; 102 | } 103 | /* Reset MPSSE controller. */ 104 | err = ftdi_set_bitmode(ftdi, 0, BITMODE_RESET); 105 | if (err != 0) { 106 | fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", 107 | err, ftdi_get_error_string(ftdi)); 108 | retval = -1; 109 | goto do_deinit; 110 | } 111 | /* Enable MPSSE controller. Pin directions are set later.*/ 112 | err = ftdi_set_bitmode(ftdi, 0, BITMODE_MPSSE); 113 | if (err != 0) { 114 | fprintf(stderr, "ftdi_set_bitmode: %d: %s\n", 115 | err, ftdi_get_error_string(ftdi)); 116 | return -1; 117 | } 118 | #define DATA_TO_READ 3 119 | uint8_t ftdi_init[] = {TCK_DIVISOR, 0x00, 0x00, 120 | /* Set High byte to zero.*/ 121 | SET_BITS_HIGH, 0, 0xff, 122 | GET_BITS_HIGH, 123 | /* Set High byte to 0x55.*/ 124 | SET_BITS_HIGH, 0x55, 0xff, 125 | GET_BITS_HIGH, 126 | /* Set High byte to 0xaa.*/ 127 | SET_BITS_HIGH, 0xaa, 0xff, 128 | GET_BITS_HIGH, 129 | /* Set back to high impedance.*/ 130 | SET_BITS_HIGH, 0x00, 0x00 }; 131 | struct ftdi_transfer_control *tc_read; 132 | struct ftdi_transfer_control *tc_write; 133 | uint8_t data[3]; 134 | if (do_read) { 135 | tc_read = ftdi_read_data_submit(ftdi, data, DATA_TO_READ); 136 | } 137 | if (do_write) { 138 | tc_write = ftdi_write_data_submit(ftdi, ftdi_init, sizeof(ftdi_init)); 139 | int transfer = ftdi_transfer_data_done(tc_write); 140 | if (transfer != sizeof(ftdi_init)) { 141 | printf("Async write failed : %d\n", transfer); 142 | } 143 | } else { 144 | int written = ftdi_write_data(ftdi, ftdi_init, sizeof(ftdi_init)); 145 | if (written != sizeof(ftdi_init)) { 146 | printf("Sync write failed: %d\n", written); 147 | } 148 | } 149 | if (do_read) { 150 | int transfer = ftdi_transfer_data_done(tc_read); 151 | if (transfer != DATA_TO_READ) { 152 | printf("Async Read failed:%d\n", transfer); 153 | } 154 | } else { 155 | int index = 0; 156 | ftdi->usb_read_timeout = 1; 157 | int i = 1000; /* Fail if read did not succeed in 1 second.*/ 158 | while (i--) { 159 | int res = ftdi_read_data(ftdi, data + index, 3 - index); 160 | if (res < 0) { 161 | printf("Async read failure at %d\n", index); 162 | } else { 163 | index += res; 164 | } 165 | if (res == 3) { 166 | break; 167 | } 168 | } 169 | if (i < 1) { 170 | printf("Async read unsuccessfull\n"); 171 | } 172 | } 173 | printf("Read %02x %02x %02x\n", data[0], data[1], data[2]); 174 | done: 175 | ftdi_usb_close(ftdi); 176 | do_deinit: 177 | ftdi_free(ftdi); 178 | return retval; 179 | } 180 | -------------------------------------------------------------------------------- /examples/baud_test.c: -------------------------------------------------------------------------------- 1 | /* baud_test.c 2 | * 3 | * test setting the baudrate and compare it with the expected runtime 4 | * 5 | * options: 6 | * -p defaults to "i:0x0403:0x6001" (this is the first FT232R with default id) 7 | * d: path of bus and device-node (e.g. "003/001") within usb device tree (usually at /proc/bus/usb/) 8 | * i:: first device with given vendor and product id, 9 | * ids can be decimal, octal (preceded by "0") or hex (preceded by "0x") 10 | * i::: as above with index being the number of the device (starting with 0) 11 | * if there are more than one 12 | * s::: first device with given vendor id, product id and serial string 13 | * -d 14 | * -b (divides by 16 if bitbang as taken from the ftdi datasheets) 15 | * -m r: serial a: async bitbang s:sync bitbang 16 | * -c 17 | * 18 | * (C) 2009 by Gerd v. Egidy 19 | * 20 | * This program is free software; you can redistribute it and/or modify 21 | * it under the terms of the GNU General Public License as published by 22 | * the Free Software Foundation; either version 2 of the License, or 23 | * (at your option) any later version. 24 | 25 | * This program is distributed in the hope that it will be useful, 26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 | * GNU General Public License for more details. 29 | * 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | double get_prec_time() 39 | { 40 | struct timeval tv; 41 | double res; 42 | 43 | gettimeofday(&tv,NULL); 44 | 45 | res=tv.tv_sec; 46 | res+=((double)tv.tv_usec/1000000); 47 | 48 | return res; 49 | } 50 | 51 | int main(int argc, char **argv) 52 | { 53 | struct ftdi_context *ftdi; 54 | int i, t; 55 | unsigned char *txbuf; 56 | unsigned char *rxbuf; 57 | double start, duration, plan; 58 | int retval= 0; 59 | 60 | // default values 61 | int baud=9600; 62 | int set_baud; 63 | int datasize=100000; 64 | 65 | char default_devicedesc[] = "i:0x0403:0x6001"; 66 | char *devicedesc=default_devicedesc; 67 | int txchunksize=256; 68 | enum ftdi_mpsse_mode test_mode=BITMODE_BITBANG; 69 | 70 | while ((t = getopt (argc, argv, "b:d:p:m:c:")) != -1) 71 | { 72 | switch (t) 73 | { 74 | case 'd': 75 | datasize = atoi (optarg); 76 | break; 77 | case 'm': 78 | switch (*optarg) 79 | { 80 | case 'r': 81 | // serial 82 | test_mode=BITMODE_RESET; 83 | break; 84 | case 'a': 85 | // async 86 | test_mode=BITMODE_BITBANG; 87 | break; 88 | case 's': 89 | // sync 90 | test_mode=BITMODE_SYNCBB; 91 | break; 92 | } 93 | break; 94 | case 'b': 95 | baud = atoi (optarg); 96 | break; 97 | case 'p': 98 | devicedesc=optarg; 99 | break; 100 | case 'c': 101 | txchunksize = atoi (optarg); 102 | break; 103 | } 104 | } 105 | 106 | txbuf=malloc(txchunksize); 107 | rxbuf=malloc(txchunksize); 108 | if (txbuf == NULL || rxbuf == NULL) 109 | { 110 | fprintf(stderr, "can't malloc\n"); 111 | return EXIT_FAILURE; 112 | } 113 | 114 | if ((ftdi = ftdi_new()) == 0) 115 | { 116 | fprintf(stderr, "ftdi_new failed\n"); 117 | retval = EXIT_FAILURE; 118 | goto done; 119 | } 120 | 121 | if (ftdi_usb_open_string(ftdi, devicedesc) < 0) 122 | { 123 | fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi)); 124 | retval = EXIT_FAILURE; 125 | goto do_deinit; 126 | } 127 | 128 | set_baud=baud; 129 | if (test_mode!=BITMODE_RESET) 130 | { 131 | // we do bitbang, so real baudrate / 16 132 | set_baud=baud/16; 133 | } 134 | 135 | ftdi_set_baudrate(ftdi,set_baud); 136 | printf("real baudrate used: %d\n",(test_mode==BITMODE_RESET) ? ftdi->baudrate : ftdi->baudrate*16); 137 | 138 | if (ftdi_set_bitmode(ftdi, 0xFF,test_mode) < 0) 139 | { 140 | fprintf(stderr,"Can't set mode: %s\n",ftdi_get_error_string(ftdi)); 141 | retval = EXIT_FAILURE; 142 | goto do_close; 143 | } 144 | 145 | if (test_mode==BITMODE_RESET) 146 | { 147 | // serial 8N1: 8 data bits, 1 startbit, 1 stopbit 148 | plan=((double)(datasize*10))/baud; 149 | } 150 | else 151 | { 152 | // bitbang means 8 bits at once 153 | plan=((double)datasize)/baud; 154 | } 155 | 156 | printf("this test should take %.2f seconds\n",plan); 157 | 158 | // prepare data to send: 0 and 1 bits alternating (except for serial start/stopbit): 159 | // maybe someone wants to look at this with a scope or logic analyzer 160 | for (i=0; i0); 180 | } 181 | 182 | start=get_prec_time(); 183 | 184 | // don't wait for more data to arrive, take what we get and keep on sending 185 | // yes, we really would like to have libusb 1.0+ with async read/write... 186 | ftdi->usb_read_timeout=1; 187 | 188 | i=0; 189 | while (i < datasize) 190 | { 191 | int sendsize=txchunksize; 192 | if (i+sendsize > datasize) 193 | sendsize=datasize-i; 194 | 195 | if ((sendsize=ftdi_write_data(ftdi, txbuf, sendsize)) < 0) 196 | { 197 | fprintf(stderr,"write failed at %d: %s\n", 198 | i, ftdi_get_error_string(ftdi)); 199 | retval = EXIT_FAILURE; 200 | goto do_close; 201 | } 202 | 203 | i+=sendsize; 204 | 205 | if (test_mode==BITMODE_SYNCBB) 206 | { 207 | // read the same amount of data as sent 208 | ftdi_read_data(ftdi, rxbuf, sendsize); 209 | } 210 | } 211 | 212 | duration=get_prec_time()-start; 213 | printf("and took %.4f seconds, this is %.0f baud or factor %.3f\n",duration,(plan*baud)/duration,plan/duration); 214 | do_close: 215 | ftdi_usb_close(ftdi); 216 | do_deinit: 217 | ftdi_free(ftdi); 218 | done: 219 | if(rxbuf) 220 | free(rxbuf); 221 | if(txbuf) 222 | free(txbuf); 223 | exit (retval); 224 | } 225 | -------------------------------------------------------------------------------- /examples/bitbang.c: -------------------------------------------------------------------------------- 1 | /* This program is distributed under the GPL, version 2 */ 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | int main(int argc, char **argv) 9 | { 10 | struct ftdi_context *ftdi; 11 | int f,i; 12 | unsigned char buf[1]; 13 | int retval = 0; 14 | 15 | if ((ftdi = ftdi_new()) == 0) 16 | { 17 | fprintf(stderr, "ftdi_new failed\n"); 18 | return EXIT_FAILURE; 19 | } 20 | 21 | f = ftdi_usb_open(ftdi, 0x0403, 0x6001); 22 | 23 | if (f < 0 && f != -5) 24 | { 25 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 26 | retval = 1; 27 | goto done; 28 | } 29 | 30 | printf("ftdi open succeeded: %d\n",f); 31 | 32 | printf("enabling bitbang mode\n"); 33 | ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG); 34 | 35 | usleep(3 * 1000000); 36 | 37 | buf[0] = 0x0; 38 | printf("turning everything on\n"); 39 | f = ftdi_write_data(ftdi, buf, 1); 40 | if (f < 0) 41 | { 42 | fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f, ftdi_get_error_string(ftdi)); 43 | } 44 | 45 | usleep(3 * 1000000); 46 | 47 | buf[0] = 0xFF; 48 | printf("turning everything off\n"); 49 | f = ftdi_write_data(ftdi, buf, 1); 50 | if (f < 0) 51 | { 52 | fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f, ftdi_get_error_string(ftdi)); 53 | } 54 | 55 | usleep(3 * 1000000); 56 | 57 | for (i = 0; i < 32; i++) 58 | { 59 | buf[0] = 0 | (0xFF ^ 1 << (i % 8)); 60 | if ( i > 0 && (i % 8) == 0) 61 | { 62 | printf("\n"); 63 | } 64 | printf("%02hhx ",buf[0]); 65 | fflush(stdout); 66 | f = ftdi_write_data(ftdi, buf, 1); 67 | if (f < 0) 68 | { 69 | fprintf(stderr,"write failed for 0x%x, error %d (%s)\n",buf[0],f, ftdi_get_error_string(ftdi)); 70 | } 71 | usleep(1 * 1000000); 72 | } 73 | 74 | printf("\n"); 75 | 76 | printf("disabling bitbang mode\n"); 77 | ftdi_disable_bitbang(ftdi); 78 | 79 | ftdi_usb_close(ftdi); 80 | done: 81 | ftdi_free(ftdi); 82 | 83 | return retval; 84 | } 85 | -------------------------------------------------------------------------------- /examples/bitbang2.c: -------------------------------------------------------------------------------- 1 | /* ftdi_out.c 2 | * 3 | * Output a (stream of) byte(s) in bitbang mode to the 4 | * ftdi245 chip that is (hopefully) attached. 5 | * 6 | * We have a little board that has a FT245BM chip and 7 | * the 8 outputs are connected to several different 8 | * things that we can turn on and off with this program. 9 | * 10 | * If you have an idea about hardware that can easily 11 | * interface onto an FTDI chip, I'd like to collect 12 | * ideas. If I find it worthwhile to make, I'll consider 13 | * making it, I'll even send you a prototype (against 14 | * cost-of-material) if you want. 15 | * 16 | * At "harddisk-recovery.nl" they have a little board that 17 | * controls the power to two harddrives and two fans. 18 | * 19 | * -- REW R.E.Wolff@BitWizard.nl 20 | * 21 | * 22 | * 23 | * This program was based on libftdi_example_bitbang2232.c 24 | * which doesn't carry an author or attribution header. 25 | * 26 | * 27 | * This program is distributed under the GPL, version 2. 28 | * Millions copies of the GPL float around the internet. 29 | */ 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | void ftdi_fatal (struct ftdi_context *ftdi, char *str) 38 | { 39 | fprintf (stderr, "%s: %s\n", 40 | str, ftdi_get_error_string (ftdi)); 41 | ftdi_free(ftdi); 42 | exit (1); 43 | } 44 | 45 | int main(int argc, char **argv) 46 | { 47 | struct ftdi_context *ftdi; 48 | int i, t; 49 | unsigned char data; 50 | int delay = 100000; /* 100 thousand microseconds: 1 tenth of a second */ 51 | 52 | while ((t = getopt (argc, argv, "d:")) != -1) 53 | { 54 | switch (t) 55 | { 56 | case 'd': 57 | delay = atoi (optarg); 58 | break; 59 | } 60 | } 61 | 62 | if ((ftdi = ftdi_new()) == 0) 63 | { 64 | fprintf(stderr, "ftdi_bew failed\n"); 65 | return EXIT_FAILURE; 66 | } 67 | 68 | if (ftdi_usb_open(ftdi, 0x0403, 0x6001) < 0) 69 | ftdi_fatal (ftdi, "Can't open ftdi device"); 70 | 71 | if (ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG) < 0) 72 | ftdi_fatal (ftdi, "Can't enable bitbang"); 73 | 74 | for (i=optind; i < argc ; i++) 75 | { 76 | sscanf (argv[i], "%x", &t); 77 | data = t; 78 | if (ftdi_write_data(ftdi, &data, 1) < 0) 79 | { 80 | fprintf(stderr,"write failed for 0x%x: %s\n", 81 | data, ftdi_get_error_string(ftdi)); 82 | } 83 | usleep(delay); 84 | } 85 | 86 | ftdi_usb_close(ftdi); 87 | ftdi_free(ftdi); 88 | exit (0); 89 | } 90 | -------------------------------------------------------------------------------- /examples/bitbang_cbus.c: -------------------------------------------------------------------------------- 1 | /* bitbang_cbus.c 2 | 3 | Example to use CBUS bitbang mode of newer chipsets. 4 | You must enable CBUS bitbang mode in the EEPROM first. 5 | 6 | Thanks to Steve Brown for the 7 | the information how to do it. 8 | 9 | The top nibble controls input/output and the bottom nibble 10 | controls the state of the lines set to output. The datasheet isn't clear 11 | what happens if you set a bit in the output register when that line is 12 | conditioned for input. This is described in more detail 13 | in the FT232R bitbang app note. 14 | 15 | BITMASK 16 | CBUS Bits 17 | 3210 3210 18 | xxxx xxxx 19 | |    |------ Output Control 0->LO, 1->HI 20 | |----------- Input/Output   0->Input, 1->Output 21 | 22 | Example: 23 | All pins to output with 0 bit high: 0xF1 (11110001) 24 | Bits 0 and 1 to input, 2 and 3 to output and masked high: 0xCC (11001100) 25 | 26 | The input is standard "0x" hex notation. 27 | A carriage return terminates the program. 28 | 29 | This program is distributed under the GPL, version 2 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | int main(void) 38 | { 39 | struct ftdi_context *ftdi; 40 | int f; 41 | unsigned char buf[1]; 42 | unsigned char bitmask; 43 | char input[10]; 44 | 45 | if ((ftdi = ftdi_new()) == 0) 46 | { 47 | fprintf(stderr, "ftdi_new failed\n"); 48 | return EXIT_FAILURE; 49 | } 50 | 51 | f = ftdi_usb_open(ftdi, 0x0403, 0x6001); 52 | if (f < 0 && f != -5) 53 | { 54 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 55 | ftdi_free(ftdi); 56 | exit(-1); 57 | } 58 | printf("ftdi open succeeded: %d\n",f); 59 | 60 | while (1) 61 | { 62 | // Set bitmask from input 63 | fgets(input, sizeof(input) - 1, stdin); 64 | if (input[0] == '\n') break; 65 | bitmask = strtol(input, NULL, 0); 66 | printf("Using bitmask 0x%02x\n", bitmask); 67 | f = ftdi_set_bitmode(ftdi, bitmask, BITMODE_CBUS); 68 | if (f < 0) 69 | { 70 | fprintf(stderr, "set_bitmode failed for 0x%x, error %d (%s)\n", bitmask, f, ftdi_get_error_string(ftdi)); 71 | ftdi_usb_close(ftdi); 72 | ftdi_free(ftdi); 73 | exit(-1); 74 | } 75 | 76 | // read CBUS 77 | f = ftdi_read_pins(ftdi, &buf[0]); 78 | if (f < 0) 79 | { 80 | fprintf(stderr, "read_pins failed, error %d (%s)\n", f, ftdi_get_error_string(ftdi)); 81 | ftdi_usb_close(ftdi); 82 | ftdi_free(ftdi); 83 | exit(-1); 84 | } 85 | printf("Read returned 0x%01x\n", buf[0] & 0x0f); 86 | } 87 | printf("disabling bitbang mode\n"); 88 | ftdi_disable_bitbang(ftdi); 89 | 90 | ftdi_usb_close(ftdi); 91 | ftdi_free(ftdi); 92 | 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /examples/bitbang_cbus_eeprom_for_windows.ept: -------------------------------------------------------------------------------- 1 | [Basic Details] 2 | Device Type=6 3 | VID PID Type=0 4 | USB VID=0403 5 | USB PID=6001 6 | [USB Power Options] 7 | Bus Powered=1 8 | Self Powered=0 9 | Max Bus Power=44 10 | [USB Serial Number Control] 11 | Prefix=FT 12 | Use Fixed Serial Number=0 13 | Fixed Serial Number=FTDECZJT 14 | [USB Remote WakeUp] 15 | Enable Remote WakeUp=1 16 | [Windows Plug and Play] 17 | Enable Plug and Play=0 18 | [USB String Descriptors] 19 | Manufacturer=FTDI 20 | Product=USB Serial Converter 21 | [Programming Options] 22 | Only Program Blank Devices=0 23 | [BM Device Specific Options] 24 | USB Version Number=1 25 | Disable Serial Number=0 26 | IO Pin Pull Down in Suspend=0 27 | [Dual Device Specific Options A] 28 | RS 232 mode=1 29 | 245 FIFO mode=0 30 | 245 CPU FIFO mode=0 31 | OPTO Isolate mode=1 32 | High Current Drive=0 33 | [Dual Device Specific Options B] 34 | RS 232 mode=1 35 | 245 FIFO mode=0 36 | 245 CPU FIFO mode=0 37 | OPTO Isolate mode=0 38 | High Current Drive=0 39 | [Dual Device Driver Options A] 40 | Virtual Com Port Driver=1 41 | D2XX Driver=0 42 | [Dual Device Driver Options B] 43 | Virtual Com Port Driver=1 44 | D2XX Driver=0 45 | [R Device Specific Options] 46 | Invert TXD=0 47 | Invert RXD=0 48 | Invert RTS#=0 49 | Invert CTS#=0 50 | Invert DTR#=0 51 | Invert DSR#=0 52 | Invert DCD#=0 53 | Invert RI#=0 54 | C0 Signal=10 55 | C1 Signal=10 56 | C2 Signal=10 57 | C3 Signal=10 58 | C4 Signal=5 59 | Enable Ext Osc=0 60 | High Current I/O=0 61 | Load D2XX Driver=0 62 | In EndPoint Size=0 63 | -------------------------------------------------------------------------------- /examples/bitbang_ft2232.c: -------------------------------------------------------------------------------- 1 | /* bitbang_ft2232.c 2 | 3 | Output some flickering in bitbang mode to the FT2232 4 | 5 | Thanks to max@koeln.ccc.de for fixing and extending 6 | the example for the second channel. 7 | 8 | This program is distributed under the GPL, version 2 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int main(int argc, char **argv) 17 | { 18 | struct ftdi_context *ftdi, *ftdi2; 19 | unsigned char buf[1]; 20 | int f,i; 21 | 22 | // Init 1. channel 23 | if ((ftdi = ftdi_new()) == 0) 24 | { 25 | fprintf(stderr, "ftdi_new failed\n"); 26 | return EXIT_FAILURE; 27 | } 28 | 29 | ftdi_set_interface(ftdi, INTERFACE_A); 30 | f = ftdi_usb_open(ftdi, 0x0403, 0x6001); 31 | if (f < 0 && f != -5) 32 | { 33 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 34 | ftdi_free(ftdi); 35 | exit(-1); 36 | } 37 | printf("ftdi open succeeded(channel 1): %d\n",f); 38 | 39 | printf("enabling bitbang mode(channel 1)\n"); 40 | ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG); 41 | 42 | // Init 2. channel 43 | if ((ftdi2 = ftdi_new()) == 0) 44 | { 45 | fprintf(stderr, "ftdi_new failed\n"); 46 | return EXIT_FAILURE; 47 | } 48 | ftdi_set_interface(ftdi2, INTERFACE_B); 49 | f = ftdi_usb_open(ftdi2, 0x0403, 0x6001); 50 | if (f < 0 && f != -5) 51 | { 52 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi2)); 53 | ftdi_free(ftdi2); 54 | exit(-1); 55 | } 56 | printf("ftdi open succeeded(channel 2): %d\n",f); 57 | 58 | printf("enabling bitbang mode (channel 2)\n"); 59 | ftdi_set_bitmode(ftdi2, 0xFF, BITMODE_BITBANG); 60 | 61 | // Write data 62 | printf("startloop\n"); 63 | for (i = 0; i < 23; i++) 64 | { 65 | buf[0] = 0x1; 66 | printf("porta: %02i: 0x%02x \n",i,buf[0]); 67 | f = ftdi_write_data(ftdi, buf, 1); 68 | if (f < 0) 69 | fprintf(stderr,"write failed on channel 1 for 0x%x, error %d (%s)\n", buf[0], f, ftdi_get_error_string(ftdi)); 70 | usleep(1 * 1000000); 71 | 72 | buf[0] = 0x2; 73 | printf("porta: %02i: 0x%02x \n",i,buf[0]); 74 | f = ftdi_write_data(ftdi, buf, 1); 75 | if (f < 0) 76 | fprintf(stderr,"write failed on channel 1 for 0x%x, error %d (%s)\n", buf[0], f, ftdi_get_error_string(ftdi)); 77 | usleep(1 * 1000000); 78 | 79 | buf[0] = 0x1; 80 | printf("portb: %02i: 0x%02x \n",i,buf[0]); 81 | f = ftdi_write_data(ftdi2, buf, 1); 82 | if (f < 0) 83 | fprintf(stderr,"write failed on channel 2 for 0x%x, error %d (%s)\n", buf[0], f, ftdi_get_error_string(ftdi2)); 84 | usleep(1 * 1000000); 85 | 86 | buf[0] = 0x2; 87 | printf("portb: %02i: 0x%02x \n",i,buf[0]); 88 | f = ftdi_write_data(ftdi2, buf, 1); 89 | if (f < 0) 90 | fprintf(stderr,"write failed on channel 2 for 0x%x, error %d (%s)\n", buf[0], f, ftdi_get_error_string(ftdi2)); 91 | usleep(1 * 1000000); 92 | } 93 | printf("\n"); 94 | 95 | printf("disabling bitbang mode(channel 1)\n"); 96 | ftdi_disable_bitbang(ftdi); 97 | ftdi_usb_close(ftdi); 98 | ftdi_free(ftdi); 99 | 100 | printf("disabling bitbang mode(channel 2)\n"); 101 | ftdi_disable_bitbang(ftdi2); 102 | ftdi_usb_close(ftdi2); 103 | ftdi_free(ftdi2); 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /examples/cmake_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required ( VERSION 2.8 ) 2 | 3 | project ( example C ) 4 | 5 | find_package ( LibFTDI1 NO_MODULE REQUIRED ) 6 | include ( ${LIBFTDI_USE_FILE} ) 7 | 8 | add_executable ( example main.c ) 9 | target_link_libraries( example ${LIBFTDI_LIBRARIES} ) 10 | 11 | install ( TARGETS example 12 | DESTINATION bin ) 13 | 14 | -------------------------------------------------------------------------------- /examples/cmake_example/main.c: -------------------------------------------------------------------------------- 1 | /* main.c 2 | 3 | Example for ftdi_new() 4 | 5 | This program is distributed under the GPL, version 2 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | struct ftdi_context *ftdi; 15 | int retval = EXIT_SUCCESS; 16 | 17 | if ((ftdi = ftdi_new()) == 0) 18 | { 19 | fprintf(stderr, "ftdi_new failed\n"); 20 | return EXIT_FAILURE; 21 | } 22 | 23 | return retval; 24 | } 25 | -------------------------------------------------------------------------------- /examples/eeprom.c: -------------------------------------------------------------------------------- 1 | /* LIBFTDI EEPROM access example 2 | 3 | This program is distributed under the GPL, version 2 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int read_decode_eeprom(struct ftdi_context *ftdi) 15 | { 16 | int i, j, f; 17 | int value; 18 | int size; 19 | unsigned char buf[256]; 20 | 21 | f = ftdi_read_eeprom(ftdi); 22 | if (f < 0) 23 | { 24 | fprintf(stderr, "ftdi_read_eeprom: %d (%s)\n", 25 | f, ftdi_get_error_string(ftdi)); 26 | return -1; 27 | } 28 | 29 | 30 | ftdi_get_eeprom_value(ftdi, CHIP_SIZE, & value); 31 | if (value <0) 32 | { 33 | fprintf(stderr, "No EEPROM found or EEPROM empty\n"); 34 | fprintf(stderr, "On empty EEPROM, use -w option to write default values\n"); 35 | return -1; 36 | } 37 | fprintf(stderr, "Chip type %d ftdi_eeprom_size: %d\n", ftdi->type, value); 38 | if (ftdi->type == TYPE_R) 39 | size = 0xa0; 40 | else 41 | size = value; 42 | ftdi_get_eeprom_buf(ftdi, buf, size); 43 | for (i=0; i < size; i += 16) 44 | { 45 | fprintf(stdout,"0x%03x:", i); 46 | 47 | for (j = 0; j< 8; j++) 48 | fprintf(stdout," %02x", buf[i+j]); 49 | fprintf(stdout," "); 50 | for (; j< 16; j++) 51 | fprintf(stdout," %02x", buf[i+j]); 52 | fprintf(stdout," "); 53 | for (j = 0; j< 8; j++) 54 | fprintf(stdout,"%c", isprint(buf[i+j])?buf[i+j]:'.'); 55 | fprintf(stdout," "); 56 | for (; j< 16; j++) 57 | fprintf(stdout,"%c", isprint(buf[i+j])?buf[i+j]:'.'); 58 | fprintf(stdout,"\n"); 59 | } 60 | 61 | f = ftdi_eeprom_decode(ftdi, 1); 62 | if (f < 0) 63 | { 64 | fprintf(stderr, "ftdi_eeprom_decode: %d (%s)\n", 65 | f, ftdi_get_error_string(ftdi)); 66 | return -1; 67 | } 68 | return 0; 69 | } 70 | 71 | int main(int argc, char **argv) 72 | { 73 | struct ftdi_context *ftdi; 74 | int f, i; 75 | int vid = 0; 76 | int pid = 0; 77 | char const *desc = 0; 78 | char const *serial = 0; 79 | int erase = 0; 80 | int use_defaults = 0; 81 | int large_chip = 0; 82 | int do_write = 0; 83 | int retval = 0; 84 | int value; 85 | 86 | if ((ftdi = ftdi_new()) == 0) 87 | { 88 | fprintf(stderr, "Failed to allocate ftdi structure :%s \n", 89 | ftdi_get_error_string(ftdi)); 90 | return EXIT_FAILURE; 91 | } 92 | 93 | while ((i = getopt(argc, argv, "d::ev:p:l:P:S:w")) != -1) 94 | { 95 | switch (i) 96 | { 97 | case 'd': 98 | use_defaults = 1; 99 | if (optarg) 100 | large_chip = 0x66; 101 | break; 102 | case 'e': 103 | erase = 1; 104 | break; 105 | case 'v': 106 | vid = strtoul(optarg, NULL, 0); 107 | break; 108 | case 'p': 109 | pid = strtoul(optarg, NULL, 0); 110 | break; 111 | case 'P': 112 | desc = optarg; 113 | break; 114 | case 'S': 115 | serial = optarg; 116 | break; 117 | case 'w': 118 | do_write = 1; 119 | break; 120 | default: 121 | fprintf(stderr, "usage: %s [options]\n", *argv); 122 | fprintf(stderr, "\t-d[num] Work with default valuesfor 128 Byte " 123 | "EEPROM or for 256 Byte EEPROM if some [num] is given\n"); 124 | fprintf(stderr, "\t-w write\n"); 125 | fprintf(stderr, "\t-e erase\n"); 126 | fprintf(stderr, "\t-v verbose decoding\n"); 127 | fprintf(stderr, "\t-p Search for device with PID == number\n"); 128 | fprintf(stderr, "\t-v Search for device with VID == number\n"); 129 | fprintf(stderr, "\t-P 1) 152 | { 153 | int i = 1; 154 | fprintf(stderr, "%d FTDI devices found: Only Readout on EEPROM done. ",res); 155 | fprintf(stderr, "Use VID/PID/desc/serial to select device\n"); 156 | for (curdev = devlist; curdev != NULL; curdev= curdev->next, i++) 157 | { 158 | f = ftdi_usb_open_dev(ftdi, curdev->dev); 159 | if (f<0) 160 | { 161 | fprintf(stderr, "Unable to open device %d: (%s)", 162 | i, ftdi_get_error_string(ftdi)); 163 | continue; 164 | } 165 | fprintf(stderr, "Decoded values of device %d:\n", i); 166 | read_decode_eeprom(ftdi); 167 | ftdi_usb_close(ftdi); 168 | } 169 | ftdi_list_free(&devlist); 170 | retval = EXIT_SUCCESS; 171 | goto do_deinit; 172 | } 173 | else if (res == 1) 174 | { 175 | f = ftdi_usb_open_dev(ftdi, devlist[0].dev); 176 | if (f<0) 177 | { 178 | fprintf(stderr, "Unable to open device %d: (%s)", 179 | i, ftdi_get_error_string(ftdi)); 180 | } 181 | } 182 | else 183 | { 184 | fprintf(stderr, "No devices found\n"); 185 | f = 0; 186 | } 187 | ftdi_list_free(&devlist); 188 | } 189 | else 190 | { 191 | // Open device 192 | f = ftdi_usb_open_desc(ftdi, vid, pid, desc, serial); 193 | if (f < 0) 194 | { 195 | fprintf(stderr, "Device VID 0x%04x PID 0x%04x", vid, pid); 196 | if (desc) 197 | fprintf(stderr, " Desc %s", desc); 198 | if (serial) 199 | fprintf(stderr, " Serial %s", serial); 200 | fprintf(stderr, "\n"); 201 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", 202 | f, ftdi_get_error_string(ftdi)); 203 | 204 | retval = -1; 205 | goto done; 206 | } 207 | } 208 | if (erase) 209 | { 210 | f = ftdi_erase_eeprom(ftdi); /* needed to determine EEPROM chip type */ 211 | if (f < 0) 212 | { 213 | fprintf(stderr, "Erase failed: %s", 214 | ftdi_get_error_string(ftdi)); 215 | retval = -2; 216 | goto done; 217 | } 218 | if (ftdi_get_eeprom_value(ftdi, CHIP_TYPE, & value) <0) 219 | { 220 | fprintf(stderr, "ftdi_get_eeprom_value: %d (%s)\n", 221 | f, ftdi_get_error_string(ftdi)); 222 | } 223 | if (value == -1) 224 | fprintf(stderr, "No EEPROM\n"); 225 | else if (value == 0) 226 | fprintf(stderr, "Internal EEPROM\n"); 227 | else 228 | fprintf(stderr, "Found 93x%02x\n", value); 229 | retval = 0; 230 | goto done; 231 | } 232 | 233 | if (use_defaults) 234 | { 235 | ftdi_eeprom_initdefaults(ftdi, NULL, NULL, NULL); 236 | if (ftdi_set_eeprom_value(ftdi, MAX_POWER, 500) <0) 237 | { 238 | fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n", 239 | f, ftdi_get_error_string(ftdi)); 240 | } 241 | if (large_chip) 242 | if (ftdi_set_eeprom_value(ftdi, CHIP_TYPE, 0x66) <0) 243 | { 244 | fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n", 245 | f, ftdi_get_error_string(ftdi)); 246 | } 247 | f=(ftdi_eeprom_build(ftdi)); 248 | if (f < 0) 249 | { 250 | fprintf(stderr, "ftdi_eeprom_build: %d (%s)\n", 251 | f, ftdi_get_error_string(ftdi)); 252 | retval = -1; 253 | goto done; 254 | } 255 | } 256 | else if (do_write) 257 | { 258 | ftdi_eeprom_initdefaults(ftdi, NULL, NULL, NULL); 259 | f = ftdi_erase_eeprom(ftdi); 260 | if (ftdi_set_eeprom_value(ftdi, MAX_POWER, 500) <0) 261 | { 262 | fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n", 263 | f, ftdi_get_error_string(ftdi)); 264 | } 265 | f = ftdi_erase_eeprom(ftdi);/* needed to determine EEPROM chip type */ 266 | if (ftdi_get_eeprom_value(ftdi, CHIP_TYPE, & value) <0) 267 | { 268 | fprintf(stderr, "ftdi_get_eeprom_value: %d (%s)\n", 269 | f, ftdi_get_error_string(ftdi)); 270 | } 271 | if (value == -1) 272 | fprintf(stderr, "No EEPROM\n"); 273 | else if (value == 0) 274 | fprintf(stderr, "Internal EEPROM\n"); 275 | else 276 | fprintf(stderr, "Found 93x%02x\n", value); 277 | f=(ftdi_eeprom_build(ftdi)); 278 | if (f < 0) 279 | { 280 | fprintf(stderr, "Erase failed: %s", 281 | ftdi_get_error_string(ftdi)); 282 | retval = -2; 283 | goto done; 284 | } 285 | f = ftdi_write_eeprom(ftdi); 286 | { 287 | fprintf(stderr, "ftdi_eeprom_decode: %d (%s)\n", 288 | f, ftdi_get_error_string(ftdi)); 289 | retval = 1; 290 | goto done; 291 | } 292 | } 293 | retval = read_decode_eeprom(ftdi); 294 | done: 295 | ftdi_usb_close(ftdi); 296 | do_deinit: 297 | ftdi_free(ftdi); 298 | return retval; 299 | } 300 | -------------------------------------------------------------------------------- /examples/find_all.c: -------------------------------------------------------------------------------- 1 | /* find_all.c 2 | 3 | Example for ftdi_usb_find_all() 4 | 5 | This program is distributed under the GPL, version 2 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | int ret, i; 15 | struct ftdi_context *ftdi; 16 | struct ftdi_device_list *devlist, *curdev; 17 | char manufacturer[128], description[128]; 18 | int retval = EXIT_SUCCESS; 19 | 20 | if ((ftdi = ftdi_new()) == 0) 21 | { 22 | fprintf(stderr, "ftdi_new failed\n"); 23 | return EXIT_FAILURE; 24 | } 25 | 26 | if ((ret = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0) 27 | { 28 | fprintf(stderr, "ftdi_usb_find_all failed: %d (%s)\n", ret, ftdi_get_error_string(ftdi)); 29 | retval = EXIT_FAILURE; 30 | goto do_deinit; 31 | } 32 | 33 | printf("Number of FTDI devices found: %d\n", ret); 34 | 35 | i = 0; 36 | for (curdev = devlist; curdev != NULL; i++) 37 | { 38 | printf("Checking device: %d\n", i); 39 | if ((ret = ftdi_usb_get_strings(ftdi, curdev->dev, manufacturer, 128, description, 128, NULL, 0)) < 0) 40 | { 41 | fprintf(stderr, "ftdi_usb_get_strings failed: %d (%s)\n", ret, ftdi_get_error_string(ftdi)); 42 | retval = EXIT_FAILURE; 43 | goto done; 44 | } 45 | printf("Manufacturer: %s, Description: %s\n\n", manufacturer, description); 46 | curdev = curdev->next; 47 | } 48 | done: 49 | ftdi_list_free(&devlist); 50 | do_deinit: 51 | ftdi_free(ftdi); 52 | 53 | return retval; 54 | } 55 | -------------------------------------------------------------------------------- /examples/find_all_pp.cpp: -------------------------------------------------------------------------------- 1 | /* final_all_pp.cpp 2 | 3 | Simple libftdi-cpp usage 4 | 5 | This program is distributed under the GPL, version 2 6 | */ 7 | 8 | #include "ftdi.hpp" 9 | #include 10 | #include 11 | #include 12 | #include 13 | using namespace Ftdi; 14 | 15 | int main(int argc, char **argv) 16 | { 17 | // Show help 18 | if (argc > 1) 19 | { 20 | if (strcmp(argv[1],"-h") == 0 || strcmp(argv[1],"--help") == 0) 21 | { 22 | std::cout << "Usage: " << argv[0] << " [-v VENDOR_ID] [-p PRODUCT_ID]" << std::endl; 23 | return EXIT_SUCCESS; 24 | } 25 | } 26 | 27 | // Parse args 28 | int vid = 0x0403, pid = 0x6010, tmp = 0; 29 | for (int i = 0; i < (argc - 1); i++) 30 | { 31 | if (strcmp(argv[i], "-v") == 0) 32 | if ((tmp = strtol(argv[++i], 0, 16)) >= 0) 33 | vid = tmp; 34 | 35 | if (strcmp(argv[i], "-p") == 0) 36 | if ((tmp = strtol(argv[++i], 0, 16)) >= 0) 37 | pid = tmp; 38 | } 39 | 40 | // Print header 41 | std::cout << std::hex << std::showbase 42 | << "Found devices ( VID: " << vid << ", PID: " << pid << " )" 43 | << std::endl 44 | << "------------------------------------------------" 45 | << std::endl << std::dec; 46 | 47 | // Print whole list 48 | Context context; 49 | List* list = List::find_all(context, vid, pid); 50 | for (List::iterator it = list->begin(); it != list->end(); it++) 51 | { 52 | std::cout << "FTDI (" << &*it << "): " 53 | << it->vendor() << ", " 54 | << it->description() << ", " 55 | << it->serial(); 56 | 57 | // Open test 58 | if(it->open() == 0) 59 | std::cout << " (Open OK)"; 60 | else 61 | std::cout << " (Open FAILED)"; 62 | 63 | it->close(); 64 | 65 | std::cout << std::endl; 66 | 67 | } 68 | 69 | delete list; 70 | 71 | return EXIT_SUCCESS; 72 | } 73 | -------------------------------------------------------------------------------- /examples/serial_test.c: -------------------------------------------------------------------------------- 1 | /* serial_test.c 2 | 3 | Read/write data via serial I/O 4 | 5 | This program is distributed under the GPL, version 2 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | static int exitRequested = 0; 16 | /* 17 | * sigintHandler -- 18 | * 19 | * SIGINT handler, so we can gracefully exit when the user hits ctrl-C. 20 | */ 21 | static void 22 | sigintHandler(int signum) 23 | { 24 | exitRequested = 1; 25 | } 26 | 27 | int main(int argc, char **argv) 28 | { 29 | struct ftdi_context *ftdi; 30 | unsigned char buf[1024]; 31 | int f = 0, i; 32 | int vid = 0x403; 33 | int pid = 0; 34 | int baudrate = 115200; 35 | int interface = INTERFACE_ANY; 36 | int do_write = 0; 37 | unsigned int pattern = 0xffff; 38 | int retval = EXIT_FAILURE; 39 | 40 | while ((i = getopt(argc, argv, "i:v:p:b:w::")) != -1) 41 | { 42 | switch (i) 43 | { 44 | case 'i': // 0=ANY, 1=A, 2=B, 3=C, 4=D 45 | interface = strtoul(optarg, NULL, 0); 46 | break; 47 | case 'v': 48 | vid = strtoul(optarg, NULL, 0); 49 | break; 50 | case 'p': 51 | pid = strtoul(optarg, NULL, 0); 52 | break; 53 | case 'b': 54 | baudrate = strtoul(optarg, NULL, 0); 55 | break; 56 | case 'w': 57 | do_write = 1; 58 | if (optarg) 59 | pattern = strtoul(optarg, NULL, 0); 60 | if (pattern > 0xff) 61 | { 62 | fprintf(stderr, "Please provide a 8 bit pattern\n"); 63 | exit(-1); 64 | } 65 | break; 66 | default: 67 | fprintf(stderr, "usage: %s [-i interface] [-v vid] [-p pid] [-b baudrate] [-w [pattern]]\n", *argv); 68 | exit(-1); 69 | } 70 | } 71 | 72 | // Init 73 | if ((ftdi = ftdi_new()) == 0) 74 | { 75 | fprintf(stderr, "ftdi_new failed\n"); 76 | return EXIT_FAILURE; 77 | } 78 | 79 | if (!vid && !pid && (interface == INTERFACE_ANY)) 80 | { 81 | ftdi_set_interface(ftdi, INTERFACE_ANY); 82 | struct ftdi_device_list *devlist; 83 | int res; 84 | if ((res = ftdi_usb_find_all(ftdi, &devlist, 0, 0)) < 0) 85 | { 86 | fprintf(stderr, "No FTDI with default VID/PID found\n"); 87 | goto do_deinit; 88 | } 89 | if (res == 1) 90 | { 91 | f = ftdi_usb_open_dev(ftdi, devlist[0].dev); 92 | if (f<0) 93 | { 94 | fprintf(stderr, "Unable to open device %d: (%s)", 95 | i, ftdi_get_error_string(ftdi)); 96 | } 97 | } 98 | ftdi_list_free(&devlist); 99 | if (res > 1) 100 | { 101 | fprintf(stderr, "%d Devices found, please select Device with VID/PID\n", res); 102 | /* TODO: List Devices*/ 103 | goto do_deinit; 104 | } 105 | if (res == 0) 106 | { 107 | fprintf(stderr, "No Devices found with default VID/PID\n"); 108 | goto do_deinit; 109 | } 110 | } 111 | else 112 | { 113 | // Select interface 114 | ftdi_set_interface(ftdi, interface); 115 | 116 | // Open device 117 | f = ftdi_usb_open(ftdi, vid, pid); 118 | } 119 | if (f < 0) 120 | { 121 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 122 | exit(-1); 123 | } 124 | 125 | // Set baudrate 126 | f = ftdi_set_baudrate(ftdi, baudrate); 127 | if (f < 0) 128 | { 129 | fprintf(stderr, "unable to set baudrate: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 130 | exit(-1); 131 | } 132 | 133 | /* Set line parameters 134 | * 135 | * TODO: Make these parameters settable from the command line 136 | * 137 | * Parameters are choosen that sending a continous stream of 0x55 138 | * should give a square wave 139 | * 140 | */ 141 | f = ftdi_set_line_property(ftdi, 8, STOP_BIT_1, NONE); 142 | if (f < 0) 143 | { 144 | fprintf(stderr, "unable to set line parameters: %d (%s)\n", f, ftdi_get_error_string(ftdi)); 145 | exit(-1); 146 | } 147 | 148 | if (do_write) 149 | for(i=0; i<1024; i++) 150 | buf[i] = pattern; 151 | 152 | signal(SIGINT, sigintHandler); 153 | while (!exitRequested) 154 | { 155 | if (do_write) 156 | f = ftdi_write_data(ftdi, buf, 157 | (baudrate/512 >sizeof(buf))?sizeof(buf): 158 | (baudrate/512)?baudrate/512:1); 159 | else 160 | f = ftdi_read_data(ftdi, buf, sizeof(buf)); 161 | if (f<0) 162 | usleep(1 * 1000000); 163 | else if(f> 0 && !do_write) 164 | { 165 | fprintf(stderr, "read %d bytes\n", f); 166 | fwrite(buf, f, 1, stdout); 167 | fflush(stderr); 168 | fflush(stdout); 169 | } 170 | } 171 | signal(SIGINT, SIG_DFL); 172 | retval = EXIT_SUCCESS; 173 | 174 | ftdi_usb_close(ftdi); 175 | do_deinit: 176 | ftdi_free(ftdi); 177 | 178 | return retval; 179 | } 180 | -------------------------------------------------------------------------------- /examples/simple.c: -------------------------------------------------------------------------------- 1 | /* simple.c 2 | 3 | Simple libftdi usage example 4 | 5 | This program is distributed under the GPL, version 2 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | int ret; 15 | struct ftdi_context *ftdi; 16 | struct ftdi_version_info version; 17 | if ((ftdi = ftdi_new()) == 0) 18 | { 19 | fprintf(stderr, "ftdi_new failed\n"); 20 | return EXIT_FAILURE; 21 | } 22 | 23 | version = ftdi_get_library_version(); 24 | printf("Initialized libftdi %s (major: %d, minor: %d, micro: %d, snapshot ver: %s)\n", 25 | version.version_str, version.major, version.minor, version.micro, 26 | version.snapshot_str); 27 | 28 | if ((ret = ftdi_usb_open(ftdi, 0x0403, 0x6001)) < 0) 29 | { 30 | fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi)); 31 | ftdi_free(ftdi); 32 | return EXIT_FAILURE; 33 | } 34 | 35 | // Read out FTDIChip-ID of R type chips 36 | if (ftdi->type == TYPE_R) 37 | { 38 | unsigned int chipid; 39 | printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(ftdi, &chipid)); 40 | printf("FTDI chipid: %X\n", chipid); 41 | } 42 | 43 | if ((ret = ftdi_usb_close(ftdi)) < 0) 44 | { 45 | fprintf(stderr, "unable to close ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi)); 46 | ftdi_free(ftdi); 47 | return EXIT_FAILURE; 48 | } 49 | 50 | ftdi_free(ftdi); 51 | 52 | return EXIT_SUCCESS; 53 | } 54 | -------------------------------------------------------------------------------- /examples/stream_test.c: -------------------------------------------------------------------------------- 1 | /* stream_test.c 2 | * 3 | * Test reading from FT2232H in synchronous FIFO mode. 4 | * 5 | * The FT2232H must supply data due to an appropriate circuit 6 | * 7 | * To check for skipped block with appended code, 8 | * a structure as follows is assumed 9 | * 1* uint32_t num (incremented in 0x4000 steps) 10 | * 3* uint32_t dont_care 11 | * 12 | * After start, data will be read in streaming until the program is aborted 13 | * Progess information wil be printed out 14 | * If a filename is given on the command line, the data read will be 15 | * written to that file 16 | * 17 | */ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | void check_outfile(char *); 28 | 29 | static FILE *outputFile; 30 | 31 | static int check = 1; 32 | static int exitRequested = 0; 33 | /* 34 | * sigintHandler -- 35 | * 36 | * SIGINT handler, so we can gracefully exit when the user hits ctrl-C. 37 | */ 38 | 39 | static void 40 | sigintHandler(int signum) 41 | { 42 | exitRequested = 1; 43 | } 44 | 45 | static void 46 | usage(const char *argv0) 47 | { 48 | fprintf(stderr, 49 | "Usage: %s [options...] \n" 50 | "Test streaming read from FT2232H\n" 51 | "[-P string] only look for product with given string\n" 52 | "[-n] don't check for special block structure\n" 53 | "\n" 54 | "If some filename is given, write data read to that file\n" 55 | "Progess information is printed each second\n" 56 | "Abort with ^C\n" 57 | "\n" 58 | "Options:\n" 59 | "\n" 60 | "Copyright (C) 2009 Micah Dowty \n" 61 | "Adapted for use with libftdi (C) 2010 Uwe Bonnes \n", 62 | argv0); 63 | exit(1); 64 | } 65 | 66 | static uint32_t start = 0; 67 | static uint32_t offset = 0; 68 | static uint64_t blocks = 0; 69 | static uint32_t skips = 0; 70 | static uint32_t n_err = 0; 71 | static int 72 | readCallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata) 73 | { 74 | if (length) 75 | { 76 | if (check) 77 | { 78 | int i,rem; 79 | uint32_t num; 80 | for (i= offset; i3) 96 | { 97 | num = *(uint32_t*) (buffer+i); 98 | if (start && (num != start +0x4000)) 99 | { 100 | uint32_t delta = ((num-start)/0x4000)-1; 101 | fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu\n", 102 | delta, start -0x4000, num, (unsigned long long) blocks); 103 | n_err++; 104 | skips += delta; 105 | } 106 | start = num; 107 | } 108 | else if (rem) 109 | start += 0x4000; 110 | if (rem != 0) 111 | { 112 | blocks ++; 113 | offset = 16-rem; 114 | } 115 | } 116 | if (outputFile) 117 | { 118 | if (fwrite(buffer, length, 1, outputFile) != 1) 119 | { 120 | perror("Write error"); 121 | return 1; 122 | } 123 | } 124 | } 125 | if (progress) 126 | { 127 | fprintf(stderr, "%10.02fs total time %9.3f MiB captured %7.1f kB/s curr rate %7.1f kB/s totalrate %d dropouts\n", 128 | progress->totalTime, 129 | progress->current.totalBytes / (1024.0 * 1024.0), 130 | progress->currentRate / 1024.0, 131 | progress->totalRate / 1024.0, 132 | n_err); 133 | } 134 | return exitRequested ? 1 : 0; 135 | } 136 | 137 | int main(int argc, char **argv) 138 | { 139 | struct ftdi_context *ftdi; 140 | int err, c; 141 | FILE *of = NULL; 142 | char const *outfile = 0; 143 | outputFile =0; 144 | exitRequested = 0; 145 | char *descstring = NULL; 146 | int option_index; 147 | static struct option long_options[] = {{NULL},}; 148 | 149 | while ((c = getopt_long(argc, argv, "P:n", long_options, &option_index)) !=- 1) 150 | switch (c) 151 | { 152 | case -1: 153 | break; 154 | case 'P': 155 | descstring = optarg; 156 | break; 157 | case 'n': 158 | check = 0; 159 | break; 160 | default: 161 | usage(argv[0]); 162 | } 163 | 164 | if (optind == argc - 1) 165 | { 166 | // Exactly one extra argument- a dump file 167 | outfile = argv[optind]; 168 | } 169 | else if (optind < argc) 170 | { 171 | // Too many extra args 172 | usage(argv[0]); 173 | } 174 | 175 | if ((ftdi = ftdi_new()) == 0) 176 | { 177 | fprintf(stderr, "ftdi_new failed\n"); 178 | return EXIT_FAILURE; 179 | } 180 | 181 | if (ftdi_set_interface(ftdi, INTERFACE_A) < 0) 182 | { 183 | fprintf(stderr, "ftdi_set_interface failed\n"); 184 | ftdi_free(ftdi); 185 | return EXIT_FAILURE; 186 | } 187 | 188 | if (ftdi_usb_open_desc(ftdi, 0x0403, 0x6010, descstring, NULL) < 0) 189 | { 190 | fprintf(stderr,"Can't open ftdi device: %s\n",ftdi_get_error_string(ftdi)); 191 | ftdi_free(ftdi); 192 | return EXIT_FAILURE; 193 | } 194 | 195 | /* A timeout value of 1 results in may skipped blocks */ 196 | if(ftdi_set_latency_timer(ftdi, 2)) 197 | { 198 | fprintf(stderr,"Can't set latency, Error %s\n",ftdi_get_error_string(ftdi)); 199 | ftdi_usb_close(ftdi); 200 | ftdi_free(ftdi); 201 | return EXIT_FAILURE; 202 | } 203 | 204 | /* if(ftdi_usb_purge_rx_buffer(ftdi) < 0) 205 | { 206 | fprintf(stderr,"Can't rx purge\n",ftdi_get_error_string(ftdi)); 207 | return EXIT_FAILURE; 208 | }*/ 209 | if (outfile) 210 | if ((of = fopen(outfile,"w+")) == 0) 211 | fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno)); 212 | if (of) 213 | if (setvbuf(of, NULL, _IOFBF , 1<<16) == 0) 214 | outputFile = of; 215 | signal(SIGINT, sigintHandler); 216 | 217 | err = ftdi_readstream(ftdi, readCallback, NULL, 8, 256); 218 | if (err < 0 && !exitRequested) 219 | exit(1); 220 | 221 | if (outputFile) { 222 | fclose(outputFile); 223 | outputFile = NULL; 224 | } 225 | fprintf(stderr, "Capture ended.\n"); 226 | 227 | if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET) < 0) 228 | { 229 | fprintf(stderr,"Can't set synchronous fifo mode, Error %s\n",ftdi_get_error_string(ftdi)); 230 | ftdi_usb_close(ftdi); 231 | ftdi_free(ftdi); 232 | return EXIT_FAILURE; 233 | } 234 | ftdi_usb_close(ftdi); 235 | ftdi_free(ftdi); 236 | signal(SIGINT, SIG_DFL); 237 | if (check && outfile) 238 | { 239 | if ((outputFile = fopen(outfile,"r")) == 0) 240 | { 241 | fprintf(stderr,"Can't open logfile %s, Error %s\n", outfile, strerror(errno)); 242 | ftdi_usb_close(ftdi); 243 | ftdi_free(ftdi); 244 | return EXIT_FAILURE; 245 | } 246 | check_outfile(descstring); 247 | fclose(outputFile); 248 | } 249 | else if (check) 250 | fprintf(stderr,"%d errors of %llu blocks (%Le), %d (%Le) blocks skipped\n", 251 | n_err, (unsigned long long) blocks, (long double)n_err/(long double) blocks, 252 | skips, (long double)skips/(long double) blocks); 253 | exit (0); 254 | } 255 | 256 | void check_outfile(char *descstring) 257 | { 258 | if(strcmp(descstring,"FT2232HTEST") == 0) 259 | { 260 | char buf0[1024]; 261 | char buf1[1024]; 262 | char bufr[1024]; 263 | char *pa, *pb, *pc; 264 | unsigned int num_lines = 0, line_num = 1; 265 | int err_count = 0; 266 | unsigned int num_start, num_end; 267 | 268 | pa = buf0; 269 | pb = buf1; 270 | pc = buf0; 271 | if(fgets(pa, 1023, outputFile) == NULL) 272 | { 273 | fprintf(stderr,"Empty output file\n"); 274 | return; 275 | } 276 | while(fgets(pb, 1023, outputFile) != NULL) 277 | { 278 | num_lines++; 279 | unsigned int num_save = num_start; 280 | if( sscanf(pa,"%6u%94s%6u",&num_start, bufr,&num_end) !=3) 281 | { 282 | fprintf(stdout,"Format doesn't match at line %8d \"%s", 283 | num_lines, pa); 284 | err_count++; 285 | line_num = num_save +2; 286 | } 287 | else 288 | { 289 | if ((num_start+1)%100000 != num_end) 290 | { 291 | if (err_count < 20) 292 | fprintf(stdout,"Malformed line %d \"%s\"\n", 293 | num_lines, pa); 294 | err_count++; 295 | } 296 | else if(num_start != line_num) 297 | { 298 | if (err_count < 20) 299 | fprintf(stdout,"Skipping from %d to %d\n", 300 | line_num, num_start); 301 | err_count++; 302 | 303 | } 304 | line_num = num_end; 305 | } 306 | pa = pb; 307 | pb = pc; 308 | pc = pa; 309 | } 310 | if(err_count) 311 | fprintf(stdout,"\n%d errors of %d data sets %f\n", err_count, num_lines, (double) err_count/(double)num_lines); 312 | else 313 | fprintf(stdout,"No errors for %d lines\n",num_lines); 314 | } 315 | else if(strcmp(descstring,"LLBBC10") == 0) 316 | { 317 | uint32_t block0[4]; 318 | uint32_t block1[4]; 319 | uint32_t *pa = block0; 320 | uint32_t *pb = block1; 321 | uint32_t *pc = block0; 322 | uint32_t start= 0; 323 | uint32_t nread = 0; 324 | int n_shown = 0; 325 | int n_errors = 0; 326 | if (fread(pa, sizeof(uint32_t), 4,outputFile) < 4) 327 | { 328 | fprintf(stderr,"Empty result file\n"); 329 | return; 330 | } 331 | while(fread(pb, sizeof(uint32_t), 4,outputFile) != 0) 332 | { 333 | blocks++; 334 | nread = pa[0]; 335 | if(start>0 && (nread != start)) 336 | { 337 | if(n_shown < 30) 338 | { 339 | fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at blocks %10llu \n", 340 | (nread-start)/0x4000, start -0x4000, nread, (unsigned long long) blocks); 341 | n_shown ++; 342 | } 343 | n_errors++; 344 | } 345 | else if (n_shown >0) 346 | n_shown--; 347 | start = nread + 0x4000; 348 | pa = pb; 349 | pb = pc; 350 | pc = pa; 351 | } 352 | if(n_errors) 353 | fprintf(stderr, "%d blocks wrong from %llu blocks read\n", 354 | n_errors, (unsigned long long) blocks); 355 | else 356 | fprintf(stderr, "%llu blocks all fine\n", (unsigned long long) blocks); 357 | } 358 | } 359 | -------------------------------------------------------------------------------- /ftdi_eeprom/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package ( Confuse REQUIRED ) 2 | find_package ( Libintl ) 3 | 4 | # determine docdir 5 | include(GNUInstallDirs) 6 | if(NOT CMAKE_INSTALL_DOCDIR) 7 | if(WIN32) 8 | set(CMAKE_INSTALL_DOCDIR .) 9 | else(WIN32) 10 | set(CMAKE_INSTALL_DOCDIR ${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}) 11 | endif(WIN32) 12 | endif(NOT CMAKE_INSTALL_DOCDIR) 13 | 14 | message(STATUS "Building ftdi_eeprom") 15 | 16 | include_directories ( ${CONFUSE_INCLUDE_DIRS} ) 17 | list ( APPEND libs ${CONFUSE_LIBRARIES} ) 18 | 19 | if ( LIBINTL_FOUND ) 20 | include_directories ( ${LIBINTL_INCLUDE_DIR} ) 21 | list ( APPEND libs ${LIBINTL_LIBRARIES} ) 22 | endif () 23 | 24 | 25 | # Version defines 26 | set ( EEPROM_MAJOR_VERSION 0 ) 27 | set ( EEPROM_MINOR_VERSION 17 ) 28 | set ( EEPROM_VERSION_STRING ${EEPROM_MAJOR_VERSION}.${EEPROM_MINOR_VERSION} ) 29 | 30 | include_directories ( BEFORE ${CMAKE_SOURCE_DIR}/src ) 31 | include_directories ( BEFORE ${CMAKE_CURRENT_BINARY_DIR} ) 32 | 33 | configure_file( 34 | ftdi_eeprom_version.h.in 35 | ${CMAKE_CURRENT_BINARY_DIR}/ftdi_eeprom_version.h 36 | ) 37 | 38 | add_executable ( ftdi_eeprom main.c ) 39 | target_link_libraries ( ftdi_eeprom ftdi1 ${CONFUSE_LIBRARIES} ) 40 | if ( LIBINTL_FOUND ) 41 | target_link_libraries ( ftdi_eeprom ${LIBINTL_LIBRARIES} ) 42 | endif () 43 | install ( TARGETS ftdi_eeprom DESTINATION bin ) 44 | install ( FILES example.conf DESTINATION ${CMAKE_INSTALL_DOCDIR} ) 45 | -------------------------------------------------------------------------------- /ftdi_eeprom/example.conf: -------------------------------------------------------------------------------- 1 | vendor_id=0x0403 # Vendor ID 2 | product_id=0x6001 # Product ID 3 | 4 | max_power=0 # Max. power consumption: value * 2 mA. Use 0 if self_powered = true. 5 | 6 | ########### 7 | # Strings # 8 | ########### 9 | manufacturer="ACME Inc" # Manufacturer 10 | product="USB Serial Converter" # Product 11 | serial="08-15" # Serial 12 | 13 | ########### 14 | # Options # 15 | ########### 16 | self_powered=true # Turn this off for bus powered 17 | remote_wakeup=false # Turn this on for remote wakeup feature 18 | use_serial=true # Use the serial number string 19 | 20 | # Normally out don't have to change one of these flags 21 | in_is_isochronous=false # In Endpoint is Isochronous 22 | out_is_isochronous=false # Out Endpoint is Isochronous 23 | suspend_pull_downs=false # Enable suspend pull downs for lower power 24 | change_usb_version=false # Change USB Version 25 | usb_version=0x0200 # Only used when change_usb_version is enabled 26 | 27 | # Only used on FT-R chips (when omitted, use chip defaults) 28 | # Possible values correspond to enum ftdi_cbus_func. 29 | cbus0=TXLED 30 | cbus1=RXLED 31 | cbus2=TXDEN 32 | cbus3=PWREN 33 | cbus4=SLEEP 34 | 35 | # Only used on FT232H chips (when omitted, use chip defaults) 36 | # Possible values correspond to enum ftdi_cbush_func. 37 | cbush0=TRISTATE 38 | cbush1=TRISTATE 39 | cbush2=TRISTATE 40 | cbush3=TRISTATE 41 | cbush4=TRISTATE 42 | cbush5=TRISTATE 43 | cbush6=TRISTATE 44 | cbush7=TRISTATE 45 | cbush8=TRISTATE 46 | cbush9=TRISTATE 47 | 48 | # Only used on FT230X chips (when omitted, use chip defaults) 49 | # Possible values correspond to enum ftdi_cbusx_func. 50 | cbusx0=TXDEN 51 | cbusx1=RXLED 52 | cbusx2=TXLED 53 | cbusx3=SLEEP 54 | 55 | ######## 56 | # Misc # 57 | ######## 58 | 59 | filename="eeprom.new" # Filename, leave empty to skip file writing 60 | -------------------------------------------------------------------------------- /ftdi_eeprom/ftdi_eeprom_version.h.in: -------------------------------------------------------------------------------- 1 | #ifndef _FTDI_EEPROM_VERSION_H 2 | #define _FTDI_EEPROM_VERSION_H 3 | 4 | #define EEPROM_MAJOR_VERSION @EEPROM_MAJOR_VERSION@ 5 | #define EEPROM_MINOR_VERSION @EEPROM_MINOR_VERSION@ 6 | #define EEPROM_VERSION_STRING "@EEPROM_VERSION_STRING@" 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /ftdipp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # vim: ts=2:sw=2:sts=2 2 | 3 | # Targets 4 | set(cpp_sources ${CMAKE_CURRENT_SOURCE_DIR}/ftdi.cpp CACHE INTERNAL "List of cpp sources" ) 5 | set(cpp_headers ${CMAKE_CURRENT_SOURCE_DIR}/ftdi.hpp CACHE INTERNAL "List of cpp headers" ) 6 | 7 | # Includes 8 | include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} 9 | ${CMAKE_CURRENT_SOURCE_DIR} 10 | ${CMAKE_SOURCE_DIR}/src) 11 | 12 | include_directories(${Boost_INCLUDE_DIRS}) 13 | 14 | # Shared library 15 | add_library(ftdipp1 SHARED ${cpp_sources}) 16 | 17 | math(EXPR VERSION_FIXUP "${MAJOR_VERSION} + 1") # Compatiblity with previous releases 18 | set_target_properties(ftdipp1 PROPERTIES VERSION ${VERSION_FIXUP}.${MINOR_VERSION}.0 SOVERSION 3) 19 | 20 | # Prevent clobbering each other during the build 21 | set_target_properties(ftdipp1 PROPERTIES CLEAN_DIRECT_OUTPUT 1) 22 | 23 | # Dependencies 24 | target_link_libraries(ftdipp1 ftdi1 ${LIBUSB_LIBRARIES} ${BOOST_LIBRARIES}) 25 | 26 | install ( TARGETS ftdipp1 27 | RUNTIME DESTINATION bin 28 | LIBRARY DESTINATION lib${LIB_SUFFIX} 29 | ARCHIVE DESTINATION lib${LIB_SUFFIX} 30 | ) 31 | 32 | # Static library 33 | if ( STATICLIBS ) 34 | add_library(ftdipp1-static STATIC ${cpp_sources}) 35 | set_target_properties(ftdipp1-static PROPERTIES OUTPUT_NAME "ftdipp1") 36 | set_target_properties(ftdipp1-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) 37 | 38 | install ( TARGETS ftdipp1-static 39 | ARCHIVE DESTINATION lib${LIB_SUFFIX} 40 | COMPONENT staticlibs 41 | ) 42 | endif () 43 | 44 | install ( FILES ${cpp_headers} 45 | DESTINATION include/${PROJECT_NAME} 46 | COMPONENT headers 47 | ) 48 | -------------------------------------------------------------------------------- /ftdipp/ftdi.hpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | ftdi.hpp - C++ wrapper for libftdi 3 | ------------------- 4 | begin : Mon Oct 13 2008 5 | copyright : (C) 2008-2017 by Marek Vavruša and libftdi developers 6 | email : opensource@intra2net.com and marek@vavrusa.com 7 | ***************************************************************************/ 8 | /* 9 | Copyright (C) 2008-2017 by Marek Vavruša and libftdi developers 10 | 11 | The software in this package is distributed under the GNU General 12 | Public License version 2 (with a special exception described below). 13 | 14 | A copy of GNU General Public License (GPL) is included in this distribution, 15 | in the file COPYING.GPL. 16 | 17 | As a special exception, if other files instantiate templates or use macros 18 | or inline functions from this file, or you compile this file and link it 19 | with other works to produce a work based on this file, this file 20 | does not by itself cause the resulting work to be covered 21 | by the GNU General Public License. 22 | 23 | However the source code for this file must still be made available 24 | in accordance with section (3) of the GNU General Public License. 25 | 26 | This exception does not invalidate any other reasons why a work based 27 | on this file might be covered by the GNU General Public License. 28 | */ 29 | #ifndef __libftdi_hpp__ 30 | #define __libftdi_hpp__ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | namespace Ftdi 38 | { 39 | 40 | /* Forward declarations*/ 41 | class List; 42 | class Eeprom; 43 | 44 | /*! \brief FTDI device context. 45 | * Represents single FTDI device context. 46 | */ 47 | class Context 48 | { 49 | /* Friends */ 50 | friend class Eeprom; 51 | friend class List; 52 | 53 | public: 54 | /*! \brief Direction flags for flush(). 55 | */ 56 | enum Direction 57 | { 58 | Input = 0x2, 59 | Output = 0x1, 60 | }; 61 | 62 | /*! \brief Modem control flags. 63 | */ 64 | enum ModemCtl 65 | { 66 | Dtr = 0x2, 67 | Rts = 0x1, 68 | }; 69 | 70 | /* Constructor, Destructor */ 71 | Context(); 72 | ~Context(); 73 | 74 | /* Properties */ 75 | Eeprom* eeprom(); 76 | const std::string& vendor(); 77 | const std::string& description(); 78 | const std::string& serial(); 79 | 80 | /* Device manipulators */ 81 | bool is_open(); 82 | int open(struct libusb_device *dev = 0); 83 | int open(int vendor, int product); 84 | int open(int vendor, int product, const std::string& description, const std::string& serial = std::string(), unsigned int index=0); 85 | int open(const std::string& description); 86 | int close(); 87 | int reset(); 88 | int flush(int mask = Input|Output); 89 | int set_interface(enum ftdi_interface interface); 90 | void set_usb_device(struct libusb_device_handle *dev); 91 | 92 | /* Line manipulators */ 93 | int set_baud_rate(int baudrate); 94 | int set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity); 95 | int set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, enum ftdi_break_type break_type); 96 | int get_usb_read_timeout() const; 97 | void set_usb_read_timeout(int usb_read_timeout); 98 | int get_usb_write_timeout() const; 99 | void set_usb_write_timeout(int usb_write_timeout); 100 | 101 | /* I/O */ 102 | int read(unsigned char *buf, int size); 103 | int write(const unsigned char *buf, int size); 104 | int set_read_chunk_size(unsigned int chunksize); 105 | int set_write_chunk_size(unsigned int chunksize); 106 | int read_chunk_size(); 107 | int write_chunk_size(); 108 | 109 | /* Async IO 110 | TODO: should wrap? 111 | int writeAsync(const unsigned char *buf, int size); 112 | void asyncComplete(int wait_for_more); 113 | */ 114 | 115 | /* Flow control */ 116 | int set_event_char(unsigned char eventch, unsigned char enable); 117 | int set_error_char(unsigned char errorch, unsigned char enable); 118 | int set_flow_control(int flowctrl); 119 | int set_modem_control(int mask = Dtr|Rts); 120 | int set_latency(unsigned char latency); 121 | int set_dtr(bool state); 122 | int set_rts(bool state); 123 | 124 | unsigned short poll_modem_status(); 125 | unsigned latency(); 126 | 127 | /* BitBang mode */ 128 | int set_bitmode(unsigned char bitmask, unsigned char mode); 129 | int set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode); 130 | int bitbang_disable(); 131 | int read_pins(unsigned char *pins); 132 | 133 | /* Misc */ 134 | const char* error_string(); 135 | 136 | protected: 137 | int get_strings(bool vendor=true, bool description=true, bool serial=true); 138 | int get_strings_and_reopen(bool vendor=true, bool description=true, bool serial=true); 139 | 140 | /* Properties */ 141 | struct ftdi_context* context(); 142 | void set_context(struct ftdi_context* context); 143 | void set_usb_device(struct libusb_device *dev); 144 | 145 | private: 146 | class Private; 147 | boost::shared_ptr d; 148 | }; 149 | 150 | /*! \brief Device EEPROM. 151 | */ 152 | class Eeprom 153 | { 154 | public: 155 | Eeprom(Context* parent); 156 | ~Eeprom(); 157 | 158 | int init_defaults(char *manufacturer, char* product, char * serial); 159 | int chip_id(unsigned int *chipid); 160 | int build(unsigned char *output); 161 | 162 | int read(unsigned char *eeprom); 163 | int write(unsigned char *eeprom); 164 | int read_location(int eeprom_addr, unsigned short *eeprom_val); 165 | int write_location(int eeprom_addr, unsigned short eeprom_val); 166 | int erase(); 167 | 168 | private: 169 | class Private; 170 | boost::shared_ptr d; 171 | }; 172 | 173 | /*! \brief Device list. 174 | */ 175 | class List 176 | { 177 | public: 178 | List(struct ftdi_device_list* devlist = 0); 179 | ~List(); 180 | 181 | static List* find_all(Context &context, int vendor, int product); 182 | 183 | /// List type storing "Context" objects 184 | typedef std::list ListType; 185 | /// Iterator type for the container 186 | typedef ListType::iterator iterator; 187 | /// Const iterator type for the container 188 | typedef ListType::const_iterator const_iterator; 189 | /// Reverse iterator type for the container 190 | typedef ListType::reverse_iterator reverse_iterator; 191 | /// Const reverse iterator type for the container 192 | typedef ListType::const_reverse_iterator const_reverse_iterator; 193 | 194 | iterator begin(); 195 | iterator end(); 196 | const_iterator begin() const; 197 | const_iterator end() const; 198 | 199 | reverse_iterator rbegin(); 200 | reverse_iterator rend(); 201 | const_reverse_iterator rbegin() const; 202 | const_reverse_iterator rend() const; 203 | 204 | ListType::size_type size() const; 205 | bool empty() const; 206 | void clear(); 207 | 208 | void push_back(const Context& element); 209 | void push_front(const Context& element); 210 | 211 | iterator erase(iterator pos); 212 | iterator erase(iterator beg, iterator end); 213 | 214 | private: 215 | class Private; 216 | boost::shared_ptr d; 217 | }; 218 | 219 | } 220 | 221 | #endif 222 | -------------------------------------------------------------------------------- /libftdi-1.0.kdev4: -------------------------------------------------------------------------------- 1 | [Project] 2 | Manager=KDevCMakeManager 3 | Name=libftdi-1.0 4 | -------------------------------------------------------------------------------- /libftdi.lnt: -------------------------------------------------------------------------------- 1 | // PC-Lint 9.00 settings 2 | --iz:\usr\include\libusb-1.0 3 | --i../src 4 | --i../ftdipp 5 | 6 | -emacro(527, ftdi_error_return) // ignore "unreachable code" 7 | -emacro(717, ftdi_error_return) 8 | 9 | -epu // Pointer to unsigned/signed of the same type is ok 10 | 11 | +fie // Allow enum to int conversion 12 | 13 | -ecall(534, usb_close) // silence ignored return value from usb_close 14 | 15 | // Disable bogus BOOST warnings 16 | -emacro(58,BOOST_ASSERT) 17 | -emacro(506, BOOST_FOREACH) 18 | -emacro(666, BOOST_FOREACH) 19 | -esym(666, BOOST_FOREACH) 20 | -emacro(1023, BOOST_FOREACH) 21 | -emacro(1793, BOOST_FOREACH) 22 | -esym(665, BOOST_FOREACH) 23 | -e123 24 | 25 | // Don't complain we are running with -wlib(0) 26 | // as the boost headers can't be parsed properly 27 | -estring(686, -wlib(0)) 28 | -wlib(0) 29 | -------------------------------------------------------------------------------- /libftdi1-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | exec_prefix_set=no 6 | 7 | usage() 8 | { 9 | cat <&2 23 | fi 24 | 25 | while test $# -gt 0; do 26 | case "$1" in 27 | -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; 28 | *) optarg= ;; 29 | esac 30 | 31 | case $1 in 32 | --prefix=*) 33 | prefix=$optarg 34 | if test $exec_prefix_set = no ; then 35 | exec_prefix=$optarg 36 | fi 37 | ;; 38 | --prefix) 39 | echo_prefix=yes 40 | ;; 41 | --exec-prefix=*) 42 | exec_prefix=$optarg 43 | exec_prefix_set=yes 44 | ;; 45 | --exec-prefix) 46 | echo_exec_prefix=yes 47 | ;; 48 | --version) 49 | echo @VERSION@ 50 | exit 0 51 | ;; 52 | --cflags) 53 | if test "@includedir@" != /usr/include ; then 54 | includes="-I@includedir@" 55 | fi 56 | echo_cflags=yes 57 | ;; 58 | --libs) 59 | echo_libs=yes 60 | ;; 61 | *) 62 | usage 1 1>&2 63 | ;; 64 | esac 65 | shift 66 | done 67 | 68 | if test "$echo_prefix" = "yes"; then 69 | echo $prefix 70 | fi 71 | if test "$echo_exec_prefix" = "yes"; then 72 | echo $exec_prefix 73 | fi 74 | if test "$echo_cflags" = "yes"; then 75 | echo $includes 76 | fi 77 | if test "$echo_libs" = "yes"; then 78 | echo -L@libdir@ -lftdi1 @LIBS@ 79 | fi 80 | -------------------------------------------------------------------------------- /libftdi1.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libftdi1 7 | Description: Library to program and control the FTDI USB controller 8 | Requires: libusb-1.0 9 | Version: @VERSION@ 10 | Libs: -L${libdir} -lftdi1 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /libftdi1.spec.in: -------------------------------------------------------------------------------- 1 | %{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} 2 | 3 | Summary: Library to program and control the FTDI USB controller 4 | Name: libftdi1 5 | Version: @VERSION@ 6 | Release: 1 7 | License: LGPL for libftdi and GPLv2+linking exception for the C++ wrapper 8 | Group: System Environment/Libraries 9 | Vendor: Intra2net AG 10 | Source: https://www.intra2net.com/en/developer/libftdi/download/%{name}-%{version}.tar.bz2 11 | Buildroot: /tmp/%{name}-%{version}-root 12 | Requires: libusb1 13 | BuildRequires: libusb1, libusb1-devel, pkgconfig, doxygen 14 | BuildRequires: swig python-devel 15 | Prefix: /usr 16 | URL: https://www.intra2net.com/en/developer/libftdi 17 | 18 | %package devel 19 | Summary: Header files and static libraries for libftdi1 20 | Group: Development/Libraries 21 | Requires: libftdi1 = %{version}, libusb1-devel 22 | 23 | %package python 24 | Summary: Python bindings for libftdi 25 | License: LGPL 26 | Group: Development/Libraries 27 | Requires: %{name} = %{version}-%{release} 28 | 29 | %description 30 | Library to program and control the FTDI USB controller 31 | 32 | %description devel 33 | Header files and static libraries for libftdi1 34 | 35 | %description python 36 | Python bindings for libftdi1 generated by SWIG 37 | 38 | %prep 39 | %setup -q 40 | 41 | %build 42 | 43 | mkdir build 44 | cd build 45 | 46 | export CFLAGS="$RPM_OPT_FLAGS" 47 | export CXXFLAGS="$RPM_OPT_FLAGS" 48 | cmake -DCMAKE_INSTALL_PREFIX="%{prefix}" ../ 49 | 50 | make %{?_smp_mflags} 51 | 52 | %install 53 | cd build 54 | make DESTDIR=$RPM_BUILD_ROOT install 55 | 56 | # Remove example programs 57 | rm -f $RPM_BUILD_ROOT/usr/bin/simple 58 | rm -f $RPM_BUILD_ROOT/usr/bin/bitbang 59 | rm -f $RPM_BUILD_ROOT/usr/bin/bitbang2 60 | rm -f $RPM_BUILD_ROOT/usr/bin/bitbang_ft2232 61 | rm -f $RPM_BUILD_ROOT/usr/bin/bitbang_cbus 62 | rm -f $RPM_BUILD_ROOT/usr/bin/find_all 63 | rm -f $RPM_BUILD_ROOT/usr/bin/find_all_pp 64 | rm -f $RPM_BUILD_ROOT/usr/bin/serial_test 65 | rm -f $RPM_BUILD_ROOT/usr/bin/baud_test 66 | 67 | # Clean python compiled files in examples dir 68 | find $RPM_BUILD_ROOT%{prefix}/share/libftdi/examples -name "*.pyc" -or -name "*.pyo" -exec rm -f \{\} \; 69 | 70 | # move documentation to version specific directory 71 | # Is there an easy way in cmake to set the DOCDIR? 72 | mkdir -p $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{version} 73 | mv $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}/* $RPM_BUILD_ROOT%{prefix}/share/doc/%{name}-%{version} 74 | 75 | %clean 76 | rm -fr $RPM_BUILD_ROOT 77 | 78 | %files 79 | %defattr(-,root,root) 80 | %doc COPYING.LIB COPYING.GPL LICENSE 81 | %{_libdir}/libftdi1*.so* 82 | %{_libdir}/libftdipp1*.so* 83 | 84 | %files devel 85 | %defattr(-,root,root) 86 | %doc build/doc/html build/doc/man 87 | %{_bindir}/ftdi_eeprom 88 | %{_bindir}/libftdi1-config 89 | %{prefix}/include/libftdi1/*.h 90 | %{prefix}/include/libftdi1/*.hpp 91 | %{prefix}/share/libftdi/examples/* 92 | %{_libdir}/libftdi1*.*a 93 | %{_libdir}/libftdipp1*.*a 94 | %{_libdir}/pkgconfig/*.pc 95 | %{_libdir}/cmake/libftdi1/* 96 | 97 | %files python 98 | %defattr(-,root,root,-) 99 | %attr(755,root,root) %{python_sitearch}/_ftdi1.so 100 | %{python_sitearch}/ftdi1.py* 101 | -------------------------------------------------------------------------------- /libftdipp1.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libftdipp1 7 | Description: C++ wrapper for libftdi1 8 | Requires: libftdi1 9 | Version: @VERSION@ 10 | Libs: -L${libdir} -lftdipp1 11 | Cflags: -I${includedir} 12 | -------------------------------------------------------------------------------- /packages/99-libftdi.rules: -------------------------------------------------------------------------------- 1 | # FTDI Devices: FT232BM/L/Q, FT245BM/L/Q, FT232RL/Q, FT245RL/Q, VNC1L with VDPS Firmware 2 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0664", GROUP="plugdev" 3 | 4 | # FTDI Devices: FT2232C/D/L, FT2232HL/Q 5 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="0664", GROUP="plugdev" 6 | 7 | # FTDI Devices: FT4232HL/Q 8 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6011", MODE="0664", GROUP="plugdev" 9 | 10 | # FTDI Devices: FT232H 11 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="0664", GROUP="plugdev" 12 | 13 | # FTDI Devices: FT230X 14 | SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", MODE="0664", GROUP="plugdev" 15 | -------------------------------------------------------------------------------- /packages/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Debian 2 | if("${PACKAGE}" STREQUAL "Debian") 3 | 4 | # Settings 5 | set(REVISION 0) 6 | set(CPACK_GENERATOR "DEB" PARENT_SCOPE) 7 | set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}-${REVISION} PARENT_SCOPE) 8 | 9 | # Dependencies 10 | set(CPACK_DEBIAN_PACKAGE_DEPENDS "libusb-1.0-0" PARENT_SCOPE) 11 | set(DEBIAN_PACKAGE_BUILDS_DEPENDS "cmake, libusb2-dev" PARENT_SCOPE) 12 | 13 | # Bundles 14 | message("-- Installing udev rules to /etc/udev/rules.d") 15 | install(FILES 99-libftdi.rules 16 | DESTINATION /etc/udev/rules.d) 17 | 18 | endif("${PACKAGE}" STREQUAL "Debian") 19 | 20 | # General RPM rules 21 | set(CPACK_RPM_PACKAGE_DEPENDS "libusb1" PARENT_SCOPE) 22 | -------------------------------------------------------------------------------- /python/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # workaround for cmake bug #0013449 2 | if ( NOT DEFINED CMAKE_FIND_ROOT_PATH ) 3 | find_package ( SWIG REQUIRED ) 4 | else () 5 | find_program ( SWIG_EXECUTABLE NAMES swig2.0 swig ) 6 | if ( SWIG_EXECUTABLE ) 7 | set ( SWIG_USE_FILE ${CMAKE_ROOT}/Modules/UseSWIG.cmake ) 8 | set ( SWIG_FOUND TRUE ) 9 | endif () 10 | endif () 11 | find_package ( PythonLibs REQUIRED ) 12 | find_package ( PythonInterp REQUIRED ) 13 | 14 | include ( UseSWIG ) 15 | include_directories ( BEFORE ${CMAKE_SOURCE_DIR}/src ) 16 | include_directories ( ${PYTHON_INCLUDE_DIRS} ) 17 | link_directories ( ${CMAKE_CURRENT_BINARY_DIR}/../src ) 18 | 19 | if ( DOCUMENTATION ) 20 | set(CMAKE_SWIG_FLAGS -DDOXYGEN=${DOXYGEN_FOUND}) 21 | endif() 22 | swig_add_module ( ftdi1 python ftdi1.i ) 23 | swig_link_libraries ( ftdi1 ftdi1 ) 24 | 25 | if ( LINK_PYTHON_LIBRARY ) 26 | swig_link_libraries ( ftdi1 ${PYTHON_LIBRARIES} ) 27 | elseif( APPLE ) 28 | set_target_properties ( ${SWIG_MODULE_ftdi1_REAL_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" ) 29 | endif () 30 | 31 | set_target_properties ( ${SWIG_MODULE_ftdi1_REAL_NAME} PROPERTIES NO_SONAME ON ) 32 | 33 | execute_process ( COMMAND ${PYTHON_EXECUTABLE} -c "from distutils import sysconfig; print( sysconfig.get_python_lib( plat_specific=True, prefix='${CMAKE_INSTALL_PREFIX}' ) )" 34 | OUTPUT_VARIABLE _ABS_PYTHON_MODULE_PATH 35 | OUTPUT_STRIP_TRAILING_WHITESPACE ) 36 | 37 | get_filename_component ( _ABS_PYTHON_MODULE_PATH ${_ABS_PYTHON_MODULE_PATH} ABSOLUTE ) 38 | file ( RELATIVE_PATH _REL_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX} ${_ABS_PYTHON_MODULE_PATH} ) 39 | 40 | set ( PYTHON_MODULE_PATH ${_REL_PYTHON_MODULE_PATH} ) 41 | 42 | install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/ftdi1.py DESTINATION ${PYTHON_MODULE_PATH} ) 43 | install ( TARGETS ${SWIG_MODULE_ftdi1_REAL_NAME} LIBRARY DESTINATION ${PYTHON_MODULE_PATH} ) 44 | 45 | if ( DOCUMENTATION ) 46 | # Run doxygen to only generate the xml 47 | add_custom_command ( OUTPUT ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml 48 | COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/doc 49 | COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile.xml 50 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 51 | DEPENDS ${c_headers};${c_sources};${cpp_sources};${cpp_headers} 52 | ) 53 | 54 | # generate .i from doxygen .xml 55 | add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i 56 | COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/doxy2swig.py -n 57 | ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml 58 | ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i 59 | DEPENDS ${CMAKE_BINARY_DIR}/doc/xml/ftdi_8c.xml 60 | ) 61 | add_custom_target ( doc_i DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ftdi1_doc.i ) 62 | add_dependencies( ${SWIG_MODULE_ftdi1_REAL_NAME} doc_i ) 63 | 64 | endif () 65 | 66 | set ( LIBFTDI_PYTHON_MODULE_PATH ${CMAKE_INSTALL_PREFIX}/${PYTHON_MODULE_PATH} ) 67 | set ( LIBFTDI_PYTHON_MODULE_PATH ${LIBFTDI_PYTHON_MODULE_PATH} PARENT_SCOPE ) # for ftdiconfig.cmake 68 | 69 | add_subdirectory ( examples ) 70 | -------------------------------------------------------------------------------- /python/doxy2swig.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Doxygen XML to SWIG docstring converter. 3 | 4 | Usage: 5 | 6 | doxy2swig.py [options] input.xml output.i 7 | 8 | Converts Doxygen generated XML files into a file containing docstrings 9 | that can be used by SWIG-1.3.x. Note that you need to get SWIG 10 | version > 1.3.23 or use Robin Dunn's docstring patch to be able to use 11 | the resulting output. 12 | 13 | input.xml is your doxygen generated XML file and output.i is where the 14 | output will be written (the file will be clobbered). 15 | 16 | """ 17 | # 18 | # 19 | # This code is implemented using Mark Pilgrim's code as a guideline: 20 | # http://www.faqs.org/docs/diveintopython/kgp_divein.html 21 | # 22 | # Author: Prabhu Ramachandran 23 | # License: BSD style 24 | # 25 | # Thanks: 26 | # Johan Hake: the include_function_definition feature 27 | # Bill Spotz: bug reports and testing. 28 | # Sebastian Henschel: Misc. enhancements. 29 | # 30 | # 31 | 32 | from xml.dom import minidom 33 | import re 34 | import textwrap 35 | import sys 36 | import os.path 37 | import optparse 38 | 39 | 40 | def my_open_read(source): 41 | if hasattr(source, "read"): 42 | return source 43 | else: 44 | return open(source) 45 | 46 | 47 | def my_open_write(dest): 48 | if hasattr(dest, "write"): 49 | return dest 50 | else: 51 | return open(dest, 'w') 52 | 53 | 54 | class Doxy2SWIG: 55 | 56 | """Converts Doxygen generated XML files into a file containing 57 | docstrings that can be used by SWIG-1.3.x that have support for 58 | feature("docstring"). Once the data is parsed it is stored in 59 | self.pieces. 60 | 61 | """ 62 | 63 | def __init__(self, src, include_function_definition=True, quiet=False): 64 | """Initialize the instance given a source object. `src` can 65 | be a file or filename. If you do not want to include function 66 | definitions from doxygen then set 67 | `include_function_definition` to `False`. This is handy since 68 | this allows you to use the swig generated function definition 69 | using %feature("autodoc", [0,1]). 70 | 71 | """ 72 | f = my_open_read(src) 73 | self.my_dir = os.path.dirname(f.name) 74 | self.xmldoc = minidom.parse(f).documentElement 75 | f.close() 76 | 77 | self.pieces = [] 78 | self.pieces.append('\n// File: %s\n' % 79 | os.path.basename(f.name)) 80 | 81 | self.space_re = re.compile(r'\s+') 82 | self.lead_spc = re.compile(r'^(%feature\S+\s+\S+\s*?)"\s+(\S)') 83 | self.multi = 0 84 | self.ignores = ['inheritancegraph', 'param', 'listofallmembers', 85 | 'innerclass', 'name', 'declname', 'incdepgraph', 86 | 'invincdepgraph', 'programlisting', 'type', 87 | 'references', 'referencedby', 'location', 88 | 'collaborationgraph', 'reimplements', 89 | 'reimplementedby', 'derivedcompoundref', 90 | 'basecompoundref'] 91 | #self.generics = [] 92 | self.include_function_definition = include_function_definition 93 | if not include_function_definition: 94 | self.ignores.append('argsstring') 95 | 96 | self.quiet = quiet 97 | 98 | def generate(self): 99 | """Parses the file set in the initialization. The resulting 100 | data is stored in `self.pieces`. 101 | 102 | """ 103 | self.parse(self.xmldoc) 104 | 105 | def parse(self, node): 106 | """Parse a given node. This function in turn calls the 107 | `parse_` functions which handle the respective 108 | nodes. 109 | 110 | """ 111 | pm = getattr(self, "parse_%s" % node.__class__.__name__) 112 | pm(node) 113 | 114 | def parse_Document(self, node): 115 | self.parse(node.documentElement) 116 | 117 | def parse_Text(self, node): 118 | txt = node.data 119 | txt = txt.replace('\\', r'\\\\') 120 | txt = txt.replace('"', r'\"') 121 | # ignore pure whitespace 122 | m = self.space_re.match(txt) 123 | if m and len(m.group()) == len(txt): 124 | pass 125 | else: 126 | self.add_text(textwrap.fill(txt, break_long_words=False)) 127 | 128 | def parse_Element(self, node): 129 | """Parse an `ELEMENT_NODE`. This calls specific 130 | `do_` handers for different elements. If no handler 131 | is available the `generic_parse` method is called. All 132 | tagNames specified in `self.ignores` are simply ignored. 133 | 134 | """ 135 | name = node.tagName 136 | ignores = self.ignores 137 | if name in ignores: 138 | return 139 | attr = "do_%s" % name 140 | if hasattr(self, attr): 141 | handlerMethod = getattr(self, attr) 142 | handlerMethod(node) 143 | else: 144 | self.generic_parse(node) 145 | #if name not in self.generics: self.generics.append(name) 146 | 147 | def parse_Comment(self, node): 148 | """Parse a `COMMENT_NODE`. This does nothing for now.""" 149 | return 150 | 151 | def add_text(self, value): 152 | """Adds text corresponding to `value` into `self.pieces`.""" 153 | if isinstance(value, (list, tuple)): 154 | self.pieces.extend(value) 155 | else: 156 | self.pieces.append(value) 157 | 158 | def get_specific_nodes(self, node, names): 159 | """Given a node and a sequence of strings in `names`, return a 160 | dictionary containing the names as keys and child 161 | `ELEMENT_NODEs`, that have a `tagName` equal to the name. 162 | 163 | """ 164 | nodes = [(x.tagName, x) for x in node.childNodes 165 | if x.nodeType == x.ELEMENT_NODE and 166 | x.tagName in names] 167 | return dict(nodes) 168 | 169 | def generic_parse(self, node, pad=0): 170 | """A Generic parser for arbitrary tags in a node. 171 | 172 | Parameters: 173 | 174 | - node: A node in the DOM. 175 | - pad: `int` (default: 0) 176 | 177 | If 0 the node data is not padded with newlines. If 1 it 178 | appends a newline after parsing the childNodes. If 2 it 179 | pads before and after the nodes are processed. Defaults to 180 | 0. 181 | 182 | """ 183 | npiece = 0 184 | if pad: 185 | npiece = len(self.pieces) 186 | if pad == 2: 187 | self.add_text('\n') 188 | for n in node.childNodes: 189 | self.parse(n) 190 | if pad: 191 | if len(self.pieces) > npiece: 192 | self.add_text('\n') 193 | 194 | def space_parse(self, node): 195 | self.add_text(' ') 196 | self.generic_parse(node) 197 | 198 | do_ref = space_parse 199 | do_emphasis = space_parse 200 | do_bold = space_parse 201 | do_computeroutput = space_parse 202 | do_formula = space_parse 203 | 204 | def do_compoundname(self, node): 205 | self.add_text('\n\n') 206 | data = node.firstChild.data 207 | self.add_text('%%feature("docstring") %s "\n' % data) 208 | 209 | def do_compounddef(self, node): 210 | kind = node.attributes['kind'].value 211 | if kind in ('class', 'struct'): 212 | prot = node.attributes['prot'].value 213 | if prot != 'public': 214 | return 215 | names = ('compoundname', 'briefdescription', 216 | 'detaileddescription', 'includes') 217 | first = self.get_specific_nodes(node, names) 218 | for n in names: 219 | if first.has_key(n): 220 | self.parse(first[n]) 221 | self.add_text(['";', '\n']) 222 | for n in node.childNodes: 223 | if n not in first.values(): 224 | self.parse(n) 225 | elif kind in ('file', 'namespace'): 226 | nodes = node.getElementsByTagName('sectiondef') 227 | for n in nodes: 228 | self.parse(n) 229 | 230 | def do_includes(self, node): 231 | self.add_text('C++ includes: ') 232 | self.generic_parse(node, pad=1) 233 | 234 | def do_parameterlist(self, node): 235 | text = 'unknown' 236 | for key, val in node.attributes.items(): 237 | if key == 'kind': 238 | if val == 'param': 239 | text = 'Parameters' 240 | elif val == 'exception': 241 | text = 'Exceptions' 242 | elif val == 'retval': 243 | text = 'Returns' 244 | else: 245 | text = val 246 | break 247 | self.add_text(['\n', '\n', text, ':', '\n']) 248 | self.generic_parse(node, pad=1) 249 | 250 | def do_para(self, node): 251 | self.add_text('\n') 252 | self.generic_parse(node, pad=1) 253 | 254 | def do_parametername(self, node): 255 | self.add_text('\n') 256 | try: 257 | data = node.firstChild.data 258 | except AttributeError: # perhaps a tag in it 259 | data = node.firstChild.firstChild.data 260 | if data.find('Exception') != -1: 261 | self.add_text(data) 262 | else: 263 | self.add_text("%s: " % data) 264 | 265 | def do_parameterdefinition(self, node): 266 | self.generic_parse(node, pad=1) 267 | 268 | def do_detaileddescription(self, node): 269 | self.generic_parse(node, pad=1) 270 | 271 | def do_briefdescription(self, node): 272 | self.generic_parse(node, pad=1) 273 | 274 | def do_memberdef(self, node): 275 | prot = node.attributes['prot'].value 276 | id = node.attributes['id'].value 277 | kind = node.attributes['kind'].value 278 | tmp = node.parentNode.parentNode.parentNode 279 | compdef = tmp.getElementsByTagName('compounddef')[0] 280 | cdef_kind = compdef.attributes['kind'].value 281 | 282 | if prot == 'public': 283 | first = self.get_specific_nodes(node, ('definition', 'name')) 284 | name = first['name'].firstChild.data 285 | if name[:8] == 'operator': # Don't handle operators yet. 286 | return 287 | 288 | if not 'definition' in first or \ 289 | kind in ['variable', 'typedef']: 290 | return 291 | 292 | if self.include_function_definition: 293 | defn = first['definition'].firstChild.data 294 | else: 295 | defn = "" 296 | self.add_text('\n') 297 | self.add_text('%feature("docstring") ') 298 | 299 | anc = node.parentNode.parentNode 300 | if cdef_kind in ('file', 'namespace'): 301 | ns_node = anc.getElementsByTagName('innernamespace') 302 | if not ns_node and cdef_kind == 'namespace': 303 | ns_node = anc.getElementsByTagName('compoundname') 304 | if ns_node: 305 | ns = ns_node[0].firstChild.data 306 | self.add_text(' %s::%s "\n%s' % (ns, name, defn)) 307 | else: 308 | self.add_text(' %s "\n%s' % (name, defn)) 309 | elif cdef_kind in ('class', 'struct'): 310 | # Get the full function name. 311 | anc_node = anc.getElementsByTagName('compoundname') 312 | cname = anc_node[0].firstChild.data 313 | self.add_text(' %s::%s "\n%s' % (cname, name, defn)) 314 | 315 | for n in node.childNodes: 316 | if n not in first.values(): 317 | self.parse(n) 318 | self.add_text(['";', '\n']) 319 | 320 | def do_definition(self, node): 321 | data = node.firstChild.data 322 | self.add_text('%s "\n%s' % (data, data)) 323 | 324 | def do_sectiondef(self, node): 325 | kind = node.attributes['kind'].value 326 | if kind in ('public-func', 'func', 'user-defined', ''): 327 | self.generic_parse(node) 328 | 329 | def do_header(self, node): 330 | """For a user defined section def a header field is present 331 | which should not be printed as such, so we comment it in the 332 | output.""" 333 | data = node.firstChild.data 334 | self.add_text('\n/*\n %s \n*/\n' % data) 335 | # If our immediate sibling is a 'description' node then we 336 | # should comment that out also and remove it from the parent 337 | # node's children. 338 | parent = node.parentNode 339 | idx = parent.childNodes.index(node) 340 | if len(parent.childNodes) >= idx + 2: 341 | nd = parent.childNodes[idx + 2] 342 | if nd.nodeName == 'description': 343 | nd = parent.removeChild(nd) 344 | self.add_text('\n/*') 345 | self.generic_parse(nd) 346 | self.add_text('\n*/\n') 347 | 348 | def do_simplesect(self, node): 349 | kind = node.attributes['kind'].value 350 | if kind in ('date', 'rcs', 'version'): 351 | pass 352 | elif kind == 'warning': 353 | self.add_text(['\n', 'WARNING: ']) 354 | self.generic_parse(node) 355 | elif kind == 'see': 356 | self.add_text('\n') 357 | self.add_text('See: ') 358 | self.generic_parse(node) 359 | else: 360 | self.generic_parse(node) 361 | 362 | def do_argsstring(self, node): 363 | self.generic_parse(node, pad=1) 364 | 365 | def do_member(self, node): 366 | kind = node.attributes['kind'].value 367 | refid = node.attributes['refid'].value 368 | if kind == 'function' and refid[:9] == 'namespace': 369 | self.generic_parse(node) 370 | 371 | def do_doxygenindex(self, node): 372 | self.multi = 1 373 | comps = node.getElementsByTagName('compound') 374 | for c in comps: 375 | refid = c.attributes['refid'].value 376 | fname = refid + '.xml' 377 | if not os.path.exists(fname): 378 | fname = os.path.join(self.my_dir, fname) 379 | if not self.quiet: 380 | print("parsing file: %s" % fname) 381 | p = Doxy2SWIG(fname, self.include_function_definition, self.quiet) 382 | p.generate() 383 | self.pieces.extend(self.clean_pieces(p.pieces)) 384 | 385 | def write(self, fname): 386 | o = my_open_write(fname) 387 | if self.multi: 388 | o.write("".join(self.pieces)) 389 | else: 390 | o.write("".join(self.clean_pieces(self.pieces))) 391 | o.close() 392 | 393 | def clean_pieces(self, pieces): 394 | """Cleans the list of strings given as `pieces`. It replaces 395 | multiple newlines by a maximum of 2 and returns a new list. 396 | It also wraps the paragraphs nicely. 397 | 398 | """ 399 | ret = [] 400 | count = 0 401 | for i in pieces: 402 | if i == '\n': 403 | count = count + 1 404 | else: 405 | if i == '";': 406 | if count: 407 | ret.append('\n') 408 | elif count > 2: 409 | ret.append('\n\n') 410 | elif count: 411 | ret.append('\n' * count) 412 | count = 0 413 | ret.append(i) 414 | 415 | _data = "".join(ret) 416 | ret = [] 417 | for i in _data.split('\n\n'): 418 | if i == 'Parameters:' or i == 'Exceptions:' or i == 'Returns:': 419 | ret.extend([i, '\n' + '-' * len(i), '\n\n']) 420 | elif i.find('// File:') > -1: # leave comments alone. 421 | ret.extend([i, '\n']) 422 | else: 423 | _tmp = textwrap.fill(i.strip(), break_long_words=False) 424 | _tmp = self.lead_spc.sub(r'\1"\2', _tmp) 425 | ret.extend([_tmp, '\n\n']) 426 | return ret 427 | 428 | 429 | def convert(input, output, include_function_definition=True, quiet=False): 430 | p = Doxy2SWIG(input, include_function_definition, quiet) 431 | p.generate() 432 | p.write(output) 433 | 434 | 435 | def main(): 436 | usage = __doc__ 437 | parser = optparse.OptionParser(usage) 438 | parser.add_option("-n", '--no-function-definition', 439 | action='store_true', 440 | default=False, 441 | dest='func_def', 442 | help='do not include doxygen function definitions') 443 | parser.add_option("-q", '--quiet', 444 | action='store_true', 445 | default=False, 446 | dest='quiet', 447 | help='be quiet and minimize output') 448 | 449 | options, args = parser.parse_args() 450 | if len(args) != 2: 451 | parser.error("error: no input and output specified") 452 | 453 | convert(args[0], args[1], not options.func_def, options.quiet) 454 | 455 | 456 | if __name__ == '__main__': 457 | main() 458 | -------------------------------------------------------------------------------- /python/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | install ( FILES simple.py complete.py cbus.py 2 | DESTINATION share/libftdi/examples 3 | PERMISSIONS OWNER_READ GROUP_READ WORLD_READ 4 | ) 5 | 6 | -------------------------------------------------------------------------------- /python/examples/cbus.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | """ 3 | Copyright 2015, Sinclair R.F., Inc. 4 | 5 | This program is distributed under the GPL, version 2. 6 | 7 | Demonstrate how to configure the FT230X USB UART bridge as follows: 8 | max_power 500 mA 9 | CBUS3 Drive 1 (accomodate PCB error) 10 | """ 11 | 12 | import sys 13 | 14 | # Need to install libftdi for the following to work (see README.txt) 15 | import ftdi1 as ftdi 16 | 17 | # Define class for displaying errors. 18 | class ErrorMsg(Exception): 19 | def __init__(self,message): 20 | self.message = message 21 | def __str__(self): 22 | return self.message 23 | 24 | # Function to convert CBUSX values to human-readable strings 25 | def cbush_string(value): 26 | if value == ftdi.CBUSX_AWAKE: 27 | return 'AWAKE' 28 | if value == ftdi.CBUSX_BAT_DETECT: 29 | return 'BAT_DETECT' 30 | if value == ftdi.CBUSX_BAT_DETECT_NEG: 31 | return 'BAT_DETECT_NEG' 32 | if value == ftdi.CBUSX_BB_RD: 33 | return 'BB_RD' 34 | if value == ftdi.CBUSX_BB_WR: 35 | return 'BB_WR' 36 | if value == ftdi.CBUSX_CLK24: 37 | return 'CLK24' 38 | if value == ftdi.CBUSX_CLK12: 39 | return 'CLK12' 40 | if value == ftdi.CBUSX_CLK6: 41 | return 'CLK6' 42 | if value == ftdi.CBUSX_DRIVE_0: 43 | return 'DRIVE_0' 44 | if value == ftdi.CBUSX_DRIVE1: 45 | return 'DRIVE_1' 46 | if value == ftdi.CBUSX_I2C_RXF: 47 | return 'I2C_RXF' 48 | if value == ftdi.CBUSX_I2C_TXE: 49 | return 'I2C_TXE' 50 | if value == ftdi.CBUSX_IOMODE: 51 | return 'IOMODE' 52 | if value == ftdi.CBUSX_PWREN: 53 | return 'PWREN' 54 | if value == ftdi.CBUSX_RXLED: 55 | return 'RXLED' 56 | if value == ftdi.CBUSX_SLEEP: 57 | return 'SLEEP' 58 | if value == ftdi.CBUSX_TIME_STAMP: 59 | return 'TIME_STAMP' 60 | if value == ftdi.CBUSX_TRISTATE: 61 | return 'TRISTATE' 62 | if value == ftdi.CBUSX_TXDEN: 63 | return 'TXDEN' 64 | if value == ftdi.CBUSX_TXLED: 65 | return 'TXLED' 66 | if value == ftdi.CBUSX_TXRXLED: 67 | return 'TXRXLED' 68 | if value == ftdi.CBUSX_VBUS_SENSE: 69 | return 'VBUS_SENSE' 70 | return 'UNKNOWN' 71 | 72 | # Surround the program with a try ... except clause. 73 | try: 74 | 75 | # Allocate and inialize an ftdi context. 76 | ftdic = ftdi.new() 77 | if ftdic == 0: 78 | raise ErrorMsg('ftdi.new() failed') 79 | 80 | # List all the FT230X devices. 81 | nDevices, devlist = ftdi.usb_find_all(ftdic, 0x0403, 0x6015) 82 | if nDevices < 0: 83 | raise ErrorMsg('ftdi.usb_find_all error = %s' % ftdi.get_error_string(ftdic)) 84 | elif nDevices == 0: 85 | raise ErrorMsg('No FT230X devices found') 86 | elif nDevices != 1: 87 | raise ErrorMsg('More than one FT230X device found') 88 | 89 | # Display the identified single FT230X device. 90 | ret, manufacturer, description, serial = ftdi.usb_get_strings(ftdic, devlist.dev) 91 | if ret < 0: 92 | raise ErrorMsg('ftdi.usb_get_strings error = %s' % ftdi.get_error_string(ftdic)) 93 | print 'manufacturer="%s" description="%s" serial="%s"' % (manufacturer, description, serial) 94 | 95 | # Open the identified single FT230X device. 96 | ret = ftdi.usb_open_desc(ftdic, 0x0403, 0x6015, description, serial) 97 | if ret < 0: 98 | raise ErrorMsg('ftdi.usb_open_desc error = %s' % ftdi.get_error_string(ftdic)) 99 | 100 | # Read the chip id. 101 | ret, chipid = ftdi.read_chipid(ftdic) 102 | if ret < 0: 103 | raise ErrorMsg('ftdi.read_chipid error = %s' % ftdi.get_error_string(ftdic)) 104 | print 'chip id=0x%08X' % (chipid % 2**32) 105 | 106 | # Read the EEPROM 107 | ret = ftdi.read_eeprom(ftdic) 108 | if ret < 0: 109 | raise ErrorMsg('ftdi.read_eeprom error = %s' % ftdi.get_error_string(ftdic)) 110 | 111 | # Get a read-only copy of the EEPROM 112 | if True: 113 | eeprom_size = ftdic.eeprom.size 114 | ret, eeprom_buf = ftdi.get_eeprom_buf(ftdic, eeprom_size) 115 | if ret < 0: 116 | raise ErrorMsg('ftdi.get_eeprom_buf error = %s' % ftdi.get_error_string(ftdic)) 117 | for i in range(0,eeprom_size,16): 118 | sys.stdout.write('%04x: ' % i) 119 | for j in range(16): 120 | sys.stdout.write('%02x ' % ord(eeprom_buf[i+j])) 121 | if j in (7,15,): 122 | sys.stdout.write(' ') 123 | for j in range(16): 124 | x = eeprom_buf[i+j] 125 | if 32 <= ord(x) <= 0x7E: 126 | sys.stdout.write(x) 127 | else: 128 | sys.stdout.write('.') 129 | sys.stdout.write('\n') 130 | 131 | # Read and display the EEPROM (in human readable format) 132 | ret = ftdi.eeprom_decode(ftdic, 1) 133 | if ret < 0: 134 | raise ErrorMsg('ftdi.eeprom_decode error = %s' % ftdi.get_error_string(ftdic)) 135 | 136 | # Set the maximum power to 500mA. 137 | print 'initial max_power = %dmA' % ftdic.eeprom.max_power 138 | ftdic.eeprom.max_power = 500 139 | print 'new max_power = %dmA' % ftdic.eeprom.max_power 140 | 141 | # Set CBUS3 to DRIVE_1 (the board needs to be reworked to use PWREN# and BCD#) 142 | ret, value = ftdi.get_eeprom_value(ftdic,ftdi.CBUS_FUNCTION_3) 143 | if ret < 0: 144 | raise ErrorMsg('ftdi.get_eeprom_value error = %s' % ftdi.get_error_string(ftdic)) 145 | print 'initial CBUS3 = %d (%s)' % (value,cbush_string(value),) 146 | ret = ftdi.set_eeprom_value(ftdic,ftdi.CBUS_FUNCTION_3,ftdi.CBUSX_DRIVE1) 147 | if ret < 0: 148 | raise ErrorMsg('ftdi.set_eeprom_value error = %s' % ftdi.get_error_string(ftdic)) 149 | ret, value = ftdi.get_eeprom_value(ftdic,ftdi.CBUS_FUNCTION_3) 150 | if ret < 0: 151 | raise ErrorMsg('ftdi.get_eeprom_value error = %s' % ftdi.get_error_string(ftdic)) 152 | print 'new CBUS3 = %d (%s)' % (value,cbush_string(value),) 153 | 154 | # Write the new EEPROM settings. 155 | if False: 156 | ret = ftdi.eeprom_build(ftdic) 157 | if ret < 0: 158 | raise ErrorMsg('ftdi.eeprom_build error = %s' % ftdi.get_error_string(ftdic)) 159 | ret = ftdi.write_eeprom(ftdic) 160 | if ret < 0: 161 | raise ErrorMsg('ftdi.write_eeprom error = %s' % ftdi.get_error_string(ftdic)) 162 | print 'EEPROM write succeeded' 163 | else: 164 | print 'EEPROM write not attempted' 165 | 166 | # Close the ftdi context. 167 | ret = ftdi.usb_close(ftdic) 168 | if ret < 0: 169 | raise ErrorMsg('ftdi.usb_close error = %s' % ftdi.get_error_string(ftdic)) 170 | 171 | except ErrorMsg, msg: 172 | print >> sys.stderr, 'FATAL ERROR: ' + str(msg) 173 | exit(1) 174 | -------------------------------------------------------------------------------- /python/examples/complete.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """Python example program. 5 | 6 | Complete program to demonstrate the usage 7 | of the swig generated python wrapper 8 | 9 | You need to build and install the wrapper first""" 10 | 11 | import os 12 | import sys 13 | import ftdi1 as ftdi 14 | import time 15 | 16 | # version 17 | print ('version: %s\n' % ftdi.__version__) 18 | 19 | # initialize 20 | ftdic = ftdi.new() 21 | if ftdic == 0: 22 | print('new failed: %d' % ret) 23 | os._exit(1) 24 | 25 | # try to list ftdi devices 0x6010 or 0x6001 26 | ret, devlist = ftdi.usb_find_all(ftdic, 0x0403, 0x6010) 27 | if ret <= 0: 28 | ret, devlist = ftdi.usb_find_all(ftdic, 0x0403, 0x6001) 29 | 30 | if ret < 0: 31 | print('ftdi_usb_find_all failed: %d (%s)' % 32 | (ret, ftdi.get_error_string(ftdic))) 33 | os._exit(1) 34 | print('devices: %d' % ret) 35 | curnode = devlist 36 | i = 0 37 | while(curnode != None): 38 | ret, manufacturer, description, serial = ftdi.usb_get_strings( 39 | ftdic, curnode.dev) 40 | if ret < 0: 41 | print('ftdi_usb_get_strings failed: %d (%s)' % 42 | (ret, ftdi.get_error_string(ftdic))) 43 | os._exit(1) 44 | print('#%d: manufacturer="%s" description="%s" serial="%s"\n' % 45 | (i, manufacturer, description, serial)) 46 | curnode = curnode.next 47 | i += 1 48 | 49 | # open usb 50 | ret = ftdi.usb_open(ftdic, 0x0403, 0x6001) 51 | if ret < 0: 52 | print('unable to open ftdi device: %d (%s)' % 53 | (ret, ftdi.get_error_string(ftdic))) 54 | os._exit(1) 55 | 56 | 57 | # bitbang 58 | ret = ftdi.set_bitmode(ftdic, 0xff, ftdi.BITMODE_BITBANG) 59 | if ret < 0: 60 | print('Cannot enable bitbang') 61 | os._exit(1) 62 | print('turning everything on') 63 | ftdi.write_data(ftdic, chr(0xff), 1) 64 | time.sleep(1) 65 | print('turning everything off\n') 66 | ftdi.write_data(ftdic, chr(0x00), 1) 67 | time.sleep(1) 68 | for i in range(8): 69 | val = 2 ** i 70 | print('enabling bit #%d (0x%02x)' % (i, val)) 71 | ftdi.write_data(ftdic, chr(val), 1) 72 | time.sleep(1) 73 | ftdi.disable_bitbang(ftdic) 74 | print('') 75 | 76 | 77 | # read pins 78 | ret, pins = ftdi.read_pins(ftdic) 79 | if (ret == 0): 80 | if sys.version_info[0] < 3: # python 2 81 | pins = ord(pins) 82 | else: 83 | pins = pins[0] 84 | print('pins: 0x%x' % pins) 85 | 86 | 87 | # read chip id 88 | ret, chipid = ftdi.read_chipid(ftdic) 89 | if (ret == 0): 90 | print('chip id: %x\n' % chipid) 91 | 92 | 93 | # read eeprom 94 | eeprom_addr = 1 95 | ret, eeprom_val = ftdi.read_eeprom_location(ftdic, eeprom_addr) 96 | if (ret == 0): 97 | print('eeprom @ %d: 0x%04x\n' % (eeprom_addr, eeprom_val)) 98 | 99 | print('eeprom:') 100 | ret = ftdi.read_eeprom(ftdic) 101 | size = 128 102 | ret, eeprom = ftdi.get_eeprom_buf(ftdic, size) 103 | if (ret == 0): 104 | for i in range(size): 105 | octet = eeprom[i] 106 | if sys.version_info[0] < 3: # python 2 107 | octet = ord(octet) 108 | sys.stdout.write('%02x ' % octet) 109 | if (i % 8 == 7): 110 | print('') 111 | print('') 112 | 113 | # close usb 114 | ret = ftdi.usb_close(ftdic) 115 | if ret < 0: 116 | print('unable to close ftdi device: %d (%s)' % 117 | (ret, ftdi.get_error_string(ftdic))) 118 | os._exit(1) 119 | 120 | print ('device closed') 121 | ftdi.free(ftdic) 122 | -------------------------------------------------------------------------------- /python/examples/simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """Python example program. 5 | 6 | Small program to demonstrate the usage 7 | of the swig generated python wrapper 8 | 9 | You need to build and install the wrapper first""" 10 | 11 | import ftdi1 as ftdi 12 | 13 | 14 | def main(): 15 | """Main program""" 16 | context = ftdi.new() 17 | 18 | version_info = ftdi.get_library_version() 19 | print("[FTDI version] major: %d, minor: %d, micro: %d" 20 | ", version_str: %s, snapshot_str: %s" % 21 | (version_info.major, version_info.minor, version_info.micro, 22 | version_info.version_str, version_info.snapshot_str)) 23 | 24 | # try to open an ftdi 0x6010 or 0x6001 25 | ret = ftdi.usb_open(context, 0x0403, 0x6010) 26 | if ret < 0: 27 | ret = ftdi.usb_open(context, 0x0403, 0x6001) 28 | 29 | print("ftdi.usb_open(): %d" % ret) 30 | print("ftdi.set_baudrate(): %d" % ftdi.set_baudrate(context, 9600)) 31 | 32 | ftdi.free(context) 33 | 34 | main() 35 | -------------------------------------------------------------------------------- /python/ftdi1.i: -------------------------------------------------------------------------------- 1 | /* File: ftdi1.i */ 2 | 3 | %module(docstring="Python interface to libftdi1") ftdi1 4 | %feature("autodoc","1"); 5 | 6 | #ifdef DOXYGEN 7 | %include "ftdi1_doc.i" 8 | #endif 9 | 10 | %{ 11 | #include "Python.h" 12 | 13 | inline PyObject* charp2str(const char *v_, long len) 14 | { 15 | #if PY_MAJOR_VERSION >= 3 16 | return PyBytes_FromStringAndSize(v_, len); 17 | #else 18 | return PyString_FromStringAndSize(v_, len); 19 | #endif 20 | } 21 | 22 | inline char * str2charp_size(PyObject* pyObj, int * size) 23 | { 24 | char * v_ = 0; 25 | #if PY_MAJOR_VERSION >= 3 26 | PyBytes_AsStringAndSize(pyObj, &v_, (Py_ssize_t*)size); 27 | #else 28 | PyString_AsStringAndSize(pyObj, &v_, (Py_ssize_t*)size); 29 | #endif 30 | return v_; 31 | } 32 | %} 33 | 34 | %include 35 | %include 36 | 37 | %typemap(in) unsigned char* = char*; 38 | 39 | %immutable ftdi_version_info::version_str; 40 | %immutable ftdi_version_info::snapshot_str; 41 | 42 | %rename("%(strip:[ftdi_])s") ""; 43 | 44 | %newobject ftdi_new; 45 | %typemap(newfree) struct ftdi_context *ftdi "ftdi_free($1);"; 46 | %delobject ftdi_free; 47 | 48 | %define ftdi_usb_find_all_docstring 49 | "usb_find_all(context, vendor, product) -> (return_code, devlist)" 50 | %enddef 51 | %feature("autodoc", ftdi_usb_find_all_docstring) ftdi_usb_find_all; 52 | %typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp) %{ $1 = &temp; %} 53 | %typemap(argout) SWIGTYPE** OUTPUT %{ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj((void*)*$1,$*descriptor,0)); %} 54 | %apply SWIGTYPE** OUTPUT { struct ftdi_device_list **devlist }; 55 | int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, 56 | int vendor, int product); 57 | %clear struct ftdi_device_list **devlist; 58 | 59 | %define ftdi_usb_get_strings_docstring 60 | "usb_get_strings(context, device) -> (return_code, manufacturer, description, serial)" 61 | %enddef 62 | %feature("autodoc", ftdi_usb_get_strings_docstring) ftdi_usb_get_strings; 63 | %feature("autodoc", ftdi_usb_get_strings_docstring) ftdi_usb_get_strings2; 64 | %feature("autodoc", ftdi_usb_get_strings_docstring) ftdi_eeprom_get_strings; 65 | %apply char *OUTPUT { char * manufacturer, char * description, char * serial }; 66 | %cstring_bounded_output( char * manufacturer, 256 ); 67 | %cstring_bounded_output( char * description, 256 ); 68 | %cstring_bounded_output( char * product, 256 ); 69 | %cstring_bounded_output( char * serial, 256 ); 70 | %typemap(default,noblock=1) int mnf_len, int desc_len, int product_len, int serial_len { $1 = 256; } 71 | int ftdi_usb_get_strings(struct ftdi_context *ftdi, struct libusb_device *dev, 72 | char * manufacturer, int mnf_len, 73 | char * description, int desc_len, 74 | char * serial, int serial_len); 75 | int ftdi_usb_get_strings2(struct ftdi_context *ftdi, struct libusb_device *dev, 76 | char * manufacturer, int mnf_len, 77 | char * description, int desc_len, 78 | char * serial, int serial_len); 79 | int ftdi_eeprom_get_strings(struct ftdi_context *ftdi, 80 | char *manufacturer, int mnf_len, 81 | char *product, int product_len, 82 | char *serial, int serial_len); 83 | 84 | %clear char * manufacturer, char * description, char * serial; 85 | %clear char * product; 86 | %clear int mnf_len, int desc_len, int product_len, int serial_len; 87 | 88 | %define ftdi_read_data_docstring 89 | "read_data(context) -> (return_code, buf)" 90 | %enddef 91 | %feature("autodoc", ftdi_read_data_docstring) ftdi_read_data; 92 | %typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %} 93 | %typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result = SWIG_Python_AppendOutput($result, charp2str((char*)$1, $2)); free($1); %} 94 | int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size); 95 | %clear (unsigned char *buf, int size); 96 | 97 | %define ftdi_write_data_docstring 98 | "write_data(context, data) -> return_code" 99 | %enddef 100 | %feature("autodoc", ftdi_write_data_docstring) ftdi_write_data; 101 | %typemap(in,numinputs=1) (const unsigned char *buf, int size) %{ $1 = (unsigned char*)str2charp_size($input, &$2); %} 102 | int ftdi_write_data(struct ftdi_context *ftdi, const unsigned char *buf, int size); 103 | %clear (const unsigned char *buf, int size); 104 | 105 | %apply int *OUTPUT { unsigned int *chunksize }; 106 | int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); 107 | int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); 108 | %clear unsigned int *chunksize; 109 | 110 | %define ftdi_read_pins_docstring 111 | "read_pins(context) -> (return_code, pins)" 112 | %enddef 113 | %feature("autodoc", ftdi_read_pins_docstring) ftdi_read_pins; 114 | %typemap(in,numinputs=0) unsigned char *pins ($*ltype temp) %{ $1 = &temp; %} 115 | %typemap(argout) (unsigned char *pins) %{ $result = SWIG_Python_AppendOutput($result, charp2str((char*)$1, 1)); %} 116 | int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins); 117 | %clear unsigned char *pins; 118 | 119 | %typemap(in,numinputs=0) unsigned char *latency ($*ltype temp) %{ $1 = &temp; %} 120 | %typemap(argout) (unsigned char *latency) %{ $result = SWIG_Python_AppendOutput($result, charp2str((char*)$1, 1)); %} 121 | int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency); 122 | %clear unsigned char *latency; 123 | 124 | %apply short *OUTPUT { unsigned short *status }; 125 | int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status); 126 | %clear unsigned short *status; 127 | 128 | %apply int *OUTPUT { int* value }; 129 | int ftdi_get_eeprom_value(struct ftdi_context *ftdi, enum ftdi_eeprom_value value_name, int* value); 130 | %clear int* value; 131 | 132 | %typemap(in,numinputs=1) (unsigned char *buf, int size) %{ $2 = PyInt_AsLong($input);$1 = (unsigned char*)malloc($2*sizeof(char)); %} 133 | %typemap(argout) (unsigned char *buf, int size) %{ if(result<0) $2=0; $result = SWIG_Python_AppendOutput($result, charp2str((char*)$1, $2)); free($1); %} 134 | int ftdi_get_eeprom_buf(struct ftdi_context *ftdi, unsigned char * buf, int size); 135 | %clear (unsigned char *buf, int size); 136 | 137 | %define ftdi_read_eeprom_location_docstring 138 | "read_eeprom_location(context, eeprom_addr) -> (return_code, eeprom_val)" 139 | %enddef 140 | %feature("autodoc", ftdi_read_eeprom_location_docstring) ftdi_read_eeprom_location; 141 | %apply short *OUTPUT { unsigned short *eeprom_val }; 142 | int ftdi_read_eeprom_location (struct ftdi_context *ftdi, int eeprom_addr, unsigned short *eeprom_val); 143 | %clear unsigned short *eeprom_val; 144 | 145 | %define ftdi_read_eeprom_docstring 146 | "read_eeprom(context) -> (return_code, eeprom)" 147 | %enddef 148 | %feature("autodoc", ftdi_read_eeprom_docstring) ftdi_read_eeprom; 149 | 150 | %define ftdi_read_chipid_docstring 151 | "ftdi_read_chipid(context) -> (return_code, chipid)" 152 | %enddef 153 | %feature("autodoc", ftdi_read_chipid_docstring) ftdi_read_chipid; 154 | %apply int *OUTPUT { unsigned int *chipid }; 155 | int ftdi_read_chipid(struct ftdi_context *ftdi, unsigned int *chipid); 156 | %clear unsigned int *chipid; 157 | 158 | %include ftdi.h 159 | %{ 160 | #include 161 | %} 162 | 163 | %include ftdi_i.h 164 | %{ 165 | #include 166 | %} 167 | 168 | %pythoncode %{ 169 | __version__ = get_library_version().version_str 170 | %} 171 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Includes 2 | include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} 3 | ${CMAKE_CURRENT_SOURCE_DIR} 4 | ) 5 | 6 | if (UNIX) 7 | add_compile_options(-Wno-sign-compare -Wno-missing-field-initializers -Wno-implicit-fallthrough) 8 | endif() 9 | 10 | # Version information 11 | set(SNAPSHOT_VERSION "unknown") 12 | #execute_process(COMMAND git describe 13 | # OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT 14 | # RESULT_VARIABLE GIT_DESCRIBE_RESULT 15 | # OUTPUT_STRIP_TRAILING_WHITESPACE 16 | # ) 17 | #if(${GIT_DESCRIBE_RESULT} STREQUAL 0) 18 | # set(SNAPSHOT_VERSION ${GIT_DESCRIBE_OUTPUT}) 19 | #endif () 20 | #message(STATUS "Detected git snapshot version: ${SNAPSHOT_VERSION}") 21 | 22 | configure_file(ftdi_version_i.h.in "${CMAKE_CURRENT_BINARY_DIR}/ftdi_version_i.h" @ONLY) 23 | 24 | # Targets 25 | set(c_sources ${CMAKE_CURRENT_SOURCE_DIR}/ftdi.c ${CMAKE_CURRENT_SOURCE_DIR}/ftdi_stream.c CACHE INTERNAL "List of c sources" ) 26 | set(c_headers ${CMAKE_CURRENT_SOURCE_DIR}/ftdi.h CACHE INTERNAL "List of c headers" ) 27 | 28 | add_library(ftdi1 SHARED ${c_sources}) 29 | 30 | math(EXPR VERSION_FIXUP "${MAJOR_VERSION} + 1") # Compatiblity with previous releases 31 | set_target_properties(ftdi1 PROPERTIES VERSION ${VERSION_FIXUP}.${MINOR_VERSION}.0 SOVERSION 2) 32 | # Prevent clobbering each other during the build 33 | set_target_properties ( ftdi1 PROPERTIES CLEAN_DIRECT_OUTPUT 1 ) 34 | 35 | 36 | # Dependencies 37 | target_link_libraries(ftdi1 PUBLIC ${LIBUSB1_LIBRARIES}) 38 | 39 | install ( TARGETS ftdi1 40 | RUNTIME DESTINATION bin 41 | LIBRARY DESTINATION lib${LIB_SUFFIX} 42 | ARCHIVE DESTINATION lib${LIB_SUFFIX} 43 | ) 44 | 45 | if ( STATICLIBS ) 46 | add_library(ftdi1-static STATIC ${c_sources}) 47 | target_link_libraries(ftdi1-static PUBLIC ${LIBUSB1_LIBRARIES}) 48 | set_target_properties(ftdi1-static PROPERTIES OUTPUT_NAME "ftdi1") 49 | set_target_properties(ftdi1-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) 50 | install ( TARGETS ftdi1-static 51 | ARCHIVE DESTINATION lib${LIB_SUFFIX} 52 | COMPONENT staticlibs 53 | ) 54 | if (UNIX) 55 | target_compile_options(ftdi1-static PRIVATE -fPIC) 56 | endif() 57 | endif () 58 | 59 | install ( FILES ${c_headers} 60 | DESTINATION include/${PROJECT_NAME} 61 | COMPONENT headers 62 | ) 63 | -------------------------------------------------------------------------------- /src/ftdi_i.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | ftdi_i.h - description 3 | ------------------- 4 | begin : Don Sep 9 2011 5 | copyright : (C) 2003-2017 by Intra2net AG and the libftdi developers 6 | email : opensource@intra2net.com 7 | ***************************************************************************/ 8 | 9 | /*************************************************************************** 10 | * * 11 | * This program is free software; you can redistribute it and/or modify * 12 | * it under the terms of the GNU Lesser General Public License * 13 | * version 2.1 as published by the Free Software Foundation; * 14 | * * 15 | *************************************************************************** 16 | 17 | Non public definitions here 18 | 19 | */ 20 | 21 | /* Even on 93xx66 at max 256 bytes are used (AN_121)*/ 22 | #define FTDI_MAX_EEPROM_SIZE 256 23 | 24 | /** Max Power adjustment factor. */ 25 | #define MAX_POWER_MILLIAMP_PER_UNIT 2 26 | 27 | /** 28 | \brief FTDI eeprom structure 29 | */ 30 | struct ftdi_eeprom 31 | { 32 | /** vendor id */ 33 | int vendor_id; 34 | /** product id */ 35 | int product_id; 36 | 37 | /** Was the eeprom structure initialized for the actual 38 | connected device? **/ 39 | int initialized_for_connected_device; 40 | 41 | /** self powered */ 42 | int self_powered; 43 | /** remote wakeup */ 44 | int remote_wakeup; 45 | 46 | int is_not_pnp; 47 | 48 | /* Suspend on DBUS7 Low */ 49 | int suspend_dbus7; 50 | 51 | /** input in isochronous transfer mode */ 52 | int in_is_isochronous; 53 | /** output in isochronous transfer mode */ 54 | int out_is_isochronous; 55 | /** suspend pull downs */ 56 | int suspend_pull_downs; 57 | 58 | /** use serial */ 59 | int use_serial; 60 | /** usb version */ 61 | int usb_version; 62 | /** Use usb version on FT2232 devices*/ 63 | int use_usb_version; 64 | /** maximum power */ 65 | int max_power; 66 | 67 | /** manufacturer name */ 68 | char *manufacturer; 69 | /** product name */ 70 | char *product; 71 | /** serial number */ 72 | char *serial; 73 | 74 | /* 2232D/H specific */ 75 | /* Hardware type, 0 = RS232 Uart, 1 = 245 FIFO, 2 = CPU FIFO, 76 | 4 = OPTO Isolate */ 77 | int channel_a_type; 78 | int channel_b_type; 79 | /* Driver Type, 1 = VCP */ 80 | int channel_a_driver; 81 | int channel_b_driver; 82 | int channel_c_driver; 83 | int channel_d_driver; 84 | /* 4232H specific */ 85 | int channel_a_rs485enable; 86 | int channel_b_rs485enable; 87 | int channel_c_rs485enable; 88 | int channel_d_rs485enable; 89 | 90 | /* Special function of FT232R/FT232H devices (and possibly others as well) */ 91 | /** CBUS pin function. See CBUS_xxx defines. */ 92 | int cbus_function[10]; 93 | /** Select hight current drive on R devices. */ 94 | int high_current; 95 | /** Select hight current drive on A channel (2232C */ 96 | int high_current_a; 97 | /** Select hight current drive on B channel (2232C). */ 98 | int high_current_b; 99 | /** Select inversion of data lines (bitmask). */ 100 | int invert; 101 | /** Enable external oscillator. */ 102 | int external_oscillator; 103 | 104 | /*2232H/4432H Group specific values */ 105 | /* Group0 is AL on 2322H and A on 4232H 106 | Group1 is AH on 2232H and B on 4232H 107 | Group2 is BL on 2322H and C on 4232H 108 | Group3 is BH on 2232H and C on 4232H*/ 109 | int group0_drive; 110 | int group0_schmitt; 111 | int group0_slew; 112 | int group1_drive; 113 | int group1_schmitt; 114 | int group1_slew; 115 | int group2_drive; 116 | int group2_schmitt; 117 | int group2_slew; 118 | int group3_drive; 119 | int group3_schmitt; 120 | int group3_slew; 121 | 122 | int powersave; 123 | 124 | int clock_polarity; 125 | int data_order; 126 | int flow_control; 127 | 128 | /** user data **/ 129 | int user_data_addr; 130 | int user_data_size; 131 | const char *user_data; 132 | 133 | /** eeprom size in bytes. This doesn't get stored in the eeprom 134 | but is the only way to pass it to ftdi_eeprom_build. */ 135 | int size; 136 | /* EEPROM Type 0x46 for 93xx46, 0x56 for 93xx56 and 0x66 for 93xx66*/ 137 | int chip; 138 | unsigned char buf[FTDI_MAX_EEPROM_SIZE]; 139 | 140 | /** device release number */ 141 | int release_number; 142 | }; 143 | 144 | -------------------------------------------------------------------------------- /src/ftdi_stream.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | ftdi_stream.c - description 3 | ------------------- 4 | copyright : (C) 2009 Micah Dowty 2010 Uwe Bonnes 5 | email : opensource@intra2net.com 6 | ***************************************************************************/ 7 | 8 | /*************************************************************************** 9 | * * 10 | * This program is free software; you can redistribute it and/or modify * 11 | * it under the terms of the GNU Lesser General Public License * 12 | * version 2.1 as published by the Free Software Foundation; * 13 | * * 14 | ***************************************************************************/ 15 | 16 | /* Adapted from 17 | * fastftdi.c - A minimal FTDI FT232H interface for which supports bit-bang 18 | * mode, but focuses on very high-performance support for 19 | * synchronous FIFO mode. Requires libusb-1.0 20 | * 21 | * Copyright (C) 2009 Micah Dowty 22 | * 23 | * Permission is hereby granted, free of charge, to any person obtaining a copy 24 | * of this software and associated documentation files (the "Software"), to deal 25 | * in the Software without restriction, including without limitation the rights 26 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 27 | * copies of the Software, and to permit persons to whom the Software is 28 | * furnished to do so, subject to the following conditions: 29 | * 30 | * The above copyright notice and this permission notice shall be included in 31 | * all copies or substantial portions of the Software. 32 | * 33 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 34 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 35 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 36 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 37 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 38 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 39 | * THE SOFTWARE. 40 | */ 41 | 42 | #include 43 | #include 44 | #ifndef _WIN32 45 | #include 46 | #endif 47 | #include 48 | 49 | #include "ftdi.h" 50 | 51 | typedef struct 52 | { 53 | FTDIStreamCallback *callback; 54 | void *userdata; 55 | int packetsize; 56 | int activity; 57 | int result; 58 | FTDIProgressInfo progress; 59 | } FTDIStreamState; 60 | 61 | /* Handle callbacks 62 | * 63 | * With Exit request, free memory and release the transfer 64 | * 65 | * state->result is only set when some error happens 66 | */ 67 | static void LIBUSB_CALL 68 | ftdi_readstream_cb(struct libusb_transfer *transfer) 69 | { 70 | FTDIStreamState *state = transfer->user_data; 71 | int packet_size = state->packetsize; 72 | 73 | state->activity++; 74 | if (transfer->status == LIBUSB_TRANSFER_COMPLETED) 75 | { 76 | int i; 77 | uint8_t *ptr = transfer->buffer; 78 | int length = transfer->actual_length; 79 | int numPackets = (length + packet_size - 1) / packet_size; 80 | int res = 0; 81 | 82 | for (i = 0; i < numPackets; i++) 83 | { 84 | int payloadLen; 85 | int packetLen = length; 86 | 87 | if (packetLen > packet_size) 88 | packetLen = packet_size; 89 | 90 | payloadLen = packetLen - 2; 91 | state->progress.current.totalBytes += payloadLen; 92 | 93 | res = state->callback(ptr + 2, payloadLen, 94 | NULL, state->userdata); 95 | 96 | ptr += packetLen; 97 | length -= packetLen; 98 | } 99 | if (res) 100 | { 101 | free(transfer->buffer); 102 | libusb_free_transfer(transfer); 103 | } 104 | else 105 | { 106 | transfer->status = -1; 107 | state->result = libusb_submit_transfer(transfer); 108 | } 109 | } 110 | else 111 | { 112 | fprintf(stderr, "unknown status %d\n",transfer->status); 113 | state->result = LIBUSB_ERROR_IO; 114 | } 115 | } 116 | 117 | /** 118 | Helper function to calculate (unix) time differences 119 | 120 | \param a timeval 121 | \param b timeval 122 | */ 123 | static double 124 | TimevalDiff(const struct timeval *a, const struct timeval *b) 125 | { 126 | return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec); 127 | } 128 | 129 | /** 130 | Streaming reading of data from the device 131 | 132 | Use asynchronous transfers in libusb-1.0 for high-performance 133 | streaming of data from a device interface back to the PC. This 134 | function continuously transfers data until either an error occurs 135 | or the callback returns a nonzero value. This function returns 136 | a libusb error code or the callback's return value. 137 | 138 | For every contiguous block of received data, the callback will 139 | be invoked. 140 | 141 | \param ftdi pointer to ftdi_context 142 | \param callback to user supplied function for one block of data 143 | \param userdata 144 | \param packetsPerTransfer number of packets per transfer 145 | \param numTransfers Number of transfers per callback 146 | 147 | */ 148 | 149 | int 150 | ftdi_readstream(struct ftdi_context *ftdi, 151 | FTDIStreamCallback *callback, void *userdata, 152 | int packetsPerTransfer, int numTransfers) 153 | { 154 | struct libusb_transfer **transfers; 155 | FTDIStreamState state = { callback, userdata, ftdi->max_packet_size, 1 }; 156 | int bufferSize = packetsPerTransfer * ftdi->max_packet_size; 157 | int xferIndex; 158 | int err = 0; 159 | 160 | /* Only FT2232H and FT232H know about the synchronous FIFO Mode*/ 161 | if ((ftdi->type != TYPE_2232H) && (ftdi->type != TYPE_232H)) 162 | { 163 | fprintf(stderr,"Device doesn't support synchronous FIFO mode\n"); 164 | return 1; 165 | } 166 | 167 | /* We don't know in what state we are, switch to reset*/ 168 | if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET) < 0) 169 | { 170 | fprintf(stderr,"Can't reset mode\n"); 171 | return 1; 172 | } 173 | 174 | /* Purge anything remaining in the buffers*/ 175 | if (ftdi_usb_purge_buffers(ftdi) < 0) 176 | { 177 | fprintf(stderr,"Can't Purge\n"); 178 | return 1; 179 | } 180 | 181 | /* 182 | * Set up all transfers 183 | */ 184 | 185 | transfers = calloc(numTransfers, sizeof *transfers); 186 | if (!transfers) 187 | { 188 | err = LIBUSB_ERROR_NO_MEM; 189 | goto cleanup; 190 | } 191 | 192 | for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) 193 | { 194 | struct libusb_transfer *transfer; 195 | 196 | transfer = libusb_alloc_transfer(0); 197 | transfers[xferIndex] = transfer; 198 | if (!transfer) 199 | { 200 | err = LIBUSB_ERROR_NO_MEM; 201 | goto cleanup; 202 | } 203 | 204 | libusb_fill_bulk_transfer(transfer, ftdi->usb_dev, ftdi->out_ep, 205 | malloc(bufferSize), bufferSize, 206 | ftdi_readstream_cb, 207 | &state, 0); 208 | 209 | if (!transfer->buffer) 210 | { 211 | err = LIBUSB_ERROR_NO_MEM; 212 | goto cleanup; 213 | } 214 | 215 | transfer->status = -1; 216 | err = libusb_submit_transfer(transfer); 217 | if (err) 218 | goto cleanup; 219 | } 220 | 221 | /* Start the transfers only when everything has been set up. 222 | * Otherwise the transfers start stuttering and the PC not 223 | * fetching data for several to several ten milliseconds 224 | * and we skip blocks 225 | */ 226 | if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_SYNCFF) < 0) 227 | { 228 | fprintf(stderr,"Can't set synchronous fifo mode: %s\n", 229 | ftdi_get_error_string(ftdi)); 230 | goto cleanup; 231 | } 232 | 233 | /* 234 | * Run the transfers, and periodically assess progress. 235 | */ 236 | 237 | gettimeofday(&state.progress.first.time, NULL); 238 | 239 | do 240 | { 241 | FTDIProgressInfo *progress = &state.progress; 242 | const double progressInterval = 1.0; 243 | struct timeval timeout = { 0, ftdi->usb_read_timeout * 1000}; 244 | struct timeval now; 245 | 246 | int err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout); 247 | if (err == LIBUSB_ERROR_INTERRUPTED) 248 | /* restart interrupted events */ 249 | err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout); 250 | if (!state.result) 251 | { 252 | state.result = err; 253 | } 254 | if (state.activity == 0) 255 | state.result = 1; 256 | else 257 | state.activity = 0; 258 | 259 | // If enough time has elapsed, update the progress 260 | gettimeofday(&now, NULL); 261 | if (TimevalDiff(&now, &progress->current.time) >= progressInterval) 262 | { 263 | progress->current.time = now; 264 | progress->totalTime = TimevalDiff(&progress->current.time, 265 | &progress->first.time); 266 | 267 | if (progress->prev.totalBytes) 268 | { 269 | // We have enough information to calculate rates 270 | 271 | double currentTime; 272 | 273 | currentTime = TimevalDiff(&progress->current.time, 274 | &progress->prev.time); 275 | 276 | progress->totalRate = 277 | progress->current.totalBytes /progress->totalTime; 278 | progress->currentRate = 279 | (progress->current.totalBytes - 280 | progress->prev.totalBytes) / currentTime; 281 | } 282 | 283 | state.callback(NULL, 0, progress, state.userdata); 284 | progress->prev = progress->current; 285 | 286 | } 287 | } while (!state.result); 288 | 289 | /* 290 | * Cancel any outstanding transfers, and free memory. 291 | */ 292 | 293 | cleanup: 294 | fprintf(stderr, "cleanup\n"); 295 | if (transfers) 296 | free(transfers); 297 | if (err) 298 | return err; 299 | else 300 | return state.result; 301 | } 302 | 303 | -------------------------------------------------------------------------------- /src/ftdi_version_i.h.in: -------------------------------------------------------------------------------- 1 | #ifndef FTDI_VERSION_INTERNAL_H 2 | #define FTDI_VERSION_INTERNAL_H 3 | 4 | #define FTDI_MAJOR_VERSION @MAJOR_VERSION@ 5 | #define FTDI_MINOR_VERSION @MINOR_VERSION@ 6 | #define FTDI_MICRO_VERSION 0 7 | 8 | const char FTDI_VERSION_STRING[] = "@VERSION_STRING@"; 9 | const char FTDI_SNAPSHOT_VERSION[] = "@SNAPSHOT_VERSION@"; 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Boost COMPONENTS unit_test_framework REQUIRED) 2 | 3 | enable_testing() 4 | 5 | INCLUDE_DIRECTORIES(BEFORE ${CMAKE_SOURCE_DIR}/src ${Boost_INCLUDE_DIRS}) 6 | 7 | set(cpp_tests basic.cpp baudrate.cpp) 8 | 9 | add_executable(test_libftdi1 ${cpp_tests}) 10 | target_link_libraries(test_libftdi1 ftdi1 ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) 11 | 12 | add_test(test_libftdi1 test_libftdi1) 13 | 14 | # Add custom target so we run easily run "make check" 15 | add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS test_libftdi1) 16 | -------------------------------------------------------------------------------- /test/basic.cpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | @brief Test basic FTDI functionality 3 | 4 | @author Thomas Jarosch 5 | */ 6 | 7 | /*************************************************************************** 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU Lesser General Public License * 11 | * version 2.1 as published by the Free Software Foundation; * 12 | * * 13 | ***************************************************************************/ 14 | 15 | #define BOOST_TEST_DYN_LINK 16 | #define BOOST_TEST_MAIN 17 | #include 18 | 19 | #include 20 | 21 | BOOST_AUTO_TEST_SUITE(Basic) 22 | 23 | BOOST_AUTO_TEST_CASE(SimpleInit) 24 | { 25 | ftdi_context ftdi; 26 | 27 | int rtn_init = ftdi_init(&ftdi); 28 | BOOST_REQUIRE_EQUAL(0, rtn_init); 29 | 30 | ftdi_deinit(&ftdi); 31 | } 32 | 33 | BOOST_AUTO_TEST_SUITE_END() 34 | -------------------------------------------------------------------------------- /test/baudrate.cpp: -------------------------------------------------------------------------------- 1 | /**@file 2 | @brief Test baudrate calculator code 3 | 4 | @author Thomas Jarosch and Uwe Bonnes 5 | */ 6 | 7 | /*************************************************************************** 8 | * * 9 | * This program is free software; you can redistribute it and/or modify * 10 | * it under the terms of the GNU Lesser General Public License * 11 | * version 2.1 as published by the Free Software Foundation; * 12 | * * 13 | ***************************************************************************/ 14 | 15 | #include 16 | 17 | #define BOOST_TEST_DYN_LINK 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace std; 25 | 26 | extern "C" int convert_baudrate_UT_export(int baudrate, struct ftdi_context *ftdi, 27 | unsigned short *value, unsigned short *index); 28 | 29 | /// Basic initialization of libftdi for every test 30 | class BaseFTDIFixture 31 | { 32 | protected: 33 | ftdi_context *ftdi; 34 | 35 | public: 36 | BaseFTDIFixture() 37 | : ftdi(NULL) 38 | { 39 | ftdi = ftdi_new(); 40 | } 41 | 42 | virtual ~BaseFTDIFixture() 43 | { 44 | delete ftdi; 45 | ftdi = NULL; 46 | } 47 | }; 48 | 49 | BOOST_FIXTURE_TEST_SUITE(Baudrate, BaseFTDIFixture) 50 | 51 | /// Helper class to store the convert_baudrate_UT_export result 52 | struct calc_result 53 | { 54 | int actual_baudrate; 55 | unsigned short divisor; 56 | unsigned short fractional_bits; 57 | unsigned short clock; 58 | 59 | calc_result(int actual, unsigned short my_divisor, unsigned short my_fractional_bits, unsigned short my_clock) 60 | : actual_baudrate(actual) 61 | , divisor(my_divisor) 62 | , fractional_bits(my_fractional_bits) 63 | , clock(my_clock) 64 | { 65 | } 66 | 67 | calc_result() 68 | : actual_baudrate(0) 69 | , divisor(0) 70 | , fractional_bits(0) 71 | , clock(0) 72 | { 73 | } 74 | }; 75 | 76 | /** 77 | * @brief Test convert_baudrate code against a list of baud rates 78 | * 79 | * @param baudrates Baudrates to check 80 | **/ 81 | static void test_baudrates(ftdi_context *ftdi, const map &baudrates) 82 | { 83 | typedef std::pair baudrate_type; 84 | BOOST_FOREACH(const baudrate_type &baudrate, baudrates) 85 | { 86 | unsigned short calc_value = 0, calc_index = 0; 87 | int calc_baudrate = convert_baudrate_UT_export(baudrate.first, ftdi, &calc_value, &calc_index); 88 | 89 | const calc_result *res = &baudrate.second; 90 | 91 | unsigned short divisor = calc_value & 0x3fff; 92 | unsigned short fractional_bits = (calc_value >> 14); 93 | unsigned short clock = (calc_index & 0x200) ? 120 : 48; 94 | 95 | switch (ftdi->type) 96 | { 97 | case TYPE_232H: 98 | case TYPE_2232H: 99 | case TYPE_4232H: 100 | fractional_bits |= (calc_index & 0x100) ? 4 : 0; 101 | break; 102 | case TYPE_R: 103 | case TYPE_2232C: 104 | case TYPE_BM: 105 | case TYPE_230X: 106 | fractional_bits |= (calc_index & 0x001) ? 4 : 0; 107 | break; 108 | default:; 109 | } 110 | 111 | // Aid debugging since this test is a generic function 112 | BOOST_CHECK_MESSAGE(res->actual_baudrate == calc_baudrate && res->divisor == divisor && res->fractional_bits == fractional_bits 113 | && res->clock == clock, 114 | "\n\nERROR: baudrate calculation failed for --" << baudrate.first << " baud--. Details below: "); 115 | 116 | BOOST_CHECK_EQUAL(res->actual_baudrate, calc_baudrate); 117 | BOOST_CHECK_EQUAL(res->divisor, divisor); 118 | BOOST_CHECK_EQUAL(res->fractional_bits, fractional_bits); 119 | BOOST_CHECK_EQUAL(res->clock, clock); 120 | } 121 | } 122 | 123 | BOOST_AUTO_TEST_CASE(TypeAMFixedBaudrates) 124 | { 125 | ftdi->type = TYPE_AM; 126 | 127 | map baudrates; 128 | baudrates[183] = calc_result(183, 16383, 0, 48); 129 | baudrates[300] = calc_result(300, 10000, 0, 48); 130 | baudrates[600] = calc_result(600, 5000, 0, 48); 131 | baudrates[1200] = calc_result(1200, 2500, 0, 48); 132 | baudrates[2400] = calc_result(2400, 1250, 0, 48); 133 | baudrates[4800] = calc_result(4800, 625, 0, 48); 134 | baudrates[9600] = calc_result(9600, 312, 1, 48); 135 | baudrates[19200] = calc_result(19200, 156, 2, 48); 136 | baudrates[38400] = calc_result(38400, 78, 3, 48); 137 | baudrates[57600] = calc_result(57554, 52, 3, 48); 138 | baudrates[115200] = calc_result(115385, 26, 0, 48); 139 | baudrates[230400] = calc_result(230769, 13, 0, 48); 140 | baudrates[460800] = calc_result(461538, 6, 1, 48); 141 | baudrates[921600] = calc_result(923077, 3, 2, 48); 142 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); 143 | baudrates[1090512] = calc_result(1000000, 3, 0, 48); 144 | baudrates[1090909] = calc_result(1000000, 3, 0, 48); 145 | baudrates[1090910] = calc_result(1000000, 3, 0, 48); 146 | baudrates[1200000] = calc_result(1200000, 2, 1, 48); 147 | baudrates[1333333] = calc_result(1333333, 2, 2, 48); 148 | baudrates[1411764] = calc_result(1411765, 2, 3, 48); 149 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); 150 | baudrates[2000000] = calc_result(1500000, 2, 0, 48); 151 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); 152 | 153 | test_baudrates(ftdi, baudrates); 154 | } 155 | 156 | BOOST_AUTO_TEST_CASE(TypeBMFixedBaudrates) 157 | { 158 | // Unify testing of chips behaving the same 159 | std::vector test_types; 160 | test_types.push_back(TYPE_BM); 161 | test_types.push_back(TYPE_2232C); 162 | test_types.push_back(TYPE_R); 163 | test_types.push_back(TYPE_230X); 164 | 165 | map baudrates; 166 | baudrates[183] = calc_result(183, 16383, 7, 48); 167 | baudrates[184] = calc_result(184, 16304, 4, 48); 168 | baudrates[300] = calc_result(300, 10000, 0, 48); 169 | baudrates[600] = calc_result(600, 5000, 0, 48); 170 | baudrates[1200] = calc_result(1200, 2500, 0, 48); 171 | baudrates[2400] = calc_result(2400, 1250, 0, 48); 172 | baudrates[4800] = calc_result(4800, 625, 0, 48); 173 | baudrates[9600] = calc_result(9600, 312, 1, 48); 174 | baudrates[19200] = calc_result(19200, 156, 2, 48); 175 | baudrates[38400] = calc_result(38400, 78, 3, 48); 176 | baudrates[57600] = calc_result(57554, 52, 3, 48); 177 | baudrates[115200] = calc_result(115385, 26, 0, 48); 178 | baudrates[230400] = calc_result(230769, 13, 0, 48); 179 | baudrates[460800] = calc_result(461538, 6, 1, 48); 180 | baudrates[921600] = calc_result(923077, 3, 2, 48); 181 | baudrates[1000000] = calc_result(1000000, 3, 0, 48); 182 | baudrates[1050000] = calc_result(1043478, 2, 7, 48); 183 | baudrates[1400000] = calc_result(1411765, 2, 3, 48); 184 | baudrates[1500000] = calc_result(1500000, 2, 0, 48); 185 | baudrates[2000000] = calc_result(2000000, 1, 0, 48); 186 | baudrates[3000000] = calc_result(3000000, 0, 0, 48); 187 | 188 | baudrates[(3000000*16/(2*16+15))-1] = calc_result(round(3000000/3.000), 3, 0, 48); 189 | baudrates[ 3000000*16/(2*16+15) ] = calc_result(round(3000000/3.000), 3, 0, 48); 190 | baudrates[(3000000*16/(2*16+15))+1] = calc_result(round(3000000/2.875), 2, 7, 48); 191 | baudrates[ 3000000*16/(2*16+13) ] = calc_result(round(3000000/2.875), 2, 7, 48); 192 | baudrates[(3000000*16/(2*16+13))+1] = calc_result(round(3000000/2.750), 2, 6, 48); 193 | baudrates[ 3000000*16/(2*16+11) ] = calc_result(round(3000000/2.750), 2, 6, 48); 194 | baudrates[(3000000*16/(2*16+11))+1] = calc_result(round(3000000/2.625), 2, 5, 48); 195 | baudrates[ 3000000*16/(2*16+ 9) ] = calc_result(round(3000000/2.625), 2, 5, 48); 196 | baudrates[(3000000*16/(2*16+ 9))+1] = calc_result(round(3000000/2.500), 2, 1, 48); 197 | baudrates[ 3000000*16/(2*16+ 7) ] = calc_result(round(3000000/2.500), 2, 1, 48); 198 | baudrates[(3000000*16/(2*16+ 7))+1] = calc_result(round(3000000/2.375), 2, 4, 48); 199 | baudrates[ 3000000*16/(2*16+ 5) ] = calc_result(round(3000000/2.375), 2, 4, 48); 200 | baudrates[(3000000*16/(2*16+ 5))+1] = calc_result(round(3000000/2.250), 2, 2, 48); 201 | baudrates[ 3000000*16/(2*16+ 3) ] = calc_result(round(3000000/2.250), 2, 2, 48); 202 | baudrates[(3000000*16/(2*16+ 3))+1] = calc_result(round(3000000/2.125), 2, 3, 48); 203 | baudrates[ 3000000*16/(2*16+ 1) ] = calc_result(round(3000000/2.125), 2, 3, 48); 204 | baudrates[(3000000*16/(2*16+ 1))+1] = calc_result(round(3000000/2.000), 2, 0, 48); 205 | 206 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) 207 | { 208 | ftdi->type = test_chip_type; 209 | test_baudrates(ftdi, baudrates); 210 | } 211 | } 212 | 213 | BOOST_AUTO_TEST_CASE(TypeHFixedBaudrates) 214 | { 215 | // Unify testing of chips behaving the same 216 | std::vector test_types; 217 | test_types.push_back(TYPE_2232H); 218 | test_types.push_back(TYPE_4232H); 219 | test_types.push_back(TYPE_232H); 220 | 221 | map baudrates; 222 | baudrates[183] = calc_result(183, 16383, 7, 48); 223 | baudrates[184] = calc_result(184, 16304, 4, 48); 224 | baudrates[300] = calc_result(300, 10000, 0, 48); 225 | baudrates[600] = calc_result(600, 5000, 0, 48); 226 | baudrates[1200] = calc_result(1200, 10000, 0, 120); 227 | baudrates[2400] = calc_result(2400, 5000, 0, 120); 228 | baudrates[4800] = calc_result(4800, 2500, 0, 120); 229 | baudrates[9600] = calc_result(9600, 1250, 0, 120); 230 | baudrates[19200] = calc_result(19200, 625, 0, 120); 231 | baudrates[38400] = calc_result(38400, 312, 1, 120); 232 | baudrates[57600] = calc_result(57588, 208, 4, 120); 233 | baudrates[115200] = calc_result(115246, 104, 3, 120); 234 | baudrates[230400] = calc_result(230216, 52, 3, 120); 235 | baudrates[460800] = calc_result(461538, 26, 0, 120); 236 | baudrates[921600] = calc_result(923077, 13, 0, 120); 237 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); 238 | baudrates[1000000] = calc_result(1000000, 12, 0, 120); 239 | baudrates[6000000] = calc_result(6000000, 2, 0, 120); 240 | baudrates[4173913] = calc_result(4173913, 2, 7, 120); 241 | baudrates[8000000] = calc_result(8000000, 1, 0, 120); 242 | baudrates[12000000] = calc_result(12000000, 0, 0, 120); 243 | 244 | baudrates[(12000000*16/(2*16+15))-1] = calc_result(round(12000000/3.000), 3, 0, 120); 245 | baudrates[ 12000000*16/(2*16+15) ] = calc_result(round(12000000/3.000), 3, 0, 120); 246 | baudrates[(12000000*16/(2*16+15))+1] = calc_result(round(12000000/2.875), 2, 7, 120); 247 | baudrates[ 12000000*16/(2*16+13) ] = calc_result(round(12000000/2.875), 2, 7, 120); 248 | baudrates[(12000000*16/(2*16+13))+1] = calc_result(round(12000000/2.750), 2, 6, 120); 249 | baudrates[ 12000000*16/(2*16+11) ] = calc_result(round(12000000/2.750), 2, 6, 120); 250 | baudrates[(12000000*16/(2*16+11))+1] = calc_result(round(12000000/2.625), 2, 5, 120); 251 | baudrates[ 12000000*16/(2*16+ 9) ] = calc_result(round(12000000/2.625), 2, 5, 120); 252 | baudrates[(12000000*16/(2*16+ 9))+1] = calc_result(round(12000000/2.500), 2, 1, 120); 253 | baudrates[ 12000000*16/(2*16+ 7) ] = calc_result(round(12000000/2.500), 2, 1, 120); 254 | baudrates[(12000000*16/(2*16+ 7))+1] = calc_result(round(12000000/2.375), 2, 4, 120); 255 | baudrates[ 12000000*16/(2*16+ 5) ] = calc_result(round(12000000/2.375), 2, 4, 120); 256 | baudrates[(12000000*16/(2*16+ 5))+1] = calc_result(round(12000000/2.250), 2, 2, 120); 257 | baudrates[ 12000000*16/(2*16+ 3) ] = calc_result(round(12000000/2.250), 2, 2, 120); 258 | baudrates[(12000000*16/(2*16+ 3))+1] = calc_result(round(12000000/2.125), 2, 3, 120); 259 | baudrates[ 12000000*16/(2*16+ 1) ] = calc_result(round(12000000/2.125), 2, 3, 120); 260 | baudrates[(12000000*16/(2*16+ 1))+1] = calc_result(round(12000000/2.000), 2, 0, 120); 261 | 262 | BOOST_FOREACH(const enum ftdi_chip_type &test_chip_type, test_types) 263 | { 264 | ftdi->type = test_chip_type; 265 | test_baudrates(ftdi, baudrates); 266 | } 267 | } 268 | 269 | BOOST_AUTO_TEST_SUITE_END() 270 | --------------------------------------------------------------------------------