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.

用dma的方式从mcbsp接收和发送数据,接收中断和发送中断只能进去一次

为什么我用dma的方式从mcbsp接收和发送数据,接收中断和发送中断只能进去一次,我用的是5509A,音频芯片是AIC23B。并且奇怪的是先进发送中断,再进的接收中断,我采用的是所谓的ping-pong缓存的方式,dma的中断寄存器CICR是设置的半帧中断。关键代码如下:

void AIC23_Init()
{
    I2C_INIT();

    // Reset the AIC23 and turn on all power
    AIC23_Write(AIC23_RESET_REG,0);
    AIC23_Write(AIC23_POWER_DOWN_CTL,0);
    AIC23_Write(AIC23_ANALOG_AUDIO_CTL,ANAPCTL_DAC | ANAPCTL_INSEL); // 使用麦克风音源
    AIC23_Write(AIC23_DIGITAL_AUDIO_CTL,0);

    // Turn on volume for line inputs
    AIC23_Write(AIC23_LT_LINE_CTL,0x000);
    AIC23_Write(AIC23_RT_LINE_CTL,0x000);

    // Configure the AIC23 for master mode, 44.1KHz stereo, 16 bit samples
    // Use 12MHz USB clock
    AIC23_Write(AIC23_DIGITAL_IF_FORMAT,DIGIF_FMT_MS | DIGIF_FMT_IWL_16 | DIGIF_FMT_FOR_DSP);
    AIC23_Write(AIC23_SAMPLE_RATE_CTL,SRC_SR_8 | SRC_BOSR | SRC_MO);

    // Turn on headphone volume and digital interface
    AIC23_Write(AIC23_LT_HP_CTL, 0x07f);  // 0x79 for speakers
    AIC23_Write(AIC23_RT_HP_CTL, 0x07f);
    AIC23_Write(AIC23_DIG_IF_ACTIVATE, DIGIFACT_ACT);//数字界面激活,激活状态

     hMcbsp = MCBSP_open(MCBSP_PORT0, MCBSP_OPEN_RESET);
 //   xmtEventId = MCBSP_getXmtEventId(hMcbsp); //后续的函数中用到了xmtEventId,应该把该条和下一条语句去掉注释?
//    rcvEventId = MCBSP_getRcvEventId(hMcbsp);
   

    /* Open DMA channels 4 & 5 and set regs to power on defaults */
    hDmaRcv = DMA_open(DMA_CHA4,DMA_OPEN_RESET);
    hDmaXmt = DMA_open(DMA_CHA5,DMA_OPEN_RESET); 

    /* Get interrupt event associated with DMA receive and transmit */
    xmtEventId = DMA_getEventId(hDmaXmt);
    rcvEventId = DMA_getEventId(hDmaRcv);
   
    /* Temporarily disable interrupts and clear any pending */
    /* interrupts for MCBSP transmit */
    old_intm = IRQ_globalDisable();
   
    /* Clear any pending interrupts for DMA channels */
    IRQ_clear(xmtEventId);
    IRQ_clear(rcvEventId);

    /* Enable DMA interrupt in IER register */
    IRQ_enable(xmtEventId);
    IRQ_enable(rcvEventId);

    /* Place DMA interrupt service addresses at associate vector */
    IRQ_plug(xmtEventId,&dmaXmtIsr);
    IRQ_plug(rcvEventId,&dmaRcvIsr);

    /* Write values from configuration structure to MCBSP control regs */
    MCBSP_config(hMcbsp, &CodeCMcBSP);
   
    /* Write values from configuration structure to DMA control regs */
    DMA_config(hDmaRcv,&dmaRcvConfig);
    DMA_config(hDmaXmt,&dmaXmtConfig);
 
   /* Enable all maskable interrupts */
    IRQ_globalEnable();

    /* Start Sample Rate Generator and Enable Frame Sync */
    MCBSP_start(hMcbsp,
                MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC,
                0x300u);//设置的参数需要核实,是否满足要求?

    /* Enable DMA */
    DMA_start(hDmaRcv);
    DMA_start(hDmaXmt);

    /* Take MCBSP transmit and receive out of reset */
    MCBSP_start(hMcbsp,
                MCBSP_XMIT_START | MCBSP_RCV_START,
                0u);


    // Set McBSP0 to be transmit slave 设置McBSP0为传送从模式
    //McBSP0_InitSlave();    //  McBSP0传送从模式初始化
}
void AIC23_Mixer()
{
    CSL_init();

    IRQ_setVecs((Uint32)(&VECSTART));

    taskFxn();
    
}

