サンプルプログラミング例 T
 Classic Programming Interface

2003/02/27(更新日 )


パソコンから FT8U245AM/BM (FTDI社) にデータを送るためには,ドライバは不要ですが制御のためにプログラムする必要があります.D2XX Direct ドライバ の場合には,2種類の関数を利用することができます.

D2XX Classic
FT-Win32

FT-Win32 は,従来の Win32 API の関数名や引数と互換性のある仕様となっています.従来のCOMアプリケーションを修正し,D2XX Direct ドライバ 用に変換することが容易です.具体的には,次のようなものです.

FT_W32_CreateFile
FT_W32_ReadFile
FT_W32_WriteFile

” FT_W32_ ”を省けば,Win32 API の CreateFile,ReadFile,WriteFile になります.CreateFile の第6引数には,FT_OPEN_BY_DESCRIPTION など固有のものもあり,完全に互換ではありません.また,FT245(パラレルタイプ)は,ポーレートや RTS/CTS の制御はできず,関数は無効となります.

すでにAPI 関数のアプリケーションがある場合には,仮想COMポートドライバを利用するか,ダイレクトドライバとFT_W32によるプログラミングをお勧めします.しかしながら,既存のリソースを利用できない場合,D2XX Classic によるプログラミングの方が容易に記述できます.

D2XX Direct ドライバ と D2XX Classic を利用したプログラミングの例を紹介します.PC(パソコン) と ASB-004 を接続し,4096バイト( 00 01 02 .. FF )を受信すると 5Mバイト( 00 01 02 .. FF )を返信する仕様としました.
VHDLファイルやVisual C++のプロジェクトはページの一番下にあります.

<通信方法>



パソコン側のサンプルプログラムは,Visual C++を利用し,簡単な API 関数のみを利用しています.使用した関数を順に,全て説明します.

 <実行画面>

エラー処理は全て行っていませんので,ご了承ください.



ftStatus = FT_OpenEx("ASB-004 TEST", FT_OPEN_BY_DESCRIPTION, &ftHandle);
USB機器を特定するためには, FT_OPEN_BY_DESCRIPTION と FT_OPEN_BY_SERIAL_NUMBER があります.EEPROMの内容と一致させてください.

FT_ResetDevice( ftHandle );
デバイスのリセット

FT_Purge( ftHandle, FT_PURGE_RX | FT_PURGE_TX);
送信と受信のバッファをクリア

FT_SetTimeouts( ftHandle, NULL, NULL );
タイムアウト時間を設定します.タイムアウトしない場合には,この関数を記述しないか,引数をゼロとしてください.タイムアウト設定しないで,バッファからデータの読み込みを行うと,待機状態となります.デッドロックに注意して下さい.

hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
非シグナル状態として,イベントオブジェクトを生成します.もし,シグナル状態にすれば,起動時に WaitForSingleObject( hEvent, INFINITE ); を通過します.

FT_SetEventNotification( ftHandle, FT_EVENT_RXCHAR, hEvent );
イベントは FT_EVENT_RXCHAR と FT_EVENT_MODEM_STATUS がありますが,FT245(パラレル)なので,データ受信時のイベントを発生のみとします.

hRxThread = CreateThread( NULL, 0, GetRxQueue, NULL, 0, &ThRxID ) ;
受信時にプログラムを待機状態にしないために,受信用のスレッドを生成します.

SetEvent( hEvent );
WaitForSingleObject( hEvent, INFINITE ); を通過させることができます.受信スレッド生成後に,読込みしたい場合になどに利用して下さい.

受信スレッド
while( 条件 )
 {
   WaitForSingleObject( hEvent, INFINITE ) ;
   FT_GetQueueStatus( ftHandle, &RxQueSize );
   ftRxStatus = FT_Read( ftHandle, FT_RXD, RxQueSize, &dwRxBytes );
   (省略)
 }

タイムアウト設定していない場合には,データを受信するまで待機状態となります.この状態では,データを送信することができません.そのためにFT_GetQueueStatus によって,現在キューに格納されているバイト数を得ます.その数だけ FT_Read 関数で読み取ります.つまり,タイムアウト設定していないので,取れる分だけ取るということになります.受信できる上限は,4096バイトとなります.dwRxBytes には読み込んだバイト数です.

注意点ですが,(省略)部分の処理が遅いとイベントを取りこぼします.これは,Sleep(1); を挿入することで,再現できます.メモリにデータを転送する程度で終了させてください.取りこぼすとは,受信データを取りこぼすという意味ではありません.

押しボタンによる送信
ftTxStatus = FT_Write( ftHandle, FT_TXD, 4096, &dwTxBytes );
一回で送信できる4096バイトを送信します.dwTxBytes には読み込んだバイト数です.以下のように4096バイトを1バイトづつ送信すると,遅くなりますので注意して下さい.
 for ( i=0; i<4096; i++ ) {
  FT_Write( ftHandle, FT_TXD, 1, &dwTxBytes );
 }



FTD2XX によるプログラミングには,「FTD2XX.H」 と 「FTD2XX.LIB」 が必要となります.同じディレクトリに格納するか,パスを通してください.以下のように,[プロジェクトの設定]にライブラリ( FTD2XX.LIB )を追加して下さい.




下の波形はRD#とWRをロジアナで観測したものです.送信 ( 4096byte ) から受信 ( 5M byte ) までに,7.6秒かかりました.ASB-004の回路を修正することによって,より速くなります.制御回路のステートマシーンが18.432MHzで動作しているためです.
RD# WR

VHDL
FT245_SDRV.ucf
FT245_SDRV.vhd
RCV_CNT.vhd
SND_CNT.vhd
USB_ARBITER.vhd

Visual C++
FT245_EV03.ZIP

メールでのご質問はこちらへどうぞ

HDLのホームページへ