<GPIFとは?>

GPIFは480Mbpsもの高速なUSB転送データを、外部ハードウエアと自動的にやり取りするためのFX2独自の仕組みです。
GPIFのデーターバスは8bitあるいは16bitに設定することが出来ます。
外部回路からFX2チップに入力される信号をRDY信号、FX2チップから外部回路に出て行く信号をCTL信号と呼びます。
GPIFには8つのステートを設定することが可能であり、RDY信号の変化でステートの遷移を行ったり、ステート毎に各CTL信号を変化させたり、クロックに同期してウエイトを設けたりといったことが可能です。GPIFを使用することで最大98Mbyte/秒ものデータを転送することが可能になります。
チップタイプ別GPIF機能
キット(チップタイプ) 入力(RDY) 出力(CTL) GPIF
アドレス
デバッグステートピン
MINI FX2(56ピン) 2本 3本 無し 無し
FX2 USB2.0(128ピン) 5本 5本 あり(9本) あり(3本)
デバッグステートピンはGPIFの現在のステート番号(0-7)をリアルタイムで表示しますので、ロジアナなどで監視することでGPIFのステート遷移を確認しながらデバッグ出来ます。

GPIFアドレスはGPIFの転送に伴ってアドレスのカウントアップが出来ますので、バースト転送と組み合わせて使用することでアドレス信号のあるデバイスに一括してデータを転送出来ます。

FX2FWのGPIFでは、PCから送信されたデータはFX2のOUT2エンドポイント受信され、GPIFのシングルライト、あるいはバーストライトによって外部ハードウエアに引き渡されます。
一方、外部ハードウエアからGPIFによって取り込まれたデータは、FX2のIN6エンドポイントに取り込まれ、PCに転送されます。
FX2FWのGPIFエンドポイント
データ方向 エンドポイント Hi-Speed
(USB2.0)
Full-Speed
(USB1.1)
シングル転送コマンド
(1Word)
バースト転送コマンド
(nWord)
PC→FX2 OUT2(バースト)
OUT8(シングル)
512Byte
(トリプル)
64Byte
(トリプル)
CMD_SWRITE CMD_BWRITE
FX2→PC IN6
(バースト/シングル)
512Byte
(トリプル)
64Byte
(トリプル)
CMD_SREAD CMD_BREAD
(シングル転送時16bitバスの場合はデーターはHi、Lowの順番になります)
データ送受信用のエンドポイントはトリプルバッファに設定されているため、USBバスを効率的に使用することが出来ます。また、USB1.1のインターフェイスに接続した場合は自動的にバッファサイズが64Byteに変更されます。USB1.1接続時でも動作するアプリケーションを開発するためには、USB1.1接続時に発行するコマンドの長さを64Byteに制限する必要があります。(アプリケーション側でHi-Speed接続なのか、Full-Speed接続なのかを判断することでことは出来ます。)

GPIFにはシングル転送とバースト転送の2種類の転送モードがあります。シングルは1Word(GPIFバスが8bitの場合は1byte、16bitの場合は2byte)を転送するためのモードです。バースト転送はCPUの介在無しに指定したWord数分のデータをエンドポイントから連続して転送するモードです。バース転送を使用することでUSB2.0の高速転送を活用することが出来ます。

<GPIFデザイナー>

GPIFを使用するためにはGPIF用のデータを作成する必要があります。GPIF用のデーターは大きく分けて3種類あります。
GPIFに必要なデータ
データ種別 関連レジスタ FX2FWコマンド
制御データ
(IFCLK周波数など)
(RDY/CTL動作)
(ウエーブ選択)
IFCONFIG
GPIFREADYCFG
GPIFCTLCFG
GPIFIDLECS
GPIFIDLECTL
GPIFWFSELECT
GPIFREADYSTAT
CMD_GPIF
 +8byte
ウエーブデータ Waveform CMD_WAVE
 +32*4byte

CMD_WAVEn
 +32byte
フローデータ
(UDMAなど高度な設定)
FLOWSTATE
FLOWLOGIC
FLOWEQ0CTL
FLOWEQ1CTL
FLOWHOLDOFF
FLOWSTB
FLOWSTBEDGE
FLOWSTBHPERIOD
CMD_FLOW
 +9*4byte
ウエーブデータの設定コマンドが2種類(CMD_WAVEとCMD_WAVEn)ありますが、Full-Speed接続の場合はコマンド転送用のパイプ(CPIPE OUT8)が64byteしかありませんので、CMD_WAVEnを使用します。

この3種類のデーターは全てCypress社の提供するGUIの無償ツールGPIFデザイナー(GPIF Designer)を使用することで作成することが出来ます。

GPIFデザイナーを起動して、File->Newで使用するデバイスを選択します。
ここではとりあえず「CY FX2(128pin)」を選択しておきます。


「Block Diagram」タブの画面で右クリックをすることで各種の信号の設定を行うことが出来ます。

