This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

28335的DMA连接McBSP传送AIC23采集到的数据;



采用的乒乓缓存的形式,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;
}