Microchip MPLABX/MPLAB harmonyでUSBオーディオデバイスを作る(前編)
必要に駆られ、PCからUSBオーディオデバイスとして見えるブツを作ることに。
数社のデバイスをピックアップし一通り試したのですが、PIC32を選定しました。
PICを選定した理由とか思った事とか、嵌まった所などメモ。
このブログの最後に今回作ったプロジェクトのgithubリンクを掲載しています。
MPLAB harmony
いつのまにかMicrochipからPIC32専用ファーム開発環境フレームワークが出ていました。
MPLAB Harmony | Home | Microchip Technology Inc.
MPLABXが採用しているNetbeansの機能に完全に支配されたフレームワークのようですが、使ってみた所感としてはMicrochip Libraries for Applications(MLA)のifdef地獄ライブラリから開放され、デバイススペシフィックにコードが生成できるため見通しは非常に良いです。
また生成されたアプリケーションはステートマシンが状態遷移をするコード構成になっておりRTOS移行時も比較的楽にできそうです。
またGPIOの入出力設定、初期状態のピンの論理もGUIで設定でき、かなり助かってます。(←ここ重要)
といいつつも今回のようにUSB周りを詳細にいじる場合はUSBデバイスディスクリプタなどスタック構造の知識を少し持っておかないといません。これは開発が容易といわれているCypress PSoC Creatorなどでも同様なので、設計自由度の高いUSBデバイスを作る開発環境では宿命なのかもしれません。しかしながらMPLAB harmonyもサンプルプロジェクトが豊富にあるのでそれを参考にできます。
PID/VIDでケチがつかないデバイスを作ることができる
MicrochipはNXPやFTDIなどと同様にUSBコントローラが自社デバイスであり、該当プロダクトの生産台数が10000台に達しないという条件の下、PIDをマイクロチップのVIDとともに使用する許可を申請できます(この情報について信頼を置ける権威ある文章は本家の英文です。必ず本家を参照のこと)https://www.microchip.com/usblicensing/Default.aspx
そのためオリジナルUSBデバイスで少量のデバイスしか作らない場合、PID/VIDにかかわる問題でケチがつかないデバイスを作ることができます。
使用したソフト/ハードなど
MPLAB harmonyはバージョンによってAPIが変わる可能性があります。このブログの内容を検証する際には以下の組み合わせを使用してください。
(インストール手順は割愛します。MPLAB harmonyはインストール後にMPLABXからロードできるようにする必要があります。この方法はMPLAB Harmonyのインストール完了後の画面で説明されます。)
使用したPICは秋月でお安いPIC32シリーズのPIC32MX220F032Bです。
PIC32MXは残念ながら正規の手法でUSBFS通信を行うには外部クロックが必要となります。16MHzのオシレータを接続しました。
また外付けオーディオDACを接続しようと思いますが、前編では、USBデバイスとして認識されるところまでの確認をしたいので、LEDを1つ、確認用に用意するだけにします。
参考回路図
サンプルコードaudio_speakerを参考にUSBデバイスディスクリプタを修正
USBスピーカサンプルがharmonyに同梱されています。ターゲットデバイスがPIC32MZ2048なのでちょっと違うのですが参考になります。
参考にするのはsystem_init.cの"USB Stack Configuration"(123~470行目です)
このサンプルプロジェクトをPIC32MX220F032B用に書き換えていくという手もありかもしれませんが、構成が複雑なのでやめました。
まず新規にPIC32MX220F032B用にMPLABXプロジェクトをつくり、Tools->Embedded->MPLAB harmony Configurator を起動しMBLAB Harmony Configuratorタブで設定を行います。
変更するのは
USB Library
Device & Project Configuration
の二つです。
USB Libraryは下図の青でマーカーされている部分が変更点です
Use USB Stack? -> check
Number of Endpoints Used: 2
USB Device Instance 0 -> check
Function 1 -> check
Number of Interfaces: 2
Device Class: AUDIO
Device & Project ConfigurationではPIC32MX220F032Bのクロックの設定がメインとなっています。ここが間違っているとどんなにがんばっても「USBデバイスが認識されません」とWindowsから言われてしまいます.
Device & Project Configuration ->
PIC32MX220F032B Device Configuration->
DEVCFG2->
FPLLDIV: DIV_4
FPLLMUL: MUL_20
UPLLDIV: DIV_4
UPLLEN: ON
FPLLODIV: DIV_1
DEVCFG1->
FNOSC: PRI
FSOSCEN: OFF
IESO: OFF
POSCMOD: HS
FPBDIV: DIV_1
FWDTEN: OFF
DEVCFG0
ICESEL: ICS_PGx2
PWP: 0xff
ポートの設定も行います。USBはポート固定されていますが、LEDを接続したRA0を出力に設定します。
MPLAB Harmony Pin Diagramタブを選択し、下部のMPLAB Pin Tableで、
Package: SPDIP
を選択し、Flagsをクリック。
RA0の項目を
TRIS: OUT
LAT: Low
を選択しウィンドウを閉じる。
ここまでできたら、Configurationボタンを押し、保存後Generateでコードを生成します。初回はOverwrite local changesにチェックをしても良いと思いますが、今後はsystem_init.cを手動で変更するので気をつけます。ここにチェックをしない場合、コードを変更してよいかGeneratorが聞いてきます。
生成後、先ほどのサンプルコードのsystem_init.cの"USB Stack Configuration"(123~470行目です)をコピーペーストしてしまいます。
メインとなるコードはapp.cです。ここにステートマシンが記述され、USBの状態により遷移するコードを記述します。
なお、audio_speakerのサンプルコードを元にapp.cを作りました。後述するgithubからダウンロードしてください。
今回LEDのみで実験する前提でした。なのでとりあえず動作(してるんだろうな?…って)確認ができる用のコードを記述します。
Windows上でオーディオスピーカをミュートする度にLEDがON->OFF->ONを繰り返すコードをapp.cに記述します。
app.cの276行目付近の”case USB_DEVICE_AUDIO_EVENT_CONTROL_TRANSFER_DATA_RECEIVED:”の部分を記述します。
case USB_DEVICE_AUDIO_EVENT_CONTROL_TRANSFER_DATA_RECEIVED: USB_DEVICE_ControlStatus(appData.usbDevHandle, USB_DEVICE_CONTROL_STATUS_OK ); if (appData.currentAudioControl == APP_USB_AUDIO_MUTE_CONTROL) { SYS_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_A, 0); // <- これを追記 appData.state = APP_MUTE_AUDIO_PLAYBACK; appData.currentAudioControl = APP_USB_CONTROL_NONE; //Handle Mute Control Here. } break;
コンパイル、書き込みを終え、PIC32MXをUSBで接続し、Harmony USB Speaker Exampleが認識できることを確認する。
ミュートするたびにRA0に接続したLEDが点灯→消灯を繰り返すはずです。