USBのシステムはFWとホストアプリケーション(PCで動作)が協調して動きます。
このページで作成しているホストアプリケーションは、EZ-USBのPORT-Bを出力に設定して、カウントアップする値を出力します。同時にPORT-Cを入力ポートに設定して、入力された値をDOS窓に表示するという簡単なアプリケーションです。
I/Oポートを制御してLEDを点滅させる
ホストアプリケーションの開発は、このHPで紹介している「カメレオンUSB」という、EZ−USB+CPLDのシステムで使用しているカメレオンUSBライブラリを使用します。
まずカメレオンUSBライブラリを十分に理解してください。このページで「カメレオンUSB」と記述している部分を「MINI EZ-USB」と置き換えて読むと読みやすいかもしれません。
さて、カメレオンUSBライブラリが理解できたところで、先ほど作成したFWを使用する簡単なアプリケーションを作成してみましょう。
- #include <windows.h>
- #include "cusb.h"
-
- #define RGIO_CPIPE 0 //コマンド用パイプ(1OUT)への番号
- #define RGIO_RPIPE 7 //リードデータパイプ(1IN)への番号
-
- #define SFR_WRITE 0x00
- #define SFR_READ 0x01
- #define EZR_WRITE 0x02
- #define EZR_READ 0x03
-
- #define _PORTACFG (u8)0x7F93;
- #define _PORTBCFG (u8)0x7F94;
- #define _PORTCCFG (u8)0x7F95;
- #define _OUTA (u8)0x7F96;
- #define _OUTB (u8)0x7F97;
- #define _OUTC (u8)0x7F98;
- #define _PINSA (u8)0x7F99;
- #define _PINSB (u8)0x7F9A;
- #define _PINSC (u8)0x7F9B;
- #define _OEA (u8)0x7F9C;
- #define _OEB (u8)0x7F9D;
- #define _OEC (u8)0x7F9E;
-
- #define DEBUG_FW //FWのデバッグが終了したらコメントアウトする
-
- #ifdef DEBUG_FW
- #define FW_VERSION "XXXX"
- #else
- #define FW_VERSION "V100"
- #endif
-
- u8 fw_bin[0x1000];
- HANDLE dev_handle;
-
- int main( int argc, char *argv[] ){
- s32 i,j;
- u8 buf[64];
-
- #ifdef DEBUG_FW //FWのデバッグ時は直接FWのバイナリを読み込む
- FILE *fp;
- fp=fopen("..\\fw\\miniezusb.bix","rb");
- fread(fw_bin,1,0x1000,fp);
- fclose(fp);
- #endif
-
- //カメレオンUSBライブラリの初期化
- if(cusb_init(0,&dev_handle,fw_bin,"RGIO",FW_VERSION)){
- printf("Can't found Chameleon USB.\n");
- exit(-1);
- }
-
- i=0;
- //PORT-B 出力に設定
- buf[i++]=EZR_WRITE;
- buf[i++]=_PORTBCFG;
- buf[i++]=0x00;
- buf[i++]=EZR_WRITE;
- buf[i++]=_OEB;
- buf[i++]=0xff;
- //PORT-C 入力に設定
- buf[i++]=EZR_WRITE;
- buf[i++]=_PORTCCFG;
- buf[i++]=0x00;
- buf[i++]=EZR_WRITE;
- buf[i++]=_OEC;
- buf[i++]=0x00;
- usb_bulk_write(&dev_handle,RGIO_CPIPE,buf,i);
-
- for(j=0;;j++){
- i=0;
- buf[i++]=EZR_WRITE; //PORT-Bの出力コマンド
- buf[i++]=_OUTB;
- buf[i++]=(u8)j;
- buf[i++]=EZR_READ; //PORT-Cの読み込みコマンド
- buf[i++]=_PINSC;
- usb_bulk_write(&dev_handle,RGIO_CPIPE,buf,i);
- usb_bulk_read(&dev_handle,RGIO_RPIPE,buf,1);
- printf("PORT-C=%2.2X\n",buf[0]);
- }
- }
4行目でRGIO_CPIPE をコマンド出力用のパイプ、5行目でRGIO_RPIPE を読み出したデータ用のパイプを定義しています。
7−10行目で使用するコマンドの定義、12−23行目でI/Oポートのレジスタアドレスを定義しています。このI/Oポートのレジスタの値は上位8bitは0x7fに固定のため、本来は下位8bitの値でよいのですが、可読性を高めるために16bit分の定義を行っています。
25行目のDEBUG_FW のデファインですが、これはFW開発中は有効にして、FWの開発が終了した時点でコメントアウトします。
デバッグ中はホストアプリの要求するバージョンは常に"XXXX"になり、FWの提供するバージョン(おそらく"V100")と必ず異なることになるため、ホストアプリを起動する度にFWをEZ-USBに転送します。(27−31行目)
また、FWの内容もKeilの統合環境が生成するbixファイルを毎回読み込むようにしてあります。(40−45行目)
このようにしておくことで、Keilの統合環境でコンパイルの後に、VCに戻って実行をするだけでFWとホストアプリの連携したデバッグが簡単に出来ます。
48行目でカメレオンUSBライブラリの初期化を行い、68行目でコマンド用のパイプにコマンドを転送し、78行目で入力用のパイプからポートの値を1バイト読み出しています。(カメレオンUSBライブラリのページを参照)
I/Oポートの使い方を簡単に説明しておきます。
PORTxCFG(xはA、B、Cのポートが入る)レジスタは、指定したビットが0の場合はI/Oポートとして使用して、1の場合は別の機能として動くことを指定します。これはEZ-USBのI/Oポートはほとんどが別の目的(例えばタイマー、割り込みなど)にも使用することが出来るため、どちらとして使用するか指定します。
OExレジスタはそのI/Oポートを入出力のどちらで使用するかビット単位に指定します。1が出力で、0が入力になります。
OUTxレジスタは出力ポートとして指定した場合に出力する値を設定します。入力ポートに指定されている場合は無視されます。
PINSxレジスタは入力ポートとして指定した場合の、入力の値です。
このプログラムの大部分は、上記の4種類のポートレジスタの制御処理です。
<ダウンロード>
ソースコード一式