EZ-USBを使う

サブタイトル: EZ-USBでお気楽USBデバイス製作記

まえがき
このページでは、Interface増刊 Vol.8 「USBハード&ソフト開発のすべて」
第5章 に扱われている、Cypress社製USBマイコン"EZ-USB"を扱っていきます。

この記事の中では、開発ボードとしてFLEX10KE評価キットを用いていますが、
こいつは 5万円近くするボードで、しかも今回はFPGA部は全く必要ありません。

また、この記事ではターゲット用コンパイラとしてTasking社 8051Cコンパイラ(試用版)
を使用していますが、こいつの正規版は数十万円します。試用版ではシンボル数と
ソースコードサイズに制限があり、記事のコードから拡張する余地がほとんどありません。

そこでハマケンでは、IPI Shopで売られているAN2131SC基板(@6800)を用いて開発を
行います。この基板は記事のP109に載っている回路図と機能的にはほぼ同じもので、
AN2131で実験をするにはもっとも適当な基板といえます。ちなみにIPI Shopでは他にも
無線通信モジュールなど面白い物が扱われているので、一度見てみると良いと思います。

コンパイラには、フリーの8051用CコンパイラSDCCを使ってみます。フリーですが
結構しっかりしたコンパイラで、割り込みルーチンも特別なコードをほとんど書かずに
実現できます。ただ、SDCCのWin32版はちょっとヤバイという話を小耳に挟んだので
ハマケンではCygwin版を使いました。

ホスト側の開発環境は、申し訳ないですがタダで使える環境はまだ未検証です。
Visual C++6.0 か Visual BASIC 6.0上でしかまだ試せてません。ゆくゆくはCygwin
出来ればと考えていますが。。。


準備するもの

ハードウエア ソフトウエア
その他


下ごしらえ

Cygwin

まずCygwinをインストールします。http://www.cygwin.com/ の"Install now!!"と
書いてあるリンクを押すと、setup.exeをダウンロード出来ます。
ダウンロードしたら実行します。Setupは単なるインストーラで、Cygwin本体はネットから
落とす必要があります。その際、一度ローカルディスクにダウンロードしてからインストール
するか、それともネットから直でインストールするかを選べます。好きな方を選んでください。
サイズがでかい(フルインストールで90MB?程度)ので、どちらにせよインストールには
時間的な覚悟が必要です。(ADSLならそうでもないです)

インストールが完了すると、デスクトップにCygwinのアイコンが出ます。こいつを起動
するとDOS窓みたいなのが出てきますが、これがCygwin環境です。Win上で動く仮想
UNIX環境と思えば良いでしょう。GCCも入っていますのでプログラミングも可能です。

SDCC

Cygwinが導入できたら、次はSDCCです。
SDCCには、ソース版とバイナリ版があります。バイナリが楽で良いですが、ドキュメントが
付いてきません。ので、私はソース版をコンパイルして入れました。インストールは、
 

$ gzip -dc sdcc-2.2.1-src.tar.gz | tar xvf -
$ cd sdcc-2.2.1
$ ./configure
$ make
$ make install


いわゆる典型的なソースからのインストール手順でOKでした。
 

SDCCへの移植
まずは難しいことは考えずに、「USBハード&ソフト開発のすべて」のP119〜120の
ソースをSDCCに移植してみましょう。

基本的にほとんどそのままで動くのですが、XDATAや割り込みといった8051特有の
部分をコンパイラ固有のコードで書かなくてはなりません。また、配列変数やポインタの
使い方が、Taskingとは多少異なる(SDCCの方が厳密?)ので、その部分にも改造を
施す必要があります。

以下、改造部分を見ていきます

93〜133行
volatile _xdat unsigned char PORTCCFG  _at(0x7f95);

この部分をSDCCでは
xdata at 0x7f95 volatile unsigned char PORTCCFG;
と表現します。
 
 

138〜141行
_sfrbyte IE       _at(0xa8);

この部分をSDCCでは
sfr at 0xa8 IE;
と表現します。
 
 

