USB 3.0プログラムの作成方法
デバイスのオープン
デバイスをオープンするには、TKUSBFX3Open関数を呼び出します。
TKUSBFX3Openの使い方の例を次のリストに示します。
char DeviceName[100];
unsigned short pid,vid;
int status = TKUSBFX3Open(0,&vid,&pid,DeviceName,sizeof(DeviceName));
if(status) {
printf("USB open success. VID=%04x PID=%04x DeviceName=¥"%s¥"¥n"
,vid,pid,DeviceName);
}
else {
printf("USB open failed.");
}
if((vid == 0x2129) && (pid == 0x0520)) {
printf("NP1052(特電FX3ボード)を発見しました¥n");
}
if((vid == 0x2129) && (pid == 0x0640)) {
printf("NP1064(特電Artix-7ボード)を発見しました¥n");
}
TKUSBFX3Open関数の引数にある、vidとpid、DeviceNameは、見つかったデバイスのベンダIDや名前を格納して返します。
このTKUSBFX3Open関数は、CyAPIが実行されるすべてのデバイスがオープンできます。
複数のボードを区別するには
もし、1つのPCに複数個のFX3デバイスがつながっている場合、そのどれもがTKUSBFX3Openでオープンできてしまいます。したがって、目的の特電FX3ボードがどうかを判断するため、VIDとPIDを活用してください。
TKUSBFX3Open関数の第一引数は、PCにつながっている何個目のFX3デバイスをオープンするかを指定します。PCに接続されているFX3デバイスの個数を調べるには、TKUSBFX3DeviceCount関数を使います。
イメージファイルの転送
ファームウェアが書き込まれていないCypress EZ-USB FX3にイメージファイル(*.img)を転送するには、TKUSBFX3WriteToRAMまたはTKUSBFX3WriteToSPIROMを使います。
SPI ROMから起動している場合は、この関数は不要です。
TKUSBFX3WriteToRAMの使い方の例を次のリストに示します。
char ErrorReason[100];
if(TKUSBFX3WriteToRAM("SlaveFifoNP1052.img",ErrorReason,100)) {
printf("ファームウェアを書き込みました¥n");
Sleep(1000);
}
else {
printf("ファームウェアの転送に失敗しました 理由:%s¥n",ErrorReason);
return false;
}
バルク転送のやりかた
低レベルな転送
FX3のエンドポイントにデータを転送するには、TKUSBFX3BulkOutとTKUSBFX3BulkInを使います。
下のコードを参考にしてください。このコードでは、wbufに格納されたデータをエンドポイント2に1024バイト送り、エンドポイント6から1024バイトのデータを受け取って、rbufに格納しています。
TKUSBFX3BulkOut(2, wbuf, 1024); TKUSBFX3BulkIn(6, rbuf, 1024);
ただし、これらの関数は低レベルなパケットの送信を行うものなので、あまり使いません。
また、BulkInを実行したときに、FPGAが送信可能状態になっている必要があります。必要なデータが送られてこないと、この関数は制御を返しません。しかも、BulkInを要求しているかどうかはFPGA内部のロジックには伝えられません。
(FPGA内部ロジックは、ホストPCがBulkInを要求しているかどうかを認知できません)
このように低レベルなので、普段の通信では次の「高機能データ送受信」を使います。
高機能なデータ転送のやりかた
高機能データ送受信
特電IPコアにデータを送受信するには、USBWriteDataとUSBReadDataを使います。
unsigned long addr = 0x10000; unsigned short flag = 1; unsigned long len = 0x8000; USBWriteData(addr,wdata,len,flag); USBReadData(addr,wdata,len,flag);
バルク転送と比べて、
- 転送先のアドレス(通常はDDR3メモリだったり、FPGA内部レジスタだったり)の指定が可能
- 転送時にフラグ(ユーザが自由に使える16bitのデータ)が付けられる
- BulkInやBulkOutの要求が、FPGA内に制御信号として出てくる
という利点があります。
これらの関数のaddrに指定した値は、IPコアのaddr_o[31:0]ポートから出力されます。
これらの関数のflagに指定した値は、IPコアのflga_o[15:0]ポートから出力されます。
addrとflagはアプリケーションでに自由に使うことができます。
簡単なサンプルプログラム
一番簡単な、プログラムを次のリストに示します。
#include <stdio.h>
#include <stdlib.h>
#include <tkusbfx3.h>
int main()
{
char DeviceName[100];
unsigned short pid,vid;
// FX3をオープンする
int status = TKUSBFX3Open(0,&vid,&pid,DeviceName,sizeof(DeviceName));
if(status) {
printf("USB open success. VID=%04x PID=%04x DeviceName=¥"%s¥"¥n"
,vid,pid,DeviceName);
}
else {
printf("USB open failed.");
return 0;
}
if((vid == 0x2129) && (pid == 0x0640)) {
printf("NP1064(特電Artix-7ボード)を発見しました¥n");
}
else
{
// 違うデバイスが見つかった
return 0;
}
unsigned long addr = 0x10000;
unsigned short flag = 1;
unsigned long len = 0x8000;
USBWriteData(addr,wdata,len,flag); // 特電IPコアにデータ送信
USBReadData(addr,wdata,len,flag); // 特電IPコアからデータ送信
}
このプログラムをuserapp.cppとして保存してください。
APIの詳しい説明は、こちらのページをご覧ください。
プログラムのビルド
プログラムをビルドするには、ヘッダファイル(*.h)とインポートライブラリ(*.lib)が必要です。また、プログラムを実行するにはDLLが必要です。これらはUSB3.0の通信テストプログラムをの中にあるので、ダウンロードしてください。
その中にあるtkusbfx3.dllがDLL本体です。このDLLはプログラムの実行時にEXEと同じディレクトリに入れておいてください。
tkusbfx3.hがDLLを使うためのヘッダ、tkusbfx3_bcc.libがBorlandC++用のインポートライブラリ、tkusbfx3.libがVC用のインポートライブラリです。これらはプログラムのコンパイル時に必要です。
コンパイルするには以下のようにします。
Borland C++ Compilerの場合
bcc32 userapp.cpp tkusbfx3_bcc.lib setupapi.lib
Visual C++の場合
cl userapp.cpp tkusbfx3.lib setupapi.lib
いずれも、cppのファイルのほかに、tkusbfx3(_bcc).libと、setupapi.libが必要です。



