標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第631回]

●USBデバイスのセットアップ(Enumeration)の仕組み(前回の続きです)

前回の訂正です。
前回はホストから送られたreset信号に対して、PIC18F14K50の私のプログラムでは特にアクションはしていません、と書きましたが、その後にプログラムをあらためて見直したところ、それじゃまずいことがわかりました。
現在は、リセットを検出したら、PIC18F14K50のプログラムも初期クリアして、USB受信動作のトップに戻るようにプログラムを直してあります。

ところで、前回の説明に使いました[第626回]のデータはEnumerationの流れを理解するにはちょっとわかりにくいところがあるかもしれません。
[第627回]にお見せした「自作USBアナライザ」のデータも合わせて見ていただくとわかりやすいかもしれません。
ということで、今回は前回説明したこととダブリますが、[第627回]のデータを使って説明してみたいと思います。

b=0825 SOF FNO=0E8 [101001010001011100000000]
b=0873 SOF FNO=0E9 [101001011001011100011111]
b=090E SOF FNO=0EB [101001011101011100000010]
b=095C SOF FNO=0EC [101001010011011100011100]
b=098C SETUP  [10110100]
b=09B2 DATA0 
        80 06 00 01 00 00 40 00 
b=0A1A ACK 
b=0A4A SOF FNO=0ED [101001011011011100000011]
b=0A77 IN ADRS=00 ENDP=00  [1001011000000000000]
b=0A9F DATA1 
        12 01 00 02 00 00 00 08 
b=0B05 ACK 
b=0B38 SOF FNO=0EE [101001010111011100000001]
b=0B76 SOF FNO=0EF [101001011111011100011110]
b=0BA3 OUT ADRS=00 ENDP=00  [1000011100000000000]
b=0BC9 DATA1 
        00 00 FE 80 D2 FE FF FF 
b=0C2D SOF FNO=10A [101001010101000010001111]
b=0C7B SOF FNO=10B [101001011101000010010000]
b=0CC9 SOF FNO=10C [101001010011000010001110]
b=0D27 SOF FNO=10D [101001011011000010010001]
b=0D65 SOF FNO=10E [101001010111000010010011]
b=0DA3 SOF FNO=10F [101001011111000010001100]

USBの接続動作は、パソコンのUSBホストコントローラからSETUPパケットが送出されることによって開始されます。
SETUPパケットはPID=1101、PID_=0010です。上のデータではビットの並びの関係で左右が逆になっています。
このあたりのことについては[第511回]で説明をしております。
上のデータで、SOFはStart Of Frameです。フレームの始まりを示しています。
その次のFNOはフレームbナす。
上のデータでは、FNO=0ECでSETUPパケットが送られています。
同じフレームで、前回も説明しました、デバイスデスクリプタの送信要求が送られています。
80 06 00 01 00 00 40 00
です。
その次にある、ACKはUSB端末がホストからのデータを正しく受け取った印として、ホストに対して送られます。
このへんのやりとりはPIC18F14K50のUSBコントローラがオートマチックにこなしてくれます。
ホストから送られたデータは、あらかじめ用意したバッファに読み込まれたあと、任意の時点でユーザープログラムによって読み出すことができます。

うーん。やっぱり前回のデータよりもこちらのデータのほうがわかりやすいですねえ。

次のFNO=0E0はINトランザクションです。
ホストがUSB端末に、データを送れ、と要求しているトランザクションです。
INというのは、ホストから見て入力になるようなデータの向きのことです。端末からは出力になります。
まだ装置のアドレスは決まっていませんから、アドレス=0(ADRS=00)で送られます。
セットアップはエンドポイント=0(ENDP=00)を使って行われます。
デバイスデスクリプタの最初の8バイトを送ります。
12 01 00 02 00 00 00 08
です。

このあとホストから無意味(?)なデータが出力されるようですが、これは無視してしまって構わないようです。

b=2005 SOF FNO=152 [101001010100101010011100]
b=2053 SOF FNO=153 [101001011100101010000011]
b=20A1 SOF FNO=154 [101001010010101010011101]
b=20EF SOF FNO=155 [101001011010101010000010]
b=2121 SETUP  [10110100]
b=2147 DATA0 
        00 05 02 00 00 00 00 00 
b=21AF ACK 
b=21DD SOF FNO=156 [101001010110101010000000]
b=2207 IN ADRS=00 ENDP=00  [1001011000000000000]
b=222F DATA1 
        00 00 3E A0 B4 FF FF FF 
