前回までに USB ハブからのリセット信号を受けた後に Get_Descriptor ( device ) を受信する SETUP トランザクションを経験しました。 今回は IN トランザクションの経験について説明します。 <PICデバイス=18F2550> ターゲットは秋月電子通商さんの USBマイコンボード 完成品(PIC18F2550) +α の RRP2550-0 です。

Get_Descriptor ( device ) の次のフレームで IN トランザクションを行うことが決まっていて、それまで(1msec未満)に IN トランザクション時に送信するデータとエンドポイント0のINバッファに準備する必要があります。 Device Descriptor として下図を準備しました。

device_desk

エンドポイント0のバッファサイズは 8byte に決まっているようなので、実際にバッファに準備するのは 8byte づつに区切ったデータになります。 まずは最初の 8byte をバッファに転送し、BDステータスレジスターに Data1 , トグル同期させる設定と、BDバイトカウンターレジスターに 8byte を設定します。
ピンポンバッファを使わない設定の場合のBDステータスレジスターとBDアドレスレジスターの値は以下の通りです。

 BD ステータスレジスター(アドレス404H)      値 C8H
 BDアドレスカウンターレジスター(アドレス405H) 値 08H

さらに、IN トランザクションの最後にホストが送ってくる空の OUT トランザクションに自動で ACK 応答するために、エンドポイント0の OUT側 BDステータスレジスターに 88H を書き込みます。

 BD ステータスレジスター(アドレス400H)      値 88H
 BDアドレスカウンターレジスター(アドレス401H) 値 08H

また、SETUP 動作中は UCON<PKTDIS> が自動的にセットされるので、このビットをクリアします。

以上の設定を行って、次のフレームを待つと(Windows XPで) IN トランザクションを完了して、RESET 信号が送られてきます。 先に送られて来た Get_Descriptor ( device ) は以下の通りですから、データ・ステージのbyte数 64byteに対して8byteだけで IN トランザクションが完了したことになりますが、とにかく完了します。

 BDステータス = 34 ( bit2~bit5 がSETUPを示す)
 受信バッファ  = 80 06 00 01 00 00 40 00

          2byte目 06 は Get_Descriptor()
          4byte目 01 は 標準device
          7byte目 40 は データ・ステージのbyte数

セットアップステージに続く、データステージとして IN トランザクションが完了し、ステータスステージでホストからDATA1 として空のデータを送る OUT トランザクションがあるのですが、前述の通り OUT側 BDステータスレジスターに 88H を設定している為に受信バッファを更新することなく(割り込みも無く)ACK応答しています。

BD ステータスレジスターの bit4 ( DTSEN )をセットしていると、指定された DATA0/1 と異なる場合にはバッファを更新せず、割り込みフラグもセットしない(割り込みも発生しない)まま ACK を返す仕様を利用しています。 BD ステータスレジスターの値 88H は bit6 ( DTS )が 0 なので DATA0 を待っているのに対して、DATA1 を受信することで割り込み無しで ACK 応答している訳です。

Windows XPでは、2度目の RESET に続いて、Set_Address() が送られてきます。 受信例は以下の通りでした。

 BDステータス = 34 (bit2~bit5 がSETUPを示す)
 受信バッファ  = 00 05 02 00 00 00 00 00

          2byte目 05 は Set_Address()
          3byte目 02 は デバイス・アドレス


USB関連記事のインデックスは右記事の末尾にあります。→ USB CDC 


楽々PIC」は楽しい道具を作りながら学ぶブログを目指します。