NanoPi Neo2 I2S Audio Kernel alpha1 release

これは何?

  • NanoPi Neo2用のカーネルにI2Sオーディオ関連のパッチを当てたものになります。
  • カーネルのみのリリースとなります。音を出すにはSoXやmpdなどを自力で導入する必要があります。
  • 手軽に音を出したい方は、本カーネルを適用したVolumio2を作成予定ですので、それまでお待ちください。

  • 標準のカーネルに加えて下記の修正が施してあります

    • 特定sampling resolutionで音が出ない問題の修正(24bitでノイズになるなど)
    • MCLK出力の有効化
    • 768/1536kHzのサンプリングレートに対応
    • HifiBerry DAC+ PRO or 互換ボードに対応
    • PCM Right Justified16/24bit出力に対応
    • BCLK外部クロック駆動など特殊動作に対応
  • baseは4.11になります。

  • 現在はalpha3にアップデート済みです。

ダウンロード・使い方

バイナリダウンロード

メーカ提供 UbuntuCoreの場合

  • FriendlyArm提供のUbuntuCore ImageをSDに書き込む
  • PC上でもターゲット上でも構わないので、/bootのImageを上記からダウンロードしたもので上書きする
  • ターゲット上でmodulesを展開する
# tar xvfz npi_audio_modules_1807_alpha3.tgz -C /
or
$ sudo tar xvfz npi_audio_modules_1807_alpha3.tgz -C /
  • 再起動でAudio Kernelに差し替わります

動作モードの切り替え方

  • dtbファイルを差し替えて機能の切り替えを行ってください。
  • NanoPi Neo2のbootスクリプトは、defaultではsun50i-h5-nanopi-neo2.dtbで起動するので、sun50i-h5-nanopi-neo2.dtbへ上書きしてやるのが簡単です。
$ cd /boot
$ cp sun50i-h5-nanopi-neo2-i2s-generic.dtb sun50i-h5-nanopi-neo2.dtb
  • dtbの種類と動作モードは下の方で説明していますのでご確認ください。

ソースコード

制約など

dtbファイルと動作モードの紹介

通常利用向けdtb

  • I2S Generic
    • I2S出力に対応します。MCLKは出力しません。
    • デフォルトは64fsは32bit長固定とします。16/24bit再生時、LSBは0パディングします。
    • 32fsは16bit長固定とします。Philipsなどの16bit長DACに最適です。
    • PCM5102AやES9023PなどMCLKが不要なDACの接続に利用します。
sun50i-h5-nanopi-neo2-i2s-generic.dtb
sun50i-h5-nanopi-neo2-i2s-generic_32fs.dtb
  • I2S Generic + MCLK
    • MCLK出力に対応します。MCLKはPA6に出力します。
    • デフォルトは64fsは32bit長固定とします。16/24bit再生時、LSBは0パディングします。
    • 32fsは16bit長固定とします。
    • PCM179X/AK449XなどのMCLKが必要なI2S DACの接続に利用します。
    • 出力されるMCLKの周波数とサンプリングレートの対応は以下の通りです。
サンプリングレート MCLK周波数
48/96/192/384kHz 24.576MHz
44.1/88.2/176.4/352.8kHz 22.5792MHz
768kHz 49.152MHz
1536kHz 98.304MHz
sun50i-h5-nanopi-neo2-i2s-generic_mclk.dtb
sun50i-h5-nanopi-neo2-i2s-generic_mclk_32fs.dtb
  • HiFiBerry DAC+ Pro or compatible
    • HiFiBerry DAC+/DAC+ PROの両方に対応
    • BCLKは16bit時は32fs。24/32bit時は64fsで出力します。
    • DAC+ PRO使用時には外部クロックで動作します。
    • DAC+ PRO使用時においても強制的にDAC+モードの利用(slaveモード)も可能
    • 必要な接続はI2S(BCLK/LRCLK/DATA)とI2C(SDA/SCK)、3.3V、5V、GNDとなります。
    • NanoPi Neo2ではボード上にI2C PullUpが無いため、必ず外部にて3.3VにPullUpしてください。
sun50i-h5-nanopi-neo2-i2s-dacpluspro.dtb
sun50i-h5-nanopi-neo2-i2s-dacpluspro_slave.dtb
  • PCM RJ16/RJ24bit
    • 古いDACに多いRight Justifiedフォーマット出力に対応します。
    • MCLK出力に対応します。MCLKはPA6に出力します。
    • Right Juistifiedではbit長が自動認識できませんので、ターゲットのDACに合ったbit長を選択してください。
    • 32fsは16bit長固定とします。Philipsなどの16bit長DACに最適です。
    • FN1242Aにて動作確認済みです。
