What worked for me - FT232H and D2XX maybe FT_Prog too

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mailhouse
 
Posts: 107
Joined: Sat Jul 25, 2015 8:06 pm

What worked for me - FT232H and D2XX maybe FT_Prog too

Post by mailhouse »

I'm on a mac so FT_Prog isn't something I'm dealing with, but I bet it uses the same code as the D2XX drivers, which I AM using.

With the virtual com port drivers, the vendor id/product id and serial number are read fine, and the drivers work fine, because those fields are populated. The issue rears its head when we try to use the deeper level drivers such as the D2XX drivers. After erasing and repopulating the EEPROM, i was able to get the board working as advertised, with the exception of the power LED. Perhaps these code snippets will allow a person to fix the EEPROM settings without complete erasure. Please test and post results.

I'm going to presume you know how to install drivers, and have already installed the D2XX drivers from the FTDI web site. If not, install them.

this code lists ftdi devices on the usb bus and displays basic eeprom info:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/include/ftd2xx.h"

FT_STATUS ftStatus;
FT_HANDLE ftHandle;
FT_DEVICE_LIST_INFO_NODE *devInfo;
DWORD numDevs;
DWORD Flags;
DWORD ID;
DWORD Type;
char SerialNumber[16];
char Description[64];


int main (void) {

ftStatus = FT_CreateDeviceInfoList(&numDevs);

if (ftStatus == FT_OK) {
        printf("Found %d device", numDevs);
                if (numDevs > 1 || numDevs == 0) {
                        printf("s:\n");
                } else {
                        printf(":\n");
                }
    }

if (numDevs > 0) {
        devInfo =
(FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs);
        ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs);
        if (ftStatus == FT_OK) {
                for (int i = 0; i < numDevs; i++) {
                        printf("Device %d:\n",i);
                        printf("   Flags=0x%x\n",devInfo[i].Flags);
                        printf("   Type=0x%x\n",devInfo[i].Type);
                        printf("   ID=0x%x\n",devInfo[i].ID);
                        printf("   SerialNumber=%s\n",devInfo[i].SerialNumber);
                        printf("   Description=%s\n",devInfo[i].Description);
                }
         }
     }
}
on a mac, it's

gcc -o list list.c -L/usr/local/lib -lftd2xx
if you saved the code as list.c

then execute ./list and it should spit out something like this

Code: Select all

Found 1 device:
Device 0:
   Flags=0x2
   Type=0x8
   ID=0x4036014
   SerialNumber=FTQTRXJL
   Description=FT232H
so jot down your serial number and edit it into the serial number of this code:

Code: Select all

#include <stdio.h>
#include "/usr/local/include/ftd2xx.h"

int main(int argc, char *argv[])
{
        FT_STATUS       ftStatus;
        FT_HANDLE       ftHandle0;
        int iport;
        FT_PROGRAM_DATA Data;
        
        if(argc > 1) {
                sscanf(argv[1], "%d", &iport);
        }
        else {
                iport = 0;
        }
        printf("opening port %d\n", iport);
        FT_SetVIDPID(0x0403, 0x6014);
        ftStatus = FT_Open(iport, &ftHandle0);
        
        if(ftStatus != FT_OK) {
                /* 
                        This can fail if the ftdi_sio driver is loaded
                        use lsmod to check this and rmmod ftdi_sio to remove
                        also rmmod usbserial
                 */
                printf("FT_Open(%d) failed\n", iport);
                return 1;
        }

        printf("ftHandle0 = %p\n", ftHandle0);

        Data.Signature1 = 0x00000000;
        Data.Signature2 = 0xffffffff;
        Data.VendorId = 0x0403;                         
        Data.ProductId = 0x6014;
        Data.Manufacturer =  "Adafruit";
        Data.ManufacturerId = "FT";
        Data.Description = "FT232H";
        Data.SerialNumber = "FTQTRXJL"; 
        Data.BANNED = 90;
        Data.PnP = 1;
        Data.SelfPowered = 0;
        Data.RemoteWakeup = 0;
        
        Data.PullDownEnableH = 0;
        Data.SerNumEnableH = 1;
        Data.ACSlowSlewH = 0;
        Data.ACSchmittInputH = 0;
        Data.ACDriveCurrentH = 4;
        Data.ADSlowSlewH = 0;
        Data.ADSchmittInputH = 0;
        Data.ADDriveCurrentH = 4;
        Data.Cbus0H = 0;
        Data.Cbus1H = 0;
        Data.Cbus2H = 0;
        // Data.Cbus3H = FT_232H_CBUS_TXLED;
        Data.Cbus3H = 0;
        //Data.Cbus4H = FT_232H_CBUS_RXLED;
        Data.Cbus4H = 0;
        Data.Cbus5H = 0;
        Data.Cbus6H = 0;
        Data.Cbus7H = 0;
        Data.Cbus8H = 0;
        Data.Cbus9H = 0;
        Data.IsFifoH = 0;
        Data.IsFifoTarH = 0;
        Data.IsFastSerH = 0;
        Data.IsFT1248H = 0;
        Data.FT1248CpolH = 0;
        Data.FT1248LsbH = 0;
        Data.FT1248FlowControlH = 0;
        Data.IsVCPH = 0;
        Data.PowerSaveEnableH = 0;




        ftStatus = FT_EE_Program(ftHandle0, &Data);
        if(ftStatus != FT_OK) {
                printf("FT_EE_Program failed (%d)\n", (int)ftStatus);
                FT_Close(ftHandle0);
        }
        FT_Close(ftHandle0);
        return 0;
}