b=22B9 SOF FNO=158 [101001010001101010001111]
b=2317 SOF FNO=159 [101001011001101010010000]
b=2355 SOF FNO=15A [101001010101101010010010]
b=23C0 SOF FNO=15C [101001010011101010010011]

ホストからは、アドレスセットコマンドが送られます。
00 05 02 00 00 00 00 00
です。
前回も説明しましたように、00 05がアドレスセットコマンドで、その次の02がこのUSB装置(PIC18F14K50)に与えられたアドレスです。

次のINトランザクションでは、アドレス02ではなくて、アドレス00のまま、空データを送ります。
ここではそのこと(空データ)はわかりませんが、PIC18F14K50のプログラムでは、このときは「0バイトの送信」をUSBコントローラに命じています。

ここまでが前回の説明でした。

b=25A2 SOF FNO=163 [101001011100011010010101]
b=25F0 SOF FNO=164 [101001010010011010001011]
b=2622 SETUP  [10110100]
b=2648 DATA0 
        80 06 00 01 98 E1 FF FF 
b=26DD SOF FNO=165 [101001011010011010010100]
b=2709 IN ADRS=02 ENDP=00  [1001011001000000000]
b=2731 DATA1 
        12 01 00 02 00 00 00 08 
b=2797 ACK 
b=27CB SOF FNO=166 [101001010110011010010110]
b=27F5 IN ADRS=02 ENDP=00  [1001011001000000000]
b=281D DATA0 
        D8 04 0A 00 01 00 00 00 
b=2883 ACK 
b=28B9 SOF FNO=167 [101001011110011010001001]
b=28E8 IN ADRS=02 ENDP=00  [1001011001000000000]
b=2910 DATA1 
        00 01 3F 1E 7F 40 69 FF 
b=2977 SOF FNO=168 [101001010001011010011001]
b=29A3 OUT ADRS=02 ENDP=00  [1000011101000000000]
b=29C9 DATA1 
        00 00 FE 80 D2 FE FF FF 
b=2A35 SOF FNO=169 [101001011001011010000110]

ホストからは最初と同じ、デバイスデスクリプタの送信要求が送られてきます。
実はFNO=164のコマンドデータは化けてしまっています。なにしろやっつけの自作USBアナライザですから、時々解読ミスをしてしまいます。
ここは[第626回]のデータのほうがまともです。

8060  40 40 40 40 40 40 40 40-40 40 40 40 08 41 80 06  @@@@@@@@@@@@.A..
8070  00 01 00 00 12 00 40 42-12 01 00 02 00 00 00 08  ......@B........
8080  08 40 08 42 D8 04 0A 00-01 00 00 00 40 08 42 00  .@.Bリ.......@.B.
8090  01 0A 00 01 00 00 00 40-40 40 08 41 80 06 00 02  .......@@@.A....

80 06 00 01 00 00 12 00
です。
後ろから2番目が送信要求バイト数です。12は16進数ですから18バイトです。
FNO=165〜167で、連続してINトランザクションが出されますから、デバイスデスクリプタを8バイト、8バイト、2バイトと順に送ります。
このときは、ADRS=02で送っています。
送り終わると、またホストから意味不明(?)のデータが送られるようですが、これも無視して構わないようです。

b=2A73 SOF FNO=16A [101001010101011010000100]
b=2AA3 SETUP  [10110100]
b=2AC9 DATA0 
        80 06 00 02 00 00 09 00 
b=2B31 ACK 
b=2B71 SOF FNO=16B [101001011101011010011011]
b=2B9E IN ADRS=02 ENDP=00  [1001011001000000000]
b=2C2C ACK 
b=2C6F SOF FNO=16C [101001010011011010000101]
b=2C9C IN ADRS=02 ENDP=00  [1001011001000000000]
b=2CF3 ACK 
b=2D2D SOF FNO=16D [101001011011011010011010]
b=2D5A OUT ADRS=02 ENDP=00  [1000011101000000000]
b=2D80 DATA1 
        00 00 FE 3F 5F FF FF FF 
b=2E08 SOF FNO=16F [101001011111011010000111]
b=2E3C SETUP  [10110100]
b=2E62 DATA0 
        80 06 00 02 00 00 BF 01 
b=2F16 SOF FNO=170 [101001010000111010010000]
b=2F43 IN ADRS=02 ENDP=00  [1001011001000000000]
b=2F6B DATA1 
        09 02 29 00 01 01 00 C0 
