みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

raspberrypi2 yoctoでPifi DAC+(HifiBerry DAC+互換)

ハイレゾオーディオの波に乗るために、Pifi DAC+ v2.0を購入した。 実際にはAmazon.co.jpで4000円弱で買うことができた。

RPi2でDACオーディオというと、Volumioばかり出てくるが、 それだと面白みがないので、ここでは当然yoctoで利用する。

Pifi DAC+について

実はこのボード、HifiBerry DAC+と同じ「pcm5122」というCodec ICが搭載されており、同じドライバで動作させることができる。

ドライバ

HifiBerry DAC+の動作に必要なドライバはmeta-raspberrypiのカーネル3.18には組み込まれており、 実はconfig.txtでdtoverlayを有効化するだけで利用できるようになる。

RaspbianなどRPi向けLinuxのための設定手順はここが詳しい。

yocto環境の作成手順

Pifi DAC+を動作させるために、今回はmeta-hifiberry-rpiというレイヤを作成した。 これはlocal.confの設定で使用するhifiberryを有効化できるようにしたもの。

yoctoの基本環境およびmeta-raspberrypi

$ mkdir ~/work/rpi2
$ cd ~/work/rpi2
$ git clone git://git.yoctoproject.org/poky.git
$ cd ~/work/rpi2/poky
$ git clone git://git.yoctoproject.org/meta-raspberrypi

meta-hifiberry-rpi

config.txtを設定するrpi-configのレシピにbbappendを作成した。 これはconfig.txtにdtoverlayを設定し、必要なデバイス設定を有効化するもの。

$ cd ~/work/rpi2/poky
$ git clone https://github.com/mickey-happygolucky/meta-hifiberry-rpi.git

dtoverlayとは、device tree overlayの設定で、名前の通りdevice treeの設定を上書きする仕組みである。

device treeについて

device treeはハードウェアの詳細を表現したデータ構造。

ARMプロセッサ向けのデバイスドライバは制御する中身は同じなのに、デバイスのアドレスだけが異なるというものが多く、そのようなコードが大量にカーネルにコミットされようとした時に、デバイス構造の差分を吸収して共用できるコードは統一しようという目的で導入されたもの。

device treeはdtsというテキスト形式で記述され、dtbというバイナリ形式に変換される。 カーネルへは変換済みのdtbが読み込まれる。

device treeで構成されたハードウェアの制御に必要なドライバはcompatibleのキーワードによって自動的にカーネルに読み込まれる。

dtoverlayについて

device tree overlayは、変換済みのdtbを上書きする。 そのため、dtsからdtbを作りなおさずにデバイス構造を上書きできる。

ビルド環境の設定

ビルドのための環境変数の設定とビルドディレクトリの作成。 このコマンド実行後は自動的にビルドディレクトリに移動される。

$ cd ~/work/rpi2
$ source poky/oe-init-build-env build_pifidac

今回はビルドディレクトリを、build_pifidacとする。

conf/bblayers.conf

レイヤーの設定。

BBLAYERS ?= " \
    /home/mickey/work/rpi2/poky/meta \
    /home/mickey/work/rpi2/poky/meta-yocto \
    /home/mickey/work/rpi2/poky/meta-yocto-bsp \
    /home/mickey/work/rpi2/poky/meta-raspberrypi \
    /home/mickey/work/rpi2/poky/meta-hifiberry-rpi \
  "

今回は、meta-raspberrypiとmeta-hifiberry-rpiを追加している。

conf/local.conf

MACHINE ?= "raspberrypi2"
BB_NUMBER_THREADS = "6"
PARALLEL_MAKE = "-j 6"
VIDEO_CAMERA = "1"
GPU_MEM = "128"
LICENSE_FLAGS_WHITELIST += "commercial"
DL_DIR ?= "${TOPDIR}/../downloads"

HIFIBERRY_DACPLUS = "1"

IMAGE_INSTALL_append = " alsa-utils"

「HIFIBERRY_DACPLUS = "1"」の行でHifiBerry DAC+のデバイスを有効化して、 alsa関連のツールである「alsa-utils」を追加でインストールしている。

動作確認

ビルド

今回はRPi向け最小構成(おそらく)のrpi-basic-imageをbitbakeする。

$ cd ~/work/rpi2/build_pifidac
$ bitbake rpi-basic-image

焼きこみ

$ sudo dd if=./tmp/deploy/images/raspberrypi2/rpi-basic-image-raspberrypi2.rpi-sdimg of=/dev/sdb bs=40M

RPi2での確認

ドライバ確認

# lsmod
Not tainted
ipv6 332166 16 [permanent], Live 0x7f19d000
joydev 8487 0 - Live 0x7f197000
evdev 9802 0 - Live 0x7f190000
snd_soc_pcm512x_i2c 1651 1 - Live 0x7f18c000
snd_soc_pcm512x 6280 1 snd_soc_pcm512x_i2c, Live 0x7f187000
snd_soc_hifiberry_dacplus 2684 0 - Live 0x7f183000
snd_soc_bcm2708_i2s 6659 2 - Live 0x7f17e000
snd_soc_hifiberry_dac 2419 0 - Live 0x7f13f000
regmap_mmio 3394 1 snd_soc_bcm2708_i2s, Live 0x7f10f000
regmap_i2c 2320 1 snd_soc_pcm512x_i2c, Live 0x7f10b000
snd_soc_core 132200 4 snd_soc_pcm512x,snd_soc_hifiberry_dacplus,snd_soc_bcm2708_i2s,snd_soc_hifiberry_dac, Live 0x7f09f000
snd_compress 7564 1 snd_soc_core, Live 0x7f095000
snd_pcm_dmaengine 3303 1 snd_soc_core, Live 0x7f08b000
snd_pcm 71771 3 snd_soc_hifiberry_dac,snd_soc_core,snd_pcm_dmaengine, Live 0x7f051000
snd_timer 17315 1 snd_pcm, Live 0x7f03d000
i2c_bcm2708 4916 0 - Live 0x7f038000
snd 49399 4 snd_soc_core,snd_compress,snd_pcm,snd_timer, Live 0x7f00a000
uio_pdrv_genirq 2916 0 - Live 0x7f006000
uio 7608 1 uio_pdrv_genirq, Live 0x7f000000

再生デバイス確認

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dacplus], device 0: HiFiBerry DAC+ HiFi pcm512x-hifi-0 []
Subdevices: 1/1
  Subdevice #0: subdevice #0

wavファイルをSDカードへコピーしてaplayで再生すると音が再生された。

f:id:mickey_happygolucky:20150630235217j:plain