🐯

ZYBO Z7によるZYNQ入門 (8)Audio Codec

2021/11/15に公開

環境

  • 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にあります。
https://github.com/Digilent/Zybo-Z7-10-DMA/releases

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)であることがわかります。

audio.c fnAudioRecord()
XAxiDma_SimpleTransfer(&AxiDma,(u32) MEM_BASE_ADDR, 5*u32NrSamples, XAXIDMA_DEVICE_TO_DMA);
audio.c fnAudioPlay()
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のトーン信号)を出力することができます。

audio.c
#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