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.

EDMA链接多个channel事件的问题?

TI的工程师

        我有一个需要请教,目前我司有一个音频设备开发使用C6748作为平台。目前用到了MCASP和MABSP两条总线,MCASP接了AIC3106,用于录音和放音。MCBSP接了一个usb codec用于把算法处理后的数据送到PC上。两条总线分别用EDMA3链接了MCASP的Tx、Rx和MCBSP的TX。

        如果单独用任意MCASP或者MCBSP总线进行录音和播放都没有问题。但是两个合并在一起的时候录音和播放都有卡断,而且过了几分钟就不会进入中断了。

        EDMA3触发通道分别用了0、1、3。中断事件绑定的是INT5。

        目前没有什么解决的思路,请TI的工程帮忙分析一下,可能哪里出了问题。

        

  • 请问mcsbp和mcasp绑定的是同一个中断?中断函数里主要做什么?中断函数越简单越好。

  • 三个EDMA事件都是绑定的一个中断,通过事件号进行区别,一般运行几分钟就进不了中断了,代码如下:

    unsigned int temp;
    	IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);
    
    	// 判断接收 DMA 完成
        if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_RX)) 
        { 
        	// 清除 0 通道中断标志
            EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX); 
            McASPRxDMAComplHandler();
        }
    
        // 判断发送 DMA 完成
        if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_TX)) 
        { 
            // 清除 1 通道中断标志
            EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX); 
            McASPTxDMAComplHandler();
        }
    
        // 判断发送 DMA 完成 清除MCBSP发送标志
        if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCBSP0_TX))
        {
    
        	temp = CC0_SR1_IPR;
        	CC0_SR1_ICR = temp;
        	cnt1++;
        	RxCnt++;
        	RxCnt = RxCnt % 2;
        }

     
  • 不进中断的情况下,是中断没有发生还是程序跑飞了?

    合并到一起后,有没有试过中断一个个开开来调试。

  • 程序并没有跑飞,我在主循环里面有一个计数器这个计数器是一直增加的,除非我把程序都停下来。

    我刚才走读了一遍代码,我的EDMA3 CC0绑定了3个事件,这个是不是有点“多”。

  • IntEventClear(SYS_INT_EDMA3_0_CC0_INT1); 这个函数做了啥,好像没有必要存在。

    McASPRxDMAComplHandler();和McASPTxDMAComplHandler();做了什么?尽量不要在处理函数里呆过长时间,最好是直接post一个信号量,交给处理的task。

    ISR的最后没有看到再读IPR判断有没有新的中断进来。

  • 这个一个一个开是什么意思,我在初始化的时候已经把三个都链接了。如果只进行单个MCBSP或者MCASP传输是没有问题的。

  • McASPRxDMAComplHandler();和McASPTxDMAComplHandler();这个没有做太多事情,主要是更新参数集,所有算法处理的工作都没有在中断里面完成。

        // 更新 lastFullRxBuf 标志一个新的接收 buffer 接收完成
        lastFullRxBuf = (lastFullRxBuf + 1) % NUM_BUF;
        nxtParToUpdate =  PAR_RX_START + parOffRcvd;  
        parOffRcvd = (parOffRcvd + 1) % NUM_PAR;
    
        // 激活 DMA 传输器的一个参数集,用于接收数据到给定的buffer
        BufferRxDMAActivate(nxtBufToRcv, nxtParToUpdate,
                            PAR_RX_START + parOffRcvd);
    
        // 更新下一个要接收数据的buffer
        nxtBufToRcv = (nxtBufToRcv + 1) % NUM_BUF;
  • 中断函数最后要再判断一下IPR的状态,看有没有没处理的中断。

    而且从你的中断服务函数的写法来看,是每个分支固定的检查一个位,假设进中断是因为最后一个分支产生的中断,但在退出ISR前,第一个分支的bit也置位了,这个ISR并不会处理,这样就会导致退出ISR后,不会再响应EDMA中断。

  • 我上周就试了,出问题的时候,这三个位都被pending了,但是通过仿真器直接ICR的对应3位好像不太起作用。

  • 唐工你这个说的有道理,我这里单独清理好像是有些问题。实验一下在中断处理完以后再判断一次。

  • 试了啥,在哪pending了,为什么要处理ICR?不是应该在ISR里处理IPR么?

    原理很简单,就是因为退出ISR前又有新的EDMA中断进来没有被处理就退出ISR了。

  • 唐工:

             我加了二次判断IPR的操作,现在连续运行了3个小时,没有出现进不了中断的现象。正如你说的,是有中断标志位pengding了没有及时清除掉。

  • 您好,能不能教教我C6748的mcasp录音保存在sd卡上和放音

  • 这个我也不会,我们没有加入sd卡,你要用SD卡的话可能要用文件系统了。这一部分我无能为力,确实不熟悉。

  • 谢谢你的回复,sd卡的文件系统读写程序我有,就是不知道如何将输入的音频写进pcm文件保存。请问你们做的mcasp的录音是如何做的呢?用什么方式?录音的文件保存在哪?

  • 我们是实时的运算处理,不会保存数据的。

  • 好吧,谢谢你