PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.7.13

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

PIC18F2550では大きすぎて、計画中のTK80互換マイコンボードND80ZVには組み込めそうにないことがわかりました。
USB機能内蔵のPICにはPIC18F4550、PIC18F2550のほかに20pinのPIC18F14K50があることはちょっと前から知っていました。しかしUSBに関する部分がPIC18F2550とはかなり異なっているようです。
案の定しっかり泥沼にはまってしまいました。

[第82回]

●いよいよ「PIC18F14K50でUSBを認識できません」というお話です

[第72回]で、PIC18F2550ではうまくいったUSBのプログラムがPIC18F14K50では動いてくれなくて、みごとに泥沼にはまってしまいました、と書きました。
もちろん、現在はクリアしてPIC18F14K50でもUSBにアクセスできるようになりました。
しかし、最初に、PIC18F2550でちゃんと動いているUSBプログラムをPIC18F14K50に移植したときは、それこそまったくうんともすんともいってくれなくて、ほんと、途方に暮れてしまいました。

その悪戦苦闘の記録です。

とにかく。
PIC18F2550では、USBケーブルを接続すると、デバイスマネージャーでちゃんとHIDデバイスとして認識してくれます。

ところが、どういうわけかPIC18F14K50では、全く反応がありません。
?も!も何もなしです。

むむ。
いくらなんでも、これは、ちょっとひどいのではありませんかあ?

もちろん、48MHzクロックについては先刻確認済みですし、USBバッファのアドレスもちゃんと変更いたしました(もっとも、実はそこのところにもミスがあって、変更できていないアドレスが残っていたために、事態はより混沌としたものになってしまったのでありますが)。

それこそ目を皿のようにして、DataSheetを繰り返し読んではみたのですが、とりたててPIC18F2550とPIC18F14K50との違いは見当たりませんでした。
これも、実はあとになってみると、フシ穴もいいところで、PIC18F2550とPIC18F14K50との間には、とんでもない、まったくもってけしからぬ相違があったのでありますが、ま、それにつきましてはいずれ後ほど。

とにかく、途方に暮れてしまいました。
どこからさぐってよいのやら、これではてがかりもなにもあったものではありません。
なにしろ、全く反応なしで、接続してもしなくても、全然変化なしという状況です。

こうなってきますと、誰しも考えることは大抵同じことになりまして、まずはハードを疑うことになります。
PIC18F14K50はとりあえず2個購入しましたから、その両方で試してみましたし、簡単な動作プログラムを何回も書き込んで繰り返し動作テストをして、チップが破損していたり、書き込みミスがあったりする可能性はまず考えられないことはほぼ確信いたしました。
ハードではないとすると、一体どこに原因があるのでしょう?
やっぱりソフトにその原因を求めるしかないのでは?

で、プログラムのあちこちにトラップを仕掛けて(なんていうとなんだか滅法格好がよいのでありますが、その実は適当なところにポートのビット出力を仕込んで、それをLEDで確認する、というきわめて原始的な方法に過ぎないのであります)、全く気乗りのしないまま追求を開始いたしました。

だんだん絞り込んでいきましたところ、なんと。
PIC18F14K50は、全然、ぜーんぜん、USBを認識していないらしいことがわかってきました。

お話の進行につれまして、徐々にUSBの仕組みについても、触れていくつもりなのですが、とにかく。
USBは、ホストからデバイスに対して、SETUPコマンドを送るところから始まります。
このあたりの信号につきましては、[第32回]のあたりで、すこしだけ説明をいたしました。

USBは、最初にホスト(パソコン)からのデータ信号送出で開始されます。
情報はパケットという単位で送られます。
パケットの最初は信号の同期をとるためのSYNCという8ビットの信号から始まります。
SYNCは80H(10000000)という値です。
その次に、そのパケットがどういう種類であるかを示す、PIDという信号が続きます。
PIDは4ビットからなっていて、その後にPIDの各ビットを反転したPID_が続きます。

USBは、ホストからSETUPパケットが送出されることで開始されます。
SETUPのPID信号は、1101です(その後に各ビットの1と0を反転した0010が続きます)。


[出典]Universal Serial Bus Specification(Revision2.0)

USBデバイスはこの信号をキャッチして、そこからセットアップための情報をホストからの指示にしたがって送信する(Enumeration)ことになります。

PIC18F14K50の動作を追及していきましたところ、その肝心かなめの、SETUP信号を全く認識していないらしいことが明らかになってきました。

テストに使ったプログラムはPIC18F2550でHIDの送受信に成功したところまでの全てを含むプログラムですからかなり長いものです。
その最初のSETUPを認識するあたりのところにLED出力を挿入して動作を確認してみました。
下はプログラムのその部分です。

;
	movlw 0ff
	movwf PORTC
	movlw 48
	movwf UCON;clear bit4,for SIE enbl
loop_ucon
	btfss UCON,4
	goto loop_ucon
	bcf PORTC,0
;

む?
UCONてなんだ?
知らんぞ。そんなレジスタは。今まで見たこともないぞ。

ごもっともです。
UCONはUSBのためだけに用意された特殊なレジスタです。


[出典]MICROCHIP社PIC18F1xK50DataSheet

いきなりPIC18F14K50のUSBコントロールレジスタが出て来てしまいます。
順をおって説明するつもりだったのですけれど…。

PIC18F14K50でUSBを使うためには、いくつかのUSB関連のレジスタを設定する必要があります。
このUCONレジスタもそのひとつです。
PICでUSBを制御するプログラムでは一般には、SETUP信号はこれとは別の手続きで認識することが多いようです。
しかし私は、UCONのbit4のコメントに着目しました。
UCONのbit4を0にしないとSIE(PIC内蔵USBコントローラ)はパケットの送信も受信もできません。
当然このビットを0にしてスタートすることになります。

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



[出典]MICROCHIP社PIC18F1xK50DataSheet

そこで、さきほどのプログラムです。
UCONのビット4をひたすら監視していて、ビット4が1になったらPORTCのビット0から0を出力するようなプログラムを実行すれば、そこに接続したLEDの表示によって、PIC18F14K50がSETUP信号をキャッチできたことがわかるはずです。
あ。
もちろん、それだけでUSB接続が完了する、などという甘いものではありません。
これは、はじめのはじめの第1歩で、これからながながと退屈なEnumerationという手続きが始まります。

しかし、ともあれ、とりあえずはここだけ見れば、ホストから送られてきたSETUP信号をチェックすることはできる、はずなのです。
論より証拠。
PIC18F2550で実行してみますと、USBケーブルを接続した途端に、PORTCのビット0に取り付けたLEDが消灯します。

ところが、PIC18F14K50だと、USBケーブルを接続しても、LEDは点灯したまま、だったのです。
CPUをつくろう!第511回(2010.5.29upload)を再編集

PICでUSBを![第82回]
2011.7.13upload

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