采用的乒乓缓存的形式,DMA从Mcbsp的DRR寄存器搬运数据,搬320个产生一个DMA中断,将数据保存到RAM,再从SRAM通过DMA发送给Mcbsp的DXR寄存器返回AIC23,但是听到的声音都是噪声,当一次搬运4个数据时就很清楚,但数据增多噪音就增加很多,求大神帮助
void I2CA_Init(void);
void init_dma(void);
void start_dma(void);
void mcbspa_init();
Uint16 AIC23Write(int Address,int Data);
void Delay(int time);
void delay();
interrupt void local_D_INTCH1_ISR();
interrupt void local_D_INTCH2_ISR();
/********定义DMA中转数组*******/
#define BUF_SIZE 8
#pragma DATA_SECTION(ping_buffer,"DMARAML4");
#pragma DATA_SECTION(pong_buffer,"DMARAML4")
Uint16 ping_buffer[BUF_SIZE];
Uint16 pong_buffer[BUF_SIZE];
Uint16 *ping_buff_offset = &ping_buffer[0];
Uint16 *pong_buff_offset = &pong_buffer[0];
volatile Uint16 *DMASource1;
volatile Uint16 *DMASource2;
Uint16 first_interrupt = 1;
void main(void)
{
Uint16 i;
InitSysCtrl();
// InitXintf16Gpio(); //zq
InitMcbspaGpio(); //zq//初始化gpio管脚为Mcbspa;
InitI2CGpio();//初始化GPIO为I2C管脚;
// AUDIOEN = 0;
// Disable CPU interrupts
DINT;
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
I2CA_Init();
//整个下边是对AIC23的系统配置;
//注意:AIC23控制寄存器地址为7位,而寄存器的内容为9位,因此用8位来表示其地址时,相当于将其左移一位;
AIC23Write(0x00,0x00);//左声道输入音量;
Delay(100);
AIC23Write(0x02,0x00);
Delay(100);//延迟10ms?并不是,大约为6.8ms;
AIC23Write(0x04,0x7f);//设置左声道输出音量
Delay(100);
AIC23Write(0x06,0x7f);//右声道输出音量
Delay(100);
AIC23Write(0x08,0x14);//DAC选择,mic输入
Delay(100);
AIC23Write(0x0A,0x00);
Delay(100);
AIC23Write(0x0C,0x00);//
Delay(100);
AIC23Write(0x0E,0x43);//数字音频接口格式控制,AIC23主模式,dsp初始化,转换比特值设定00即:16bit-->96dB
Delay(100);
AIC23Write(0x10,0x23);//设置采样率为16kHz;//采样率控制;(0x10,0x23)USB模式下时钟为12MHz,采样率为12Mhz/272=44.1KHz;
Delay(100);
AIC23Write(0x12,0x01);//激活标志;
Delay(100); //AIC23Init
init_dma();
start_dma();
mcbspa_init(); // Initalize the Mcbsp-A
EALLOW; // This is needed to write to EALLOW protected registers
//PieVectTable.MRINTA = &ISRMcbspSend;//中断子程序;
PieVectTable.DINTCH1 = &local_D_INTCH1_ISR;
PieVectTable.DINTCH2 = &local_D_INTCH2_ISR;
EDIS; // This is needed to disable write to EALLOW protected registers
for(i=0; i<BUF_SIZE; i++){
ping_buffer[i] = 0;
pong_buffer[i] = 0;
}
// init_dma();
// start_dma();
// mcbspa_init(); // Initalize the Mcbsp-A
//InitMcbspa();
/*使能PIE7.1,7.2*/
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
PieCtrlRegs.PIEIER7.bit.INTx1 = 1; //使能DMA通道1,2的中断
PieCtrlRegs.PIEIER7.bit.INTx2 = 1;
IER = M_INT7; // Enable CPU INT7
EINT; // Enable Global interrupt INTM
//ERTM; // Enable Global realtime interrupt DBGM
while(1){
}
} // end of main
void I2CA_Init(void)
{
// Initialize I2C
I2caRegs.I2CSAR = 0x001A; // Slave address - EEPROM control code
#if (CPU_FRQ_150MHZ) // Default - For 150MHz SYSCLKOUT
I2caRegs.I2CPSC.all = 14; // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)
#endif
#if (CPU_FRQ_100MHZ) // For 100 MHz SYSCLKOUT
I2caRegs.I2CPSC.all = 9; // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)
#endif
I2caRegs.I2CCLKL = 100; // NOTE: must be non zero决定高低电平的持续时间,(ICCL+d)
I2caRegs.I2CCLKH = 100; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
// I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
I2caRegs.I2CMDR.all = 0x0420; // Take I2C out of reset //zq
// Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
//codec的初始化,通过i2c配置;
Uint16 AIC23Write(int Address,int Data)
{
if (I2caRegs.I2CMDR.bit.STP == 1)
{
return I2C_STP_NOT_READY_ERROR;
}
// Setup slave address
I2caRegs.I2CSAR = 0x1A;//AIC23芯片地址(作为从属)
// Check if bus busy
if (I2caRegs.I2CSTR.bit.BB == 1)
{
return I2C_BUS_BUSY_ERROR;
}
// Setup number of bytes to send
// MsgBuffer + Address
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = Address;//数据发送寄存器
I2caRegs.I2CDXR = Data;
// Send start as master transmitter发送start作为主发送器
I2caRegs.I2CMDR.all = 0x6E20;
return I2C_SUCCESS;
}
interrupt void local_D_INTCH1_ISR(void) // DMA Ch1
{
EALLOW;
if(first_interrupt==1) // No processing needs to be done (B/c interrupt occurs
{ // at beginning of DMA transfers to ping buffer - no data received yet)
first_interrupt=0; // Turn flag off and exit interrupt
} else
{
// Do whatever processing is needed on the buffered data here
// Once that is done, switch to the other buffer
DmaRegs.CH2.CONTROL.bit.RUN = 1; // Start tx on CH2 after CH1 has finished ping buffer
}
// When DMA first starts working on ping buffer, set the shadow registers
// to start at pong buffer next time and vice versa
if(DmaRegs.CH1.DST_ADDR_SHADOW == (Uint32)ping_buff_offset)
{
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)pong_buff_offset;
DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)pong_buff_offset;
}
else
{
DmaRegs.CH1.DST_ADDR_SHADOW = (Uint32)ping_buff_offset;
DmaRegs.CH1.DST_BEG_ADDR_SHADOW = (Uint32)ping_buff_offset;
}
// To receive more interrupts from this PIE group, acknowledge this interrupt
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
EDIS;
}
interrupt void local_D_INTCH2_ISR(void) // DMA Ch2
//{
// //EALLOW; // NEED TO EXECUTE EALLOW INSIDE ISR !!!
// DmaRegs.CH2.CONTROL.bit.HALT = 1 ; // Re-enable DMA CH2. Should be done every transfer
// PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // To receive more interrupts from this PIE group, acknowledge this interrupt
//
// //EDIS;
// return;
//}
{
EALLOW;
// When DMA first starts working on ping buffer, set the shadow registers
// to start at pong buffer next time and vice versa
if(DmaRegs.CH2.SRC_ADDR_SHADOW == (Uint32)ping_buff_offset)
{
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32)pong_buff_offset;
DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32)pong_buff_offset;
}
else
{
DmaRegs.CH2.SRC_ADDR_SHADOW = (Uint32)ping_buff_offset;
DmaRegs.CH2.SRC_BEG_ADDR_SHADOW = (Uint32)ping_buff_offset;
}
PieCtrlRegs.PIEACK.all = PIEACK_GROUP7; // To receive more interrupts from this PIE group, acknowledge this interrupt
EDIS;
}
void mcbspa_init()
{
EALLOW;
McbspaRegs.SPCR2.all=0x0000; // Reset FS generator, sample rate generator & transmitter
McbspaRegs.SPCR1.all=0x0000; // Reset Receiver, Right justify word
McbspaRegs.MFFINT.all=0x0; // Disable all interrupts
McbspaRegs.SPCR1.bit.RINTM = 0; // McBSP interrupt flag to DMA - RRDY
McbspaRegs.SPCR2.bit.XINTM = 0; // McBSP interrupt flag to DMA - XRDY
McbspaRegs.RCR2.all=0x04; //发送帧长度1,每帧2个字,每字16bit
McbspaRegs.RCR1.all=0x0140; // Single-phase frame, 2 word/frame, No companding (Receive)
McbspaRegs.XCR2.all=0x04;
McbspaRegs.XCR1.all=0x0140; // Single-phase frame, 2 word/frame, No companding (Transmit)
McbspaRegs.SRGR1.all=0x0001; // Frame Width = 1 CLKG period, CLKGDV must be 1 as slave
// SRG clocked by LSPCLK - SRG clock MUST be at least 2x external data shift clk
McbspaRegs.PCR.all=0x0000; // Frame sync generated externally, CLKX/CLKR driven
McbspaRegs.PCR.bit.FSXM = 0; // FSX is always an i/p signal
McbspaRegs.PCR.bit.FSRM = 0; // FSR is always an i/p signal
McbspaRegs.PCR.bit.SCLKME = 0;
// In normal DSP McBSP mode:
McbspaRegs.PCR.bit.FSRP = 0; // 0-FSRP is active high (data rx'd from rising edge)
McbspaRegs.PCR.bit.FSXP = 0 ; // 0-FSXP is active high (data tx'd from rising edge)
McbspaRegs.PCR.bit.CLKRP = 1; // 1-Rcvd data sampled on rising edge of CLKR
McbspaRegs.PCR.bit.CLKXP = 0; // 0- Tx data sampled on falling edge of CLKX
McbspaRegs.SRGR2.bit.CLKSM = 1; // LSPCLK is clock source for SRG
McbspaRegs.PCR.bit.CLKXM = 0; // 0-MCLKXA is an i/p driven by an external clock
McbspaRegs.PCR.bit.CLKRM = 0; // MCLKRA is an i/p signal
McbspaRegs.SPCR2.all |=0x00C0; // Frame sync & sample rate generators pulled out of reset
delay_loop();
McbspaRegs.SPCR2.bit.XRST=1; // Enable Transmitter
McbspaRegs.SPCR1.bit.RRST=1; // Enable Receiver
EDIS;
}
void start_dma (void)
{
EALLOW;
DmaRegs.CH1.CONTROL.bit.RUN = 1; // Start DMA Transmit from McBSP-A
DmaRegs.CH2.CONTROL.bit.RUN = 1; // Start DMA Receive from McBSP-A
EDIS;
}
void init_dma()
{
EALLOW;
DMASource1 = &McbspaRegs.DXR1.all;
DMASource2 = &McbspaRegs.DRR1.all;
DMACH1AddrConfig(ping_buff_offset, DMASource2);
//DmaRegs.DMACTRL.bit.HARDRESET = 1; // 写1复位;
//__asm(" NOP"); // Only 1 NOP needed per Design
// Channel 1, McBSPA transmit/DMA接收
DMACH1BurstConfig(0,0,0); // 1 word/burst// no effect when using 1 word/burst// no effect when using 1 word/burst
DMACH1TransferConfig(BUF_SIZE-1,0,1);// 此处应为320,传送320个数字请求一次中断,把数据读入Interrupt every frame (127 bursts/transfer)
DMACH2WrapConfig(1,0,0,1);
DMACH1ModeConfig(DMA_MREVTA,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,SYNC_DISABLE,SYNC_SRC,
OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_BEGIN,CHINT_ENABLE);//chintemode标志位用连续模式实现ping-pong操作;
//中断在传送开始时就产生;
// Channel 2, McBSPA Receive/DMA发送;
DMACH2AddrConfig(DMASource1,pong_buff_offset);
DMACH2BurstConfig(0,0,0);
DMACH2TransferConfig(BUF_SIZE-1,0,1);
DMACH2WrapConfig(1,0,0,0);
DMACH2ModeConfig(DMA_MXEVTA,PERINT_ENABLE,ONESHOT_DISABLE,CONT_ENABLE,SYNC_DISABLE,SYNC_SRC,
OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_BEGIN,CHINT_ENABLE);
EDIS;
}