これまでマイコン使ったUSBデバイスは幾つも作ってきましたが、USBデバイスをつなぐUSBホストについては一度も扱ったことがありませんでした。USBホスト機能を持つマイコンは限られていますし、USBデバイス機能ほど単純ではないからです。
でもUSBホストを使えば、USBキーボードやUSBメモリなどをI2Cやシリアル信号に変換して他のマイコンや古いPCに接続するなど楽しいことが出来ます。
そこでPIC32MX250F128Bを使ってUSBホスト機能を試してみることにしました。今は秋月電子で350円で販売されています。安いですね。
まず手始めにUSBキーボードをつないでキー入力を拾うところまで試してみます。
このマイコンはRAMが32Kバイトもありますが、調べてみるとキーボードの様なHIDデバイスをつなぎ、さらにI2Cなどを使うと容量的に少し心細い感じです。ネットでのPIC32系でキーボードをつないだ事例としてはこちらとかこちらが参考になったのですが、使用しているマイコンはPIC32MX270F256BとPIC32MZ2048EFH100でRAM64Kバイトと512Kバイトという高性能なマイコンでした。
メモリ容量的に不安な面もありますが、とりあえず試してみることにしました。
開発はMPLAB X IDEのHarmony v3を使うのですが、最新のMPLAB X IDE v6.20を使ったところPICのピン設定を行うダイアログがまったく表示されないトラブルが発生しました。詳細はこちらの議論を読むと分かります。v6.20でトラブったときはここを参考にするといいかもしれません。
これにはかなり悩まされましたが、結局v6.20はアンインストールして設定ファイルなども全て手作業で消してからv6.15のインストールで対処しました。
Harmonyはバージョンによって操作メニューも変わりますし、トラブルも多いので慣れてないとUSBホスト構築は難しいかもしれません。操作に慣れて経験を積んでからチャレンジすることをお勧めします。
いきなりつまずきましたが、気を取り直してブレッドボードに回路を組んでみました。
電源はPICの動作に3.3V、USBに5Vが必要です。今回は5V電源に三端子レギュレータをつないで3.3Vを作っています。
USBには48MHzの正確なクロック供給が必要なので水晶発振子をつなげます。8MHzと20Mz二つのクリスタルで動作確認はしましたが将来的には他のデバイスに接続して使うつもりなので、PICの消費電力を抑えるために8MHzのクリスタルを採用することにしました。
クロックコンフィグレーションはこうなります。
8MHzでも高クロックでPICを動作させることはできます。使用目的によって使い分けるといいでしょう。
使用するピンはUSBとI2Cです。ピンダイアグラムとピン設定はこうなります。
USBキーボード接続に必要なHarmony v3のライブラリは、Host LayerとHID Client Driverです。また、キー入力の表示のためにI2C接続のAQM1602Yを利用しましたので、I2C2ドライバも使いました。これらをプロジェクトに追加するとプロジェクトグラフはこんな感じになりました。
ここからそれぞれのコンフィグレーションを設定していきます。まずはPIC32MX250F128Bのコンフィグレーションレジスタから。
クロック関連の設定はクロックコンフィグレーションで設定済みなのでいじりません。
それとXC32のリンク時のヒープ領域を増やさないとコンパイルエラーになります。
今回のプロジェクトでは1Kバイト確保しました。
次はFreeRTOSの設定です。こちらもヒープ領域の設定が必要なのですが、デフォルトでは大きすぎてプログラムを実行するためのRAMが足りなくなります。そこでヒープサイズを28,000から20,000に減らします。
ネットのUSBホスト関連ではヒープを増やせという記事が目立ちますが、PIC32MX250F128BはRAMが32KBなので減らす必要があります。
今回はUSBキーボードをつなぐので、HID Client DriverではUSBキーボードドライバを選んでおきます。
これでGenerateボタンを押してひな形のソースコードを生成します。このとき生成されるinitialization.cのVBUS_AH_PowerEnable()とVBUS_AH_PowerDisable()はコメントアウトしておかないとコンパイル時にエラーになります。
ここから生成されたapp.hとapp.cにUSBキーボードの処理を記述していきます。上記のサイトを参考にキーボードから送られてきたスキャンコードを表示するための最低限の処理だけを記述します。AQM1602Yの表示にAQM1602Y.hとAQM1602Y.cという自作のライブラリを組み込んであります。
ちなみにmain.cは使用しないので変更せずそのままです。
作成したプログラムはこちらになります。
USBkeyboard.zip (クリックしてウィンドウが開いたら右上のダウンロードボタンを押してください)
生成されたapp.hやapp.cと差し替えてコンパイルしてください。USBキーボードをつなぐとキーボードを認識した後に、押されたキーと離されたキーのスキャンコードを表示します。今回使用したLCDは2行表示なので、CtrlやAltなどのモデファイヤーキーが押されたときは2行目にモデファイヤーキーの種類を2文字で表示します。文字の意味はソースコードで確認してください。
これでUSBキーボード接続のベースプログラムが完成しました。あとは読み取ったスキャンコードを接続先デバイスのキーコードに変換するルーチンを作り、I2Cスレーブとかシリアル接続などを組み込んで利用することになります。
ちなみに現時点でのメモリ使用状況はこんな感じです。
RAM領域が84%も使われています。LCD表示ルーチンも含んでいるのでキー処理部分だけならもう少し使用領域は少なくなるのかもしれませんが、これをベースに作成するプログラムによってはヒープ領域やスタック領域を調整する必要があるかもしれません。
※コメント投稿者のブログIDはブログ作成者のみに通知されます