263〜269行
unsigned char endpoint_desc[5][7] = {
    0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 10, /* Interrupt-IN Endpoint */
    0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, /* Bulk-OUT Endpoint  */
    0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00, /* Bulk-IN Endpoint  */
    0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00, /* Bulk-OUT Endpoint  */
    0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00 /* Bulk-IN Endpoint  */
};

この部分をSDCCでは
code unsigned char endpoint_desc[5][7] = {
    {0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 10}, /* Interrupt-IN Endpoint */
    {0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00}, /* Bulk-OUT Endpoint  */
    {0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00}, /* Bulk-IN Endpoint  */
    {0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00}, /* Bulk-OUT Endpoint  */
    {0x07, 0x05, 0x85, 0x02, 0x40, 0x00, 0x00} /* Bulk-IN Endpoint  */
};
と表現します
 
 

280〜288行
unsigned char *config_ptr[] = {
  (unsigned char *)&config_desc,
  (unsigned char *)&interface_desc[0], /* インターフェース#1  */
  (unsigned char *)&endpoint_desc[0][0], /* インタラプトIN  */
  (unsigned char *)&endpoint_desc[1][0], /* バルクIN   */
  (unsigned char *)&endpoint_desc[2][0], /* バルクOUT   */
  (unsigned char *)&endpoint_desc[3][0], /* バルクIN   */
  (unsigned char *)&endpoint_desc[4][0], /* バルクOUT   */
  (unsigned char *)NULL };

この部分はsetup_usb_inf関数でディスクリプタテーブルを初期化するために
書かれているのですが、この辺のポインタ操作がSDCCでは上手く受け付けて
くれません。
ここはsetup_usb_inf関数で*config_ptrを使わない様に書き換えます。
なので280〜288行は、SDCC版では単純に削除しました。
 
 

429〜446行 setup_usb_inf関数
void setup_usb_inf(void)
{
 unsigned char p,cp,siz;
 unsigned char *dp;
 p = 0;
 dp = &dev_desc[0];
 siz = *dp;
 while(siz--) {
  IN7BUF[p++] = *dp++;
 }
 cp = 0;
 while((dp = config_ptr[cp++]) != (unsigned char *)NULL) {
  siz = *dp;
  while(siz--) {
   IN7BUF[p++] = *dp++;
  }
 }
}

この部分は、config_ptrを全く使わない様に書き換えます。
そのため、テーブル内容のサイズは固定値を与えています。
美しくないのですが、とりあえずこれで動きます。
void setup_usb_inf(void)
{
 unsigned int p,cnt,cnt2;

 p=0;
 for (cnt=0;cnt<0x12;cnt++) {
  IN7BUF[p]=dev_desc[cnt];
  p++;
 }

 for (cnt=0;cnt<9;cnt++) {
  IN7BUF[p]=config_desc[cnt];
  p++;
 }

 for (cnt=0;cnt<9;cnt++) {
  IN7BUF[p]=interface_desc[cnt];
  p++;
 }

 for (cnt2=0;cnt2<5;cnt2++){
  for (cnt=0;cnt<7;cnt++){
   IN7BUF[p]=endpoint_desc[cnt2][cnt];
   p++;
  }
 }
}


 

最後、574行の割り込み関数の宣言ですが、
interrupt(8) void usb_int(void)

この部分をSDCCでは
void usb_int(void) interrupt 8
と表現します。
これだけで割り込みの細々したことはすべてSDCCが仕込んでくれます。ラクチン!


ここまででSDCCでコンパイルが通る様になりました。
が、本に載っているこのサンプルはFLEXボード用であり、FPGAを叩くようにプログラミング
されています。
これではコンパイルが出来るだけで意味ないジャン! って状態です。

そこで、次はこのサンプルをIPI製基板用のプログラムに改造していきます。
が、とりあえず今回はここまで(^^;
 

また近いうちに続きをまとめます。それにホスト側ソフトも必要ですしね。
ある程度スキルのある人ならば、ここまでに書いたSDCCのヒントがあれば、あとは自分で
コーディングできるのではないでしょうか。ぜひチャレンジしてみてください。
 


ハマケン トップページに戻る