StartKITでI2S Communication, Rpi Audio Board (TI/PCM5102A)を鳴らす
( XMOS startKIT, Raspberry PI Audio Board Connection )
( XMOS I2S Slave Audio )
XMOS StartKITには、Raspberry PI Extension Boardとピンコンパチブルな端子があります。
ここにRaspberry Piのオーディオボードを接続します。
関連URL:
TI社デバイスページ
http://www.tij.co.jp/product/jp/PCM5102A/description
Amazon.co.jp
http://www.amazon.co.jp/gp/product/B00KMMO8H2
UC Electronics
http://www.uctronics.com/raspberry-pi-hifi-dac-audio-sound-card-module-i2s-interface-p-1960.html
コネクション:
上記StarKITレイアウトのDがRaspberry PIコンパチブルな端子です。今回はここにピンヘッダを搭載し、オーディオボードと接続します。
(ただ、実際に使用するのは、電源、グランドラインのみだけです。TI社のPCM5102Aは電源オンでDACとして動作し始めます)
I2S(BCLK,LRCK,DIN)はCコネクタのいくつかの1ビットポートとRaspberry PI Audio Board P5コネクタのBCLK/LRCK/DINと接続します。
Raspberry PI P5コネクタ:
Raspberry PI P5コネクタは上記のようになっています。ここで、今回使用するのは#3/BCLK, #4/LRCK, #5/DINです。
DACが正しく動作するかの確認:
接続が完了したら、DACから音が出力されるかを確認します。
上記、J7の#2,#3,#4にそれぞれ、BCLK, LRCK, DINを入力します。それをXMOSより出力し、J7の#1,#10,#11から出力します。
このJ7の#1,#10,#11をRaspberry PI P5の#3, #4,#5に接続してオーディオ出力を確認します。
実際の接続状況
コード1(パススルー):
port J7_1 = XS1_PORT_1F; // J7#1 port BCLK_IN = XS1_PORT_1H; // J7#2 port LRCK_IN = XS1_PORT_1G; // J7#3 port ADIN_IN = XS1_PORT_1E; // J7#4 port J7_10 = XS1_PORT_1J; port J7_11 = XS1_PORT_1K; clock clk1 = XS1_CLKBLK_1; clock clk2 = XS1_CLKBLK_2; clock clk3 = XS1_CLKBLK_3; void port_test(void) { printf("port_test() started.\n"); configure_clock_src(clk1, BCLK_IN); configure_port_clock_output(J7_1, clk1); configure_clock_src(clk2, LRCK_IN); configure_port_clock_output(J7_10, clk2); configure_clock_src(clk3, ADIN_IN); configure_port_clock_output(J7_11, clk3); start_clock(clk1); start_clock(clk2); start_clock(clk3); }
コード2(ストリームチャネルを使用してループバック):
#include <stdio.h>
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <timer.h>
port J7_1 = XS1_PORT_1F; // J7#1 -> BCLK out
port BCLK_IN = XS1_PORT_1H; // J7#2
port LRCK_IN = XS1_PORT_1G; // J7#3
in buffered port:32 ADIN_IN = XS1_PORT_1E; // J7#4
out buffered port:32 ADOUT_OUT = XS1_PORT_1K; // J7#11
port J7_10 = XS1_PORT_1J; // LRCK out
clock clk1 = XS1_CLKBLK_1;
clock clk2 = XS1_CLKBLK_2;
void set_audio_thru( streaming chanend cin,streaming chanend cout)
{
int lr = 0;
unsigned frame_counter = 0;
unsigned int x;
int t;
printf("set_audio_thru() started.\n");
set_clock_src(clk1, BCLK_IN);
set_port_clock(LRCK_IN, clk1);
set_port_clock(ADIN_IN, clk1);
set_port_clock(ADOUT_OUT, clk1);
configure_port_clock_output(J7_1, clk1);
configure_clock_src(clk2, LRCK_IN);
configure_port_clock_output(J7_10, clk2);
start_clock(clk1);
start_clock(clk2);
while (1) {
LRCK_IN when pinsneq(lr) :> lr @ t;
asm("setpt res[%0], %1" :: "r"(ADIN_IN), "r"(t + 24));
cout :> x;
partout_timed(ADOUT_OUT,24,bitrev(x),(t + 33));
asm("in %0, res[%1]" : "=r"(x) : "r"(ADIN_IN));
x = bitrev(x) << 8;
cin <: x;
frame_counter++;
}
}
void aud_inout(streaming chanend cin, streaming chanend cout)
{
unsigned int x;
printf("aud_inout() started.\n");
while(1) {
cout <: x;
cin :> x;
}
}
int main(void)
{
streaming chan cin, cout;
printf("main():hello world.\n");
par {
set_audio_thru(cin,cout);
aud_inout(cin,cout);
}
return 0;
}
コード:LEDによるオーディオレベル表示(Audio Level Meter : 1bit)
port led1 = XS1_PORT_1A;
void aud_inout(streaming chanend cin, streaming chanend cout)
{
unsigned int x;
printf("aud_inout() started.\n");
while(1) {
cout <: x;
cin :> x;
a = (x>>8) & 0xFFFFFF;
if (a & 0x800000) {
a = ~a & 0xFFFFFF;
a = a + 1;
}
if (a > 0x180000) led1 <: 1; else led1 <: 0;
}
}
ストリームチャネルを転送している箇所で、オーディオの大きさを確認して、あるしきい値を超えたらLEDを点灯するようにしています。
(StartKITレイアウトのHブロックにあるLED)
DACの違いについて
かくして、Raspberry Pi用のI2Sオーディオ拡張ボードは数種類ありますが、XMOSで
動作させる上で一番大きな違いはMCLK(Master Clock)が必要かどうかという点です。
一般にI2Sで動作するDACの場合、サンプリング周波数fsと同じLRCKと、データ転送に
同期したシリアルデータ用ビットクロックSCLK(BCLK)という64fsのクロックに加えて、
fsの256倍や384倍あるいは512倍の周波数のMCLKの3種類が必須のものが殆どです。
国産の旭化成(AKM)製のDACには電源を入れた状態でクロックを止めてしまうと
発熱し、しまいには壊れてしまうという恐ろしい石もありますが、webで見つかる
Raspberry Pi用のボードはBurr Brown(現TI)製のものかWolfson製を搭載した物が殆ど
のようです。
両者ともクロックを止めてしまっても壊れることはありませんが、例えば
S/PDIFレシーバーで外部からデジタル入力する場合などに、Bi-Phase信号から抽出
したクロックをPLLで逓倍する回路を追加しないと、普通のDACは動いてくれませんが
BBのこの石は違います。
近年リリースされたBurr Brown PCM5100シリーズのDACは内部にPLL回路を搭載しているため、
MCLKを与えなくても、GNDレベルにするだけで自分で勝手に必要なクロックを作って
動作してくれるという、AKMには爪のアカでも煎じて呑ませたい位に逞しい石なのです。
想定外な事に弱い日本と、何でもアリな国民性の違いだというには考え過ぎなのでしょうか・・・