2011年7月3日日曜日

LPC11U14 LPCXpressoを使ってUSBを研究しよう! - USB研究部会 - (LPCXpresso週間)

USB! USB! USB!

以前の記事、LPCXpressoの放置を防ぐお勧め取り組み方法(LPCXpresso週間)では、放置を防ぐアイデアの1つとして「具体的な目標に繋げる」というものを挙げました。
今回はLPC11U14 LPCXpressoを使って、USBを研究する例を取り上げてみましょう。

LPC11U14の概要

LPC11U14は最大クロック周波数50MHzのARM Cortex-M0をコアに持つNXPセミコンダクターズ社のプロセッサです。
LPC11U14の場合、内臓フラッシュは32KB、SRAMは6KBあり、そのうち2KBがUSB用となっています。


GPIOは40本、ADCも8チャンネル搭載されており、USBも接続できるため様々な応用例が考えられます。

まずはデータシートからブロック図を見てみましょう。
おっと、データシートはまだドラフトのようですね。


USARTやI2C、SPI(SSP)はもとより、SMARTCARD INTERFACEやPMU(Power Management Unit)が搭載されています。
PMUはLPC11U14では特徴的な機能の1つと言えそうです。

メモリマップは以下のようになっています。


メモリマップを見てもわかるように6KBのSRAMは連続した領域ではなく、2KBのUSB用RAMと残りの4KBに分かれていることがわかります。

で?USBは?

ひとくにちUSBといってもホストやらデバイスやら色々あるわけです。
LPC11U14で言うUSBは「USB 2.0デバイス」を指します。