void taskFxn(void)
{
    Uint16 srcAddrHi, srcAddrLo;
    Uint16 dstAddrHi, dstAddrLo;
    Uint16 DataTempLeft;  // 暂存采样数据
    Uint16 DataTempRight;
    /* By default, the TMS320C55xx compiler assigns all data symbols word */
    /* addresses. The DMA however, expects all addresses to be byte       */
    /* addresses. Therefore, we must shift the address by 2 in order to   */
    /* change the word address to a byte address for the DMA transfer.    */
    srcAddrHi = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) >> 15) & 0xFFFFu;
    srcAddrLo = (Uint16)(((Uint32)(MCBSP_ADDR(DRR10))) << 1) & 0xFFFFu;
    dstAddrHi = (Uint16)(((Uint32)(&rcv)) >> 15) & 0xFFFFu;
    dstAddrLo = (Uint16)(((Uint32)(&rcv)) << 1) & 0xFFFFu;

    dmaRcvConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
    dmaRcvConfig.dmacssau = srcAddrHi;
    dmaRcvConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
    dmaRcvConfig.dmacdsau = dstAddrHi;

    srcAddrHi = (Uint16)(((Uint32)(&xmt[0])) >> 15) & 0xFFFFu;
    srcAddrLo = (Uint16)(((Uint32)(&xmt[0])) << 1) & 0xFFFFu;
    dstAddrHi = (Uint16)(((Uint32)(MCBSP_ADDR(DXR10))) >> 15) & 0xFFFFu;
    dstAddrLo = (Uint16)(((Uint32)(MCBSP_ADDR(DXR10))) << 1) & 0xFFFFu;

    dmaXmtConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
    dmaXmtConfig.dmacssau = srcAddrHi;
    dmaXmtConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
    dmaXmtConfig.dmacdsau = dstAddrHi;
    AIC23_Init();


while(1)
   {
     if(RecvComplete==TRUE)   //满足该条件表示dsp接收到dma给dsp的接收终端。
      { 
      if(dmaRcvIsr_count==1)  //如果满足该条件则处理前半帧的数据
               front_rcv_process();
            if(dmaRcvIsr_count==0)    //如果满足该条件则处理后半帧的数据
            rear_rcv_process();
   for(i=0,pxmt=xmt;i<N/4;i++)  //对左右声道的数据进行合并,以便DMA输出
      {
         *pxmt++=*pL++;

      *pxmt++=*pR++;
  
      }
           printf("%d,",k);


       } 

              
    }
                
}

void  front_rcv_process()  //前半帧处理函数
{
    prcv=rcv;
    for(i = 0;i<N/4;i++)
    {
            *pL++ = *prcv++;
               *pR++ = *prcv++;

    }
  pL = Left;
     pR = Right;
}
void  rear_rcv_process() //后半帧处理函数
{
        prcv=&rcv[N/2];
        for(i = 0;i<N/4;i++)
     {
           *pL++ = *prcv++;
            *pR++ = *prcv++;
     }
  pL = Left;
     pR = Right;

 }

//接收中断函数
interrupt void dmaRcvIsr(void) {

  
    RecvComplete = TRUE;
 
 if(++dmaRcvIsr_count>1)
    dmaRcvIsr_count=0;
  


}
//发送中断函数
interrupt void dmaXmtIsr(void) {

    RecvComplete = FALSE;

}