マイコン工作実験日記

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

AVRCP Cover Art -- その2

2023-10-02 21:49:40 | Weblog

AVRCP Cover Artは、200x200画素のJPEG データとして送られるという仕様になっています。STM32H7B3I-DKでは、LCDの画面サイズが480x272ですので、JPEG展開してそのまま表示してやるのにはピッタシの画面サイズになっています。また、MCUがJPEGデコーダをハードウェアとしてサポートしているので、展開も簡単に行うことができます。

そんなわけでLVGLを使って簡単なプレーヤ画面を作成して、アルバム画像を表示してみました。音楽のアプリとしてはAndroid携帯で Sportifyの無料バージョンを使ってみました。ところが、曲名やアーティスト名は正しく表示できるのですが、アルバム画像が1曲遅れて表示されてしまいます。

Bluetoothで接続後、最初の1曲目は正しくタイトルと画像が表示されているのですが、2曲目ではタイトルとアーティスト名は正しく表示されるものの、画像が変化せず。3曲目以降では1つ前の曲の画像が表示されてしまうのです。

Spotifyアプリの問題だろうと思い、Pulsar というアプリも試してみたのですが、同じ症状でした。使用端末の問題かとも考えたのですが、検索してみたところspotifyのコミュニティで同じ問題が報告されていることがわかり、どうやらアプリ側の問題のようです。アプリの問題であれば、Google純正であれば間違いがないのではと考えが至ったところでで、「そういえば、YouTube Music というサービスがあったなぁ」と思い出し、試してみました。

やっぱりGoogle純正アプリだけのことはあって、ちゃんと正しいアルバム画像が表示されます。しかし、無料サービスではバックグラウンド再生ができないというのが、致命的でとてもスマホで使う気になれませんね。

なお、曲名とアーティスト名の表示には、Zen Maru Gothic を使っています。


AVRCP Cover Art

2023-09-22 13:44:51 | Weblog

LVGLでTrueTypeフォントを使って容易に漢字表示もできることが確認できたので、これを使ってBluetooth経由での音楽プレーヤを作ろうかと思っていたところ、BlueKitchenのブログでまさしくやろうと思ったことが紹介されていました。おまけに、カバーアートの画像表示まで実現されています。

最近のスマホはAVRCP 1.6に対応しており、最新のBTstackを使えば画像データのダウンロードも可能とのこと。動画で使われているのは、Pico wを搭載しているCosmic UncornというRGB LEDボードです。Pico wでは今年の6月に更新されたSDKでBluetooth対応が追加されていますが、ここで採用されているBluetoothスタックはBTstackに他なりません。

Pico wは元々Wifi/BTのモジュールと3本の線だけで通信しており、WiFi機能の通信も通信方向を切り替える半2重通信となっています。BTのサポートを追加するための信号が別途用意されているわけでもないので、どうやってサポートするのかと思っていましたが、ファームウェアが頑張って、WiFiとBluetoothの両方の通信を同じ信号線を使ってやりとりしているようです。まぁ、Pico w のようなボードでは実用上WiFiとBluetoothの両方を使った高速通信が求められることもないでしょうから、こういった思い切った割り切りでも良いのでしょう。ただし、通信のリアルタイム性が求められるBluetoothのSCOチャネルをサポートするのは流石に無理なので、Pico wでもHFPを使って電話の通話をすることはできません。

Pico wでは日本語のTTFフォントまで載せてLCD表示させるのは苦しいので、DoomPlayerで使ったSTM32H7B3I-DKにUSBドングルをつなげて実現する方向で作業中です。


TrueTypeフォントを表示してみる

2023-07-23 12:19:25 | Weblog

DoomPlayerの開発にはLVGLのv8.3を使用していましたが、現在LVGLプロジェクトではv9.0に向けての開発が進行中です。最新のmasterを覗いてみたところ'Tiny TTF font engine'というTrueTypeフォントの使用を可能とするライブラリが用意されていることを知ったので、どんなもんか試しに使ってみました。

使用したボードはSTM32H7B3I-DK. フォントデータはGoogle fontsから日本語のフォントを適当に選んでダウンロード。ダウンロードしたttf ファイルは '.bin' に拡張子を変更すれば、そのままSTM32CubeProg を使ってボード上のOctal SPI Flashに書き込むことができます。ライブラリのAPIとしては

lv_font_t * lv_tiny_ttf_create_data(const void * data, size_t data_size, lv_coord_t line_height);

という関数が用意されており、TTFファイルデータのあるアドレスと、そのサイズ、希望する高さを与えてやるとlv_font_t 構造体を用意してくれます。あとは、通常のフォントと同じように文字列表示を行うことができます。表示するビットマップデータは、文字表示操作が呼ばれた時にTTFデータから必要な大きさに展開されて作成されるので、RAMの使用量も抑えることができます。動画で示したように大きさを変えながら表示する場合には、ビットマップへの展開し直しが発生していますが 280MHz動作のSTM32H7B3をもってすればかなりスムーズに表示できることが確認できました。

これまではTTFのフォントデータから、あらかじめ必要なサイズのフォントビットマップデータを作成しておき、それをSDカードやフラッシュに書き込んでおくということをしていましたが、OctSPI/QuadSPIフラッシュをMemory Mappedで使えば、もうSDカードは不要な上に複数の書体/サイズのビットマップを動的に作成して使用できますね。


DoomPlayer with Wireless Controllers

2023-06-09 19:40:34 | DoomPlayer

これまでの作業のまとめとして、BluetoothでDualSenseとDUALSHOCK4を接続するデモ動画を用意しました。

動画でも示したように途中でDualSenseのBT接続を切断して、DUALSHOCK4につなぎかえるということもできます。


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