build it using
gcc -o write write-232h.c -L/usr/local/lib -lftd2xx and then execute ./write

I strongly suggest against changing either Signature fields, VendorId, ProductId, or ManufacturerId fields.
If you examine the code, you can see where you could comment out the zero values, and uncomment the values to turn those pins to transmit and receive LED mode while using the virtual com port drivers, or d2xx drivers in UART mode.


it should spit out something similar to:

Code: Select all

opening port 0
ftHandle0 = 0x7fa3bc002000
ok, now some code to read it back. this code is

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "/usr/local/include/ftd2xx.h"

int main(int argc, char *argv[])
{
        FT_STATUS       ftStatus;
        FT_HANDLE       ftHandle0;
        DWORD dwDriverVer;
        int iport;
        static FT_PROGRAM_DATA Data;
        static FT_DEVICE ftDevice;
        DWORD libraryVersion = 0;
        int retCode = 0;
        UCHAR BitMode;
                
        
        ftStatus = FT_GetLibraryVersion(&libraryVersion);
        if (ftStatus == FT_OK)
        {
                printf("Library version = 0x%x\n", (unsigned int)libraryVersion);
        }
        else
        {
                printf("Error reading library version.\n");
                return 1;
        }
        
        if(argc > 1) {
                sscanf(argv[1], "%d", &iport);
        }
        else {
                iport = 0;
        }
        printf("Opening port %d\n", iport);
        
        ftStatus = FT_Open(iport, &ftHandle0);
        if(ftStatus != FT_OK) {
                /* 
                        This can fail if the ftdi_sio driver is loaded
                        use lsmod to check this and rmmod ftdi_sio to remove
                        also rmmod usbserial
                 */
                printf("FT_Open(%d) failed\n", iport);
                return 1;
        }
        
        printf("FT_Open succeeded.  Handle is %p\n", ftHandle0);


        ftStatus = FT_GetDriverVersion(ftHandle0, &dwDriverVer);
        if (ftStatus != FT_OK)
        {
                printf("FT_GetDriverVersion FAILED!\n");
                retCode = 1;
                goto exit;
        }

        printf("FT_GetDriverVersion succeeded. Driver version is 0x%X\n", dwDriverVer);
        ftStatus = FT_GetBitMode(ftHandle0, &BitMode);
        if (ftStatus != FT_OK)
        {
                printf("FT_GetBitMode FAILED!\n");
                retCode = 1;
                goto exit;
        }
        
        printf("FT_GetBitMode succeeded. Pin mode is 0x%X\n", BitMode);


        ftStatus = FT_GetDeviceInfo(ftHandle0,
                                    &ftDevice,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL); 
        if (ftStatus != FT_OK) 
        { 
                printf("FT_GetDeviceType FAILED!\n");
                retCode = 1;
                goto exit;
        }  

        printf("FT_GetDeviceInfo succeeded.  Device is type %d.\n", 
               (int)ftDevice);

        /* MUST set Signature1 and 2 before calling FT_EE_Read */
        Data.Signature1 = 0x00000000;
        Data.Signature2 = 0xffffffff;
        Data.Manufacturer = (char *)malloc(256); /* E.g "FTDI" */
        Data.ManufacturerId = (char *)malloc(256); /* E.g. "FT" */
        Data.Description = (char *)malloc(256); /* E.g. "USB HS Serial Converter" */
        Data.SerialNumber = (char *)malloc(256); /* E.g. "FT000001" if fixed, or NULL */
        if (Data.Manufacturer == NULL ||
            Data.ManufacturerId == NULL ||
            Data.Description == NULL ||
            Data.SerialNumber == NULL)
        {
                printf("Failed to allocate memory.\n");
                retCode = 1;
                goto exit;
        }

        ftStatus = FT_EE_Read(ftHandle0, &Data);
        if(ftStatus != FT_OK) {
                printf("FT_EE_Read failed\n");
                retCode = 1;
                goto exit;
        }

        printf("FT_EE_Read succeeded.\n\n");
                
        printf("Signature1 = %d\n", (int)Data.Signature1);                      
        printf("Signature2 = %d\n", (int)Data.Signature2);                      
        printf("Version = %d\n", (int)Data.Version);                                                                        
        printf("VendorId = 0x%04X\n", Data.VendorId);                           
        printf("ProductId = 0x%04X\n", Data.ProductId);
        printf("Manufacturer = %s\n", Data.Manufacturer);                       
        printf("ManufacturerId = %s\n", Data.ManufacturerId);           
        printf("Description = %s\n", Data.Description);                 
        printf("SerialNumber = %s\n", Data.SerialNumber);                       
        printf("BANNED = %d\n", Data.BANNED);                               
        printf("PnP = %d\n", Data.PnP) ;                                        
        printf("SelfPowered = %d\n", Data.SelfPowered);                 
        printf("RemoteWakeup = %d\n", Data.RemoteWakeup);                       
        printf("\n");


        if (ftDevice == FT_DEVICE_232H)
        {
                /* Rev 9 (FT232H) Extensions */
                printf("232H:\n");
                printf("-----\n");
                printf("\tPullDownEnableH = 0x%X\n", Data.PullDownEnableH);
                printf("\tSerNumEnableH = 0x%X\n", Data.SerNumEnableH);
                printf("\tACSlowSlewH = 0x%X\n", Data.ACSlowSlewH);
                printf("\tACSchmittInputH = 0x%X\n", Data.ACSchmittInputH);
                printf("\tACDriveCurrentH = 0x%X\n", Data.ADDriveCurrentH);
                printf("\tADSlowSlewH = 0x%X\n", Data.ADSlowSlewH);
                printf("\tADSchmittInputH = 0x%X\n", Data.ADSlowSlewH);
                printf("\tADDriveCurrentH = 0x%X\n", Data.ADDriveCurrentH);
                printf("\tCbus0H = 0x%X\n", Data.Cbus0H);
                printf("\tCbus1H = 0x%X\n", Data.Cbus1H);
                printf("\tCbus2H = 0x%X\n", Data.Cbus2H);
                printf("\tCbus3H = 0x%X\n", Data.Cbus3H);
                printf("\tCbus4H = 0x%X\n", Data.Cbus4H);
                printf("\tCbus5H = 0x%X\n", Data.Cbus5H);
                printf("\tCbus6H = 0x%X\n", Data.Cbus6H);
                printf("\tCbus7H = 0x%X\n", Data.Cbus7H);
                printf("\tCbus8H = 0x%X\n", Data.Cbus8H);
                printf("\tCbus9H = 0x%X\n", Data.Cbus9H);
                printf("\tIsFifoH = 0x%X\n", Data.IsFifoH);
                printf("\tIsFastSerH = 0x%X\n", Data.IsFastSerH);
                printf("\tIsFT1248H = 0x%X\n", Data.IsFT1248H);
                printf("\tFT1248CpolH = 0x%X\n", Data.FT1248CpolH);
                printf("\tFT1248LsbH = %d\n", Data.FT1248LsbH);
                printf("\tFT1248FlowControlH = %d\n", Data.FT1248FlowControlH);
                printf("\tIsVCPH = %d\n", Data.IsVCPH);
                printf("\tPowerSaveEnableH = %d\n", Data.PowerSaveEnableH);
        }
        
exit:
        free(Data.Manufacturer);
        free(Data.ManufacturerId);
        free(Data.Description);
        free(Data.SerialNumber);
        FT_Close(ftHandle0);
        printf("\nReturning %d\n", retCode);
        return retCode;
}
save it as read-ft232h.c and build it with
gcc -o read-ft232h read-ft232h.c -L/usr/local/lib -lftd2xx and then execute ./read-ft232h

