Visual Basic 2019で、FT232HLの汎用出力を使ってみる

FT232H

前のブログで、FTDI社のホームページからダウンロードしたサンプルプログラムを使って、Visual Basic 2019でFTD2XX.DLLを使ってみました。

今回もFTD2XX.DLLを使い、FT232HLをUSB-GPO(汎用出力)変換ボードとして使ってみたいと思います。

スポンサーリンク

目標仕様

以下に目標仕様をだらだらと書いていますが、結局は、GPOのHigh/Lowレベル信号を、LEDのON/OFFで確認するだけです。

ハードウェア

今回の目標仕様です。使うのは、パソコン、FT232HL(秋月電子)、FPGAボードのDE0-Nanoです。

FT232HLの出力ポートをFPGAに接続し、それでDE0-Nanoに実装されたLEDをON/OFFさせます。

接続は上図です。

パソコンからUSB経由でFT232HLに設定やコマンドを送信します。FT232HLへの給電もUSBから行います。

パソコンとDE0-NanoもUSBで接続しますが、FPGAの書き込み後は給電を行うだけで、データの送受信はしていません。

FT232HのGPO(汎用出力)信号は、DE0-Nano上のFPGAに出力します。ちなみに、信号数は8本です。

FPGAは必要ないのですが、LEDがFPGAのポートに接続されているので、FPGA経由でLEDをON/OFFさせます。

そのため、FPGA内の回路は、下図のように入力したGPO信号をそのままLEDにつなげているだけです。

ソフトウェア

FTD2XX.DLLを使ったVBでのアプリ開発ですが、これまで同様、FTDI社のサンプルプログラムをベースにしています。

今回もFormのデザインなどは全て流用させてもらいました。

サンプルプログラムがうまく起動すると、上図のウインドウが起動します。

ここで”String to Write”のテキストボックスに、1byteのデータを16進数で入力し、”Click here to run”のボタンをクリックします。

ここの例では0x55を入力しているので、8個あるLEDに01010101が出力され、0出力のLEDは消灯、1出力のLEDは点灯すれば成功です。

Visual Basic 2019でのアプリケーション開発

FT232Hのコンフィギュレーション

FTDIさんのICは多機能で、FT232Hにも色々な機能があります。

FT232Hのデータシートによると、以下のコンフィギュレーションがあるようです。

どの機能を使いたいかで、FT232Hのコンフィギュレーションを選択する必要があるようです。

前回は”ASYNC Serial(RS232)”を使用しましたが、今回は”MPSSE”を使ってみます。

たぶん、”MPSSE”以外でもGPIOは使用できると思うのですが、FT232HLの説明書のピン機能表を見てMPSSEに決めました。

ちなみに、FT232HLでUSBからJTAG、I2C、SPIに変換する際も、MPSSEを使用するようです。

ソースコード

ソースコードは前回と比較し、”Button1_Click”の関数だけ修正しました。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim DeviceCount As Integer
        Dim DeviceIndex As Integer
        Dim TempDevString As String
        Dim BytesWritten As Integer
        Dim TempStringData As String
        Dim BytesRead As Integer

        ' Get the number of device attached
        FT_Status = FT_GetNumberOfDevices(DeviceCount, vbNullChar, FT_LIST_NUMBER_ONLY)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If
        ' Display device count on form
        TextBox1.Text = DeviceCount.ToString

        ' Get serial number of device with index 0
        ' Allocate space for string variable
        TempDevString = Space(16)
        FT_Status = FT_GetDeviceString(DeviceIndex, TempDevString, FT_LIST_BY_INDEX Or FT_OPEN_BY_SERIAL_NUMBER)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If
        FT_Serial_Number = Microsoft.VisualBasic.Left(TempDevString, InStr(1, TempDevString, vbNullChar) - 1)
        ' Display serial number on form
        TextBox2.Text = FT_Serial_Number

        ' Get description of device with index 0
        ' Allocate space for string variable
        TempDevString = Space(64)
        FT_Status = FT_GetDeviceString(DeviceIndex, TempDevString, FT_LIST_BY_INDEX Or FT_OPEN_BY_DESCRIPTION)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If
        FT_Description = Microsoft.VisualBasic.Left(TempDevString, InStr(1, TempDevString, vbNullChar) - 1)
        ' Display serial number on form
        TextBox3.Text = FT_Description

        'Open device by serial number
        FT_Description = "USB <-> Serial Converter"

        FT_Status = FT_OpenByDescription(FT_Description, 2, FT_Handle)
        If FT_Status <> FT_OK Then
            MsgBox("Failed to open device.", , )
            Exit Sub
        End If

        ' Reset device
        FT_Status = FT_ResetDevice(FT_Handle)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If

        FT_Status = FT_SetBitMode(FT_Handle, &H0, &H2)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If

        'Output Port Data Write
        Dim SendBuffer(2) As Byte

        SendBuffer(0) = &H82
        SendBuffer(1) = "&H" + TextBox4.Text
        SendBuffer(2) = &HFF

        FT_Status = FT_Write_Bytes(FT_Handle, SendBuffer(0), 3, BytesWritten)

        ' Check
        If FT_Status <> FT_OK Then
            MsgBox("Write Error")
            Exit Sub
        End If

        ' Close device
        FT_Status = FT_Close(FT_Handle)
        If FT_Status <> FT_OK Then
            Exit Sub
        End If

    End Sub

