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を落とせることがわかったので、これを使って対処することにしました。