ZYBO Z7によるZYNQ入門 (8)Audio Codec
- (1)Vivado, Xilink SDK開発環境構築
- (2)Hello Worldプログラムによる動作確認
- (3)Ubuntu, PetaLinuxツール環境構築
- (4)ベアメタル環境のlwIPでUDP通信
- (5)PetaLinuxツールでLinuxイメージを作成
- (6)Linux環境でUDP通信(iperf)
- (7)Linux環境でUDP通信(ユーザアプリ)
- (8)Audio Codec
- (9)AXI DMAを使用したPL-PS間のデータ転送
環境
- PC: Windows 10 64bit
- Vivado 2019.1 WebPACKライセンス
- Xilink SDK 2019.1
- Tera Term
- ボード: ZYBO (Z7-10)
- micro USBケーブル
- マイク、スピーカー or マイク付きイヤホン 3.5mm
DMA Audioデモ
ZYBOのAudio Codecを使用するため、Digilentが提供しているDMA Audio Demoを動かします。今回はベアメタル環境です。
- PSからIICでAudio Codec(SSM2663)の制御を行います。
- BTN1/BTN3を押すと、MIC IN/LINE INからAudio Codec経由でac_recdatに入力される5秒間の音声データ(ac_recdat)をAXI DMAを使用してPSに接続されたDDRに書き込みます。
- BTN2を押すと、AXI DMAを使用してDDRから5秒間の音声データを読み出し、ac_pbdatからAudio Codec経由でHPM OUTから出力します。
ソースコードのダウンロード
DigilentのGitHubにあります。
Vivado 2019.1を使用するため、Zybo-Z7-10-DMA-2018.2-1.zipをダウンロードします。
PL部の作成(Vivado)
zipファイルを解凍して、Vivadoでvivado_proj\Zybo-Z7-10-DMA.xprをオープンします。IPをアップグレードするようメッセージが出るので、Upgrade Selectedをクリックします。IPのアップグレード後、Generate Output Productsするようメッセージが出るので、実行します。
Generate Bitstreamでビットストリームファイル生成後、Export Hardwareを実行し、Include bitstreamにチェックをつけてOKします。
PS部の作成(Xilinx SDK)
VivadoからLaunch SDKを実行してXilinx SDKを起動します。
SDKでNew -> Application Project で新しいソフトウェアプロジェクトを作成します。
- Project name: Zybo-Z7-10-DMA
- OS Platform: standalone
- Hardware Platform: design_1_wrapper_hw_platform_0
- Processor: ps7_cortexa9_0
- Language: C
TemplatesにはEmpty Applicationを使用します。
Project Explorer上のZybo-z7-10の下のsrc選択後、右クリックでImportを選択します。General -> File Systemでsdk_appsrcを選択して、ファイルをImportします。
プログラムの実行
ZYBOのボード上でJP5のジャンパ接続をJTAGにします。MIC IN(or LINE IN)にマイク、HPM OUTにスピーカーを接続します。ZYBOとPCをUSBケーブルで接続してZYBOの電源をONにします。
Xilinx SDKのメニュー -> Xilinx -> Program FPGAでハードウェア情報(ビットストリームファイル)を書き込みます。
Project Explorer上でZybo-Z7-10を選択しておきます。
Run As -> Launch on Hardware (System Debugger)を実行すると、プログラムが実行されます。
BTN1(or BTN3)を押すと、MIC INの音声信号を5秒間記録し、BTN2を押すと記録した音声信号をHMP OUTから出力します。
おまけ
BTN1/3押下時にaudio.cのfnAudioRecord、BTN2押下時にfnAudioPlayが実行されます。XAxiDma_SimpleTransferの設定からDMA転送先/元はMEM_BASE_ADDR(0x10100000)であることがわかります。
XAxiDma_SimpleTransfer(&AxiDma,(u32) MEM_BASE_ADDR, 5*u32NrSamples, XAXIDMA_DEVICE_TO_DMA);
XAxiDma_SimpleTransfer(&AxiDma,(u32) MEM_BASE_ADDR, 5*u32NrSamples, XAXIDMA_DMA_TO_DEVICE);
Xilinx SDKのDebugでMEM_BASE_ADDR(0x10100000)がBTN1を押すと値が変わることが確認できます。
fnAudioPlayでDMA転送前に下記のようにMEM_BASE_ADDRの値を書き換えると、所望の音声信号(下記の例は500Hzのトーン信号)を出力することができます。
#include <math.h>
void fnAudioPlay(XAxiDma AxiDma, u32 u32NrSamples)
{
int i;
double out;
for(i = 0; i < 5*u32NrSamples; i++){
out = cos(2.0*M_PI*i*500.0/48000.0)*100000.0;
Xil_Out32(MEM_BASE_ADDR+i*4, (u32)out);
}
...
uTransferVariable.l = XAxiDma_SimpleTransfer(&AxiDma,(u32) MEM_BASE_ADDR, 5*u32NrSamples, XAXIDMA_DMA_TO_DEVICE);
...
}
math.hを使用するためには-mオプションをC/C++ Buildのライブラリに追加します。
Discussion