標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第653回]
●DEVICE DESCRIPTOR
前回は、GET DEVICE DESCRIPTORを検出したところまで説明をいたしました。
PICのプログラムは、それに応えて、DEVICE DESCRIPTORを送出する用意をします。
GET DEVICE DESCRIPTORを検出したあとのプログラムは次のようになっていました。
;(1)"GET DESCRIPTOR('80'+'06')" received movf db3,w sublw 1; 1 or 2? 1:dev.descriptor 2:config descreptor bnz sendconf ;send DEVice DSCRPTR movlw 12 cpfseq db6 call resetADDR call setbd2 call setbd0 call setbd1 goto looptop
DEVICE DESCRIPTORを送出する準備をしているのはsetbd2サブルーチンです。
下にsetbd2サブルーチンを示します。
;ep0(IN) data set setbd2 call devdset1 call setbd2odd movlw 1 movwf bd2mk;=1 return ; setbd2odd lfsr 1,20b movlw 02;address high movwf POSTDEC1 movlw 30;address low movwf POSTDEC1 movlw 8;bytes movwf POSTDEC1 movlw 0c8 movwf INDF1 return
devdset1サブルーチンがDEVICE DESCRIPTORをデータバッファにセットするサブルーチンです。このサブルーチンについてはあとで説明をします。
setbd2oddサブルーチンはsetbd2サブルーチンの下にあります。
EP0(IN)のBUFFER DESCRIPTORに必要な値をセットします。
BUFFER DESCRIPTORについては[第638回]、[第639回]で説明をしています。
EP0(IN)のBUFFER DESCRIPTORはアドレス208〜20Bの4バイトです。
アドレス208はBUFFER DESCRIPTORの第1バイトBD2STATです。
そのビット7を1にすると、SIEに制御が移ってしまいます。
ですから、まずdevdset1サブルーチンでEP0(IN)バッファにデータをセットし、それからBUFFERE DESCRIPTORの後ろのアドレスから値をセットしていって、最後にアドレス208のBD2STATをセットします。
setbd2oddサブルーチンがアドレス208からではなく、アドレス20bから値をセットしているのはその理由からです。
アドレス20bはデータバッファアドレスの上位バイト、20aは下位バイトを示す値をセットします。
EP0(IN)データバッファはアドレス230〜237の8バイトです。
アドレス209は送出するバイト数を示します。
USBホストコントローラからのコマンドやそれに応えて送るデバイスディスクリプタなどのデータはEP0を使ってコントロール転送モードで送信、受信します。
コントロール転送では1度に送信するバイト数は8バイトです。
8バイト以上あるデータは8バイトに区切って送ります。
EP0(IN)はUSBホストコントローラにデータを送出するパイプです。
IN、OUTはホストコントローラから見た向きですから、PICから見たときは入力、出力の動作はその名前の意味と逆になります。
EP0(OUT)はPing−Pong Bufferの設定にしましたので、EP0(OUT)のDATA0(EVEN)とEP0(OUT)のDATA1(ODD)の2つのパイプを使います。
しかし、EP0(IN)はPing−Pong Bufferではありませんから、1つだけです。
でもデータを送信するときは、DATA0とDATA1を交互に使い分けて送信しなければなりません。
USBホストコントローラから送られてくるGET DESCRIPTORなどのデータ送信要求コマンドはDATA0(EVEN)で送られてきます。
それに応えてPICが送信するDEVICE DESCRIPTORの最初の8バイトはDATA1(ODD)になります。
アドレス208のBD2STATの値はDATA0とDATA1のときとでビットの一部が異なります。
BDnSTATについては、[第651回]で説明をしました。
DATA0(EVEN)のときは、ビット6=0にします。
DATA1(ODD)のときはビット6=1にします。
今回はDATA1を送りますから、アドレス208の値はC8(ビット6=1)にします。
説明の順序が逆になってしまいましたが、下にDEVICE DESCRIPTORの最初の8バイトをデータバッファにセットするサブルーチン devdset1を示します。
; ;device descriptor data set ; devdset1 lfsr 1,230 movlw 12;size(bytes) movwf POSTINC1 movlw 01;type(DEVUCE DESCRIPTOR) movwf POSTINC1 movlw 00;USB version 02.00(Low) movwf POSTINC1 movlw 02;(High) movwf POSTINC1 movlw 00;HID class movwf POSTINC1 movlw 00;SUB class movwf POSTINC1 movlw 00;protocol code movwf POSTINC1 movlw 08;max packet size of EP0 movwf POSTINC1 return
DEVICE DESCRIPTORの最初の8バイトの内容は、プログラムリストにコメントしている通りです。
第1バイトはDESCRIPTORのバイト数(16進数)です。
DEVICE DESCRIPTORは18バイトです。16進数に直すと12になります。
第2バイトはDESCRIPTORの種類を示します。
DEVICE DESCRIPTORは01です。
第3、第4バイトはUSBのバージョンを示します。
USBのバージョンは2.0です。
第5バイトはclassコードです。
HIDクラスは00にします。
第6、第7バイトも00にします。
第8バイトはEP0の最大パケットサイズを示します。
8バイトです。
以上のプログラムを実行するとあとはSIE(PIC内蔵のUSBコントローラ)が、セットした値を決められたフォーマットでUSBホストコントローラに向けて送出してくれます。
しかし。
待ってください。
DEVICE DESCRIPTORは18バイトあると書きました。
ここまでのところで、最初の8バイトはデータバッファにセットしましたから、それをSIEが送出してくれるところまではわかりますが、残りの10バイトはどうするのでしょう?
実はそのための仕掛けがさきほどお見せしたsetbd2サブルーチンに仕込んであるのです。
movlw 1 movwf bd2mk;=1 return
という部分です。
bd2mkはその仕掛けのためのワークレジスタです。
2010.11.4upload
前へ
次へ
ホームページトップへ戻る