「Clk」を右クリックでClkプロパティが開きます。

GPIFで使用するIFCLKを内部(Internal)か外部(External)を選択します。
内部の場合は30/48MHzの選択や、反転(Invert)などの設定が出来ます。
「IFCLK Output」をチェックすることでFX2のIFCLK端子から出力することが出来ます。

「ADR」を右クリックでアドレス信号に関するプロパティが開きます。

FX2FWではここで設定した内容は反映されません。
(CMD_MODEコマンドでuse_addr(bit4)を立てることで設定)

「RDY」を右クリックでRDY信号に関するプロパティが開きます。

信号の名前を変更したり、RDY信号の取り込みをIFCLKと同期させて行うといったことを設定できます。

「CTL」を右クリックでCTL信号に関するプロパティが開きます。

CTL信号の名前や信号の属性を変更できます。


波形を設定するタブは4つあります。FIFO Read/Writeはバースト転送用の波形です。

この画面で波形の形や、ステート遷移の条件などを設定します。

<波形データを作成する>

GPIFを使用するアプリケーションの作成手順は以下のようになります。
  1. GPIFデザイナーを使用して「Block Diagram」、「FIFO Write」などの波形データの作成。
  2. GPIFデザイナーの「Tools->Export to GPIF.c file」を使用して波形データをGPIF.cにエクスポートする。
  3. DOS窓からコンバータツールを使用して「gpifcnv gpif.c」により、gpif_dat.cを作成。
  4. gpif_dat.cをPCのFX2FWアプリケーションにリンクする。
今回のアプリケーションではPCからの連続データをGPIFを使用して外部ロジックに書き出すことをにします。

GPIFデザイナーで「File->New」で「CY FX2(128pin)」を選択してください。
「Block Diagram」タブで、「Clk」を右クリックしてClkプロパティ開き、Internalの30MHzに設定してください。
(カメレオンUSBロジアナ100MHzで測定しやすくするため)

使用するのはバーストライトになりますので、「FIFO Write」タブの波形を編集します。

とりあえずこんな形になるように編集してください。
編集方法はポイント(三角や十字)をつけたいところで左クリックします。ポイントの属性は右クリックで設定します。(実際に少し触れば理解できると思います)

statusをポイントする際にDecision Pointウインドウが開きますので

このように設定してください。
(これは無条件にIDLEステートに遷移させる設定です)
(本来はこのDecision PointでRDY信号の状態を判断して、ステート遷移させることで外部ロジックとのインターフェイスを可能にします)
(LOOP (Re-Execute)をチェックしておくと、条件判定で同一ステート(この場合はs3です)に遷移したときに、データバス・アドレスラインの更新が指定されているばあいに、データバスあるいはアドレスバスの更新を行います。)

Dataのシグナルの色がピンクから黄色に変わっていますが、これはDataのポイントの属性が"Same Data"か"Next FIFO Data"の違いです。右クリックで設定します。
"Next FIFO Data"を設定することでPCから送信された次のデータをGPIFのデータバスに送り出します。

Addrのラインにポイントを設定することでGPIFのアドレスラインをインクリメントすることが出来ます。

波形を編集していくと自動的にStatesの行にs0-s6、IDLEのステートが生成されます。GPIFではs0-s6以上のステートを追加することは出来ません。(あまりにも複雑なことは出来ませんので、ポイントの設定には注意が必要です。)

波形の編集が完了したら、「Tools->Export to GPIF.c file」を使用して波形データをエクスポートします。
エクスポート先とファイル名を聞いてきますので、適当なディレクトリでgpifという名前で保存してください。

gpif.cの本来の目的はFX2のファームウエアの一部としてコンパイルして使用するものですが、FX2FWではこのgpif.cから必要な波形データを抽出して使用しています。
その抽出するためのコンバータがgpifcnv.exe(こちらからダウンロード)です。
Windowsのコマンドプロンプト画面から「gpifcnv gpif.c」と実行することで、gpif_dat.cとgpif_dat.binファイルが作成されます。gpif_dat.cはCのソース形式ですので、PCのFX2FWアプリケーションプログラムとコンパイルすることで使用します。

コンバートされたデータの内容
オフセット 長さ データの内容
0 8 制御データ
8 32 Wave0
(GPIFデザイナーの最初の波形)
40 32 wave1
72 32 wave2
104 32 wave3
136 9 flow0(wave0のフローデータ)
145 9 flow1(wave1のフローデータ)
154 9 flow2(wave2のフローデータ)
163 9 flow3(wave3のフローデータ)

<PCアプリケーション>