sun50i-h5-nanopi-neo2-pcm_rj16_32fs_mclk.dtb
sun50i-h5-nanopi-neo2-pcm_rj16_64fs_mclk.dtb
sun50i-h5-nanopi-neo2-pcm_rj24_64fs_mclk.dtb

実験向けdtb

  • I2S CBM_CFS fixed clock mode 実験用
    • 外部から固定BCLKを入力するモードです。
    • 水晶発振器などを利用して、NanoPi Neo2及びDACのBCLKにクロックを入力してください。
    • LRCLKはNanoPi NEO2にて生成します。
    • MCLKは出力できません。
    • 64fs固定です。(dtsを編集すれば32fs/48fsも設定可)
      • 24.576MHz入力で32bit 384kHz固定
      • 12.288MHz入力で32bit 192kHz固定
    • mpdなどでリサンプリングを有効にして利用することを想定しています。
    • クロックに合ったサンプリングレートで再生しない場合、音程が正しく出力されません。
sun50i-h5-nanopi-neo2-i2s-cbmcfs_bclkin.dtb
  • I2S Generic + MCLK less than 100MHz 実験用
    • MCLKに100MHz未満で設定可能な最大周波数を設定
    • ES9018SでMCLKをNanoPi Neo2から入力する場合に使用します。
    • I2C制御はしませんので、ES9018Sはデフォルト動作とさせるか外部マイコンで制御または、i2c-toolsなどで制御が必要です。
 sun50i-h5-nanopi-neo2-i2s-generic_mclk_lt100m.dtb
  • I2S Generic + MCLK less than 50MHz 実験用
    • MCLKに50MHz未満で設定可能な最大周波数を設定
    • PCM5102A/ES9023Pなどで、MCLKをNanoPi Neo2から入力する場合に使用します。
    • MCLKのクロックによって音が変化するか実験するときにどうぞ
 sun50i-h5-nanopi-neo2-i2s-generic_mclk_lt50m.dtb

今後の予定(あくまで予定です)

  • Volumio2のNanoPi Neo2版提供(本カーネル導入済み)
  • beta版ではbaseバージョンを最新の4.14にアップデート
  • rt patchの取り込み
  • オーディオフォーマット対応のリファクタリング

もしかしたらやるかも

  • 外部I2S Master基板の製作とドライバ作成

NanoPiNEO2 HiFiBerry DAC+対応 β版

HiFiBerry DAC+ PRO対応のβ版リリース

HiFiBerry DAC+ PROに対応しました。
twitterには書いてましたがこっちにも簡単にまとめます。

  • HiFiBerry DAC+ PROにて動作確認しています。クローンもたぶん動くはず。
  • HiFiBerry DAC+(外部クロックなし)は未検証です。動くかもしれません。
  • ソフトウェアはmpdとplay(SoX)にて動作確認しています。
  • 対応フォーマット(確認済みのもの)
    • CBM_CFM/CBM_CFS(CBM_CFSは未検証)
    • 16/24/32bit (16bitはバグっててちゃんと出ません。修正版を評価中です。)
    • 44.1/88.2/176.4/352.8k 44.1k系
    • 48/96/192/384k 48k系

接続方法

NanoPiとRPiでピン配置が微妙に異なります。 そのままピンヘッダで接続せず、下記のピンのみ接続したほうが安全です。

RPiとNanoPiで互換配置ピン(I2CのPU追加は必須)

  • PWR
    • Pin01 3.3V
    • Pin17 3.3V
    • Pin02 5V
    • Pin06 GND
  • I2C
    NanoPi NEO2は基板内でI2CのPullUpが実装されていません。NanoPiとRPiを接続したうえで、3.3Vに4.7k-22kくらいの抵抗でPullUpしてください。
    • Pin03 I2C0_SDA 3.3VにPU
    • Pin05 I2C0_SCL 3.3VにPU

RPIとNanoPiで非互換配置ピン

  • I2S (NanoPi to DAC+ PRO)
    • Audio Pin08 I2S0_LRC to Pin35 LRCK
    • Audio Pin09 I2S0_BCK to Pin12 BCK
    • Audio Pin10 I2S0_SDOUT to Pin40 DATA