should produce output similar to

Code: Select all

Library version = 0x10202
Opening port 0
FT_Open succeeded.  Handle is 0x7fe7f3006200
FT_GetDriverVersion succeeded. Driver version is 0x10202
FT_GetBitMode succeeded. Pin mode is 0xFF
FT_GetDeviceInfo succeeded.  Device is type 8.
FT_EE_Read succeeded.

Signature1 = 0
Signature2 = -1
Version = 5
VendorId = 0x0403
ProductId = 0x6014
Manufacturer = Adafruit
ManufacturerId = FT
Description = FT232H
SerialNumber = FTQTRXJL
BANNED = 90
PnP = 1
SelfPowered = 0
RemoteWakeup = 0

232H:
-----
	PullDownEnableH = 0x0
	SerNumEnableH = 0x1
	ACSlowSlewH = 0x0
	ACSchmittInputH = 0x0
	ACDriveCurrentH = 0x4
	ADSlowSlewH = 0x0
	ADSchmittInputH = 0x0
	ADDriveCurrentH = 0x4
	Cbus0H = 0x0
	Cbus1H = 0x0
	Cbus2H = 0x0
	Cbus3H = 0x1
	Cbus4H = 0x2
	Cbus5H = 0x0
	Cbus6H = 0x0
	Cbus7H = 0x0
	Cbus8H = 0x0
	Cbus9H = 0x0
	IsFifoH = 0x0
	IsFastSerH = 0x0
	IsFT1248H = 0x0
	FT1248CpolH = 0x0
	FT1248LsbH = 0
	FT1248FlowControlH = 0
	IsVCPH = 0
	PowerSaveEnableH = 0

Returning 0
hopefully this fixes the issue without having to blank the EEPROM becuase I really would like my power LED back (its the principle of it. i hate things that dont work.) maybe just changing settings works, without having to blank the EEPROM. Someone please test this on a new board.

this code is quick and dirty and pieced together mostly from the d2xx driver sample code
lots of good info found at ftdichip.com in the data sheet and the d2xx programmer's guide

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”