Raspberry Pi CM4とCSI-2接続HDMI入力基板で音も取る

Raspberry Pi CM4とCSI-2接続HDMI入力基板で音も取る

2年前に投稿したHDMI入力をRaspberry Piで取り込む記事では映像しか取得していませんでしたが、このHDMI入力基板には音声も取り込めるチップTC358743が搭載されています。 取り込める端子は購入したHDMI入力基板にもちゃんと用意されていたので、ピンヘッダを取り付けて信号を見たりしたものの、音声出力が正常に取得できませんでした。 この問題をあれこれ探し回って解決した記録を残しておきます。

HDMI入力をRaspberry Piで駆使する HDMI入力をRaspberry Piで駆使する

昨今の衰えることのない技術トレンドに追従すべく、映像配信とかやりたいなーと思っていた2019年。 めっきり時間がなく何もできず、気付けば2020年になっていました。今年も時間がないだろうなぁと思っていたところ、連日の在宅勤務のおかげで通勤時間がゼロになり、余暇が生まれたので色々やってみることにしました。お題はHDMI入力で遊ぶ、です。...

目次

Open 目次

  1. HDMI入力基板で音声も取り出そうとした2020
  2. HDMI入力基板 H2C-RPI-B01とTC358743XBG
  3. I2S (Inter-IC Sound Bus)
  4. 音声を取り出す最初の挑戦(2020年4月)
    1. ハードウェアの配線
    2. Raspberry Pi OSのファームウェア設定
      1. Device Tree
      2. Device Tree Overlay
    3. 音声出力信号の取り込み
  5. 音声を取り出すリベンジ
    1. 足りない配線とI2S APLLパッチ
      1. ユニバーサル基板に実装
    2. 再度録音に挑戦
  6. reTerminalやCM4で使えるようにする
  7. まとめ

HDMI入力基板で音声も取り出そうとした2020

実は当時、ブログ記事を投稿する直前まで音声出力が正しく得られないかどうかを色々と試行錯誤していました。参考リンクにその調査に使ったリンクが一部残してあります。 しかし一筋縄ではいかず音声出力を得ることはできなかったため、その時に書いていた下書きをボツにしていました。 しばらくして解決したものの、記事を完成させるモチベーションもなくお蔵入りになる予定でしたが、ちょうどreTerminal拡張モジュールコンテストHDMI入力モジュールとして応募したこともあって、ゴミ箱から拾ってきて記事として完成させました。 なので内容としては2年前の記録になりますが、ブラッシュアップしてあります。

なお、当時はBullseyeベースの新しいRaspberry Pi OSは登場していなかったこともあり、この記事の内容は全てBusterベースのRaspberry Pi OSでの動作を記しています。また、本記事執筆時(2022/02/26)の最新版である以下の構成で動作確認をし直しています。

OS: Raspberry Pi OS

Raspberry Pi OS (Legacy) with desktop Release date: January 28th 2022

ハードウェア: Raspberry Pi 4B

Hardware : BCM2711 Revision : c03112 Model : Raspberry Pi 4 Model B Rev 1.2

カーネル: 5.10.63-v7l+

Linux raspberrypi 5.10.63-v7l+ #1496 SMP Wed Dec 1 15:58:56 GMT 2021 armv7l GNU/Linux

ファームウェア: Dec 1 2021 15:02:46

Dec 1 2021 15:02:46 Copyright (c) 2012 Broadcom version 71bd3109023a0c8575585ba87cbb374d2eeb038f (clean) (release) (start_x)



HDMI入力基板 H2C-RPI-B01とTC358743XBG

以前の記事で使ったHDMI入力基板、H2C-RPI-B01はRaspbianRaspberry Pi OSの標準ドライバで処理され、接続するだけでRaspberry Pi Camera Moduleと同様のV4L2デバイスとして認識され、映像入力を扱えました。 何もしなくても動いたのは良かったのですが、何もしなかったためにCamera Moduleと同様に映像しか扱えませんでした。

