libftdi-git Archives

Subject: A library to talk to FTDI chips branch, master, updated. v0.15-17-g49c5ac7

From: libftdi-git@xxxxxxxxxxxxxxxxxxxxxxx
To: libftdi-git@xxxxxxxxxxxxxxxxxxxxxxx
Date: Sat, 14 Mar 2009 23:08:47 +0100 (CET)
The branch, master has been updated
       via  49c5ac7264ef3e1bed2a4a1e290028eb48b3bf44 (commit)
       via  fb4e5dbfcb0a875c3d63a3adc3b63c1c215d672d (commit)
       via  4af1d1bb1cdb000f010781f5cce9a27ecb5e0223 (commit)
       via  a5e1bd8cb666ea95a8e0854ab197fe1387912601 (commit)
       via  ba5329be05b33e08aa836d703989c9fc95c3fca0 (commit)
       via  b56d5a64309e1d705d34f42a28c2371a7bf7f9fe (commit)
       via  4e79ea5f1383b431a1361e201b0860e7c4d09af1 (commit)
       via  2a3bfc54266a8b7e54e7f6fa8b753fb22ebabf9e (commit)
       via  89a3169e7d78b6aff609aa88760af2fd5c61cf7c (commit)
      from  f64fc3baaeabbc52fd6aa929f1fb31e5ca7687cc (commit)


- Log -----------------------------------------------------------------
commit 49c5ac7264ef3e1bed2a4a1e290028eb48b3bf44
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date:   Sat Mar 14 22:57:11 2009 +0100

    Fix return value of ftdi_eeprom_decode as noted by Jim Paris, thanks.

commit fb4e5dbfcb0a875c3d63a3adc3b63c1c215d672d
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date:   Sat Mar 14 22:55:12 2009 +0100

    Updated ChangeLog

commit 4af1d1bb1cdb000f010781f5cce9a27ecb5e0223
Author: Marius Kintel <kintel@xxxxxx>
Date:   Mon Mar 2 18:37:36 2009 +0100

    Cleanup of decode function

commit a5e1bd8cb666ea95a8e0854ab197fe1387912601
Author: Marius Kintel <kintel@xxxxxx>
Date:   Mon Mar 2 17:51:11 2009 +0100

    Cleaned up control message defines

commit ba5329be05b33e08aa836d703989c9fc95c3fca0
Author: Marius Kintel <kintel@xxxxxx>
Date:   Mon Mar 2 17:36:14 2009 +0100

    Correct writing of EEPROM

commit b56d5a64309e1d705d34f42a28c2371a7bf7f9fe
Author: Marius Kintel <kintel@xxxxxx>
Date:   Thu Feb 19 17:33:53 2009 +0100

    Added ftdi_eeprom_decode()

commit 4e79ea5f1383b431a1361e201b0860e7c4d09af1
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date:   Sat Mar 14 22:24:41 2009 +0100

    Improve source package generator, remove unused "patch" version level

commit 2a3bfc54266a8b7e54e7f6fa8b753fb22ebabf9e
Author: Thomas Jarosch <thomas.jarosch@xxxxxxxxxxxxx>
Date:   Sat Mar 14 22:09:11 2009 +0100

    Added COPYING-CMAKE-SCRIPTS file

commit 89a3169e7d78b6aff609aa88760af2fd5c61cf7c
Author: Marius Kintel <kintel@xxxxxx>
Date:   Mon Feb 16 14:54:34 2009 +0100

    Added FindUSB cmake macro

-----------------------------------------------------------------------

Summary of changes:
 .gitignore            |    9 ++
 CMakeLists.txt        |   11 ++-
 COPYING-CMAKE-SCRIPTS |   22 +++++
 ChangeLog             |    3 +-
 FindUSB.cmake         |   38 ++++++++
 ftdipp/CMakeLists.txt |    2 +-
 src/CMakeLists.txt    |    2 +-
 src/ftdi.c            |  228 +++++++++++++++++++++++++++++++++++++++++++------
 src/ftdi.h            |   40 +++++----
 9 files changed, 306 insertions(+), 49 deletions(-)
 create mode 100644 COPYING-CMAKE-SCRIPTS
 create mode 100644 FindUSB.cmake