ビルド方法

ソースはGitHub - tkztkztkz/linux: Linux kernel source treeのREL_HIFIBERRYDACPLUSPRO_BETAブランチにあります。

NanoPi NEO2 4.11系カーネルビルド手順メモ - _tkz_ memoを参考に、checkoutするブランチを下記に変えてビルドしてください。

git checkout REL_HIFIBERRYDACPLUSPRO_BETA

ビルド後は、zImageのほか下記のdtbもターゲットにコピーしてください。
arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2-audio.dtb をターゲットの/boot/sun50i-h5-nanopi-neo2.dtbに上書きコピーする

モジュールも必要な人はmodluesもビルドして、なんとかmodules以下を固めてターゲットで展開してください。
私は面倒なので必要なモジュールだけ手でコピーしてます。

今後の予定

improve

  • dtsの整理
    • 1イメージでI2S Generic(PCM510x)とHifiBerry DAC+ PROの両対応
    • MCLKの有効・無効もdtbの差し替えで対応できるようにしたい
    • Neo PLUS2対応
  • digi+ PRO対応(評価用のボードを入手できれば)
  • バイナリの提供
  • volumio2対応

bugfix

  • 再生中に停止したあと、再度再生するときにノイズの修正
  • メモリリーク(初期化時)

こんな感じであたりで考えていますが、思いがけずSwitch(10G L2と任天堂)を入手してしまったのでいつになるか不明です。
dt-overlay対応はあんまりやる気が無いです。

コードの修正内容抜粋(詳細はコミットログを見てください)

AllWinner系のコード

  • sun8i-i2s.c
    • DAIFMTのCBM_CFM/CBM_CFSサポート
    • Codecノードが見つからない場合にも登録するように修正
      若干メモリリークしていますが、初期化一発のみなのでとりあえず放置。そのうち直す

RPiからポーティングしたコード

  • hifiberry_dacplus.c
    • ディレクトリをbcmからcodecに移動
    • i2s-codecをdt参照対応 RPiへの影響は無いはず
    • 352.8k対応
  • pcm512x.c
    • 20/24bitデータ再生時に、BCLKを64fs(32bit WORD)強制
      bcm系は24bit WORDも可能だけど、sunxiは未対応のため
    • 44.1kクロック時に384k再生するときの上限チェックを無効化
      バグに仮対処。44.1kHz系のクロックで再生後、384kHzを設定しようとすると上限が44.1k x 8 = 352.8kとなり、384k再生がエラーとなる模様。
      clk-hifiberry-dacproの設定が後に走ることが原因の模様。クロック設定が先に走ればいいんだけど、RPiだとどうやって動いてるんだ?
  • clk-hifiberry-dacpro.c
    • 修正なし

Amazonマーケットプレイスで購入した商品が不良品だった場合の対処方法 メモ

 Amazonマーケットプレイス登録業者が商品を用意しAmazonが配送するスタイルの注文で、届いた商品が不良品だったので交換を依頼しました。

 手順がとても分かりにくかったのでメモしておきます。

販売店のページを表示

  • まずは購入した商品のページを開く
  • 「この商品は、HOGEHOGEが販売し、Amazon.co.jp が発送します。」 と記載されているところを探し、店名HOGEHOGEをクリックする
  • 右上の「質問する」ボタンを押す

出品者に連絡する

  • お問い合わせの種類にて「注文について」を選択
  • 注文履歴が表示されるので、該当する注文を選ぶ
  • 「お問い合わせ内容を選択してください」から「破損または不具合のある商品が届いた」を選択
  • メッセージを入力をクリック  詳細な故障状況などを記入し、送信する。

あとは販売店から連絡が来るのでやり取りする。

 この時の注意点は直接届いたメールに返信するのではなく、アカウントサービスの「Eメールとメッセージ」メニュー内にあるメッセージセンターを選び「出品者/購入者の連絡」から返信する必要があります。

 面倒くさいですね。

 交換について、Amazon発送の商品だったので今回はクーポン提供となりました。  クーポンを使って無料で新品を再購入する形です。Amazon側の倉庫から交換品を送付することができないため、このような手順になるようです。  今回は購入価格が低かったため、返送は不要でした。

 ちなみに再購入時、色を変えて注文したところ上記クーポンは使えませんでした。購入したものとまったく同じもののみ使用できるようです。

