PICでUSBを!(知識ゼロからのスタートです)
PIC18F14K50のUSB機能を100%自前のソフトで制御する試みです。しかもアセンブラで!
当記事は2009年12月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 |
2011.7.13 前へ 次へ 目次へ戻る ホームページトップへ戻る |
☆PIC18F14K50 PIC18F2550では大きすぎて、計画中のTK80互換マイコンボードND80ZVには組み込めそうにないことがわかりました。 USB機能内蔵のPICにはPIC18F4550、PIC18F2550のほかに20pinのPIC18F14K50があることはちょっと前から知っていました。しかしUSBに関する部分がPIC18F2550とはかなり異なっているようです。 案の定しっかり泥沼にはまってしまいました。 |
[第93回]
●PIC18F14K50用「動作する」USBプログラム(その2)
前回、PIC18F14K50は、USBに関係するシステムレジスタの多くが、バンク切り換えを使わない簡便なアクセス方式であるAccess Bankではアクセスできない「領域外」に置かれているために、PIC18F2550で動作するプログラムも、そこの部分を書き直す必要がある、ということについて説明をいたしました。
その対策として、前回はバンク切り換えによる方法を説明しました。
システムレジスタのあるバンク15を指定するためにBSRレジスタに0Fh(=15)をセットしておいて、バンクを切り換えてアクセスしたい命令のときだけ、命令の末尾に’a’パラメータとして’1’を表記する、という方法です。
当初私はBSRによるバンク切り換え方式はかなり面倒なプログラムになってしまうのではないか、と思っていたのですが、よくよく考えてみますと、そもそもバンク切り換えが必要なところはそれほど多くはないことがわかってきました。
それは、
@USB関係のレジスタを除いて、その他のほとんどのシステムレジスタはAccess Bankとして普通にアクセスできる
AAccess Bankとして普通にアクセスできるユーザー用の汎用メモリはアドレス000〜05Fの96バイトもあるので、ワークエリアとしては十分な場合が多い
という2つの理由からです。
Access Bankとしてアクセスする、ということは、PIC16Fと同じように、何も気にしないで(特別のパラメータを付加したりしないで)ごく普通に命令を表記するればよい、ということなのですから、普通はそうするのが最も都合が良い、と思います。
では、BSRレジスタによるバンク切り換えが必要になるときとは、どんなときなのでしょうか。
そのひとつが、前回から書いております、Access Bankではアクセスできないシステムレジスタをアクセスするとき、です。
そのシステムレジスタはUSBに関するレジスタで、アドレスF5F〜F53にあります([第91回]参照)。
USBのみに直接関係するシステムレジスタは、UCON(F64)からUEP0(F53)まで18あって、そのうちF5F〜F53にある13のレジスタはAccess Bankではアクセスできません。
数だけで言いますと、USB関係のほとんどのシステムレジスタがAccess Bankの対象外になってしまう、ということになりますが、よくよくその内容を見てみますと、対象外になるシステムレジスタのうちでも、UEP7〜UEP0はエンドポイントのためのレジスタで、それが13のうちの8個であることがわかります。
エンドポイントのためのレジスタはそのエンドポイントを使わなければ、アクセスすることはありません。
とすると、普通にHIDとして使うならば、UEP0とUEP1の2つあれば十分ですから、UEP2〜UEP7は除外して考えてもよい、ということになります。
UFRMHとUFRMLは使わなくても済むレジスタですし、UEIRとUEIEも使わなければならない、というレジスタではありません。
UEIRとUEIEはUSBの割り込みのためのレジスタですから、そりゃあ必須だろう、と思われるかも知れませんが、全然そんなことはありません。
PIC18F14K50は高速(48MHz)で動作しますし、USB(Full Speedモード)は1msごとにしか送受信しませんから、割り込みなど考える必要はないのです。
まあ割り込みを使う使わないは好き好きですから、そりゃあ使っても構わないわけですけれども、私は必要無いと考えましたので使いませんでした。
ということで、するとAccess Bankではアクセスできないシステムレジスタ、というのは、実際のところ、UADDRとUEP1とUEP0だけ、ということになります。
しかも、このいずれのレジスタも初期設定のときに必要なだけですから、プログラムの最初にBSRに0Fをセットして、処理をすませておけば、あとはアクセスする必要はありません。
実は、それ以外に、Access Bankではアクセスできない範囲外にあって、もっと頻繁にアクセスしなければならないレジスタがあります。
それは、アドレス200〜2FFにある「汎用メモリ」です。
ここはUSBのための双方向メモリになっていて、USBの送受信のたびに頻繁にアクセスしなければなりません。
このメモリエリアをBSRベースのバンク切り換えでアクセスしようとする場合には、BSRレジスタに02をセットしておいてから、そのメモリ範囲にアクセスする命令のときだけ、’a’パラメータとして’1’を付加する、ことになります。
それはちょいと面倒くさいプログラムになります。
このUSBのためのメモリバッファをアクセスするところでは、次に説明するFSRとINDFを使った間接アドレッシングに依る方が楽だと思います。
●FSRとINDFを使ったプログラム
前回の、PIC18F14K50に限って対策が必要なUSBプログラムの、その部分をFSRとINDFを使って書き直してみると、次のようになります。
; usbreset movlw 16 lfsr 2,0f53;UEP0 movwf INDF2 movlw 15;ping-pong buffer set for EP0(out) only movwf UCFG ; |
; ;ep0 out data0(even) setbd0 lfsr 1,203 movlw 05;address high movwf POSTDEC1 movlw 00;address low movwf POSTDEC1 movlw 08;bytes movwf POSTDEC1 movlw 80;STAS(even) movwf POSTDEC1 return ; |