製品情報>Artix-7評価ボード>Artix-7技術コラム>USB 3.0プログラムの作成方法

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のエンドポイントにデータを転送するには、TKUSBFX3BulkOutTKUSBFX3BulkInを使います。

下のコードを参考にしてください。このコードでは、wbufに格納されたデータをエンドポイント2に1024バイト送り、エンドポイント6から1024バイトのデータを受け取って、rbufに格納しています。

TKUSBFX3BulkOut(2, wbuf, 1024);
TKUSBFX3BulkIn(6, rbuf, 1024);

ただし、これらの関数は低レベルなパケットの送信を行うものなので、あまり使いません。

また、BulkInを実行したときに、FPGAが送信可能状態になっている必要があります。必要なデータが送られてこないと、この関数は制御を返しません。しかも、BulkInを要求しているかどうかはFPGA内部のロジックには伝えられません。

(FPGA内部ロジックは、ホストPCがBulkInを要求しているかどうかを認知できません)

このように低レベルなので、普段の通信では次の「高機能データ送受信」を使います。

高機能なデータ転送のやりかた

高機能データ送受信

特電IPコアにデータを送受信するには、USBWriteDataUSBReadDataを使います。

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が必要です。

 


© 2017 TokushuDenshiKairo Inc. All rights reserved