> 文章列表 > ADSP21489之CCES开发笔记(八)

ADSP21489之CCES开发笔记(八)

ADSP21489之CCES开发笔记(八)

一、简介
异步采样转换器(ASRC):ASYNCHRONOUS SAMPLERATE CONVERTER,包含4个SRC模块,具有与192 kHz立体声异步采样速率转换器AD1896相同的内核,SNR高达128 dB。SRC模块用于在独立的立体声通道上执行同步或异步采样速率转换,不占用内部处理器资源。4个SRC模块也可以配置为联合工作,实现无相位失配的多通道音频数据转换。最后,SRC可以用来清除音频数据中S/PDIF接收器等抖动时钟源的影响。
二、特性
1、运行在从模式下,4个立体声异步采样率转换器。
2、简易的编程模式。
3、3种可控的静音选项(软件、硬件、自动)。
4、支持左对齐、I2S,右对齐(16,18,20,24bit)和TDM格式。
5、在TDM格式时,以菊花链的方式连接输入、输出帧。
6、不同协议的输入输出允许格式转换。
7、32k、44.1k、48K采样率可加重滤波器。
8、高达192K采样率,以7.5:1~1:8的输入输出比进行。
9、插值滤波器的延迟16个采样样本。
10、SNR从128到140 dB(取决于处理器型号)。
11、匹配相位模式(仅限ADSP-21488型号)可进行补偿用于组延迟。
12、可时钟校正。
三、引脚描述
2种输入输出端口,6个输入、2个输出
ADSP21489之CCES开发笔记(八)
四、SRU编程
通过SRU(信号路由单元)编程才能将ASRC连接到输出引脚或任何其他外围设备.
ADSP21489之CCES开发笔记(八)

五、寄存器
ADSP21489之CCES开发笔记(八)

ASRC使用5个寄存器来配置和操作ASRC模块。

1、Control Registers (ASRCCTLx).
启用或禁用采样率转换器,还指定了输入和输出数据格式。
ADSP21489之CCES开发笔记(八)

2、Mute Register (ASRCMUTE).
控制连接的输入、输出信号静音。
3、Ratio Registers (ASRCRATx).
返回输入输出信号之间的采样比率及静音信息。
ADSP21489之CCES开发笔记(八)