diff --git a/.gitignore b/.gitignore
index f7ac5b5..66068d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,12 @@ doc/html
 # libftdi specific
 libftdi-config
 libftdi.spec
+
+# CMake
+CMakeCache.txt
+cmake_install.cmake
+CMakeFiles
+
+# Misc. binaries
+*.dylib
+opt
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dd05d4b..74f45ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,8 @@
 project(libftdi)
 set(MAJOR_VERSION 0)
 set(MINOR_VERSION 15)
-set(PATCH_VERSION 0)
-set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION})
+set(VERSION_STRING ${MAJOR_VERSION}.${MINOR_VERSION})
+SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}")
 
 # CMake
 if("${CMAKE_BUILD_TYPE}" STREQUAL "")
@@ -18,6 +18,9 @@ if(${CMAKE_BUILD_TYPE} STREQUAL Debug)
    add_definitions(-DDEBUG)
 endif(${CMAKE_BUILD_TYPE} STREQUAL Debug)
 
+FIND_PACKAGE(USB REQUIRED)
+INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIR})
+
 # Set components
 set(CPACK_COMPONENTS_ALL sharedlibs staticlibs headers)
 set(CPACK_COMPONENT_SHAREDLIBS_DISPLAY_NAME "Shared libraries")
@@ -82,6 +85,10 @@ endif(${WIN32})
 
 set(CPACK_RESOURCE_FILE_LICENSE        ${CMAKE_SOURCE_DIR}/COPYING.LIB)
 
+set(CPACK_SOURCE_GENERATOR             TGZ)
+set(CPACK_SOURCE_IGNORE_FILES          "\\\\.git")
+set(CPACK_SOURCE_PACKAGE_FILE_NAME     ${CPACK_PACKAGE_FILE_NAME})
+
 # Subdirectories
 if(${UNIX})
   set(CPACK_SET_DESTDIR "ON")
diff --git a/COPYING-CMAKE-SCRIPTS b/COPYING-CMAKE-SCRIPTS
new file mode 100644
index 0000000..4b41776
--- /dev/null
+++ b/COPYING-CMAKE-SCRIPTS
@@ -0,0 +1,22 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products 
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/ChangeLog b/ChangeLog
index c51aba4..8a4511e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 New in 0.16 - 2009-XX-XX
 ------------------------
-* cmake system improvements (Marius Kintel)
+* eeprom decode function and small cleanups (Marius Kintel)
+* cmake system improvements (Marius Kintel and Intra2net)
 * Fix compilation in -ansi -pedantic mode (Matthias Janke)
 
 New in 0.15 - 2008-12-19