H2C-RPI-B01に搭載されているチップであるTC358743XBGは、実はHDMI音声入力が扱えます。データシートにはI2Sバス規格で音声データのやりとりをすると書かれています。

TC358743XBG_datasheet_en_20171026 p.1

引用元: TC358743XBG_datasheet_en_20171026.pdf TC358743XBG | HDMI® インターフェースブリッジ | 東芝デバイス&ストレージ株式会社 | 日本

I2S (Inter-IC Sound Bus)

I2SはInter-IC Soundという音声通信バス規格のことです。

I²S - Wikipedia

NXP Semiconductorsが1986年に仕様を定義したものですが、オリジナルの仕様書はインターネットの海に沈没してしまっていて、アーカイブしか見つけられません。

I2SBUS.pdf - Internet Archive

4つのピンでクロックとデータをやりとりするシリアルバス規格であり、日本語版Wikipediaの記事に要約が書かれています。

Inter-IC Sound - Wikipedia

Raspberry PiのGPIO端子は音声入力と出力の両方に対応しており、PCM_で始まるラベルのついているピン(GPIO 18,19,20,21)がI2Sです。

Raspberry Pi pinout

引用元: GPIO and the 40-pin Header - Raspberry Pi Documentation

音声を取り出す最初の挑戦(2020年4月)

I2Sのハードウェア接続とファームウェア設定を行い、音声の取り込みに挑戦していきます。

ハードウェアの配線

HDMI入力基板の出力ピンとRaspberry Pi 40ピンヘッダーのI2Sのピンとを接続します。

HDMI入力基板には10ピンの入出力端子を取り付けられるスルーホールが用意されています。 H2C-RPI-B01以外の類似品をいくつも買ってみましたが、同じTC358743XBGを搭載する基板には大抵あります。

HDMIボードピン

少し離れたところに各スルーホールの機能を記すシルクがありますが、それを参考にして下表の通り接続します。

HDMI入力基板シルクRaspberry Pi ピン番号Raspberry Pi GPIO
SCK12PCM_CLK(GPIO 18)
WFS35PCM_FS(GPIO 19)
SD38PCM_DIN(GPIO 20)

Raspberry Pi OSのファームウェア設定

I2Sの配線を済ませただけでは音声入力を扱えないので、ファームウェアの設定とドライバのロードをさせます。

Device Tree

Linuxがドライバをロードする時、接続されているデバイス情報を元に適切なドライバを選択しています。 接続デバイスを管理するのがDevice Treeというハードウェア構成情報です。Device Treeは /proc/device-tree のprocファイルシステムを覗くと、だいたいどんなものが認識されているかがわかります。文献は以下に詳しいです。

TC358743のドライバであるmedia/i2c/tc358743.cは、次のようにデバイスを見つけてドライバの初期化(probe)を行います。

static const struct of_device_id tc358743_of_match[] = {
	{ .compatible = "toshiba,tc358743" },
	{},
};
MODULE_DEVICE_TABLE(of, tc358743_of_match);

linux/drivers/media/i2c/tc358743.c#L2255-L2259

compatibleに”toshiba,tc358743”と記載のあるデバイスがあれば、tc358743のドライバが読み込まれるということです。 ただ、何も設定をしていないRaspberry Pi OSではそのような記載のあるデバイスはなく、Camera Moduleのvc04_services/bcm2835-camera.cがドライバとして読み込まれてしまっています。

linux/bcm2835-camera.c at 1.20220120 · raspberrypi/linux

Camera Moduleのドライバではなく、TC358743のドライバであるmedia/i2c/tc358743.cをロードさせるために、Device Treeを上書きしてファームウェアを設定します。

Device Tree Overlay

Device Treeを上書きする機能の名はDevice Tree Overlay。そのまんまです。 RaspbianRaspberry Pi OSではこれを読み込むことで、Device Treeを上書きできます。 Raspberry Pi OSには、 /boot/overlays にDevice Tree Overlayの構成ファイル、Device Tree Blob Overlay(.dtbo)が格納されています。

firmware/boot/overlays at 1.20220120 · raspberrypi/firmware

