libftdi Archives

Subject: RFC: patch for libftdi1-1.0 to support MS Visual C++

From: Xiaofan Chen <xiaofanc@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Wed, 20 Feb 2013 14:21:45 +0800
On Wed, Feb 20, 2013 at 10:22 AM, Xiaofan Chen <xiaofanc@xxxxxxxxx> wrote:
> Just wondering if anyone has done something to get libftdi1-1.0
> built under MSVC (2008/2010/2012)? I think some fixes are
> needed.
>
> Last time I tried it there were issues with CMake,
> Now I think the CMake issues are resolved. But there
> are still issues with  <sys/time.h> and gettimeofday.
> Ref: 
> http://developer.intra2net.com/mailarchive/html/libftdi/2011/msg00478.html
>
> And I am wondering if there is a desire to make libftdi
> compatible with MSVC or not. The examples are
> also not really compatible with MSVC last time I tried.
> If yes, I think it is worth some time to get the codes fixed.
> After all, MSVC is still the most popular compiler for
> Windows.
>
> On the other hand, it is still possible to use libftdi1-1.0
> with MSVC using the dll even if the codes are not
> compatible with MSVC. Not so sure if it is possible
> to use the Boost binding dll under MSVC though.
>

The following patch is not that correct but I think you
can get the basic ideas.

It is interesting MSVC does not like the following.
     int i;
     divisor = 24000000 / baudrate;
The small patch to revert the sequence may be good
to be included.

The LIBUSB_CALL modifications should be safe as well.

I am not so sure how to deal with the gettimeofday()
which is not there for MSVC.

libusbx has the proper fix like this. But I am not
so sure how best to adapt from the changes.

And the examples need more work with regard to
unistd.h and other things.

https://github.com/libusbx/libusbx/blob/master/libusb/libusbi.h
https://github.com/libusbx/libusbx/blob/master/libusb/core.c

#if (defined(OS_WINDOWS) || defined(OS_WINCE)) && !defined(__GCC__)
#undef HAVE_GETTIMEOFDAY
int usbi_gettimeofday(struct timeval *tp, void *tzp);
#define LIBUSB_GETTIMEOFDAY_WIN32
#define HAVE_USBI_GETTIMEOFDAY
#else
#ifdef HAVE_GETTIMEOFDAY
#define usbi_gettimeofday(tv, tz) gettimeofday((tv), (tz))
#define HAVE_USBI_GETTIMEOFDAY
#endif
#endif

/* this is defined in libusbi.h if needed */
#ifdef LIBUSB_GETTIMEOFDAY_WIN32
/*
 * gettimeofday
 * Implementation according to:
 * The Open Group Base Specifications Issue 6
 * IEEE Std 1003.1, 2004 Edition
 */

/*
 *  THIS SOFTWARE IS NOT COPYRIGHTED
 *
 *  This source code is offered for use in the public domain. You may
 *  use, modify or distribute it freely.
 *
 *  This code is distributed in the hope that it will be useful but
 *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
 *  DISCLAIMED. This includes but is not limited to warranties of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 *  Contributed by:
 *  Danny Smith <dannysmith@xxxxxxxxxxxxxxxxxxxxx>
 */

/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
#define _W32_FT_OFFSET (116444736000000000)

int usbi_gettimeofday(struct timeval *tp, void *tzp)
{
        union {
                unsigned __int64 ns100; /* Time since 1 Jan 1601, in 100ns 
units */
                FILETIME ft;
        } _now;
        UNUSED(tzp);

        if(tp) {
#if defined(OS_WINCE)
                SYSTEMTIME st;
                GetSystemTime(&st);
                SystemTimeToFileTime(&st, &_now.ft);
#else
                GetSystemTimeAsFileTime (&_now.ft);
#endif
                tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 );
                tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
        }
        /* Always return 0 as per Open Group Base Specifications Issue 6.
           Do not set errno on error.  */
        return 0;
}
#endif


/* ++++++++++++++++++++++++++
 * my patch which is not that good.
*/


diff --git a/src/ftdi.c b/src/ftdi.c
index 5570bd4..3e65ef0 100644
--- a/src/ftdi.c
+++ b/src/ftdi.c
@@ -38,6 +38,68 @@
 #include "ftdi.h"
 #include "ftdi_version_i.h"