diff --git a/FindUSB.cmake b/FindUSB.cmake
new file mode 100644
index 0000000..566cdd8
--- /dev/null
+++ b/FindUSB.cmake
@@ -0,0 +1,38 @@
+# - Try to find the freetype library
+# Once done this defines
+#
+#  LIBUSB_FOUND - system has libusb
+#  LIBUSB_INCLUDE_DIR - the libusb include directory
+#  LIBUSB_LIBRARIES - Link these to use libusb
+
+# Copyright (c) 2006, 2008  Laurent Montel, <montel@xxxxxxx>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+
+if (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
+
+  # in cache already
+  set(LIBUSB_FOUND TRUE)
+
+else (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
+  IF (NOT WIN32)
+    # use pkg-config to get the directories and then use these values
+    # in the FIND_PATH() and FIND_LIBRARY() calls
+    find_package(PkgConfig)
+    pkg_check_modules(PC_LIBUSB libusb)
+  ENDIF(NOT WIN32)
+
+  FIND_PATH(LIBUSB_INCLUDE_DIR usb.h
+    PATHS ${PC_LIBUSB_INCLUDEDIR} ${PC_LIBUSB_INCLUDE_DIRS})
+
+  FIND_LIBRARY(LIBUSB_LIBRARIES NAMES usb 
+    PATHS ${PC_LIBUSB_LIBDIR} ${PC_LIBUSB_LIBRARY_DIRS})
+
+  include(FindPackageHandleStandardArgs)
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBUSB DEFAULT_MSG LIBUSB_LIBRARIES 
LIBUSB_INCLUDE_DIR)
+
+  MARK_AS_ADVANCED(LIBUSB_INCLUDE_DIR LIBUSB_LIBRARIES)
+
+endif (LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARIES)
diff --git a/ftdipp/CMakeLists.txt b/ftdipp/CMakeLists.txt
index 2759208..411abdb 100644
--- a/ftdipp/CMakeLists.txt
+++ b/ftdipp/CMakeLists.txt
@@ -21,7 +21,7 @@ message(STATUS "Building libftdi++")
 add_library(ftdi_cpp SHARED ${cpp_sources})
 
 # Dependencies
-target_link_libraries(ftdi_cpp ftdi usb ${BOOST_LIBRARIES})
+target_link_libraries(ftdi_cpp ftdi ${LIBUSB_LIBRARIES} ${BOOST_LIBRARIES})
 
 # Install
 if(${UNIX})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6f1c40b..7965999 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,7 +10,7 @@ set(c_headers     ftdi.h)
 add_library(ftdi SHARED ${c_sources})
 
 # Dependencies
-target_link_libraries(ftdi usb)
+target_link_libraries(ftdi ${LIBUSB_LIBRARIES})
 
 # Install
 if(${UNIX})
diff --git a/src/ftdi.c b/src/ftdi.c
index 3feb9b6..e7a7274 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -31,6 +31,7 @@
 #include <usb.h>
 #include <string.h>
 #include <errno.h>
+#include <stdio.h>
 
 #include "ftdi.h"
 
@@ -518,10 +519,10 @@ int ftdi_usb_open_desc(struct ftdi_context *ftdi, int 
vendor, int product,
 */
 int ftdi_usb_reset(struct ftdi_context *ftdi)
 {
-   if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
-                       SIO_RESET_REQUEST, SIO_RESET_SIO,
-                       ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
-        ftdi_error_return(-1,"FTDI reset failed");
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+                        SIO_RESET_REQUEST, SIO_RESET_SIO,
+                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
+      ftdi_error_return(-1,"FTDI reset failed");
 
     // Invalidate data in the readbuffer
     ftdi->readbuffer_offset = 0;
@@ -540,7 +541,7 @@ int ftdi_usb_reset(struct ftdi_context *ftdi)
 */
 int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi)
 {
-   if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
+   if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                        SIO_RESET_REQUEST, SIO_RESET_PURGE_RX,
                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "FTDI purge of RX buffer failed");
@@ -562,7 +563,7 @@ int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi)
 */
 int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi)
 {
-   if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
+   if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                        SIO_RESET_REQUEST, SIO_RESET_PURGE_TX,
                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "FTDI purge of TX buffer failed");
