DoomPlayerではソニーのDualSenseコントローラーを使えるようにしています。この作業はNucleoボードを使っていた時から始めていたのですが、ようやくとさまになってきました。本記事では、DualSenseをSTM32につなぐ上での課題について書くことにします。
まず、最初にDualSenseのインターフェース仕様を入手、理解する必要があります。幸いなことに、ソニーがLinux用のドライバのソースを開示しているので、たとえばこことかを見ればUSBのHIDを介してボタンやセンサーの情報を拾ったり、LEDの点灯を制御したりできることがわかります。DualSense自体は、USBあるいはBluetoothでつなぐことができますが、DoomPlayerではUSBでつなぐことを想定しています。
USBのディスクリプタについては、このページに概要が整理されており参考になりました。lsusbの出力情報を見てわかるように全体はオーディオとHIDの2種類のクラスで構成される複合デバイスになっています。わたしは、PS5本体は持っていないし、ゲームコントローラを扱うのもPS2, Wii以来なのでDualSenseの多機能ぶりにただただ感心するばかり。ディスクリプタやHIDレポートの内容を調べてみて興味深かったのは、
- オーディオのサンプリングレートは48KHzで固定。ヘッドセットのジャックはステレオなのに、オーディオ出力は4ch分のデータを送ることになっているので、不思議に思っていたら、後半の2チャンネルを使って振動モータを制御できるんですね。
- タッチパッドはマルチポイント(2点)対応。何しろゲーム機に関する知識がほとんどなかったので、上部がスイッチだけでなくパッドになっていることが驚きでした。
STM32H7B2I-DK にはオーディオコーデックが載っているのでDoomPlayerでは音楽/効果音はボード上のコーデックを使うつもりでしたが、DualSenseのヘッドセット経由でもなかなかいい音が出るようなので、USB経由でのDualSenseでの再生もサポートすることとして、効果音をそのまま振動データとして出力することにしました。
さて、実際にDualSenseをSTM32H7につなげようとするといくつかの問題点があります。
- STM32CubeH7のUSBホスト機能では、複合デバイスをサポートしていない。ホスト機能自体では、AudioとHIDの両方のクラスをサポートしているのですが、実際は両方を同時に扱うことができません。とほほ。。両方を同時に使えるように作り直してやる必要があります。
- DualSenseのオーディオ出力は48KHz固定ですが、使うつもりのMusic PackのFLACデータは44.1KHzです。効果音のPCMデータもほとんどは44.1KHzの1/4である11.025KHzとなっています。レート変換して48KHzにすれば良いわけですが、CPUパワーを消費することになるので、とりあえずは無視して、44.1khzデータを48khzで出力してしまうことにします。ちょっとピッチが早くなるわけですが、それほどは気にならない感じ。
現時点では、DualSense経由でのオーディオと振動出力とボタンデータを拾ってのゲーム操作ができるようになりましたが、なぜか時々HIDでの入力を拾うパイプの動作が止まってしまうという問題が発生しています。調べてみると、該当のチャンネルでUSBのバブルエラーや送信エラーが発生した結果、ストールしてしまうようです。調子が良さそうに思えても10分ぐらいして止まってしまったりとか。原因がよくわからないので、USBケーブルを交換してみたらかなり改善されたように思えるのですが、それでも時々エラーが発生するようです。ひとまず、エラーを無視してストールしないようにして誤魔化しています。