+#if defined(_MSC_VER)
+
+int gettimeofday(struct timeval *tp, void *tzp);
+
+#include <time.h>
+
+const __int64 DELTA_EPOCH_IN_MICROSECS= 11644473600000000;
+
+/* IN UNIX the use of the timezone struct is obsolete;
+ I don't know why you use it. See
http://linux.about.com/od/commands/l/blcmdl2_gettime.htm
+ But if you want to use this structure to know about GMT(UTC)
+ diffrence from your local time
+ it will be next: tz_minuteswest is the real diffrence in minutes
+ from GMT(UTC) and a tz_dsttime is a flag
+ indicates whether daylight is now in use
+*/
+struct timezone2
+{
+  __int32  tz_minuteswest; /* minutes W of Greenwich */
+  BOOL  tz_dsttime;     /* type of dst correction */
+};
+
+struct timeval2 {
+__int32    tv_sec;         /* seconds */
+__int32    tv_usec;        /* microseconds */
+};
+
+int gettimeofday(struct timeval2 *tv/*in*/, struct timezone2 *tz/*in*/)
+{
+  FILETIME ft;
+  __int64 tmpres = 0;
+  TIME_ZONE_INFORMATION tz_winapi;
+  int rez=0;
+
+   ZeroMemory(&ft,sizeof(ft));
+   ZeroMemory(&tz_winapi,sizeof(tz_winapi));
+
+    GetSystemTimeAsFileTime(&ft);
+
+    tmpres = ft.dwHighDateTime;
+    tmpres <<= 32;
+    tmpres |= ft.dwLowDateTime;
+
+    /*converting file time to unix epoch*/
+    tmpres /= 10;  /*convert into microseconds*/
+    tmpres -= DELTA_EPOCH_IN_MICROSECS;
+    tv->tv_sec = (__int32)(tmpres*0.000001);
+    tv->tv_usec =(tmpres%1000000);
+
+
+    //_tzset(),don't work properly, so we use GetTimeZoneInformation
+    rez=GetTimeZoneInformation(&tz_winapi);
+    tz->tz_dsttime=(rez==2)?TRUE:FALSE;
+    tz->tz_minuteswest = tz_winapi.Bias + ((rez==2)?tz_winapi.DaylightBias:0);
+
+  return 0;
+}
+
+#else
+#include <sys/time.h>
+#endif
+
 #define ftdi_error_return(code, str) do {  \
         if ( ftdi )                        \
             ftdi->error_str = str;         \
@@ -1016,8 +1078,8 @@ static int ftdi_to_clkbits_AM(int baudrate,
unsigned long *encoded_divisor)
     static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
     static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
     int divisor, best_divisor, best_baud, best_baud_diff;
+       int i;
     divisor = 24000000 / baudrate;
-    int i;

     // Round down to supported fraction (AM only)
     divisor -= am_adjust_dn[divisor & 7];
@@ -1392,7 +1454,7 @@ int ftdi_write_data(struct ftdi_context *ftdi,
unsigned char *buf, int size)
     return offset;
 }

-static void ftdi_read_data_cb(struct libusb_transfer *transfer)
+static void LIBUSB_CALL ftdi_read_data_cb(struct libusb_transfer *transfer)
 {
     struct ftdi_transfer_control *tc = (struct ftdi_transfer_control
*) transfer->user_data;
     struct ftdi_context *ftdi = tc->ftdi;
@@ -1474,7 +1536,7 @@ static void ftdi_read_data_cb(struct
libusb_transfer *transfer)
 }


-static void ftdi_write_data_cb(struct libusb_transfer *transfer)
+static void LIBUSB_CALL ftdi_write_data_cb(struct libusb_transfer *transfer)
 {
     struct ftdi_transfer_control *tc = (struct ftdi_transfer_control
*) transfer->user_data;
     struct ftdi_context *ftdi = tc->ftdi;
diff --git a/src/ftdi.h b/src/ftdi.h
index 141a795..a7d118e 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -18,7 +18,13 @@
 #define __libftdi_h__

 #include <stdint.h>
+
+#if defined(_MSC_VER)
+#include <time.h>
+int gettimeofday(struct timeval *tp, void *tzp);
+#else
 #include <sys/time.h>
+#endif

 /** FTDI chip type */
 enum ftdi_chip_type { TYPE_AM=0, TYPE_BM=1, TYPE_2232C=2, TYPE_R=3,
TYPE_2232H=4, TYPE_4232H=5, TYPE_232H=6 };
diff --git a/src/ftdi_stream.c b/src/ftdi_stream.c
index cf3acf5..cdc1a25 100644
--- a/src/ftdi_stream.c
+++ b/src/ftdi_stream.c
@@ -45,6 +45,13 @@

 #include "ftdi.h"

+#if defined(_MSC_VER)
+#include <time.h>
+extern int gettimeofday(struct timeval *tp, void *tzp);
+#else
+#include <sys/time.h>
+#endif
+
 typedef struct
 {
     FTDIStreamCallback *callback;
@@ -61,7 +68,7 @@ typedef struct
  *
  * state->result is only set when some error happens
  */
-static void
+static void LIBUSB_CALL
 ftdi_readstream_cb(struct libusb_transfer *transfer)
 {
    FTDIStreamState *state = transfer->user_data;


-- 
Xiaofan

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

Current Thread
  • RFC: patch for libftdi1-1.0 to support MS Visual C++, Xiaofan Chen <=