@@ -753,7 +754,7 @@ int ftdi_set_baudrate(struct ftdi_context *ftdi, int 
baudrate)
                 : (baudrate * 21 < actual_baudrate * 20)))
         ftdi_error_return (-1, "Unsupported baudrate. Note: bitbang baudrates 
are automatically multiplied by 4");
 
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_BAUDRATE_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_BAUDRATE_REQUEST, value,
                         index, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return (-2, "Setting new baudrate failed");
@@ -838,7 +839,7 @@ int ftdi_set_line_property2(struct ftdi_context *ftdi, enum 
ftdi_bits_type bits,
         break;
     }
 
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_DATA_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_DATA_REQUEST, value,
                         ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return (-1, "Setting new line property failed");
@@ -1274,7 +1275,9 @@ int ftdi_enable_bitbang(struct ftdi_context *ftdi, 
unsigned char bitmask)
     /* FT2232C: Set bitbang_mode to 2 to enable SPI */
     usb_val |= (ftdi->bitbang_mode << 8);
 
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 
0, ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
+                        SIO_SET_BITMODE_REQUEST, usb_val, ftdi->index, 
+                        NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "unable to enter bitbang mode. Perhaps not a BM 
type chip?");
 
     ftdi->bitbang_enabled = 1;
@@ -1291,7 +1294,7 @@ int ftdi_enable_bitbang(struct ftdi_context *ftdi, 
unsigned char bitmask)
 */
 int ftdi_disable_bitbang(struct ftdi_context *ftdi)
 {
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, 
ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_SET_BITMODE_REQUEST, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "unable to leave bitbang mode. Perhaps not a BM 
type chip?");
 
     ftdi->bitbang_enabled = 0;
@@ -1315,7 +1318,7 @@ int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned 
char bitmask, unsigned
 
     usb_val = bitmask; // low byte: bitmask
     usb_val |= (mode << 8);
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 
0, ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_SET_BITMODE_REQUEST, usb_val, ftdi->index, NULL, 0, 
ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "unable to configure bitbang mode. Perhaps not a 
2232C type chip?");
 
     ftdi->bitbang_mode = mode;
@@ -1334,7 +1337,7 @@ int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned 
char bitmask, unsigned
 */
 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins)
 {
-    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char 
*)pins, 1, ftdi->usb_read_timeout) != 1)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_READ_PINS_REQUEST, 0, ftdi->index, (char *)pins, 1, ftdi->usb_read_timeout) 
!= 1)
         ftdi_error_return(-1, "read pins failed");
 
     return 0;
@@ -1362,7 +1365,7 @@ int ftdi_set_latency_timer(struct ftdi_context *ftdi, 
unsigned char latency)
         ftdi_error_return(-1, "latency out of range. Only valid for 1-255");
 
     usb_val = latency;
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 
0, ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_SET_LATENCY_TIMER_REQUEST, usb_val, ftdi->index, NULL, 0, 
ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-2, "unable to set latency timer");
 
     return 0;
@@ -1380,7 +1383,7 @@ int ftdi_set_latency_timer(struct ftdi_context *ftdi, 
unsigned char latency)
 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency)
 {
     unsigned short usb_val;
-    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char 
*)&usb_val, 1, ftdi->usb_read_timeout) != 1)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_GET_LATENCY_TIMER_REQUEST, 0, ftdi->index, (char *)&usb_val, 1, 
ftdi->usb_read_timeout) != 1)
         ftdi_error_return(-1, "reading latency timer failed");
 
     *latency = (unsigned char)usb_val;
@@ -1430,7 +1433,7 @@ int ftdi_poll_modem_status(struct ftdi_context *ftdi, 
unsigned short *status)
 {
     char usb_val[2];
 
-    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x05, 0, ftdi->index, usb_val, 2, 
ftdi->usb_read_timeout) != 2)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_POLL_MODEM_STATUS_REQUEST, 0, ftdi->index, usb_val, 2, 
ftdi->usb_read_timeout) != 2)
         ftdi_error_return(-1, "getting modem status failed");
 
     *status = (usb_val[1] << 8) | usb_val[0];
@@ -1450,7 +1453,7 @@ int ftdi_poll_modem_status(struct ftdi_context *ftdi, 
unsigned short *status)
 */
 int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl)
 {
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_FLOW_CTRL_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_FLOW_CTRL_REQUEST, 0, (flowctrl | ftdi->index),
                         NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "set flow control failed");
