On Sat, 2009-06-27 at 20:50 +0200, Freddie Chopin wrote: > Second version of previous patch improved with suggestions from Ronald. > > Pls try (; Works for me <:
This patch now looks 1000 times better with the changes from Ronald. Thanks to both of you for producing and refining it. My only remaining suggestion would be to add a macro that eliminates the duplicate calls the GetProcAddress. From what I can see, each of those 5 line blocks can be reduced into a single macro call with the proper symbol name as the only argument. The magic that I used to implement the parse_type helpers in command.c will be helpful to see how to do it, but you might also need to look up how to "stringify" too. Thanks for making these improvements. --Z > plain text document attachment (win32_ft2232_ftd2xx_dynamic_v2.patch) > Index: ft2232.c > =================================================================== > --- ft2232.c (revision 2405) > +++ ft2232.c (working copy) > @@ -63,6 +63,51 @@ > #include <ftdi.h> > #endif > > +/* Dynamic loading of libraries at runtime - only for Win32 and ftd2xx.dll > currently */ > + > +#if defined(_WIN32) && BUILD_FT2232_FTD2XX == 1 > +#define FTD2XX_DYNAMIC 1 > +#else > +#define FTD2XX_DYNAMIC 0 > +#endif > + > +#if FTD2XX_DYNAMIC == 1 > + > +// typedefs for all used functions from ftd2xx.dll library > +typedef FT_STATUS (WINAPI *FT_Write_t)(FT_HANDLE ftHandle, LPVOID lpBuffer, > DWORD dwBytesToWrite, LPDWORD lpBytesWritten); > +typedef FT_STATUS (WINAPI *FT_Read_t)(FT_HANDLE ftHandle, LPVOID lpBuffer, > DWORD dwBytesToRead, LPDWORD lpBytesReturned); > +typedef FT_STATUS (WINAPI *FT_OpenEx_t)(PVOID pArg1, DWORD Flags, FT_HANDLE > *pHandle); > +typedef FT_STATUS (WINAPI *FT_ListDevices_t)(PVOID pArg1, PVOID pArg2, DWORD > Flags); > +typedef FT_STATUS (WINAPI *FT_SetLatencyTimer_t)(FT_HANDLE ftHandle, UCHAR > ucLatency); > +typedef FT_STATUS (WINAPI *FT_GetLatencyTimer_t)(FT_HANDLE ftHandle, PUCHAR > pucLatency); > +typedef FT_STATUS (WINAPI *FT_SetTimeouts_t)(FT_HANDLE ftHandle, ULONG > ReadTimeout, ULONG WriteTimeout); > +typedef FT_STATUS (WINAPI *FT_SetBitMode_t)(FT_HANDLE ftHandle, UCHAR > ucMask, UCHAR ucEnable); > +typedef FT_STATUS (WINAPI *FT_GetDeviceInfo_t)(FT_HANDLE ftHandle, FT_DEVICE > *lpftDevice, LPDWORD lpdwID, PCHAR SerialNumber, PCHAR Description, LPVOID > Dummy); > +typedef FT_STATUS (WINAPI *FT_Purge_t)(FT_HANDLE ftHandle, ULONG Mask); > +typedef FT_STATUS (WINAPI *FT_Close_t)(FT_HANDLE ftHandle); > + > +// library handle > +static HINSTANCE dynamic_library; > + > +// global pointers for read and write functions > +static FT_Write_t FT_Write_ptr; > +static FT_Read_t FT_Read_ptr; > + > +// replacements for original functions > +#define FT_Write (*FT_Write_ptr) > +#define FT_Read (*FT_Read_ptr) > +#define FT_OpenEx (*FT_OpenEx_ptr) > +#define FT_ListDevices (*FT_ListDevices_ptr) > +#define FT_SetLatencyTimer (*FT_SetLatencyTimer_ptr) > +#define FT_GetLatencyTimer (*FT_GetLatencyTimer_ptr) > +#define FT_SetTimeouts (*FT_SetTimeouts_ptr) > +#define FT_SetBitMode (*FT_SetBitMode_ptr) > +#define FT_GetDeviceInfo (*FT_GetDeviceInfo_ptr) > +#define FT_Purge (*FT_Purge_ptr) > +#define FT_Close (*FT_Close_ptr) > + > +#endif > + > /* max TCK for the high speed devices 30000 kHz */ > #define FTDI_2232H_4232H_MAX_TCK 30000 > > @@ -1803,6 +1848,78 @@ > > LOG_DEBUG("'ft2232' interface using FTD2XX with '%s' layout > (%4.4x:%4.4x)", ft2232_layout, vid, pid); > > +#if FTD2XX_DYNAMIC == 1 > + > + FT_OpenEx_t FT_OpenEx_ptr; > + FT_ListDevices_t FT_ListDevices_ptr; > + FT_SetLatencyTimer_t FT_SetLatencyTimer_ptr; > + FT_GetLatencyTimer_t FT_GetLatencyTimer_ptr; > + FT_SetTimeouts_t FT_SetTimeouts_ptr; > + FT_SetBitMode_t FT_SetBitMode_ptr; > + FT_GetDeviceInfo_t FT_GetDeviceInfo_ptr; > + > + dynamic_library = LoadLibrary("ftd2xx.dll"); > + > + if(dynamic_library == NULL) > + { > + LOG_ERROR("Can't open ftd2xx.dll"); > + return ERROR_JTAG_INIT_FAILED; > + } > + else > + { > + BOOL fail = FALSE; > + > + if((FT_Write_ptr = (FT_Write_t)GetProcAddress(dynamic_library, > "FT_Write")) == NULL) > + { > + LOG_ERROR("Can't get FT_Write() function"); > + fail = TRUE; > + } > + if((FT_Read_ptr = (FT_Read_t)GetProcAddress(dynamic_library, > "FT_Read")) == NULL) > + { > + LOG_ERROR("Can't get FT_Read() function"); > + fail = TRUE; > + } > + if((FT_OpenEx_ptr = > (FT_OpenEx_t)GetProcAddress(dynamic_library, "FT_OpenEx")) == NULL) > + { > + LOG_ERROR("Can't get FT_OpenEx() function"); > + fail = TRUE; > + } > + if((FT_ListDevices_ptr = > (FT_ListDevices_t)GetProcAddress(dynamic_library, "FT_ListDevices")) == NULL) > + { > + LOG_ERROR("Can't get FT_ListDevices() function"); > + fail = TRUE; > + } > + if((FT_SetLatencyTimer_ptr = > (FT_SetLatencyTimer_t)GetProcAddress(dynamic_library, "FT_SetLatencyTimer")) > == NULL) > + { > + LOG_ERROR("Can't get FT_SetLatencyTimer() function"); > + fail = TRUE; > + } > + if((FT_GetLatencyTimer_ptr = > (FT_GetLatencyTimer_t)GetProcAddress(dynamic_library, "FT_GetLatencyTimer")) > == NULL) > + { > + LOG_ERROR("Can't get FT_GetLatencyTimer() function"); > + fail = TRUE; > + } > + if((FT_SetTimeouts_ptr = > (FT_SetTimeouts_t)GetProcAddress(dynamic_library, "FT_SetTimeouts")) == NULL) > + { > + LOG_ERROR("Can't get FT_SetTimeouts() function"); > + fail = TRUE; > + } > + if((FT_SetBitMode_ptr = > (FT_SetBitMode_t)GetProcAddress(dynamic_library, "FT_SetBitMode")) == NULL) > + { > + LOG_ERROR("Can't get FT_SetBitMode() function"); > + fail = TRUE; > + } > + if((FT_GetDeviceInfo_ptr = > (FT_GetDeviceInfo_t)GetProcAddress(dynamic_library, "FT_GetDeviceInfo")) == > NULL) > + { > + LOG_ERROR("Can't get FT_GetDeviceInfo() function"); > + fail = TRUE; > + } > + > + if(fail != FALSE) > + return ERROR_JTAG_INIT_FAILED; > + } > +#endif > + > #if IS_WIN32 == 0 > /* Add non-standard Vid/Pid to the linux driver */ > if ((status = FT_SetVIDPID(vid, pid)) != FT_OK) > @@ -1956,6 +2073,15 @@ > { > FT_STATUS status; > > +#if FTD2XX_DYNAMIC == 1 > + FT_Purge_t FT_Purge_ptr; > + > + if((FT_Purge_ptr = (FT_Purge_t)GetProcAddress(dynamic_library, > "FT_Purge")) == NULL) > + { > + LOG_ERROR("Can't get FT_Purge() function"); > + return ERROR_JTAG_INIT_FAILED; > + } > +#endif > if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK) > { > LOG_ERROR("error purging ftd2xx device: %lu", status); > @@ -2760,6 +2886,17 @@ > #if BUILD_FT2232_FTD2XX == 1 > FT_STATUS status; > > +#if FTD2XX_DYNAMIC == 1 > + FT_Close_t FT_Close_ptr; > + int retval=ERROR_OK; > + > + if((FT_Close_ptr = (FT_Close_t)GetProcAddress(dynamic_library, > "FT_Close")) == NULL) > + { > + LOG_ERROR("Can't get FT_Close() function"); > + retval = ERROR_FAIL; > + } > + else > +#endif > status = FT_Close(ftdih); > #elif BUILD_FT2232_LIBFTDI == 1 > ftdi_usb_close(&ftdic); > @@ -2770,7 +2907,17 @@ > free(ft2232_buffer); > ft2232_buffer = NULL; > > +#if FTD2XX_DYNAMIC == 1 > + if(FreeLibrary(dynamic_library) == FALSE) > + { > + LOG_ERROR("Can't close library"); > + retval = ERROR_FAIL; > + } > + > + return retval; > +#else > return ERROR_OK; > +#endif > } > > > _______________________________________________ > Openocd-development mailing list > Openocd-development@lists.berlios.de > https://lists.berlios.de/mailman/listinfo/openocd-development _______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development