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

●ふたたびUCONレジスタ

HIDプログラムのとっかかりのところで、clrf UIR の1命令の説明にずいぶん手間がかかってしまいました。
プログラムのリストは[第646回]でお見せしたのですけれど、最初のところだけもう一度お見せすることにいたします。

;connected to USB
looptop
	clrf UIR
	movlw 08
	movwf UCON
;
	call setupck

clrf UIR の次は、
movlw 08
movwf UCON
を実行しています。
[第635回]のフローチャートを見ていただければわかりますように、looptopは処理サイクルの起点です。つねにここに戻ってきます。
ということは、clrf UIRと同様に、
movlw 08
movwf UCON
も繰り返し実行されます。

UCONレジスタは[第643回]で説明をしましたが[第511回]でも説明をしています。
なぜlooptopにUCONレジスタに08をセットする処理を置かなければならないか、ということについては、[第511回]で、短い文章なのですが、ちょうどその答えを書いていますので、そのままを以下転記いたします。

[転記ここから]
UCONのbit4を0にしないとSIE(PIC内蔵USBコントローラ)はパケットの送信も受信もできません。
当然このビットを0にしてスタートすることになります。

ところがどういう理由によるのかはわかりませんが、説明によると、このビットはSIEがホストからのSETUPを受け取ると、1になるのです。

[出典]MICROCHIP社PIC18F1xK50DataSheet
[ここまで]

参考までに、PIC18F14K50DataSheetから、UCONのbit4とbit3の説明部分だけを下記引用いたします。

bit3は USB Module Enable bit ですから常に1にしなければいけません。
問題はbit4です。
このビットはSIEがSETUPトークンパケットを受け取ると1にセットされます。
ですから私のHIDプログラムでは、そのことを利用して、HIDプログラムのEnumeration手続きをスタートさせているのです。
ところが上にも書いてあります通り、UCONのbit4が1になると、SIEはパケットの送信も受信もできなくなってしまうらしいのです(上の引用文にありますように、DataSheetにはそのように書かれています)。
と、そのように当初は解釈していたのですけれど、いまあらためて上記の引用文を読んでみますと、ちょっとニュアンスが違うようです。
確かにbit4を0クリアしなければSIEはパケットの送信も受信もしてくれない、というのはその通りだと思います。
そしてSIEがSETUPトークンを受信するとbit4を1にする、というのも、その通りだと思います。
しかし、その結果、SIEが送信も受信もできなくなる、というのではなくて、SIEが送信、受信を不可にしてしまう(SIE has disabled)ということのようです。
いずれにせよ、bit4を0クリアしなければ、先に進めないことは間違いないようです。

UCONのbit4は、私のプログラムではEnumeration手続きに入るきっかけとしては有り難いのですが、そこを通過してしまったら、あとは私のプログラムにとっては、実に余計なことをしてくれているだけです。
なので、looptopでは、UCONのbit4がセットされていようがいまいが全くお構いなしに、ひたすらUCONのbit4をクリアするようにしているのです(同時にbit3は1にしています)。

ところで[第643回]のSETUP検出のところでは、UCONのbit6を1にしていました。
bit6を1にするとping−pong BufferのpointerがDATA0(even)にセットされます。
PIC18F14K50DataSheetのUCONのbit6の説明部分です。



正直なところ、ここで説明しているPing−Pong Buffer Pointerなるものがどういう役目をしているのか、はっきり理解しているわけではありません。
多分こういうことだろうなあ、とうすぼんやりとわかったつもりになっているだけです。

ping−pong Bufferについては[第637回]で説明をしています。
ping−pong BufferはEP0(OUT)のみに設定しています。
EP0(OUT)はUSBホストコントローラから送られてくるコマンドを受けるエンドポイントです。
USBホストコントローラはコマンドは必ずDATA0で送ってきます。
ですから最初にコマンドを受け取るためにはEP0(OUT)のDATA0(even)にポインタを合わせておく(?)必要があるのでは、ということで、このbit6を1にしています。
最初にそのように設定したあとは、なにしろping−pongですから、途中でリセットしてはいかんだろう、ということで、その後はbit6を0にしているのです。
そういうことで、その解釈が正しいのか間違っているのかは、正直なところ自信はないのですけれど、そのようにプログラムしたところ、どうやらまともに動いてくれているようですから、多分そういうことでよいのではないか、と思います。
2010.10.30upload

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