六、时钟:外围时钟/4
七、功能描述
图13-1显示了ASRC的顶层框图模块,图13-2显示了架构细节
ADSP21489之CCES开发笔记(八)图13-1
1、IO端口:
I/O端口提供用于传输数据的接口,异步地进出SRC模块,SRC有一个3线用于串行输入和输出端口的接口,该接口支持左对齐,I2S和右对齐(16位、18位、20位、24位)模式。此外串行接口支持TDM模式,用于菊花链连接多个SRC形成一个框架。
2、滤波器:音频滤波
3、静音控制:
当该模块启用后,输出静音设置为1,输出高电平直到SRC稳定在新的采样率上。
4、采样转换核心
采样率转换器的RAM FIFO块调整左右输入采样并将其存储用于FIR滤波器的卷积循环。
ADSP21489之CCES开发笔记(八)图13-2
八、操作模式
ASRC可以在TDM、I2S、左对齐、右对齐和直通模式。处理器的串行端口可用于移动内部存储器的ASRC数据。在I2S、左对齐和右对齐模式中,ASRC单独运行。
九、参考Demo
在ADSP安装目录下,有一个例程SPDIFto Analog TalkThru with SRC © ,可以进行参考,编程实在是非常的简便,配置一下就好。
demo用例路径:C:Program Files (x86)Analog DevicesVisualDSP5.1.2214xxExamplesADSP-21489 EZ-Board SPDIF to Analog TalkThru with SRC ©
ADSP21489之CCES开发笔记(八) 数据与时钟框图
1、音频来源SPDIF接收器和AD1939的ADC,2路输出音频到DAC.
2、2个时钟域
第1个从SPDIF输入流派生的,使用SPORT0A每个中断读取1个24位样本(左右交替),并立即将相同的值写入SPORT1A,所有音频均采用12S模式传输。
第2个时钟由AD1939提供,使用SPORT2每个中断读取1个24位样本(左右交替),并立即将相同的值写入2个SPORT3和SPORT4的A与B数据通道,所有音频均采用I2S模式传输。
3、ADC1数据在SPORT2B上接收,SPDIF给到SRC转换后的输出数据在SPORT2A上接收。
4、异步SRC用于两个喻之间数据转换,这样SPDIF接收器的数据数据就可以发送到DAC.
SRC寄存器配置
ADSP21489之CCES开发笔记(八)void InitSRC(void)
{
//============================================================
//
// Configure SRC Control Register (SRCCTL0).
//
// SRC1_IN_I2S : SRC1 Serial Input Format= I2S mode
// SRC1_OUT_I2S: SRC1 Serial Output Format= I2S mode
// SRC1_OUT_24 : Output Word Length= 24 bits
//------------------------------------------------------------

*pSRCCTL0 = SRC1_IN_I2S | SRC1_OUT_I2S | SRC1_OUT_24;
// Enable SRC1 in a different cycle than setting the configuration
pSRCCTL0 |= SRC1_ENABLE;
}
5、SRU代码实现
void InitSRU(void)
{
//-----------------------------------------------------------------------------
/

The Steps will be as follows.
1. Connect DIR to SPORT0
2. Connect SPORT1 to SRC1-INPUT
3. Connect SRC1-OUTPUT to SPORT2
4. Connect SPORT3&4 to DAC’s
*/
// Tie the pin buffer input LOW.
SRU(LOW,DAI_PB18_I);
// Tie the pin buffer enable input LOW
SRU(LOW,PBEN18_I);
// Connect the SPDIF Receiver
SRU(DAI_PB18_O,DIR_I);
//-------------------------------------------------------------------------
//Input to the DSP
// Clock in from SPDIF RX
SRU(DIR_CLK_O,SPORT0_CLK_I); //Connect CLK_O to SPO_CLK
SRU(DIR_CLK_O,SPORT1_CLK_I); //Connect CLK_O to SP1_CLK
SRU(DIR_CLK_O,SRC1_CLK_IP_I); //Connect CLK_O to SRC1_CLK
// Frame sync from SPDIF RX
SRU(DIR_FS_O,SPORT0_FS_I); //Connect FS_O to SPO_FS
SRU(DIR_FS_O,SPORT1_FS_I); //Connect FS_O to SP1_FS
SRU(DIR_FS_O,SRC1_FS_IP_I); //Connect FS_O to SRC1_FS
// Data in from SPDIF RX
SRU(DIR_DAT_O,SPORT0_DA_I); //Connect DAT_O to SPO_DA
SRU(SPORT1_DA_O,SRC1_DAT_IP_I); //Connect SP1_DA to SRC1_DAT

//-------------------------------------------------------------------------
//Output from the DSP
SRU(DAI_PB07_O,DAI_PB13_I);
SRU(DAI_PB08_O,DAI_PB14_I);
// Clock in from ADC
SRU(DAI_PB07_O,SRC1_CLK_OP_I);
SRU(DAI_PB07_O,SPORT2_CLK_I);
SRU(DAI_PB07_O,SPORT3_CLK_I);
SRU(DAI_PB07_O,SPORT4_CLK_I);
// Frame sync from ADC
SRU(DAI_PB08_O,SRC1_FS_OP_I);
SRU(DAI_PB08_O,SPORT2_FS_I);
SRU(DAI_PB08_O,SPORT3_FS_I);
SRU(DAI_PB08_O,SPORT4_FS_I);
// Data from the DSP
SRU(SRC1_DAT_OP_O,SPORT2_DA_I);
SRU(SRC1_DAT_OP_O, DAI_PB15_I); //Testdata
SRU(HIGH, PBEN15_I);
SRU(SPORT3_DA_O,DAI_PB09_I);
SRU(SPORT3_DB_O,DAI_PB10_I);
SRU(SPORT4_DA_O,DAI_PB11_I);
SRU(SPORT4_DB_O,DAI_PB12_I);
//ADC data on DAI Pin 05
SRU(DAI_PB05_O,SPORT2_DB_I);
SRU(LOW,PBEN05_I);

//------------------------------------------------------------------------
// Tie the pin buffer enable inputs HIGH to make DAI pins 9-14 outputs.
// and pins 7, 8 & 18 LOW to make them inputs
SRU(LOW,PBEN07_I);
SRU(LOW,PBEN08_I);
SRU(HIGH,PBEN09_I);
SRU(HIGH,PBEN10_I);
SRU(HIGH,PBEN11_I);
SRU(HIGH,PBEN12_I);
SRU(HIGH,PBEN13_I);
SRU(HIGH,PBEN14_I);
SRU(LOW,PBEN18_I);
//--------------------------------------------------------------------------
// Route SPI signals to AD1835.
SRU(SPI_MOSI_O,DPI_PB01_I) ; //Connect MOSI to DPI PB1.
SRU(DPI_PB02_O, SPI_MISO_I) ; //Connect DPI PB2 to MISO.
SRU(SPI_CLK_O, DPI_PB03_I) ; //Connect SPI CLK to DPI PB3.
SRU(SPI_FLG0_O, DPI_PB04_I) ; //Connect SPI FLAG3 to DPI PB4.
//---------------------------------------------------------------------------
// Tie pin buffer enable from SPI peipherals to determine whether they are
// inputs or outputs
SRU(SPI_MOSI_PBEN_O, DPI_PBEN01_I);
SRU(SPI_MISO_PBEN_O, DPI_PBEN02_I);
SRU(SPI_CLK_PBEN_O, DPI_PBEN03_I);
SRU(SPI_FLG0_PBEN_O, DPI_PBEN04_I);

//----------------------------------------------------------------------------
}
6、SPORT配置
int rx0a_buf[2]; /* SPORT0 receive buffer A (DMA) /
int tx1a_buf[2]; /
SPORT1 transmit buffer A (DMA) /
int rx2a_buf[2]; /
SPORT2 receive buffer A (DMA) /
int rx2b_buf[2]; /
SPORT2 receive buffer B (DMA) /
int tx3ab_buf[2]; /
SPORT3 transmit buffer A B (DMA) /
int tx4ab_buf[2]; /
SPORT4 transmit buffer A B (DMA) */

