マイコン工作実験日記

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

USBドングルを使ったDualSense/DUALSHOCK4のBT接続について

2023-05-30 22:20:19 | Weblog

DualSenseに加えてDUALSHOCK4のドライバを付け加えるとともに、USB接続の場合とBT接続の場合の処理を整理したりした結果、DUALSHOCK4のBT接続もできるようになりました。

写真に示したようにSTM32H7B3I-DKだけでなくSTM32F769I-DISCOにも移植しているので、動作確認の組み合わせが増えてしまって、まだ確認しきれていないところが。。。

写真でも見えますが、Bluetooth接続した場合には上図のようにBluetoothのアイコンボタンを表示するようにしました。このボタンを押すことによりBT接続を切断することができます。コントローラ側からも接続の切断はできるのですが、PSボタンを10秒押し続けねばならず面倒くさいので画面タッチで切断した方が便利です。

BTstackからのHID接続の切断は hid_host_disconnect() によって行えるのですが、この関数ではHID接続で使用していたL2CAPチャネルはクローズしてくれるのですが、HCLレイヤのACL接続はまだ残ったままになっています。そのため、gap_disconnect() によりこれをクローズしてやる必要がありました。

接続を切断しないままSTM32側をリセットしてしまうと、コントローラ側ではリセットされたことがわからずにいます。そのため、何かボタンを操作してから10秒以上経過しないとコントローラ側の電源が切れないらしく、その間コントローラからSTM32側へのPSボタン押下によるBT接続の再開操作が機能しないようです。

リセット動作に関しては、STM32H7B3I-DKを使った場合にソフトウェアリセットを掛けると、USBドングルのUSBエニュメレーションがうまくできないという問題がありました。どうやらUSBホストからUSBリセットをかけただけではBluetooth USBドングル(おそらくはCSRチップを使用?)が完全にリセットできず、一度ドングルに供給する5Vを落としてやる必要があるようです。

このリセット問題、同じUSB PHY(USB3320C)を使っているSTM32F769I-DISCOボードでは発生しないので疑問に思い両者の回路図を比較したところ、F769I-DISCOボードではPHYのRESETB信号がMCUのNRSTに接続されているのに対し、STM32H7B3I-DKボードではジャンパーを実装しないとプルアップ状態になっていることが判明。調べてみるとジャンパーを実装せずとも USB_DriveVbus() を呼ぶことでソフトウェアで VBUSを落とせることがわかったので、これを使って対処することにしました。

 


DUALSHOCK 4の接続

2023-05-22 22:51:34 | DoomPlayer

これまでDoomPlayer では使用するコントローラとして、DualSenseを使ってきましたが、新たにDUALSHOCK 4もサポートすべく作業中です。最近のLinuxのドライバを見たところ、DualSenseとDUALSHOCK4のコントローラはhid-playstation.c として統合されており、似たような扱いでサポートできることがわかったためです。

USB HIDクラスで取得できるレポートのデータ構造こそ異なってはいますが、DualSenseと同じような内容のデータが取得できるので、コントローラのボタン操作も同じように行うことができます。

DualSenseと違ってプレーヤ表示LEDはありませんが、ライトバー表示は前面にも大きく開いているので、音楽に合わせて光らせていると見栄えがします。まぁ、コントローラを手に持ったら自分では見えないんですが。。

購入してから気づいた残念な点は、DualSenseがUSB Audioとして48KHz, 4chをサポートしているのに対し、DUALSHOCK 4では32KHz, 2chしかサポートしていないこと。2ch出力なので、効果音による振動の発生はできません。また、音楽ももともとは44.1KHzの音源を32KHzで再生することになるので、かなりのスローテンポとなってしまい、何とも緊迫感に欠けるゲーム音楽になってしまうのが残念なところです。

こちらもBT接続できるようにするつもりです。

 


DualSenseのBT接続

2023-05-12 23:49:13 | DoomPlayer

DoomPlayerでは、DualSenseとUSBを使っての接続をサポートしていますが、実際に使おうとするとOTGホストケーブルを介さねばならず、ケーブルを2本つないでの接続が必要となり、ケーブルの取り回しも煩わしく感じます。そこで、Bluetoothでの接続機能を追加してみました。

上の写真のように、ホストケーブルでつないだBluetoothのUSBドングルを使うことで、DualSenseを接続して使うことができるようになりました。具体的にはBluetoothを介してのHID接続機能を実装することでUSBの場合と同じようにコントローラを用いての操作ができるようになりました。USBの場合には、音楽もUSB経由で送ってコントローラ側で再生することができましたが、Bluetooth経由での音楽データ送信はできないので、音楽はI2S経由での再生となります。

Bluetoothのスタックには、BTstackを使用。こちらのブログ記事を参考にUSBのBluetoothクラスを実装することでBTstackを移植しています。

初めてDualSenseを接続する時にはペアリングが必要となりますので、起動時にBluetoothのドングルが検出された場合には、次の画面を表示することにしました。

"Yes"を選択した場合には、BTstack側からinquilyを発行してデバイスのスキャンを行います。デバイスのCoDからコントローラらしきデバイスが見つかると、その名前を調べて"Wireless Controller" であることを確認したら、BTstack側からコントローラへのHID接続を行います。

"No"を選択した場合には、コントローラ側からの接続待ちになります。一度、ペアリングを行えば、DualSenseは最後に接続した相手を覚えているので、以後はPSボタンを押すだけでDoomPlayerへの接続を試みてくれます。

接続に成功したことがわかるように、画面左上にアイコン表示を追加しました。USBアイコンは、USBでコントローラあるいは、BTドングルが接続されたことを示します。Bluetoothアイコンは、BluetoothでのHID接続が成功したことを示します。DualSenseからのステータス取得時には、電池残量も一緒に報告されていることがわかったので、電池残量の表示もついでに追加してあります。