LPC11U14に搭載されたUSB 2.0デバイス・コントローラの機能は以下の通りです。
  • USB 2.0フル・スピード・デバイス・コントローラ搭載。
  • 1つのコントロール・エンド・ポイントを含む、10個の物理(5個の論理)エンド・ポイントをサポート。
  • シングル・バッファリングとダブル・バッファリングをサポート。
  • 非コントロール・エンド・ポイントはそれぞれ、バルク、インタラプトかアイソクロナス・エンド・ポイントをサポートします。
  • USB動作におけるディープ・スリープ・モードからのウェイク・アップとリモート・ウェイク・アップをサポートします。
  • ソフト・コネクトをサポートします。

    LPC11U14のUSBハードウェア

    ここで、ハードウェア・ブロック図を見てみましょう。

    アナログ・トランシーバが内臓されているおかげで、外付けデバイスなしでUSB接続ができます。
    DMAエンジンはAHB_MASTERに接続されています。


    SERIAL INTERFACE ENGINE(SIE)はUSBプロトコル層をハードウェアで実現したものです。
    このため、ソフトウェアの介在なしにUSBプロトコル層を処理できるようになっています。
    USB用RAMとUSBバスにおけるエンド・ポイント・バッファ間のデータ転送はこのハードウェアによって処理されます。

    LPC11U14のUSBソフトウェア

    エンド・ポイント・リスト・ポインタはアドレス0x20004000にあるUSB用RAMブロック内を指すようにします。
    データはどのSRAMにも格納することができます。

    これらを図示したのが以下の図です。


    上記のようにレジスタにアドレスを設定しておけば、SRAMにデータが格納するまでを勝手にやってくれるという仕組みです。
    このUSBコントローラにはUSB IRQ割り込み(USB_Int_Req_IRQ)とUSB FIQ割り込み(USB_Int_Req_FIQ)の2つの割り込み線が存在します。
    リクエストの処理は通常これらの割り込みを使って処理することになります。

    どこから手を付ける?

    「じゃあ、始めましょう!」と言って笑顔でコーディングを始めても良いのですが、出来上がるまでに何回くらい日が暮れるのかわかりません。

    幸いにもNXPセミコンダクターズがLPC11U14で使えるUSB HIDのサンプルを提供してくれています。
    今回はこれを使ってUSBの研究を始めることにします。

    情報が豊富で頻繁にアップデートされているサポートサイトは http://ics.nxp.com/support/lpcxpresso/ にあります。


    上記ページにある「LPCXpresso USB HID Example Project for LPC11U14」を選択してクリックして下さい。
    アーカイブされたプロジェクトをダウンロードすることができます。
    アーカイブされたプロジェクトの使い方は私の記事「LPCXpressoのサンプルを使ってみよう(LPCXpresso週間)」も参考にして下さい。

    先ほどのアーカイブ・プロジェクトにはCMSISが含まれていませんが、実際には必要です。
    これも http://ics.nxp.com/support/lpcxpresso/zip/CMSISv2p00_LPC11Uxx.zip からダウンロードして読み込んでおきましょう。


    ビルドしたバイナリを書き込んで、LPC11U14側に接続されたUSBコネクタに接続するとUSB入力デバイスとして認識されることがわかります。


    デバイス・ディスクリプタのソースコードと見比べてみても、ふむふむ確かに同じだということがわかると思います。



    USB HIDサンプル・プロジェクトの中身

    今度はUSB HIDサンプル・プロジェクトの中身について調べてみます。
    まずは「一体このサンプルは何をすることができるのか?」興味のあるところです。

    HIDと言っても色々あるので、一体何と主張しているのかを調べます。
    これはディスクリプタを見ればすぐにわかるはずです。


    キーボードかマウスかな?と思いましたが、両方外れでした。
    HID_PROTOCOL_NONE(値:0)が指定されています。

    では、具体的にどんな実装になっているのかプロジェクトからdemo.cを見てみましょう。
    demo.cのGetInReportとSetOutReportはリクエストがあった時点で呼ばれる処理関数です。
    これを見る限り1ビットの入力と4ビットの出力をサポートしているようです。


    1つずつ調べていくと色々なことがわかってきます。
    楽しいですね。

    やりたいのはPCとの連携(USBなんだから)

    さて、先ほどのSetOutReportに気になる記述があります。

    /* port1, bit 14~17 are used as LED indication from
    HID utility. */
    

    HIDユティリティとは何だ?ということで調べてみました。
    が、それが何を指すのかいまいちよくわかりません。

    今、非常にやりたいのはこの独自デバイス(今は評価基板ですが)をPCから制御できるようにしたいわけです。

    実はWindows Driver Kit (WDK)にUSB HIDクライアントのサンプルがあります。
    今回はターゲットがUSB HIDとして動作しているので、デバイスドライバを開発する必要はありません。

    今回はUSB HIDクライアントのサンプル目当てでWDKを使います。


    まずは Windows Driver Kit (WDK) をダウンロードします。(2011/07/03現在、バージョンは7600.16385.1 でした。)
    ダウンロードしたisoファイルに含まれるセットアップを実行します。
    isoファイルをファイルシステムをマウントするツールもあるのですが、そのツールの信頼性を確認したりするのが面倒なので私はCD-Rに焼いてから実行しました。

    次に VisualStudio 2010 Express から Visual C++ 2010 Express をダウンロードします。


    VisualStudioも通常通りインストールしておきましょう。

    次にWDKに含まれるHIDのサンプルをビルドします。
    USB HIDのサンプルは幾つかあります。
    今回は C:\WinDDK\7600.16385.1\src\hid\hclient を試します。


    コンソール画面が出ます。
    先ほどのディレクトリにcdしてbuildを実行します。


    これで hclient なるサンプルのビルドが完了しました。
    ターゲットディレクトリの下を見るとディレクトリが生成されていると思います。
    その中の hclient.exe を実行して下さい。
    以下のような画面が現れます。


    さて、LPC11U14の入力ポートの状態をこのクライアントアプリケーションで見てみましょう。
    まずは、接続したLPC11U14を探し出します。


    見つかったら、VID、PIDを確認して、同じVIDとPIDを持つデバイスをSample HID client appのウィンドウ上で探します。


    これで準備ができました。
    早速ポートの値を読んでみましょう。

    ウィンドウにある「Blocked Read Data」を選択します。

    以下のようなダイアログが出現します。
    このダイアログの「連続読みだし」ボタンを押すとデバイスからのブロック・データ読みだしが実行できます。


    それではLPCXpressoの入力ポートの状態を変化させてみましょう。
    基板上にある「P0_1」ポートに対して入力を与えると、上記のダイアログのように出力内容が変化します。

    要するにターゲットのHIDがホスト上のアプリケーションの要求に応答してポートの状態を返しているのです。


    Sample HID client appはMicrosoftからソースコードが公開されているアプリケーションで、今回は提供されているサンプルをそのまま使いました。
    この中で使われているAPIを調べる事で、自分のデバイスに対する自分だけのライブラリやアプリケーションを仕立てることも可能になります。

    まとめ(何が揃ったのか)

    我々は、LPCXpresso評価基板1つの投資で以下の物を手に入れました。
    • 自由にいじれるUSB HIDのデバイス側。
    • 自由にいじれるUSB HIDのホスト側アプリケーション。
    マイコンの世界でクローズするのではなく、今回のようにアプリケーションを組み合わせることで沢山の応用例に発展させることができるようになります。

    デバイス・ドライバを開発することなく、独自のUSBデバイスを接続できる手軽さは、かなり魅力的です。また、今回のようにホスト側もターゲット側も自由に改造して楽しむことができますので、USBをもっと身近に感じてみたいエンジニアにとっては格好の材料となりそうです。

    皆さんも是非「USBは難しそう」と思わずに気軽に挑戦してみませんか?

    他にどんな情報が必要ですか?

    何か必要な情報があれば、本家も訪ねてみてください。

    2 件のコメント:

    1. SimpleHIDWrite というフリーウェアがそれっぽいです.
      ttp://www.lvr.com/hidpage.htm
      「自前でホストプログラムを用意すること」からは外れますが,
      動作確認には使えそうです.

      返信削除
    2. katuwo様

      コメントありがとうございます。
      手軽に動作確認する手段は嬉しいですよね。
      情報ありがとうございます。

      返信削除