@@ -1476,7 +1479,7 @@ int ftdi_setdtr(struct ftdi_context *ftdi, int state)
     else
         usb_val = SIO_SET_DTR_LOW;
 
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index,
                         NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "set dtr failed");
@@ -1502,7 +1505,7 @@ int ftdi_setrts(struct ftdi_context *ftdi, int state)
     else
         usb_val = SIO_SET_RTS_LOW;
 
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index,
                         NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "set of rts failed");
@@ -1534,7 +1537,7 @@ int ftdi_setdtr_rts(struct ftdi_context *ftdi, int dtr, 
int rts)
     else
        usb_val |= SIO_SET_RTS_LOW;
 
-    if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
                         SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->index,
                         NULL, 0, ftdi->usb_write_timeout) != 0)
        ftdi_error_return(-1, "set of rts/dtr failed");
@@ -1561,7 +1564,7 @@ int ftdi_set_event_char(struct ftdi_context *ftdi,
     if (enable)
         usb_val |= 1 << 8;
 
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x06, usb_val, ftdi->index, NULL, 
0, ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_SET_EVENT_CHAR_REQUEST, usb_val, ftdi->index, NULL, 0, 
ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "setting event character failed");
 
     return 0;
@@ -1586,7 +1589,7 @@ int ftdi_set_error_char(struct ftdi_context *ftdi,
     if (enable)
         usb_val |= 1 << 8;
 
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x07, usb_val, ftdi->index, NULL, 
0, ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_SET_ERROR_CHAR_REQUEST, usb_val, ftdi->index, NULL, 0, 
ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "setting error character failed");
 
     return 0;