1行目から53行目は、前回と同様で、サンプルプログラムのほぼコピーです。

FT_SetBitMode

FT_Status = FT_SetBitMode(FT_Handle, &H0, &H2)

55行目の”FT_SetBitMode”でMPSSEに設定しています。以下はFTDI社の”D2XX Programmer’s Guide“からの抜粋です。ucMaskの意味がちょっと理解できていませんが、0にセットしておきました。

FT_Write_Bytes(OPCODE, Value, Direction)

以下はFTDI社の”Application Note AN_108 Command Processor for MPSSE and MCU Host Bus Emulation Modes“からの抜粋です。

まずGPO(汎用出力)ポートを使う場合、OPCODEは0x80と0x82の2つあります。

0x80は”Low Byte”で、FT232HのADBUS 7-0の8信号のことのようです。
0x82は”High Byte”で、FT232HのACBUS 7-0の8信号のことのようです。

そのため、この資料を読むと、FT232HLのGPIOピンは、ACBUSとADBUSあわせて合計16本になるみたいです。

2番目の引数であるValueは出力データです。

3番目の引数であるDirectionは、”A 1 in the Direction byte will make that bit an output.”と記載されています。”1をセットしたらそのbitは出力ポート”という意味だと思いますが、OPCODEですでに出力ポートに設定しているのに、また設定するの???という感じです。

ACBUS 3-0は出力ポート、ACBUS 7-4は入力ポート、みたいな使い方ができて、そのために使うのかな???ここは確認していないです。

引数が決まったら、byte型の配列に入力します。

ここでは、
OPCODE = 0x82
Value = 実行時にテキストボックスに入力
Direction = 0xFF
です。

        Dim SendBuffer(2) As Byte

        SendBuffer(0) = &H82
        SendBuffer(1) = "&H" + TextBox4.Text
        SendBuffer(2) = &HFF

配列にデータを入力したら、FT_Write_Bytesで送信します。

FT_Status = FT_Write_Bytes(FT_Handle, SendBuffer(0), 3, BytesWritten)

うまく動けば、これでポートに信号が出力されているはずです。

実験結果

それでは実験をした結果です。

“String to Write”のテキストボックスに55(hex)を入力して、”Click here to run”をクリックします。
この55(hex)が、第2引数のValueです。

クリック後のDE0-Nanoの状態です。

赤の8本のジャンパー線は信号線で、黒のジャンパー線はGNDです。

ちゃんと01010101で点灯しました。

AA(hex)でも試しました。

10101010で点灯してくれました。

ここまではACBUS 7-0で試しましたが、ADBUS 7-0(OPCODE=0x80)でも試してみました。

データは55とAAの2パターンです。

ADBUSの方もうまく動いてくれました。

FT232HLとDE0-Nano同時使用時の注意点

FT232Hが実装されたFT232HLを使用してきましたが、同じようなFTDI社のICはDE0-Nanoボードにも使用されています。

そのため、下図の赤枠部分には、FT232HLではなく、DE0-Nanoの情報が表示されてしまいました。

“Number of Device”にも2と表示されています。

そのため、”FT_OpenByDescription”関数でデバイスオープンするときには、DE0-Nano側のICにアクセスしてしまいます。

今回は、その回避策として、ソースコード43行目に以下のコマンドを追加しました。

FT_Description = "USB <-> Serial Converter"

あまりスマートではないですが、これでFT232Hのデバイスをオープンしてくれます。

あと、電圧にも注意しましょう。

DE0-NanoのFPGAは、確か、3.3Vだったので、FT232HLの電圧も3.3Vにしておきましょう。

まとめ

FT232HLのマニュアルにあるFT232Hピン機能表を見ると、MPSSEモードだとADBUSは4本しかGPIOピンとして使えないのかなと思っていましたが、実際には8本がGPO(汎用出力)として使えました。

ということは、8本とも入力ポートととしても使用できるのかな???ここは未確認です。

MPSSEでFPGAと高速で送受信ができるようになるといいな~と思ってます。

タイトルとURLをコピーしました