b=2FD1 ACK 
b=3004 SOF FNO=171 [101001011000111010001111]
b=3030 IN ADRS=02 ENDP=00  [1001011001000000000]
b=3058 DATA0 
        00 09 04 00 00 02 03 00 
b=30BE ACK 
b=30F2 SOF FNO=172 [101001010100111010001101]
b=311C IN ADRS=02 ENDP=00  [1001011001000000000]
b=3144 DATA1 
        00 00 09 21 11 01 00 01 
b=31AA ACK 
b=31E0 SOF FNO=173 [101001011100111010010010]
b=320E IN ADRS=02 ENDP=00  [1001011001000000000]
b=3236 DATA0 
        22 1D 00 07 05 81 03 40 
b=329C ACK 
b=32CE SOF FNO=174 [101001010010111010001100]
b=32F8 IN ADRS=02 ENDP=00  [1001011001000000000]
b=3387 ACK 
b=33BC SOF FNO=175 [101001011010111010010011]
b=33E7 IN ADRS=02 ENDP=00  [1001011001000000000]
b=343E ACK 
b=346A SOF FNO=176 [101001010110111010010001]
b=34B8 SOF FNO=177 [101001011110111010001110]
b=34E6 ? [10110111]
b=3533 ACK 
b=3575 SOF FNO=178 [101001010001111010011110]
b=35B3 SOF FNO=179 [101001011001111010000001]
b=35F1 SOF FNO=17A [101001010101111010000011]
b=362F SOF FNO=17B [101001011101111010011100]
b=366D SOF FNO=17C [101001010011111010000010]
b=36AB SOF FNO=17D [101001011011111010011101]
b=36E9 SOF FNO=27E [101001010111111001001111]
b=3737 SOF FNO=2DF [101001011111101101000000]
b=3785 SOF FNO=180 [101001010000000110010001]
b=37D2 SOF FNO=181 [101001011000000110001110]

次にFNO=16Aで、コンフィグレーションデスクリプタの送信要求が出されます。
先頭2バイトは 80 06 で、その次の00 02 がコンフィグレーションデスクリプタの指定です。
送信要求バイト数は9バイトです。

その次のFNO=16Bと16CのINトランザクションでコンフィグレーションデスクリプタを8バイト、1バイトの順に送っているはずなのですが、データが見えません。ここも自作USBアナライザがミスをして落としてしまっているようです。

FNO=16Fでふたたび同じ、80 06 00 02 が送られてきます。
今度はバイト数の指定が大きくなります。
ここではBFになっていますが、これも自作USBアナライザのミスで、ここはFFのはずです。

その次のFNO=170〜175で、コンフィグデスクリプタ全部を8バイトずつに分けて送っています。 
自作USBアナライザのデータはここまでで終わっていますので、この続きはまた、[第626回]のデータで見ていくことにいたします。



黄緑がホストからのコマンドで、青がPIC18F14K50が送出したデータです。
一番上にコンフィグデスクリプタ送信要求 80 06 00 02 00 00 FF 02 があります。
そのあと5回分、PIC18F14K50からのデータ送出が続きます。
ここまでが、さきほど説明をしたところです。

USBで、なにをやっているのかよくわからないのが、そのあとの流れです。
それ以前と同じ80 06 00 01と80 06 00 02がなんだか狂ったように繰り返しホストから送られてきます。
これはPIC18F14K50の応答が悪くてこうなるのではなくて、普通にこういう動作をするようです。
ですから、PIC18F14K50のプログラムもこういう動きに応えられるように書かなければならないことになります。
ちょいと工夫が要ることになります。

やっとホストからのコマンドが変化するのは、下から7行目です。
00 09 01 00 00 00 00 00
です。
これはset configurationというコマンドらしいのですが、これについては0バイトを返す、ことでよいようです。

つぎの 21 0A 00 00 00 00 00 00 も詳細不明なのですが、ここも0バイトを返す、ことでよいようです。

その次、81 06 00 22 00 00 5D 00 が最後のデータ要求コマンドです。
HIDレポートディスクリプタの送信要求です。
そこで、HIDレポートディスクリプタを送出すると、最後にまたホストから、 21 0A 00 00 00 00 00 00 が送られてきます。これにも0バイトを返すと、無事ホストにHIDデバイスとして認識されて、これ以後データの送信、受信ができるようになります。
2010.10.8upload

前へ
次へ
ホームページトップへ戻る