GPIFの波形データを作成しましたので、これを使用するFX2FWのPCアプリケーションを作成します。
FX2FWアプリケーションの基本的な使い方はFX2FWのページで解説していますので、ここではGPIFに関する部分を重点的に説明します。
ファイル構成は以下のようになります。
PIOのプログラム構成に加えてgpifcnv.exeでコンバートしたgpif_data.cが追加されます。
cusb.h USB操作、型宣言ヘッダ
cusb.c USB操作プログラム
fx2fw.h FX2FWヘッダ
fx2fw_prog.h FX2FW転送ファーム
main.c メインプログラム
gpif_dat.c GPIF波形データ
使用するパイプ
プログラム中での
名前
エンドポイント パイプ番号 用途
CPIPE OUT2 1 コマンド、
パラメータ、
シングルライトデータ
送信用
TFIFO OUT2 0 バーストライトデータ
送信用
RFIFO IN6 2 コマンド結果、
シングルリードデータ、
バーストリードデータ
受信用
メインプログラム(main.c)を解説します。
  1. #include <windows.h>
  2. #include <stdio.h>

  3. #include "cusb.h"
  4. #include "fx2fw.h"
  5. #include "fx2fw_prog.h"

  6. u8 buf[0x200];

  7. HANDLE dev_handle;

  8. int main( int argc, char *argv[] ){
  9.   u8 cmd[512];
  10.   s32 i;

  11.   if(cusb_init(-1,&dev_handle,fw_bin,"F2FW","V100")){
  12.     printf("Can't found EZ-USB.\n");
  13.     exit(-1);
  14.   }

  15.   i=0;
  16.   cmd[i++]=CMD_MODE;
  17.   cmd[i++]=MODE_GPIF|MODE_16BIT|MODE_ADDR|MODE_NOFLOW|MODE_DEBG;
  18.   cmd[i++]=CMD_GPIF;
  19.   memcpy(cmd+i,gpif_dat,8);
  20.   i+=8;
  21.   cmd[i++]=CMD_FLOW;
  22.   memcpy(cmd+i,gpif_dat+8+32*4,36);
  23.   i+=36;
  24.   usb_bulk_write(&dev_handle,CPIPE,cmd,i);

  25.   i=0;
  26.   cmd[i++]=CMD_WAVE3;
  27.   memcpy(cmd+i,gpif_dat+8+32*3,32);
  28.   i+=32;
  29.   usb_bulk_write(&dev_handle,CPIPE,cmd,i);

  30.   for(i=0;i<0x200;i++){
  31.     buf[i]=i;
  32.   }

  33.   i=0;
  34.   cmd[i++]=CMD_BWRITE;
  35.   cmd[i++]=0x00;//0x100*2 byte
  36.   cmd[i++]=0x01;
  37.   usb_bulk_write(&dev_handle,CPIPE,cmd,i);
  38.   usb_bulk_write(&dev_handle,TFIFO,buf,0x100*2);
  39. }
3-5行目、11-14行目 FX2FW関連の処理はPIOと同じです。

16-17行目 FX2FWをGPIFモードに設定し、データーバス16bit、GPIFアドレスラインあり、フロー制御無し、デバッグステート表示ありの設定をしています。詳しくはfx2fw.hのMODE_GPIFを参照してください。

18-19行目 GPIFの制御データを設定します。

21-22行目 GPIFのフロー制データを設定します。

24行目 コマンドをFX2に転送。

26-29行目 バースト書き込み用の波形はデフォルトでWAVE3ですので、WAVE3の波形データを登録します。
コマンドと波形データの合計が64byte以下ですので、このプログラムはUSB1.1接続時でも動作可能です。

30-32行目 とりあえずバッファにダミーパターンを設定します。

34-37行目 バーストライト転送コマンドと、転送データが0x0100ワードであることをFX2に転送します。

バーストライト/リードコマンドは単独で発行するようにします。理由はバーストデータを送受信する前に、次のバースト命令が入るとGPIFの奪い合いが起こり、ロック状態になってしまうからです。

38行目 GPIFのデータバスを16bitに設定しているので、実際に転送するデータは0x100*2バイトです。
TFIFOパイプを使用してデータをFX2に転送します。
今回のサンプルコードはこちらからダウンロードしてください。
(VC++6.0のプロジェクトファイルです)

<実行結果>

作成したGPIFアプリケーションの動作を確認するには、ロジアナを接続して波形を観測するのが最も確実です。
「EZ-USB FX2」と「カメレオンUSBロジアナ」の接続はこちらのページをご覧ください。
(リンク先のページはAVRとも接続していますが、今回のケースではAVRは不要です)


どうでしょうか?
実際にGPIFデザイナーで設定した通りの結果となりました。
難しいと思われがちなGPIFですが、PCのGUIツールで設定・変更が出来ると結構強力なツールだと思いませんか?
FX2FWを使用してUSB2.0の480Mbpsを使いこなすようなアプリケーションをどんどん開発していきましょう。

<FX2FW使いこなしTIPS>

RDY信号も使用しない非常に単純な例で解説をしてしまいましたが、まずは何よりも使ってみることが大事です。
そこでここではFX2FWでGPIFを更に使いこなすためのテクニックを紹介していきます。