USBN9603 というチップは、USB の制御用チップとしてとても有名らしい。 秋月で 600円ぐらい で手に入り入手性が良い。 このチップは、24Mhz のクリスタルが必要。
このチップを PIC や H8 で制御するための情報は あちこちにある。
USB加速度センサマウスのページは H8 使って実際にデバイスを作っている のでとても参考になる。
ほんとうは、ステートマシンで 制御回路を作ってみたかったのだが、 できたとしても、小規模の CPLD には入らないようだ。 ここでは、ステートマシンというのを視野に入れつつ H8/3664 で制御することを 考えてみたい。
実現したい機能は、USB を通して JTAG and/or SPI を扱えるもの。 JTAG でプログラミングした後は ホストとの通信経路にも使いたいので、 JTAG and SPI の 2 チャンネル?
ボードは、秋月の H8/3664(小:1600円)と USBN9603 を DIP に変換したものを C 基板に載せて使うことを考える。
6/30 方針変更
7/4 さらに変更
USBN9603 の詳細を知る。
~CS 1 28 CLKOUT ~RD 2 27 XOUT ~WR 3 26 XIN INTR 4 25 MODE0 DRQ 5 24 MODE1 ~DACK 6 23 GND A0 7 22 Vcc D0 8 21 GND D1 9 20 D- D2 10 19 D+ D3 11 18 V3.3 D4 12 17 AGND D5 13 16 ~RESET D6 14 15 D7
DMA モード
こんなかんじか。 +-----------------+ | | DRQ ---------+ +------------------- ~DACK -------------+ +--------------- | | +---------------------------+ ~RD -----------------+ +--------------------------- | ↑ +-- D7-D0 ------------------<D>--------------------------- CFGCLK ---------------------_-_-_-_-_-_-_-_----- CFGDATA -------------------<><><><><><><><>----- |----------------------------| DMA モード
DMA での転送はもっとも単純。普通は、INTR が立ったら、 (レジスタをみて)イベントを解析して それに対応する 処理を行うことになる。
それに先だって レジスタを読む、レジスタに書くという手順について レジスタは 0x00 から 0x3f まで(64個)
なかなか面倒だ。
結局 大きく4 つの状態にわけて、
<-> INIT モード IDLE モード <-> INTR モード <-> DMA モード
というかんじで状態遷移するのがよさそうだ。
INTR モード
他にもあると思うけども、最低しなければならないことはこんな感じ?
Set Adress
Get Device Descriptor
初期化
やるべきことは、
ぐらい?
このあたりのコードをみていて linux の /proc/bus/usb/devices の読み方 が少しわかったのでめも。
マウス T: Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#= 5 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=04b4 ProdID=aef9 Rev= 0.01 S: Manufacturer=PopStyle Mouse S: Product=PopStyle Mouse C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 26mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=01 Prot=02 Driver=hid E: Ad=81(I) Atr=03(Int.) MxPS= 4 Ivl= 10ms C: コンフィグレーションディスクリプタ #Ifs=1 インターフェイスが1つ Cfg#=1 Atr=a0 bit 7 バスパワー bit 5 ウェイクアップあり? MxPwr= 26mA I: インターフェイス ディスクリプタ If#= 0 インターフェイス 0 Alt= 0 オルターネーティブなし #EPs= 1 エンドポイントの数 1 Cls=03(HID ) クラス HID Sub=01 サブクラス ブートデバイス(ブート時に enable される?) Prot=02 プロトコルマウス Driver=hid E: エンドポイント ディスクリプタ Ad=81(I) Bit 7 (Host から見て入力) 1 Bit 3-0 アドレス = 1 Atr=03(Int.) Int. インタラプト伝送 MxPS= 4 パケットサイズ 4 バイト Ivl= 10ms インターバル 10ms
ってかんじ。
T: Bus=01 Lev=02 Prnt=02 Port=03 Cnt=02 Dev#= 6 Spd=1.5 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0bfe ProdID=1004 Rev= 0.01 S: Manufacturer=Morphy Planning S: Product=USB ROM Writer C: #Ifs= 1 Cfg#= 1 Atr=80 バスパワー ウェイクアップなし MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 未定義の場合 0x00 にすれば良いわけか Driver=hid E: Ad=81(I) Atr=03(Int.) MxPS= 8 パケット長 8 バイト Ivl= 4ms 4ms 間隔
T: Bus=01 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#= 7 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(unk. ) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=03ee ProdID=641f Rev= 1.14 C:* #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr=200mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(unk. ) Sub=01 Prot=01 Driver=hci_usb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl= 1ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl= 1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl= 1ms I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl= 1ms I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl= 1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl= 1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl= 1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl= 1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(unk. ) Sub=01 Prot=01 Driver=(none) E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl= 1ms E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl= 1ms I: If#= 2 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=00 Driver=(none) これは結局 インターフェイスが 3 つあって、 If#0 (クラス unk.) エンドポイント 入力 1 インタラプト転送 パケット長16 エンドポイント 出力 2 バルク転送 パケット長64 エンドポイント 入力 2 バルク転送 パケット長64 If#1 (クラス unk.) エンドポイント 出力 3 アイソクロナス転送 エンドポイント 入力 3 アイソクロナス転送 If#2 (クラス app.) (なし) こんなかんじに構成されている。それだけではなく。 If#1 には、Alt1 - Alt6 が設定されている。それぞれのパケット長が 9,17,25,33,49 バイト。これはどういうことなのかまではよく分からない。 とにかく、メインのデータストリームが流れるのは、#If 0 の バルク転送の 入出力 2 ということらしい。
ここまでわかるとなおさら疑問がいろいろ出て来るなぁ。
なんかこんな感じのバランスで設計されている。
じゃあ、自分で JTAG の デバイスをつくるときはどうしたら良いんだろう?
シリアルポートそのものにして、データを 送って 、受け取る という 動きをさせれば良いのかなぁ。
いくら遅くても良いなら、
という2つぐらいのコマンドがあれば良いような気がする。
信号線のセットがいくつかあれば良いし、トグルかセットかも 属性にしてしまう。
ヘッダ: コマンド (0: 送受信 他は スベシャルな機能) チャネル 2bit (0: 実際の信号線 1: 実際の信号線のセット 2:JTAG#1 3:JTAG#2) bit 長 : 1 バイト データ 32 バイト
さて、これだけで良いのだろうか? JTAG は、ホスト側から一方的に コントロールするだけだが ...なんらかのデバイスをSPI で制御するなら もっと多様な処理が必要だ。
こういった処理させるのなら、もはや ステートマシンじゃ無理か。
とにかく、あれだ 汎用 USB シリアル I/O ということにして、 H8 + USBN9603 で作るのをテーマに変更しよう。
だた、H8 で性能はどうかというのが問題だ。 シリアルから来たデータを処理するのに 0.5M bps でもきついらしい。
パラレルのデータを扱うが、1 bit づつ処理していくわけだから 0.1M bps も出れば良いほうではないか .. という気がする。
数Mbps で JTAG なり SPI なりを制御するには、やはり CPLD を使わないと ダメではないか。
この処理を中心にすえて、それができるように H8の処理なりプロトコルなりを を考えていくことにしよう。
1バイトヘッダ 1バイトデータ長 N バイトデータこんなのをやりとりする。送信の場合は、データ長はまったく同じで、 ヘッダも 単に最後の状態(たぶん同じもの)を返す。
ヘッダのレジスタ 受信データカウンタ 送信データカウンタ 送受信シフトレジスタ シフト数カウンタ(3bit)
これだけで、XC9536 では無理そうということが明らかだ。
でも、制御が簡単そうだから XC9572 でできるんじゃないかと思う。
さて CPLD はどうやって書き込むというと、このチップだけでは無理。
外からプログラミングしてやらないといけない。ただ、H8 使ったときも
条件いっしょだし...
これで検討してみようかなぁ。
ちなみにこのチップは、IPI で 800円。