@@ -1807,6 +1810,164 @@ int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, 
unsigned char *output)
 }
 
 /**
+   Decode binary EEPROM image into an ftdi_eeprom structure.
+
+   \param eeprom Pointer to ftdi_eeprom which will be filled in.
+   \param output Buffer of \a size bytes of raw eeprom data
+   \param size size size of eeprom data in bytes
+
+   \retval 0: all fine
+   \retval -1: something went wrong
+
+   FIXME: How to pass size? How to handle size field in ftdi_eeprom?
+   FIXME: Strings are malloc'ed here and should be freed somewhere
+*/
+int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *buf, int 
size)
+{
+    unsigned char i, j;
+    unsigned short checksum, eeprom_checksum, value;
+    unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
+    int size_check;
+    int eeprom_size = 128;
+#if 0
+    size_check = eeprom->size;
+    size_check -= 28; // 28 are always in use (fixed)
+
+    // Top half of a 256byte eeprom is used just for strings and checksum 
+    // it seems that the FTDI chip will not read these strings from the lower 
half
+    // Each string starts with two bytes; offset and type (0x03 for string)
+    // the checksum needs two bytes, so without the string data that 8 bytes 
from the top half
+    if(eeprom->size>=256)size_check = 120;
+    size_check -= manufacturer_size*2;
+    size_check -= product_size*2;
+    size_check -= serial_size*2;
+
+    // eeprom size exceeded?
+    if (size_check < 0)
+        return (-1);
+#endif
+
+    // empty eeprom struct
+    memset(eeprom, 0, sizeof(struct ftdi_eeprom));
+
+    // Addr 00: Stay 00 00
+
+    // Addr 02: Vendor ID
+    eeprom->vendor_id = buf[0x02] + (buf[0x03] << 8);
+
+    // Addr 04: Product ID
+    eeprom->product_id = buf[0x04] + (buf[0x05] << 8);
+    
+    switch (buf[0x06] + (buf[0x07]<<8)) {
+    case 0x0400:
+      eeprom->BM_type_chip = 1;
+      break;
+    case 0x0200:
+      eeprom->BM_type_chip = 0;
+      break;
+    default: // Unknown device
+      eeprom->BM_type_chip = 0;
+      break;
+    }
+
+    // Addr 08: Config descriptor
+    // Bit 7: always 1
+    // Bit 6: 1 if this device is self powered, 0 if bus powered
+    // Bit 5: 1 if this device uses remote wakeup
+    // Bit 4: 1 if this device is battery powered
+    j = buf[0x08];
+    if (j&0x40) eeprom->self_powered = 1;
+    if (j&0x20) eeprom->remote_wakeup = 1;
+
+    // Addr 09: Max power consumption: max power = value * 2 mA
+    eeprom->max_power = buf[0x09];
+
+    // Addr 0A: Chip configuration
+    // Bit 7: 0 - reserved
+    // Bit 6: 0 - reserved
+    // Bit 5: 0 - reserved
+    // Bit 4: 1 - Change USB version
+    // Bit 3: 1 - Use the serial number string
+    // Bit 2: 1 - Enable suspend pull downs for lower power
+    // Bit 1: 1 - Out EndPoint is Isochronous
+    // Bit 0: 1 - In EndPoint is Isochronous
+    //
+    j = buf[0x0A];
+    if (j&0x01) eeprom->in_is_isochronous = 1;
+    if (j&0x02) eeprom->out_is_isochronous = 1;
+    if (j&0x04) eeprom->suspend_pull_downs = 1;
+    if (j&0x08) eeprom->use_serial = 1;
+    if (j&0x10) eeprom->change_usb_version = 1;
+
+    // Addr 0B: reserved
+
+    // Addr 0C: USB version low byte when 0x0A bit 4 is set
+    // Addr 0D: USB version high byte when 0x0A bit 4 is set
+    if (eeprom->change_usb_version == 1) {
+      eeprom->usb_version = buf[0x0C] + (buf[0x0D] << 8);
+    }
+
+    // Addr 0E: Offset of the manufacturer string + 0x80, calculated later
+    // Addr 0F: Length of manufacturer string
+    manufacturer_size = buf[0x0F]/2;
+    if (manufacturer_size > 0) eeprom->manufacturer = 
malloc(manufacturer_size);
+    else eeprom->manufacturer = NULL;
+
+    // Addr 10: Offset of the product string + 0x80, calculated later
+    // Addr 11: Length of product string
+    product_size = buf[0x11]/2;
+    if (product_size > 0) eeprom->product = malloc(product_size);
+    else eeprom->product = NULL;
+
+    // Addr 12: Offset of the serial string + 0x80, calculated later
+    // Addr 13: Length of serial string
+    serial_size = buf[0x13]/2;
+    if (serial_size > 0) eeprom->serial = malloc(serial_size);
+    else eeprom->serial = NULL;
+
+    // Decode manufacturer 
+    i = buf[0x0E] & 0x7f; // offset
+    for (j=0;j<manufacturer_size-1;j++) {
+      eeprom->manufacturer[j] = buf[2*j+i+2];
+    }
+    eeprom->manufacturer[j] = '\0';
+
+    // Decode product name
+    i = buf[0x10] & 0x7f; // offset
+    for (j=0;j<product_size-1;j++) {
+      eeprom->product[j] = buf[2*j+i+2];
+    }
+    eeprom->product[j] = '\0';
+
+    // Decode serial
+    i = buf[0x12] & 0x7f; // offset
+    for (j=0;j<serial_size-1;j++) {
+      eeprom->serial[j] = buf[2*j+i+2];
+    }
+    eeprom->serial[j] = '\0';
+
+    // verify checksum
+    checksum = 0xAAAA;
+
+    for (i = 0; i < eeprom_size/2-1; i++) {
+        value = buf[i*2];
+        value += buf[(i*2)+1] << 8;
+
+        checksum = value^checksum;
+        checksum = (checksum << 1) | (checksum >> 15);
+    }
+
+    eeprom_checksum = buf[eeprom_size-2] + (buf[eeprom_size-1] << 8);
+
+    if (eeprom_checksum != checksum) {
+      fprintf(stderr, "Checksum Error: %04x %04x\n", checksum, 
eeprom_checksum);
+      return -1;
+    }
+
+    return 0;
+}
+
+/**
     Read eeprom
 
     \param ftdi pointer to ftdi_context
@@ -1820,7 +1981,7 @@ int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned 
char *eeprom)
     int i;
 
     for (i = 0; i < ftdi->eeprom_size/2; i++) {
-        if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, 
ftdi->usb_read_timeout) != 2)
+        if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_READ_EEPROM_REQUEST, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2)
             ftdi_error_return(-1, "reading eeprom failed");
     }
 
@@ -1857,10 +2018,10 @@ int ftdi_read_chipid(struct ftdi_context *ftdi, 
unsigned int *chipid)
 {
     unsigned int a = 0, b = 0;
 
-    if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, 0x43, (char *)&a, 2, 
ftdi->usb_read_timeout) == 2)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_READ_EEPROM_REQUEST, 0, 0x43, (char *)&a, 2, ftdi->usb_read_timeout) == 2)
     {
         a = a << 8 | a >> 8;
-        if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, 0x44, (char *)&b, 2, 
ftdi->usb_read_timeout) == 2)
+        if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
SIO_READ_EEPROM_REQUEST, 0, 0x44, (char *)&b, 2, ftdi->usb_read_timeout) == 2)
         {
             b = b << 8 | b >> 8;
             a = (a << 16) | b;
@@ -1891,7 +2052,9 @@ int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, 
unsigned char *eeprom, i
 
     do{
       for (j = 0; i < maxsize/2 && j<size; j++) {
-        if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, 
ftdi->usb_read_timeout) != 2)
+        if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_IN_REQTYPE, 
+                            SIO_READ_EEPROM_REQUEST, 0, i, 
+                            eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2)
          ftdi_error_return(-1, "reading eeprom failed");
        i++;
       }
@@ -1912,13 +2075,20 @@ int ftdi_read_eeprom_getsize(struct ftdi_context *ftdi, 
unsigned char *eeprom, i
 */
 int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom)
 {
-    unsigned short usb_val;
+    unsigned short usb_val, status;
     int i;
 
+    /* These commands were traced while running MProg */
+    ftdi_usb_reset(ftdi);
+    ftdi_poll_modem_status(ftdi, &status);
+    ftdi_set_latency_timer(ftdi, 0x77);
+
     for (i = 0; i < ftdi->eeprom_size/2; i++) {
         usb_val = eeprom[i*2];
         usb_val += eeprom[(i*2)+1] << 8;
-        if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, 
ftdi->usb_write_timeout) != 0)
+        if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
+                            SIO_WRITE_EEPROM_REQUEST, usb_val, i, 
+                            NULL, 0, ftdi->usb_write_timeout) != 0)
             ftdi_error_return(-1, "unable to write eeprom");
     }
 