NanoPiNEO2 HiFiBerry DAC+対応 調査メモその1

HiFiBerry DACとはなんぞ?

  • RaspberryPi向けの高音質DAC
  • いくつか種類があり、RPiのクロックで動くものと、DACに乗っけたクロックで動くものがある。
  • RPi向けAudio用のディストロで対応したカーネルが配られている

で?

  • NanoPi NEO2でDAC側にマスタークロックが載ってるHiFiBerry DAC+ PROが動かせたらいいな

ドライバの構造調査

  • soc/bcm/bcm2708-i2s.c
    • CPUのI2S制御コード
    • ここは、sun8i-i2s.cに置き換える
    • 不足機能をsun8i-i2s.cに追加する感じ
  • soc/bcm/hifiberry_dacplus.c
    • I2SとCODECの制御コード
    • ここで、外部マスター有か無しか判定してる
    • 小改造で流用する感じ
  • soc/codecs/pcm512x.c/*_i2c.cあたり
    • CODEC(PCM5122)の制御コード
    • 実際にPCM5122を引っ叩いてるコード
    • 完全流用したい

対応が必要そうな項目のざっくり洗い出し

  • i2sドライバの修正
    • SND_SOC_DAIFMT_CBM_CFM(I2S Slave/Codec Master)対応
    • 現状はMCLKのON/OFFしかしていない
    • BCK/LRCKのin/outも変更するコードを入れる感じ
  • hifiberry制御ドライバの移植
    • daiをbcm2708から変更?
    • なんかprobeでnode検索してるから、対応要らないかも
    • hifiberryのnodeからi2s-controllerを探して設定してる
    • なのでi2s-controller=sun8i-h3-i2sとか書いたら行けるかも
  • codecの動作確認

メモ

  • ただいま動作確認用に手配したhifiberry待ちです
  • Linux SoCオーディオの用語的な話
    • Master/SlaveはCODECからみた動作を表す模様
    • SoC側がクロックを生成する、I2SがMasterでCODECがSlaveの場合はSlaveモード(SND_SOC_DAIFMT_CBS_CFS)と呼んでいる
    • 今回はMasterモード(SND_SOC_DAIFMT_CBM_CFM)をの対応を行う感じ
    • CB=BitClock, CF=LRClock(Frame)
    • CBM_CBSとかCBS_CFMなんて組み合わせもできなくないが、評価できないので実装したくないな

NanoPi NEO2 I2S AUDIO でMCLKを出すメモ

前提

  • Allwinner H5ではMCLKの出力が可能
  • PA6にアサイン可能
  • NanoPi Neo2でもこのPin(PA6)は出てる

作業内容とか

  • dtsのi2s0 pinctrlにPA6を追加するもエラー
  • PA6にi2s0のfunction設定が無いっぽい
  • functionはpinctrlのdrivers/pinctrl/sunxi/pinctrl-sun50i-h5.cあたりにテーブルがあるが、PA6のi2s0は書いてないので追加する。
  • MCLKが出たことを確認

dtsの修正例

  • 元ネタのdts/dtsiではなく、/boot以下のdtbをdtcで変換して評価しました。
  • i2s0のpinsに"PA6"を追加
i2s0 {
    pins = "PA6", "PA18", "PA19", "PA20", "PA21";
    function = "i2s0";
    linux,phandle = <0x19>;
    phandle = <0x19>;
};
  • spiのpinsから"PA6"を削除
spi0_cs_pins {
    pins = "PC3" ;
    function = "gpio_out";
    linux,phandle = <0x15>;
    phandle = <0x15>;
};
  • 2017/10/06追記 なんかタッチパネル?の割り込みにPA6が割り当てられてるよう。ここもdisableしないとなんか反応してそう。まだ、未確認ですが。
pitft-ts@1 {
    compatible = "ti,ads7846";
    reg = <0x1>;
    status = "disable";

修正の影響範囲

  • PA6のfunctionにi2s0の選択肢を追加しただけ
  • dtsにてPA6のfunctionをi2s0に明示的に指定しなければ影響なし

パッチ

https://github.com/tkztkztkz/linux/commit/07f117214cf457e5b356730f68a5539402b9e5fc

メモ

  • CPU内蔵PLL生成のクロックなので低ジッタなどは期待できないと思う
  • defaultは24.571MHzだと書いてある。0.2%くらいのズレ?
  • Allwinner H3にはMCLK出力は無いっぽい
  • RPi系にはMCLK出力が無いっぽいので、NanoPi Neo2のちょっとしたアドバンテージ?
  • 古いMCLK必須DACを繋ぐのに良さそう
  • でも外部クロック貰った方が音が良いだろうね

NanoPi NEO2 I2S AUDIO 24bit再生でNG メモ

現象

  • 16/32bitは再生OK
  • 24bit再生はホワイトノイズ(かすかに音楽が聞こえる)となる

発生環境

  • 20170909版のオフィシャルイメージ
  • npi-configでPCM5102Aを選択
  • play(sox)で24/96,24/192フォーマットのFlacデータを再生

原因

  • 24/32bit再生時の下記2レジスタの設定ミス/16bit時は問題なし
    • I2S/PCM FIFO Control RegisterのTXIM
    • I2S/PCM Format Register0のSR
  • レジスタ内容のメモ
    • TXIMとは、FIFO(32bit幅)に書かれたデータをMSB(0)から取るかLSB(1)から取るか決定
    • SRとは、SamplingRateを決定
    • SRの設定値は3bitで(sampling_rate >> 2) - 1で算出可能(3.10カーネルでの算出方法)
    • SWとは、SlotWidthの指定

原因詳細

  • 24/32bit再生時にはTXIM=0(MSB)かつSR=24bit/SW=32bitを固定で指定していた
  • 32bit再生時には
    • FIFOには32bitデータを書く
    • SRが24bitのためMSBから24bitがデータとして採用される
    • 下位8bitが捨てられ、上位24bitを再生する
    • ★結果としては32bitデータを食わせても、24bitに丸められている
  • 24bit再生時には
    • FIFOには24bitデータを書く
      • ★予想だがDMAを使う関係でMSB側8bitは0埋め or nocareで、下位24bitにデータを書く
    • SRが24bitのためMSBから24bitがデータとして採用される
    • ★下位8bitが捨てられ上位24bitを再生する
      • 実際にデータが書かれているのは下位24bitなので8bit padding + 16bitのデータとなる。
      • I2Sのデータは2の補数のため、最上位bitが0固定となると負数が表現できなくなり、ホワイトノイズに若干の音楽が紛れたような音として聞こえる。
      • 負数が表現できないため、DC直結だとDCが出ちゃってたかも。こわい。
  • 16bit再生時には
    • FIFOには16bitデータを書く
    • SR/SW共に16bitなので問題なく再生できる

対策

  • 下記二点の修正
    • I2S/PCM FIFO Control RegisterのTXIMはLSB(1)に設定
    • I2S/PCM Format Register0のSRは指定されたSamplingRate(24/32bit)を設定

修正の効果確認

  • 16bit再生が問題なく行えること(デグレチェック)
  • 24bit再生時にホワイトノイズとなる現象の解消
  • 32bit再生が問題なく行えること(24bitに丸められないこと)

パッチ

メモ

  • 32bit全部出てるかは、オシロでデータの波形を見て確認
  • プルリクってどの程度レポート付けると良いのかね

NanoPi NEO2 4.11系カーネルビルド手順メモ

概要

  • NanoPi NEO2用の4.11.xカーネルビルド方法のメモ。
  • 公式イメージ20170909版のカーネルは本手順で生成できます。
  • 公式ページの手順は3.10のころのものが混ざってる模様。
  • Ubuntu 16.04.3で確認

2018/07/21追記

  • Mediafireではなく、Linaroから直接Toolchainを取ってくる記事を書きました。こちらを参照ください。

tkz.hateblo.jp

ホスト側ツールチェインのインストール(18/02/14追記)

  • sudo apt install build-essential

ツールチェインの取得と展開

mkdir -p /opt/FriendlyARM/toolchain/
tar xf gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt/FriendlyARM/toolchain/

ツールチェインにパスを通す

export PATH=/opt/FriendlyARM/toolchain/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin:$PATH

gitでカーネルを持ってきて、4.11ブランチをcheckout

git clone https://github.com/friendlyarm/linux.git
cd linux
git checkout sunxi-4.11.y

ビルド

make sunxi_arm64_defconfig ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make Image dtbs ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

ターゲットにコピー

  • 出来上がったarch/arm64/boot/ImageをNanoPi NEO2の/bootにコピー
  • dtbはarch/arm64/boot/dts/allwinner/あたりに生成されます。