PrfrrdUsrNm has asked for the wisdom of the Perl Monks concerning the following question:

I’m trying to write some code to drive an FTDI USB-COM422-PLUS2.

The plan is to use one of the ports as a VCP and run the other with the D2XX driver in asynchronous Bit Bang mode.

This requires overriding the EEPROM driver settings in FTDIBUS.INF

Let’s assume I’ve done this part correctly.

I put together some code to test this:


#!/usr/bin/perl use strict; use warnings; use Win32::FTDI::FTD2XX; use Win32::SerialPort; my $FTDIdev = Win32::FTDI::FTD2XX->new(); my $PortName = "COM6"; #name of port we want to use my $stuff = pack(“a”, “stuff I want to write”); my $CPort6 = Win32::SerialPort-> new($PortName) || die "Can't open $PortName: $^E\n"; #initalise port #write to comport my $count_out = $CPort6->write($stuff); warn "write failed\n" unless ($count_out); sleep 1; my $PrintData = $CPort10->input; #expected return data #print print "Data: $PrintData 1\n"; my $Num = 2;# GetNumDevices(); print "No. Dev: $Num\n"; my $devOpen; #check if we can talk to the device with FTD2XX if($Num) { my $i = 1; $devOpen = $FTDIdev->OpenByIndex($i); my $devInfo = $FTDIdev->GetDeviceInfo($i) || die "Unable to get device info"; # if($devInfo) # { # my $out = sprintf(" Type:\t\t%d(%s)\n ID:\t\tVID(%04X) PID( +%04X)\n Serial:\t%s\n Descr:\t%s\n", $devInfo->{TypeID}, $devInfo->{T +ypeNm}, $devInfo->{VID}, $devInfo->{PID}, $devInfo->{Serial}, $devInf +o->{Descr} ); # print "$out"; # } } my $ID = $FTDIdev->PFT_HANDLE(); # point to the port we want my $sucecess = $FTDIdev->SetBitMode($ID, 0x03, 0x1); #FTDI chip, select pin 1 an pin 2, Asynchronous bit bang print "sucecess? $sucecess\n"; my $mode = $FTDIdev->GetBitMode($ID) || die "unable to get mode"; print "Mode is $mode\n"; my $devClose = $FTDIdev->Close(); $devOpen = $FTDIdev->OpenByIndex(1); print "$devOpen\n"; my $TrigOn = pack("C", 0xFF); #Test output $FTDIdev->SetWriteTimeout(1); $FTDIdev->write($ID, $TrigOn) || die "unable to write1"; Print “it works”; #end



Writing to COM6 works as expected. $mode returns 245, which seems to be bit bang mode from what I can tell. So, I'm assuming these aren't the problem.
...245 might not be normal for mode....

The program goes into an infinite loop @ $FTDIdev->write($ID, $TrigOn) and never prints “it works”.

The perl module (see FTDI site or CPAN) seems to require fewer inputs than what is defined in the D2XX programmer’s guide.

I suspect the issue is related to not clearly specifying which port I’m writing to.

Replies are listed 'Best First'.
Re: Problem Writing to FTDI COM Port using Win32::FTDI::FTD2XX
by kschwab (Vicar) on Jan 15, 2014 at 13:35 UTC
    I don't see a write() call in the docs at all. I do see a Write() call, and it doesn't want the ID of the device as a parameter. You're passing $ID to other methods that don't want it as well, like GetBitMode() and SetBitMode(). I suspect you want:
    $FTDIdev->Write($TrigOn,1)
    And, you'll need to fix your call to SetBitMode (remove the $ID param), and check that you're sending the right params to other calls as well.

      Sorry, should have stripped back the code to what it was initially before i started using the FTDI Programers guide definitions. This causes an error @ SetBitMode(1); "Use of uninitialized value in subroutine entry at blib\lib\Win32\FTDI\FTD2XX.pm (autosplit into blib\lib\Win32\FTDI\FTD2XX\SetBitMode.al) line 2467.

      However, the code continues to run and it still gets stuck @
      FTDIdev->write($TrigOn, 1);

        Here's the source:
        sub SetBitMode { my $self = shift; my $mask = shift; my $mode = shift; unless( defined( $self->{_PFT_SetBitMode} ) ) { return( undef ) unless( _importDll( $self, "PFT_SetBitMode" ) ); } $self->{_PFT_STATUS} = $self->{_PFT_SetBitMode}->Call( $self->{_PFT_ +HANDLE}, $mask, $mode ); return( 0 ) if( $self->{_PFT_STATUS} ); return( 1 ); } # SetBitMode()
        It wants a mode and a mask, and if you're passing in the ID, it's interpreting that as the mask. Unless you've got an older version or something, passing in the ID may supress some error, but it's not likely doing the right thing.