@@ -1928,6 +2098,8 @@ int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned 
char *eeprom)
 /**
     Erase eeprom
 
+    This is not supported on FT232R/FT245R according to the MProg manual from 
FTDI.
+
     \param ftdi pointer to ftdi_context
 
     \retval  0: all fine
@@ -1935,7 +2107,7 @@ int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned 
char *eeprom)
 */
 int ftdi_erase_eeprom(struct ftdi_context *ftdi)
 {
-    if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, 
ftdi->usb_write_timeout) != 0)
+    if (usb_control_msg(ftdi->usb_dev, FTDI_DEVICE_OUT_REQTYPE, 
SIO_ERASE_EEPROM_REQUEST, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0)
         ftdi_error_return(-1, "unable to erase eeprom");
 
     return 0;
diff --git a/src/ftdi.h b/src/ftdi.h
index ec3d431..60cc6a1 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -100,29 +100,36 @@ enum ftdi_interface {
 #define SIO_SET_BAUD_RATE  3 /* Set baud rate */
 #define SIO_SET_DATA       4 /* Set the data characteristics of the port */
 
-#define SIO_RESET_REQUEST_TYPE 0x40
-#define SIO_RESET_REQUEST SIO_RESET
+#define FTDI_DEVICE_OUT_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | 
USB_ENDPOINT_OUT)
+#define FTDI_DEVICE_IN_REQTYPE (USB_TYPE_VENDOR | USB_RECIP_DEVICE | 
USB_ENDPOINT_IN)
+
+/* Requests */
+#define SIO_RESET_REQUEST             SIO_RESET
+#define SIO_SET_BAUDRATE_REQUEST      SIO_SET_BAUD_RATE
+#define SIO_SET_DATA_REQUEST          SIO_SET_DATA
+#define SIO_SET_FLOW_CTRL_REQUEST     SIO_SET_FLOW_CTRL
+#define SIO_SET_MODEM_CTRL_REQUEST    SIO_MODEM_CTRL
+#define SIO_POLL_MODEM_STATUS_REQUEST 0x05
+#define SIO_SET_EVENT_CHAR_REQUEST    0x06
+#define SIO_SET_ERROR_CHAR_REQUEST    0x07
+#define SIO_SET_LATENCY_TIMER_REQUEST 0x09
+#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A
+#define SIO_SET_BITMODE_REQUEST       0x0B
+#define SIO_READ_PINS_REQUEST         0x0C
+#define SIO_READ_EEPROM_REQUEST       0x90
+#define SIO_WRITE_EEPROM_REQUEST      0x91
+#define SIO_ERASE_EEPROM_REQUEST      0x92
+
+
 #define SIO_RESET_SIO 0
 #define SIO_RESET_PURGE_RX 1
 #define SIO_RESET_PURGE_TX 2
 
