ZedBoard板体验(四)——无奈的音频……
0赞继上一篇OLED点亮已经有一段时间了,一直在调着音频接口,当然由于最近各种事情各种忙,所以调试的时间也是有限的,又由于对软件的不熟悉出现了一些问题,同时也得到了一些经验。下面与大家分享分享,在问题上也一起探讨探讨。
1、硬件配置框图
基于测评的目标是实现音频信号分析仪,在完成了OLED的显示后,这次主要目的是实现音频的控制和数据读写。
表1中给出了ADAU1761 codec具体的接口信号,其中分为三种连接信号,串行数据I2S接口(4线)、系统控制I2C(2线)或者SPI(4线)接口和一个主时钟输入MCLK。
表1 接口信号功能描述
Signal Name |
Description |
Zed pin |
ADAU1761 pin |
Type |
AC-MCLK |
Master Clock Input |
AB2 |
MCKI |
D_IN |
AC-GPIO2 |
Digital Audio Bit Clock Input/Output |
AA6 |
BCLK/GPIO2 |
D_IO |
AC-GPIO3 |
Digital Audio Left-Right Clock Input/Output |
Y6 |
LRCLK/GPIO3 |
D_IO |
AC-GPIO0 |
DAC Serial Input Data/General Purpose Input and Output |
Y8 |
DAC_SDATA/GPIO0 |
D_IO |
AC-GPIO1 |
ADC Serial Output Data/General Purpose Input and Output |
AA7 |
ADC_SDATA/GPIO1 |
D_IO |
AC-ADR0 |
I2C Address Bit 0/SPI Latch Signal |
AB1 |
ADDR0/CDATA |
D_IN |
AC-ADR1 |
I2C Address Bit 1/SPI Data Input |
Y5 |
ADDR1/CLATCH |
D_IN |
AC-SDA |
I2C Data/SPI Data Output |
AB5 |
SDA/COUT |
D_IO |
AC-SCK |
I2C Clock/SPI Clock. |
AB4 |
SCL/CCLK |
D_IN |
硬件配置框图如下:
由上图可以看出,IIC控制总线由PS的I2C接口通过EMIO接出连接到ADAU1761,MCLK时钟信号由PL中的clock Generator生成,其余接口线均有PL中的GPIO实现。
就在硬件配置的时候出现了一个严重问题,就是在加行clock generator后综合时,总是报这个错:
各种纠结呀,是什么问题呢,因为是加上clock generator后才报的,所以问题肯定是出在这个地方,我就各种修改,先是核对了它的输入时钟100MHz跟ps_clk0一致没有问题。有检查了输入输出的连接,什么复位等信号都OK,于是凌乱了,到底什么问题呢?后来发现我设置的输出作为MCLK为12.228MHz,所以输入12228000,但是我改为12000000后没有问题了。Why?难道不识别MHz一下的!!
在这里先解释下为什么输出为12.228MHz,有ADAU1761内部寄存器R0(0x4000)设置为default模式,本着尽量简单的运用原则,关闭了PLL,所以就有了MCLK=256×fS当然在default模式下fS为48K。
但是出现了这样的问题,只能输入12MHz了,没事输入12MHz我就启用PLL嘛,根据下面表格配置,同样OK啦
2、软件驱动
配好了硬件,bitstream也生成了,那就开始写应用驱动了。哎,个人的弱项表现得凌厉精致啊。在各种资料的搜索整理后,开始动手了。当然最开始的必然是对于ADAU1761的一个初始化,根据数据手册给出的初始化步骤:
首先初始化时钟和PLL:
iic_write (IicPs, ZC702_IIC_WRITE_ADDR,ADAU_CLKCTRL,(CLKCTRL_SRC_PLL | CLKCTRL_FRQ_1024 | CLKCTRL_DISABLE)); //设置MCLK和PLL
typedef struct {
u16 Reg;
u8 Data;
u8 Init;
} Zed_I2C_CONFIG;
Zed_I2C_CONFIG PLL_Config[6] =
{
{0x4002, 0x00, 0x00},
{0x4003, 0x00, 0x7D},
{0x4004, 0x00, 0x00},
{0x4005, 0x00, 0x0C},
{0x4006, 0x00, 0x21},
{0x4007, 0x00, 0x01},
}
for ( i = 0; i < 6; i++ ) //配置PLL
{
printf("ready to write register %d\n\r", i);
iic_write(IicPs, ZC702_IIC_WRITE_ADDR, PLL_Config[i].Reg, PLL_Config[i].Init);
printf("finish to write register %d\n\r", i);
}
Delay_ms(4); //延迟4ms,等待PLL锁定
下面就是对于寄存器的配置:
/*
* Default Mode
* Analog microphones, ADC capture/DAC playback, dsp core disabled
*/
static struct Zed_I2C_CONFIG adau1761_mode0[MODE_REGISTER_COUNT] = {
/* mute outputs */
{ADAU_PLBHPVL, 0x00, 0x03},
{ADAU_PLBHPVR, 0x00, 0x03},
{ADAU_PLBLOVL, 0x00, 0x02},
{ADAU_PLBLOVR, 0x00, 0x02},
{ADAU_PLBMNOC, 0x00, 0xE5},
{ ADAU_INP_ROT, 0x00, 0x01},
{ ADAU_OUT_ROT, 0x00, 0x01},
{ADAU_CLK_EN0, 0x00, 0x5F},
{ADAU_CLK_EN1, 0x00, 0x01},
/*analog mic*/
{ADAU_RECVLCL, 0x00, 0x82},
{ADAU_RECVLCR, 0x00, 0x82},
{ADAU_MICCTRL, 0x00, 0x00},
};
这些都是要进行配置的寄存器,都是通过I2C进行输入。写的I2C写入函数如下:
//iic写函数
//IicPs:iic接口指针
//Address:接在iic上的slave设备地址
//Register:slave中寄存器地址
//Data:写入寄存器中的值
static int iic_write( XIicPs *IicPs, u16 Address, u16 Register, u8 Data )
{
u8 WriteBuffer[3];
int Status;
/*
* A temporary write buffer must be used which contains both the address
* and the data to be written, put the address in first
*/
WriteBuffer[0] = Register>>8;
WriteBuffer[1] = Register;
WriteBuffer[2] = Data;
printf("the WriteBuffer %d\n\r", WriteBuffer[0]);
printf("the WriteBuffer %d\n\r", WriteBuffer[1]);
printf("the WriteBuffer %d\n\r", WriteBuffer[2]);
/*
* Wait until bus is idle to start another transfer.
*/
while (XIicPs_BusIsBusy(IicPs)) {
/* NOP */
}
/*
* Send the buffer using the IIC and check for errors.
*/
print("IIC is not busy\n\r");
printf("Device is ready %d\n\r", IicPs->IsReady);
Status = XIicPs_MasterSendPolled(IicPs, WriteBuffer, 3, Address);
if (Status != XST_SUCCESS) {
print("XIicPs_MasterSendPolled error!\n\r");
return XST_FAILURE;
}
else print("XIicPs_MasterSendPolled ok!\n\r");
return XST_SUCCESS;
}
此处可以看出主要写函数就是XIicPs_MasterSendPolled(IicPs, WriteBuffer, 3, Address),问题也在这个地方,下板子后的打印信息就一直卡在这里:
各种检查,得到的答案就是,这条语句就没有执行。这里面的四个参数都是严格按照库函数intXIicPs_MasterSendPolled(XIicPs*InstancePtr, u8*MsgPtr,
intByteCount, u16SlaveAddr)的格式来定义的,为什么会出现这样的问题呢?还在继续排查问题中。
在此先写出这篇文章,一来算是调试文档日志,二来提出问题和经验给大家一起分享和探讨。毕竟测评就是一个排除问题的过程。