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を使用する簡単なアプリケーションを作成してみましょう。

  1. #include <windows.h>
  2. #include "cusb.h"
  3. #define RGIO_CPIPE 0 //コマンド用パイプ(1OUT)への番号
  4. #define RGIO_RPIPE 7 //リードデータパイプ(1IN)への番号
  5. #define SFR_WRITE 0x00
  6. #define SFR_READ 0x01
  7. #define EZR_WRITE 0x02
  8. #define EZR_READ 0x03
  9. #define _PORTACFG (u8)0x7F93;
  10. #define _PORTBCFG (u8)0x7F94;
  11. #define _PORTCCFG (u8)0x7F95;
  12. #define _OUTA (u8)0x7F96;
  13. #define _OUTB (u8)0x7F97;
  14. #define _OUTC (u8)0x7F98;
  15. #define _PINSA (u8)0x7F99;
  16. #define _PINSB (u8)0x7F9A;
  17. #define _PINSC (u8)0x7F9B;
  18. #define _OEA (u8)0x7F9C;
  19. #define _OEB (u8)0x7F9D;
  20. #define _OEC (u8)0x7F9E;
  21. #define DEBUG_FW //FWのデバッグが終了したらコメントアウトする
  22. #ifdef DEBUG_FW
  23. #define FW_VERSION "XXXX"
  24. #else
  25. #define FW_VERSION "V100"
  26. #endif
  27. u8 fw_bin[0x1000];
  28. HANDLE dev_handle;
  29. int main( int argc, char *argv[] ){
  30.   s32 i,j;
  31.   u8 buf[64];
  32. #ifdef DEBUG_FW //FWのデバッグ時は直接FWのバイナリを読み込む
  33.   FILE *fp;
  34.   fp=fopen("..\\fw\\miniezusb.bix","rb");
  35.   fread(fw_bin,1,0x1000,fp);
  36.   fclose(fp);
  37. #endif
  38.   //カメレオンUSBライブラリの初期化
  39.   if(cusb_init(0,&dev_handle,fw_bin,"RGIO",FW_VERSION)){
  40.     printf("Can't found Chameleon USB.\n");
  41.     exit(-1);
  42.   }
  43.   i=0;
  44.   //PORT-B 出力に設定
  45.   buf[i++]=EZR_WRITE;
  46.   buf[i++]=_PORTBCFG;
  47.   buf[i++]=0x00;
  48.   buf[i++]=EZR_WRITE;
  49.   buf[i++]=_OEB;
  50.   buf[i++]=0xff;
  51.   //PORT-C 入力に設定
  52.   buf[i++]=EZR_WRITE;
  53.   buf[i++]=_PORTCCFG;
  54.   buf[i++]=0x00;
  55.   buf[i++]=EZR_WRITE;
  56.   buf[i++]=_OEC;
  57.   buf[i++]=0x00;
  58.   usb_bulk_write(&dev_handle,RGIO_CPIPE,buf,i);
  59.   for(j=0;;j++){
  60.     i=0;
  61.     buf[i++]=EZR_WRITE; //PORT-Bの出力コマンド
  62.     buf[i++]=_OUTB;
  63.     buf[i++]=(u8)j;
  64.     buf[i++]=EZR_READ; //PORT-Cの読み込みコマンド
  65.     buf[i++]=_PINSC;
  66.     usb_bulk_write(&dev_handle,RGIO_CPIPE,buf,i);
  67.     usb_bulk_read(&dev_handle,RGIO_RPIPE,buf,1);
  68.     printf("PORT-C=%2.2X\n",buf[0]);
  69.   }
  70. }

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種類のポートレジスタの制御処理です。


<ダウンロード>

ソースコード一式