Blobと名前に含まれるように、バイナリファイルにコンパイルされたものですが、これらのソースコードはraspberrypi/linuxの /arch/arm/boot/dts/overlays にあります。

linux/arch/arm/boot/dts/overlays at 1.20220120 · raspberrypi/linux

この中にtc358743向けのoverlayが存在し、次のように書かれています。

		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			tc358743@0f {
				compatible = "toshiba,tc358743";
				reg = <0x0f>;
				status = "okay";

linux/tc358743-overlay.dts at 1.20220120 · raspberrypi/linux

compatible = "toshiba,tc358743";とあるので、このdtboを読み込めばtc358743がデバイスとして認識され、ドライバが読み込まれるということです。

ただ、これだけでは音声入力を扱うことはできません。 HDMI入力基板と音声をI2Sでやり取りするには、音声インターフェースのDevice Tree定義とドライバの読み込みが必要です。 TC358743XBGのI2S用の定義も、RaspbianRaspberry Pi OSのDevice Tree Overlayに用意されています。

linux/tc358743-audio-overlay.dts at 1.20220120 · raspberrypi/linux

これらのDevice Tree OverlayとI2Sを扱うパラメーター設定を/boot/config.txtに記述する方法を深く理解しながら/boot/config.txtに追記します。

dtparam=i2s=on
dtparam=audio=on
dtoverlay=tc358743
dtoverlay=tc358743-audio

これで再起動すると、lsmoddmesgmedia/i2c/tc358743.c のドライバーが読み込まれていることが確認できます。 overlayが正しく読み込まれているかどうかは、sudo vcdbg log msgなどで確認できます。

pi@raspberrypi:~ $ dmesg | grep tc358743
[    4.137243] tc358743 0-000f: tc358743 found @ 0x1e (bcm2835 I2C adapter)
pi@raspberrypi:~ $ lsmod | grep tc358743
tc358743               40960  1
v4l2_dv_timings        36864  2 bcm2835_unicam,tc358743
v4l2_fwnode            20480  2 bcm2835_unicam,tc358743
v4l2_common            16384  3 bcm2835_unicam,bcm2835_v4l2,tc358743
videodev              200704  9 bcm2835_unicam,v4l2_fwnode,bcm2835_codec,v4l2_common,videobuf2_common,bcm2835_v4l2,v4l2_mem2mem,videobuf2_v4l2,tc358743
media                  36864  5 bcm2835_unicam,bcm2835_codec,videodev,v4l2_mem2mem,tc358743
pi@raspberrypi:~ $ ls /dev/video*
/dev/video0  /dev/video10  /dev/video11  /dev/video12
pi@raspberrypi:~ $

音声出力信号の取り込み

ファームウェアとハードウェアの設定を済ませ、I2Sでの音声信号を取り出していきます。

TC358743は通常のI2Sオーディオデバイスとは違って、音声信号の制御などをCSI-2を通るI2Cで指示してあげる必要があります。 この制御に関してフォーラムに情報がありました。

HDMI to CSI-2 TC358743 I2S Audio - Raspberry Pi Forums

細かい操作はドライバでやってくれるので、v4l2で大体の設定をすれば良いようです。

pi@raspberrypi:~ $ wget https://raw.githubusercontent.com/mzyy94/ns-remote/master/720P30EDID.txt
pi@raspberrypi:~ $ v4l2-ctl --set-edid=file=720P30EDID.txt
pi@raspberrypi:~ $ v4l2-ctl --set-dv-bt-timings query

ここまでできたら、HDMIに接続しているデバイスから音声を出力してみると、v4l2-ctl --list-ctrlsのaudio_presentがvalue=1になってることが確認できるはずです。

I2S device detected

pi@raspberrypi:~ $ v4l2-ctl --list-ctrls

User Controls

            audio_sampling_rate 0x00981980 (int)    : min=0 max=768000 step=1 default=0 value=48000 flags=read-only
                  audio_present 0x00981981 (bool)   : default=0 value=1 flags=read-only

Digital Video Controls

                  power_present 0x00a00964 (bitmask): max=0x00000001 default=0x00000000 value=0x00000001 flags=read-only

この状態になったら、あとは取り込むだけ。ただ、いざI2Sオーディオ入力を録音しようと試みるも、一向にデータはやってきません。 そして何やらエラーが出ているようです。

pi@raspberrypi:~ $ sudo dmesg -C
pi@raspberrypi:~ $ arecord -D plughw:1 -c1 -r 48000 -f S32_LE -t wav -V mono rec.wav
Recording WAVE '/tmp/rec.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Mono
^CAborted by signal Interrupt...
arecord: pcm_read:2145: read error: Interrupted system call
pi@raspberrypi:~ $ dmesg
[  560.152152] bcm2835-i2s fe203000.i2s: I2S SYNC error!
pi@raspberrypi:~ $

I2Sのクロック周りで同期が取れないようなエラーです。オシロスコープでI2S信号を観測したところ、確かに波形がおかしく基板上に問題がありそうだということがわかったのです。

色々と試行錯誤していた時にオシロスコープを燃やしてしまったのでHDMI入力基板からの音声入力は諦め、UAC Gadget経由でお茶を濁すことにしたのでした。

UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

前回の記事 でHDMI映像入力をRaspberry Piで扱う方法を紹介し、その最後に音声の取り込みについて、まだ課題が残っていると書きました。 HDMI入力からの音声取り込みといった、本質的な課題の解決を試みているものの、なかなかに難しい問題に直面しているので、対象を限定して部分的解決に挑みます。主に今HDMI入力の対象として使おうと思っているデバイスは、Nintendo Switchです。...

音声を取り出すリベンジ

UAC Gadgetから音声入力をする記事でお茶を濁して数ヶ月経った頃、Raspberry Pi Forumsに類似品のHDMI入力基板で音声が取り込めない問題をハードウェア的にパッチを当てて解決する方法が投稿されました。

[UPDATED, SOLVED] Why “cheap” Chinese HDMI-to-CSI2 adapters (e.g.18810-1 C779) don’t provide I2S sound - Raspberry Pi Forums

これによってパッチを当てれば信号が得られるということがわかったので、試すことにしました。

足りない配線とI2S APLLパッチ

TC358743でI2S信号を正しく扱うための配線は、Functional Specificationなる仕様書に書かれているらしいのです。 「らしい」というのは、その仕様書は東芝とNDAを結ばないと手に入れられないもので、現物を確認できていないからです。

NDA下にある書類ということで、インターネットの海にはなかなか流れていなんですが、数字の末尾が3→9になった兄弟チップであるTC358749XBGの仕様書はFireflyが放流してくれています。

(U18)TC358749XBG_V074.pdf

これを参考にしてパッチを作っていきます。

Raspberry Pi Forumsの投稿によると、I2Sの信号がおかしいのは音声信号の位相同期回路(PLL)が実装されていないことによるとのこと。 このAudio PLLに関する機能仕様を兄弟チップのTC358749XBGの仕様書から探してみると、次のような回路を用意すればいいというのがわかりました。

APLL circuit schematic

抵抗値や静電容量は他のTC358シリーズの仕様をいくつも読み漁って推定したものです。

ユニバーサル基板に実装

先ほどの回路図のうち、C3とC6はH2C-RPI-B01に実装されているのでそれ以外の配線を行い、次のように配置しました。

APLL circuit board

これをユニバーサル基板に実装し、フォーラムにある類似基板の解析結果を参考にしながらH2C-RPI-B01につなげていきます。

patch circuit

patch on H2C-RPI-B01

再度録音に挑戦

前回の挑戦と同じくして、Device Tree Overlayの設定とv4l2の設定を済ませarecordで録音したところ、ちゃんとレベルメーターでも音声が入力していることを確認でき、きれいに録音されたファイルも出来上がって大成功でした。

re arecord

reTerminalやCM4で使えるようにする

Raspberry Pi 4Bで無事に録音できたので、さてケースに収めてreTerminalの拡張モジュールにするぞ!と意気込んだものの、CSI-2に通るI2Cがうまく通信できずにreTerminalでは動作してくれませんでした。

tc358743-load-failed

pi@raspberrypi:~ $ dmesg | grep tc3
[   10.534939] tc358743 10-000f: i2c_rd: reading register 0x0 from 0xf failed
[   10.534957] tc358743 10-000f: not a TC358743 on address 0x1e

I2Cの設定を変えてみたりエラーメッセージやCompute Module特有の2つのCSI-2について調べてみたりすると、ずばり解決につながるフォーラムの投稿に行き当たりました。

Two B102 TC358743 simultaneously on CM4 - Raspberry Pi Forums

CM3/CM4ではMIPI CSI-2のバスが二つあり、そのうちCSI0で動作させるにはDevice TreeのI2Cバスを変更する必要があるとのことでした。 フォーラムの投稿はちょっと古いので最新のファームウェアに合うように修正してみたところ、ちゃんと認識され録音できるようになりました。 パッチはGitHubにおいておきました。

reTerminal-HDMI-input/overlays at master · mzyy94/reTerminal-HDMI-input

まとめ

やっとこれでHDMI入力拡張モジュールとして機能する形にできました。今回の成果も以下のリポジトリでまとめておいたので、興味ある物好きな人は参考にどうぞ。

mzyy94/reTerminal-HDMI-input: HDMI input expansion module for reTerminal

ちなみにこのパッチが組み込まれた音声も取れる格安HDMI入力基板が今年の1月に発売されていたことを、今まさにこの記事を書いている最中に知りました。 少しばかり高いですが、わざわざAPLLパッチを作る必要はありません。これまでの苦労とは一体。。。😭

bought-x630

南無

Amazon | Geekworm Raspberry Pi Hdmi to CSI-2 (Hdmi入力の最大1080p/25fps)X630 拡張ボード、Raspberry Pi 4B/3B+/3B/Pi Zero/Zero Wに適用 | Geekworm | ベアボーンPC 通販

Hdmi対応にCSI 2モジュール、X630 hdmi CSI 2のためのラズベリーパイ4B/3B +/3B/パイゼロ|Demo Board Accessories| - AliExpress

Related Posts

KVMでQSVするためIntel HD Graphicsパススルーするー

この記事は Linux Advent Calendar 2014 12日目の記事です。12月も中頃となり寒い日が続きますね。みなさん体調はいかがでしょうか。先日の こたつを温める実験 で十分な...

read more

Intel QSVのH.264エンコードをLinuxで!

前回の記事 から1ヶ月以上空いてしまいました。遅ればせながらで申し訳ありません。続編です。 Intel QSVは高速にある程度の画質のエンコードできてよいです。とても。今回はKVMでIntel H...

read more

LinuxでQSVとH.264のエンコード対決

先日の記事、でLinuxでH.264の動画をエンコードできることを紹介しました。 そのベンチマークをとってみました。QSVでのエンコードとlibx264を用いたエンコードの比較となります。今回エン...

read more
Raspberry Pi2にOSMC入れてKodi(旧:XBMC)日本語化するまで

Raspberry Pi2にOSMC入れてKodi(旧:XBMC)日本語化するまで

今月頭の発表で一気に盛り上がりを見せた Raspberry Pi 2 Model B 。もちろん発売日に購入しました。 手元にはRaspberry Pi BとGalileo Gen2の2つのLinux...

read more
KodiとChinachuで地デジLive視聴 on Raspberry Pi2 w/ OSMC

KodiとChinachuで地デジLive視聴 on Raspberry Pi2 w/ OSMC

どうも、Raspberry Pi2で遊ぶ毎日が続いております。 Raspberry Pi model B(2ではない)にRaspbmcを入れて昨年の夏頃からChinachu経由で地上デジタル放送を視聴...

read more
KodiでChinachuの録画を観るAdd-on作った

KodiでChinachuの録画を観るAdd-on作った

Raspberry Pi2でKodi(旧:XBMC)が快適に動き、地デジのLIVE視聴環境として優れているので、 Chinachuの本領である録画した動画の視聴したみが高まってきました。Kodiに...

read more
Kodi Chinachu PVRアドオンでRasPi2/Android TVをテレビに

Kodi Chinachu PVRアドオンでRasPi2/Android TVをテレビに

暑い日が続きますね。こういう日はエアコンの効いた部屋でだらだらとテレビを見たいものです。 しかしテレビをもっておりません。27インチのモニタを持っているのみです。ただ、今年2月に記事にしたように、...

read more
クリスマスなのでLinuxでQSVエンコードする

クリスマスなのでLinuxでQSVエンコードする

こちらは DTV Advent Calendar 21日目の記事です。みなさん録画データの管理はどうしていますか? 視聴したら消す人もいれば、視聴しても残しておく人、視聴してない詰みTSがたくさん...

read more
Harekaze for Kodi (pvr.chinachu) 4.0.0 リリース

Harekaze for Kodi (pvr.chinachu) 4.0.0 リリース

KodiとChinachuがシームレスに連携し、快適に地デジが視聴できるアドオン Harekaze for Kodi(pvr.chinachu) をKodi 17 Krypton に対応したバージョン...

read more
HDMI入力をRaspberry Piで駆使する

HDMI入力をRaspberry Piで駆使する

昨今の衰えることのない技術トレンドに追従すべく、映像配信とかやりたいなーと思っていた2019年。 めっきり時間がなく何もできず、気付けば2020年になっていました。今年も時間がないだろうなぁと思っ...

read more
UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

UAC GadgetでNintendo Switchの音声出力をRaspberry Piに取り込む

前回の記事 でHDMI映像入力をRaspberry Piで扱う方法を紹介し、その最後に音声の取り込みについて、まだ課題が残っていると書きました。 HDMI入力からの音声取り込みといった、本質的な課題の...

read more
Raspberry PiでHDMIディスプレイを調査する[EDID/CEC]

Raspberry PiでHDMIディスプレイを調査する[EDID/CEC]

みなさん、テレビやディスプレイに備わるHDMIの情報を確認する必要に迫られることはありませんか? 1年に一度くらいはありますよね。映像がうまく映らなかったり、操作がうまくいかなかったり。 そんな時にパ...

read more
LibreELECで地デジを楽しむためにMirakurunとEPGStationを一発で動かす

LibreELECで地デジを楽しむためにMirakurunとEPGStationを一発で動かす

地上デジタル放送をRaspberry Piで視聴する定番の組み合わせを、ノーコード・コマンドライン操作なしに、すなわち一発でセットアップできるようにした。...

read more
SIRUI 35mm/F1.8 1.33xアナモルフィックレンズで夜景を撮る

SIRUI 35mm/F1.8 1.33xアナモルフィックレンズで夜景を撮る

ずっと欲しかったアナモルフィックレンズを手に入れた。SIRUI 35MM /F1.8 1.33X ANAMORPHIC LENS最近カメラを手にする人が増えているようなので、どうせならとレンズ...

read more
無印良品で買えるRaspberry Pi2にぴったりのケース

無印良品で買えるRaspberry Pi2にぴったりのケース

Raspberry Pi2を発売日に2つ注文したものの、ケースを準備していなかったので手軽に買えるRaspberry Piにぴったりの入れ物はないかと 近所のショッピングモールを回ったところ、無印良品...

read more
スマホでNintendo Switchのゲームをする

スマホでNintendo Switchのゲームをする

前々回 はNintendo Switch Pro ControllerのWeb対応。 前回 はNintendo Switchゲーム画面のWeb対応。 今回 はNintendo Switchゲーム音声の...

read more
ShapewaysでreTerminal用の電子基板ケースを3Dプリントした

ShapewaysでreTerminal用の電子基板ケースを3Dプリントした

reTerminal がSeeedから発表されたのは2021年の4月のこと。 Raspberry Pi CM4にディスプレイを搭載し、立派なケースに収められてすぐに使えるように作られているとても魅力あ...

read more