int rcv0a_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) rx0a_buf}; /* SPORT0 receive a tcb /
int rcv2a_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) rx2a_buf}; /
SPORT2 receive a tcb /
int rcv2b_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) rx2b_buf}; /
SPORT2 receive b tcb /
int xmit1a_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) tx1a_buf}; /
SPORT1 transmit a tcb /
int xmit3ab_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) tx3ab_buf}; /
SPORT3 transmit ab tcb /
int xmit4ab_tcb[8] = {0, 0, 0, 0, 0, 2, 1, (int) tx4ab_buf}; /
SPORT4 transmit ab tcb */

void InitSPORT(void)
{
//============================================================
//
// Make sure that the multichannel mode registers are cleared
//
//============================================================
*pSPMCTL0 = 0;
*pSPMCTL1 = 0;
*pSPMCTL2 = 0;
*pSPMCTL3 = 0;
*pSPMCTL4 = 0;
*pSPCTL0 = 0;
*pSPCTL1 = 0;
*pSPCTL2 = 0;
*pSPCTL3 = 0;
*pSPCTL4 = 0;
// Set up the chain pointer on all the sports
rcv0a_tcb[4] = *pCPSP0A = ((int) rcv0a_tcb + 7) & 0x7FFFF | (1<<19);
rcv2a_tcb[4] = *pCPSP2A = ((int) rcv2a_tcb + 7) & 0x7FFFF | (1<<19);
rcv2b_tcb[4] = *pCPSP2B = ((int) rcv2b_tcb + 7) & 0x7FFFF | (1<<19);
xmit1a_tcb[4] = *pCPSP1A = ((int) xmit1a_tcb + 7) & 0x7FFFF | (1<<19);
xmit3ab_tcb[4] = *pCPSP3A = *pCPSP3B =((int) xmit3ab_tcb + 7) & 0x7FFFF | (1<<19);
xmit4ab_tcb[4] = *pCPSP4A = *pCPSP4B = ((int) xmit4ab_tcb + 7) & 0x7FFFF | (1<<19);
//============================================================
//
// Configure SPORT 0 for input from ADC
// OPMODE = I2S mode
// L_FIRST = Send the Left word first (per I2S requirement)
// SLEN24 = 24 bit of data in each 32-bit word
// SPEN_A = Enable data channel A
//------------------------------------------------------------
*pSPCTL0 = OPMODE | L_FIRST | SLEN24 | SPEN_A |SCHEN_A | SDEN_A ;
//============================================================
// Configure SPORT 1 as a transmitter
//
// SPTRAN = Transmit on serial port
// OPMODE = I2S mode
// L_FIRST = Send the Left word first (per I2S requirement)
// SLEN24 = 24 bit of data in each 32-bit word
// SPEN_A = Enable data channel A
//------------------------------------------------------------
*pSPCTL1 = SPTRAN | OPMODE | L_FIRST | SLEN24 | SPEN_A|SCHEN_A|SDEN_A;
//============================================================
// Configure SPORT 2 as a receiver
//
// OPMODE = I2S mode
// L_FIRST = Send the Left word first (per I2S requirement)
// SLEN24 = 24 bit of data in each 32-bit word
// SPEN_A = Enable data channel A
//------------------------------------------------------------
*pSPCTL2 = OPMODE | L_FIRST | SLEN24 | SPEN_A | SPEN_B|SDEN_A|SCHEN_A|SDEN_B|SCHEN_B;
//============================================================
// Configure SPORTs 3 & 4 as transmiters to DACs 1-4
//
// SPTRAN = Transmit on serial port
// OPMODE = I2S mode
// L_FIRST = Send the Left word first (per I2S requirement)
// SLEN24 = 24 bit of data in each 32-bit word
// SPEN_A = Enable data channel A
//------------------------------------------------------------
*pSPCTL3 = SPTRAN | OPMODE | L_FIRST | SLEN24 | SPEN_A | SPEN_B|SDEN_A|SCHEN_A|SDEN_B|SCHEN_B;
*pSPCTL4 = SPTRAN | OPMODE | L_FIRST | SLEN24 | SPEN_A | SPEN_B |SDEN_A|SCHEN_A|SDEN_B|SCHEN_B;;
}