標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第511回]
●いよいよ「PIC18F14K50でUSBを認識できません」というお話です
[第499回]で、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コマンドを送るところから始まります。
このあたりの信号につきましては、[第424回]のあたりで、すこしだけ説明をいたしました。
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は点灯したまま、だったのです。
2010.5.29upload
2010.5.30一部追記
前へ
次へ
ホームページトップへ戻る