-#define SIO_SET_BAUDRATE_REQUEST_TYPE 0x40
-#define SIO_SET_BAUDRATE_REQUEST SIO_SET_BAUD_RATE
-
-#define SIO_SET_DATA_REQUEST_TYPE 0x40
-#define SIO_SET_DATA_REQUEST SIO_SET_DATA
-
-#define SIO_SET_FLOW_CTRL_REQUEST SIO_SET_FLOW_CTRL
-#define SIO_SET_FLOW_CTRL_REQUEST_TYPE 0x40
-
 #define SIO_DISABLE_FLOW_CTRL 0x0 
 #define SIO_RTS_CTS_HS (0x1 << 8)
 #define SIO_DTR_DSR_HS (0x2 << 8)
 #define SIO_XON_XOFF_HS (0x4 << 8)
 
-#define SIO_SET_MODEM_CTRL_REQUEST_TYPE 0x40
-#define SIO_SET_MODEM_CTRL_REQUEST SIO_MODEM_CTRL
-
 #define SIO_SET_DTR_MASK 0x1
 #define SIO_SET_DTR_HIGH ( 1 | ( SIO_SET_DTR_MASK  << 8))
 #define SIO_SET_DTR_LOW  ( 0 | ( SIO_SET_DTR_MASK  << 8))
@@ -214,7 +221,7 @@ struct ftdi_eeprom {
 
     /** self powered */
     int self_powered;
-    /** remote wakepu */
+    /** remote wakeup */
     int remote_wakeup;
     /** chip type */
     int BM_type_chip;
@@ -321,7 +328,8 @@ extern "C" {
 
     /* init and build eeprom from ftdi_eeprom structure */
     void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom);
-    int  ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output);
+    int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output);
+    int ftdi_eeprom_decode(struct ftdi_eeprom *eeprom, unsigned char *output, 
int size);
 
     /* "eeprom" needs to be valid 128 byte eeprom (generated by the eeprom 
generator)
        the checksum of the eeprom is valided */


hooks/post-receive
-- 
A library to talk to FTDI chips

--
libftdi-git - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi-git+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread
  • A library to talk to FTDI chips branch, master, updated. v0.15-17-g49c5ac7, libftdi-git <=