モノはオプティマイズさんとこのこれ。 チップに AN2131SC を使ったものと AN2135SC を使ったものの 2 種類あるが、買ったのは AN2135 版のほう。 将来こいつのデータバスに SL-811HS をはっつけることを考えているが、どーなるやら。
... クリスタルのハーネスと AN2135 のランドが危うく接触するとこやった。AN2135 のピン間 (0.8mm) の 1/3 くらいしか開いてない。 0.8mm 間隔なりのハンダ付けしてる (← つまりいいかげん) から、0.2mm 級の精度なんてねーって。![]()
本家の「回路、製作」を読み返したら
「クリスタルとチップのピンの位置が近いためショートしやすい」と、ちゃんと書いてあったし、読んでもいたんだが、 この「チップ」、クリスタルのすぐ下にあるチップ抵抗のことかと最初誤読していた。
チップといえば、これは 22pF と 0.1uF の二種類のチップコンデンサを使う。
ラベルなんか書いてないのでバラけたらおしまいである。
ふつー少ないほうの 22pF を先に付けてしまうんだろーが、
クリスタルの裏側という手のこんだトコなので先にすることもできず、
ちと緊張を強いられた。テープから外さなきゃいいんだけど、
0.1uF を順繰りに貼っつけていった結果、「0.1uF が 2 個だけのったテープ」というモノが出来て
ちょいびびった。いや、もちろんメモはしてあったんだけど。
切実に LCR メータ欲しいと思った ...。
この基板、ケースに止めるための穴が開いてない。 コネクタが一方にしかなく、USB コネクタがあって力がかかることを考えると裸で使わざるをえない。 同時に買った FX2 USB 2.0 も開いてないのですべて開いてないのかと思ったら、 残るカメレオン USB と EZ FPGA には開いているらしい。
Side A (部品面) Side B (ハンダ面) 1 FRD# (PA5) FWR# (PA4) 2 PC0/RxD0 D7 (PB7) 3 PC1/TxD0 D6 (PB6) 4 PC2/INT0# D5 (PB5) 5 PC3/INT1# D4 (PB4) 6 PC4/T0# D3 (PB3) 7 PC5/T1# D2 (PB2) 8 PC6 (WR#) D1 (PB1) 9 PC7 (RD#) D0 (PB0) 10 SDA SCL 11 CLK24 Vcc (3.3V) 12 Vbus (5V) Vbus (5V) 13 GND GND
ん、BKPT はどーでもいいが WAKEUP# は欲しかったかも。 なお、カメレオン USB 上の AN2135 では PC4 〜 PC7 を CPLD の JTAG 用に占有、 PC0 〜 PC3 が CPLD 向け GPIO になっている。
sdcc は Debian にも入っているが、サンプルやらなんやらぜんぜん足りないので sdcc 2.3.0 のソースだけは拾ってもっておく。 この場合、nightly snapshot にはサンプルなどは入ってないので持って来ても意味はない。 as31 のほうは、ソースから適当に。
1st ローダ一覧:
前二者は 213x 用、最後のは FX2 でも使えるらしい。 ただ、FX2 では fx2_programmer を使ったほうがいいかもしれない。モニタ(デバッガ)を兼ねて便利。4 つとも usbdevfs を必要とするので、事前に# mount -t usbdevfs none /proc/bus/usbしておく。
ローダ機能がオマケの usbstress は別として、使い勝手は fxload が良かったが、 物事が軌道に乗るまでは Ezusb2131 のお世話になった。 Ezusb2131 は 「EZ-USB デバイスが Linux から見える」というステップと「Linux から EZ-USB デバイスへ書き込む」というステップが 完全に分離しているのでトラブルを追いやすい。逆に言えば、ファームを書き込むたびにベンダ ID やデバイス ID が ころころかわる EZ-USB では Ezusb2131 のようにデバイスを登録してしまうタイプだと 書き込むたびにデバイスの切り離し/再接続が発生して煩い。 ... とくに音が。認識しなおすたびにピポッと鳴るわけで ... (^^;。
Ezusb2131 の注意事項として二つ:
Ezusb2131 はそのままでは書き込める HEX ファイルのレコードが 16バイトまでの制限がある。 sdcc が吐く hex ファイル相手ならこのままでいいが、世のファームバイナリでは 16 バイトを越えるレコードを持つものがある。 ま、ezusb2131.c を 1 箇所書き換えるだけだが:
- #define MAX_IHEX_RECORD_LEN 16 /* intel hex + #define MAX_IHEX_RECORD_LEN 32 /* intel hex
もうひとつ。生の (unconfigured な) EZ-USB を Ezusb2131 デバイスとして登録する関係で、 EZ-USB デバイスそのものにみえるデバイスのドライバがホストに入っていてはならない。 具体的には dabusb がこれにあたる。中身は EZ-USB なオーディオデバイスだが、こいつに認識してもらっては困るので dabusb.o は外す。
もちろん fxload とかを使う場合でも dabusb は外しておいたほうが無難だと思うし、 Ezusb2131 の README にも「外せ」って書いてある。けど、最初のうちはわざわざ dabusb をいれておいた。 Ezusb2131 入れる前でも dabusb が入ってればちゃんと MINI EZ-USB 繋ぐと認識してくれる。 これでカードが正常動作してることを確認した。
% zcat Ezusb2131-1.0.tar.gz | tar -xv % cd Exusb2131 % make % Examples/MarkII % as31 led2.asm % su root # insmod ../../exusb2131.o # cat led2.hex > /proc/bus/usb/001/002"/proc/bus/usb/" のあとのバス番号、デバイス番号は環境による。
port C の bit5 に割り当てたので、 MINI EZ-USB 端子の A7 〜 A13 間に LED 付けておいたところ点滅してくれた。 ただ予想より周期が遅い。100msec の待ちが H と L で合わせて 5 つ入れたつもりだったが、 0.5Hz な点滅になっているよーな気がする ...。
Wait1msec 関数の内部で 10 cycles x 1200 = 1msec とカウントしている。
12MHz で動いているとみていて、ひじょーにもっともらしいのだが ──
EZ USB は 水晶 (or セラロック) 12MHz を使って内部 24MHz 動作、4 クロック/サイクル動作なので命令サイクルは 6MHz ですな。
てけとーにこんな感じで:
***************
*** 111,121 ****
Wait100msec:
mov r0, #100
Wait1msec: ; A delay loop
! mov dptr,#-1200
More: inc dptr ; 3 cycles
mov a,dpl ; + 2
orl a,dph ; + 2
! jnz More ; + 3 = 10 cycles x 1200 = 1msec
djnz r0, Wait1msec ;
ret
--- 108,118 ----
Wait100msec:
mov r0, #100
Wait1msec: ; A delay loop
! mov dptr,#-600
More: inc dptr ; 3 cycles
mov a,dpl ; + 2
orl a,dph ; + 2
! jnz More ; + 3 = 10 cycles x 600 x 4clk/cycle / 24Mclk/s = 1msec
djnz r0, Wait1msec ;
ret
これ、Examples/MarkII/ 下でも Examples/Waldo/ 下でも同じコードなので、たぶん他にも潜在的に同等のコードがあるだろう。 命令サイクルが 12MHz てことは内部クロック 48MHz てことで、 ... Ezusb"2131" を主張しながら FX2 用になってんのね。FX 以降用?
# fxload -D /proc/bus/usb/001/002 -t an21 -I led2.hexとする。"-t an21" (AN213x タイプのロード動作を指定) は無くても動くことになっているし、 初回 (電源投入直後) のロードでは動くが、二度目以降 (一度以上ロードしたところへの上書き) は 自動判別がアテにならんこともあるみたいなのでつけている。
Ezusb では切断/再接続が頻繁におきるため、デバイス番号がテストのたびに変わっていくが、
fxload では物理的に切断しないかぎりおんなじ番号なので入力は楽。
... なことは楽なんだが、もう一声、できればロード先デバイスを自動的に識別していただきたい。
"/proc/bus/usb/001/002" などとうちこむのは見た目よりも面倒なんだぞぅ。
このパス文字列、あまり completion が効かない場所にあるから。
% zcat usbstress-0.3.tar.gz | tar -xv % cd usbstress-0.3 % CC=gcc-2.95 ./configure % CC=gcc-2.95 make % su root # ./usbstress -v -t c # ./usbstress -v -t b # ./usbstress -v -t rusbstress は usbstress 向けの ID を持った USB デバイスを /proc/bus/usb から自力で探し出すため、 デバイスを指定しなくても動く。また、unconfigured な EZ-USB を見付けると firmware.ihx をロードしてくれる (ロードするだけで usbstress 的テストには入らない)。名前固定だが、けっこ便利。
動かしてみると、 -t で指定するところの c (コントロールの転送)、b (バルクのピンポンな転送)、ab (バルクの窓枠シフト的転送)、 については動くんだが、i (アイソクロナス転送) がエラー出まくった。
480 バイトのパケットリクエストに対し、448 バイトしかホストが受け取れてない。 ... どこかでバッファの計算しくったんだろーな。
# ./usbstress -v -p sz=448 -t iなどとして、パケットサイズを 448 以下にしてやるとちゃんと動いた。
ちなみに、この firmware.ihx の性能はというと、TP240 相手のバルク通信で 150kB/s、 Athlon XP 1700+ な PC 相手のバルク通信で 250kB/s ほど。 遅いようにみえるがアイソクロナス転送で 1MB/s 出るので USB SIE の能力限界ではないらしい。 ま、いちいち返事を待ってるしな。
アセンブラなんで下地にするには辛いが、こういうリファレンスもないといかんだろってことで。
上記 URL から ezhid-0.8 を拾ってきて build.
まず EEEPROM への読み書き用 firm を流し込む:
# fxload -D /proc/bus/usb/001/002 -t an21 -I i2c_firm.ihxすると eeprom.pl で読み書きできるようになる:
# eeprom.pl -d /proc/bus/usb/001/002 -r -a 0x0200 -l 2eeprom.pl では I2C EEPROM は I2C アドレスの 1 にあることが仮定される (EZ USB は、この位置の EEPROM からブートする)。 違うアドレスのやつについては、 ハードコードになってるので
$i2c_wired_addressを適当に書き換える。
ブート用 firm は、ふつーに build したものから:
create_ezhid_e2.pl < i2c_firm.ihx > i2c_firm2.ihxとして作る。... が、i2c_dirm って EEPROM ブートに対応してないかも。なんか動いてくんない。