マイコン工作実験日記

Microcontroller を用いての工作、実験記録

DualSenseをつなぐには

2022-09-19 10:35:11 | DoomPlayer

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ケーブルを交換してみたらかなり改善されたように思えるのですが、それでも時々エラーが発生するようです。ひとまず、エラーを無視してストールしないようにして誤魔化しています。


STM32H7B3I-DK

2022-09-18 10:02:39 | DoomPlayer

ハードウェアをNucleo-H7A3からSTM32H7B3I-DKに変更することに伴い、Doomの実装方法を変更することにしました。

  • これまでは音楽(MIDI)の再生にはVS1053bを使っていましたが、これを使わないことにしました。音楽については、WikiにてDigital Music Pack なるものがあることを知ったので、SDカードに保存されたこの音楽データを再生することにしました。具体的にはここからFlacで圧縮されたデータをダウンロードしておき、これをソフトウェアのデコーダで展開します。データ量としては、MP3の方が圧倒的に少ないのですが、繰り返し再生の範囲を指定するLOOPタグをメタデータとして持っているFlacの方がゲームとの相性は良いようです。
  • これまでは効果音の再生にもVS1053bのミキサ機能を利用していましたが、これらも全てソフトウェアでの処理に変更。音楽/効果音の再生はDKボード上のコーデックで再生します。
  • ゲームのWADファイルは、これまでと同じようにSPIフラッシュ上に書き込むことにします。これまではQSPI Flashでしたが、STM32H7B3I-DKではOCTO SPI Flashになります。
  • 前記事で書いたように、Nucleoボードでは、ゲームWADファイルの書き換えにはUSB DFUを使っていたために操作ミスでボードを壊すという痛いめにあいました。そこで今回はゲームデータもSDカード状に置いておき、SDカードからフラッシュにコピーして書き換えを行うことにします。
  • USBポートには、ゲームコントローラとしてDualSenceをつなぎます。Nucleo-H7A3ではUSBはFSでしたが、STM32H7B3I-DKではHSで使えるのがちょっとした違いになります。

 


2度あることは3度あるに違いない

2022-09-09 13:22:24 | DoomPlayer

Nucleo-H7A3ZIで作っていたDoom Playerですが、しばらく作業を止めていましたが継続を断念することにしました。2月終わりからロシアのウクライナ侵攻や米国での乱射事件が続いたことで、乱射ゲームにも気乗りしなくなっていたのですが、トドメをさすかのようにNucleoボードが壊れてしまい、QSPIフラッシュが読めなくなってしまったのです。ボード本体に問題が生じたのは明らかで、予備で買ってあったボードに差し替えたところ問題なく使えていたのですが、そのボードも1週間ほどして動かなくなってしまいました。

原因はおそらく電源の供給です。Nucleo-H7A3ボードにはUSB端子が2つあり、片方は電源/ST-Link用で、もうひとつはターゲットのMCUに直結されているホスト/デバイスポートです。ターゲットのUSBポートは、DFUでフラッシュを書き換えるためにしばしばPCと接続していたので、両方のUSBポートをPCや電源とつなげることも頻発。そうすると、ついつい、ST-Link側のUSBポートを外した状態で、誤ってターゲット側のUSBポートだけを繋いでしまうという間違いをやらかしてしまうのです。これを何度か繰り返していたら、QSPIが読めなくなりました。STMH7のコア部分は問題なく動いて、内蔵フラッシュの読み書きには問題無さそうなのですが。。。予備のボードでも同じ過ちをおかしてしまい。同じようにQSPIフラッシュが読めなくなってしまいました。ボードを買い直しても、同じ過ちを犯すに違いないので、Nucleo-H7A3ZIを使い続けるのは止めて、代わりにSTM32H7B3I-DKを使うことにしました。

Nucleo-H7A3ZIでは、QSPIフラッシュだけでなくQSPI RAMを使ってみることを一つの目的にしていました。その目的ななんとか達成できたものの、シリコンエラッタのためにかなり制約を受けることがわかりました。MPUでQSPIのメモリ領域をStrongly orderedに設定すれば、なんとか読み書きはできるものの、メモリのunaligned accessができなくなってしまうので、使い勝手が良くありません。こんなところで苦労するのであれば、問題を回避するために、OCTO SPIのRAMを使った方が良いということがわかりました。しかしながら、OCTO SPIになるとパッケージがBGAのものしか見当たらずちょっとハードルが高いです。基板を起こさねばならないのであれば、MCUを含めて他の部品と一緒に実装してしまった方が良いのですが、このご時世ではいつになったらSTM32H7A3 MCUが買えるのかもわかりません。

そんなわけで、今度はSTM32H7B3I-DKを使ってみることにしました。このボードでは残念ながら、OCTO SPI RAMではなくFMC経由でのDRAMになってしまいますが、メモリはたっぷりあるので、Doom本体にはあまり手を入れなくても簡単に移植できます。