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.

6748的音频数据流传输时的cache使用问题



     我这里使用c6748做了一个音频降噪和音质增强的算法。现在出现了这样的问题,因为要跑算法所以使能了cache。但是使能之后喇叭的声音就断了。

     我的音频传输流是这样的。通过mcasp总线从aic3106采集音频数据,然后经过dsp算法处理后再经过mcasp总线把数据传输出去。没有加算法之前是透传,没有使能cache,我把pc端放的音乐直接从喇叭端发出来没有问题。我的代码和数据段在ddr2上,跑算法会有些迟缓,就把cache打开了。于是出现了上面的问题。

     

CacheEnableMAR((unsigned int)0xC0001000, (unsigned int)0x08000000);
CacheEnable(L1DCFG_L1DMODE_32K|L1PCFG_L1PMODE_32K|L2CFG_L2MODE_128K);

     我在接收和发送中断的时候都CacheWBInvAll();

     请问一下ti的工程师,我这里有哪些地方思路有问题。

     我的工程代码和数据段都放在ddr里面。

.text:_c_int00 > EntryPoint /* 可执行代码 C 程序入口点*/
.text > DDR2 /* 可执行代码 */
.stack > DDR2 /* 软件系统栈 */
.cio > DDR2 /* C 输入输出缓存 */
".vectors" > Vector /* 中断向量表 */
.const > DDR2 /* 常量 */
.data > DDR2 /* 已初始化全局及静态变量 */
.switch > DDR2 /* 跳转表 */
.sysmem > DDR2 /* 动态内存分配区域 */
.far > DDR2 /* 远程全局及静态变量 */
.args > DDR2
.ppinfo > DDR2
.ppdata > DDR2

  • 请问是用EDMA传数据的吗?如果跑算法只是有些迟缓功能正常,但cache打开后出现声音断的话,一般是cache一致性的问题。

  • 肯定是一致性的问题,关掉就正常了。但是不开的话,算法跑不起来。现在不清楚是需要怎么设置回写和无效cache。

  • 你应该用了EDMA吧?

    你看一下回写和无效cache放的位置对不对?在CPU读数据前做cache invalid,在CPU写之后做cache writeback。

  • 我无效和写回都做了分别是在两个中断里面

    接收中断做了无效

    /****************************************************************************/

    /* */
    /* 此函数会在接收完成中断里调用 */
    /* */
    /****************************************************************************/
    static void McASPRxDMAComplHandler(void)
    {
    FrameCnt1++;
    unsigned short nxtParToUpdate;

    // 更新 lastFullRxBuf 标志一个新的接收 buffer 接收完成
    lastFullRxBuf = (lastFullRxBuf + 1) % NUM_BUF;
    nxtParToUpdate = PAR_RX_START + parOffRcvd;
    parOffRcvd = (parOffRcvd + 1) % NUM_PAR;


    CacheInv((unsigned int)&rxBufPtr[lastFullRxBuf], sizeof(rxBuf0));

    ........

    发送中断做了写回

    /****************************************************************************/
    /* */
    /* 此函数会在发送完成中断里调用 */
    /* */
    /****************************************************************************/
    static void McASPTxDMAComplHandler(void)
    {
    FrameCnt2++;

    CacheWB((unsigned int)&txBufPtr[lastSentTxBuf], sizeof(txBuf0));

    ......

  • McASPTxDMAComplHandler是用emda从DDR2搬数据到McASP发送吗?"此函数会在发送完成中断里调用“ 发送完成了为什么还要回写?

    可以打开memory窗口,输入目的地址,对比勾选/不勾选窗口的L1D, L2,看目的地址的内容是否有变化来判断。 

  • 方便发一下完整代码嘛 我这边也是做音频处理但是I2C总线不正常 数据发不出去

  • 不好意思啊,这个是公司的项目不能随意把整个代码铁道论坛上来的。

  • 好的理解 那您能提供以下I2C初始化部分的代码嘛 我这边烧例程都不行

  • 这个只要pin设置对了就应该没有大的问题,我的固件用的stareware的I2C,只有一个初始化接口函数。

    其他的I2C的基本读写操作应该都是差不多的。

    /************************************************************************
    **  filename:
    **  target:  C6748 dsp
    **  Tools:   Code Composer Studio Version 5.5
    **  Author: ty
    **  ------------------------------------------------------------------------
    **  History:
    **        Created on: 2017-1-2
    **  ------------------------------------------------------------------------
    **  Function:I2C接口API
    **  ------------------------------------------------------------------------
    **  This software is the property of innotrik Technology Stock Co.,Ltd.
    **  All Rights Reserved
    ****************************************************************************
    */
    #include <stdio.h>
    #include <stdint.h>
    
    #include "TL6748.h"
    #include "hw_types.h"
    #include "i2c.h"
    #include "codecif.h"
    #include "interrupt.h"
    #include "soc_C6748.h"
    #include "hw_syscfg0_C6748.h"
    
    #include "delay.h"
    
    /****************************************************************************/
    /*                                                                          */
    /*              函数声明                                                    */
    /*                                                                          */
    /****************************************************************************/
    void I2CISR(void);
    static void I2CSendBlocking(unsigned int baseAddr, unsigned int dataCnt);
    static void I2CRcvBlocking(unsigned int baseAddr, unsigned int dataCnt);
    void I2CIntRegister(unsigned int cpuINT, unsigned int sysIntNum);
    
    /****************************************************************************/
    /*                                                                          */
    /*              全局变量                                                    */
    /*                                                                          */
    /****************************************************************************/
    volatile unsigned int dataIdx = 0;
    volatile unsigned int txCompFlag = 1;
    volatile unsigned int slaveData[3];
    unsigned int savedBase;
    
    /****************************************************************************/
    /*                                                                          */
    /*              动态创建I2C硬件中断                                         */
    /*                                                                          */
    /****************************************************************************/
    void I2CIntRegister(unsigned int cpuINT, unsigned int sysIntNum)
    {
    	IntRegister(cpuINT, I2CISR);
    	IntEventMap(cpuINT, sysIntNum);
    	IntEnable(cpuINT);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              初始化I2C接口                                               */
    /*                                                                          */
    /****************************************************************************/
    // baseAddr: I2C模块基地址
    // slaveAddr: 器件从地址
    void I2CSetup(unsigned int baseAddr, unsigned int slaveAddr)
    {
        // 初始化I2C0引脚PINMUX
    	I2CPinMuxSetup(0);
    
        // IIC 复位 / 禁用
        I2CMasterDisable(baseAddr);
    
        // 配置总线速度为 100KHz
        I2CMasterInitExpClk(baseAddr, 24000000, 8000000, 100000);
    
        // 设置从设备地址
        I2CMasterSlaveAddrSet(baseAddr, slaveAddr);
    
        // IIC 使能
        I2CMasterEnable(baseAddr);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              I2C发送数据                                                 */
    /*                                                                          */
    /****************************************************************************/
    // iic IIC 模块基址
    // dataCnt 数据大小
    // 阻塞函数
    static void I2CSendBlocking(unsigned int baseAddr, unsigned int dataCnt)
    {
        txCompFlag = 1;
        dataIdx = 0;    
        savedBase = baseAddr;
     
        I2CSetDataCount(baseAddr, dataCnt);
    
        I2CMasterControl(baseAddr, I2C_CFG_MST_TX | I2C_CFG_STOP);
    
        I2CMasterIntEnableEx(baseAddr, I2C_INT_TRANSMIT_READY | I2C_INT_STOP_CONDITION);
    
        I2CMasterStart(baseAddr);
       
        // 等待数据发送完成
        while(txCompFlag);
    }
    
    //static void I2CCodecSendBlockingNstop(unsigned int baseAddr, unsigned int dataCnt)
    //{
    //	txCompFlag = 1;
    //    dataIdx = 0;
    //    savedBase = baseAddr;
    //
    //    I2CSetDataCount(baseAddr, dataCnt);
    //
    //    I2CMasterControl(baseAddr, I2C_CFG_MST_TX );//| I2C_CFG_STOP
    //
    //    I2CMasterIntEnableEx(baseAddr, I2C_INT_TRANSMIT_READY | I2C_INT_STOP_CONDITION);
    //
    //    I2CMasterStart(baseAddr);
    //
    //    // 等待数据发送完成
    //    while(dataIdx == 0);
    ////    Task_sleep(19);
    //    delay_us(190);
    //}
    
    /****************************************************************************/
    /*                                                                          */
    /*              IIC 接收数据                                                */
    /*                                                                          */
    /****************************************************************************/
    // iic IIC 模块基址
    // dataCnt 数据大小
    // 阻塞函数
    static void I2CRcvBlocking(unsigned int baseAddr, unsigned int dataCnt)
    {
        txCompFlag = 1;
        dataIdx = 0;
        savedBase = baseAddr;
        
        I2CSetDataCount(baseAddr, dataCnt);
    
        I2CMasterControl(baseAddr, I2C_CFG_MST_RX | I2C_CFG_STOP);
    
        I2CMasterIntEnableEx(baseAddr, I2C_INT_DATA_READY | I2C_INT_STOP_CONDITION);
    
        I2CMasterStart(baseAddr);
    
        // 等待数据接收完成
        while(txCompFlag);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              IIC 中断服务函数                                            */
    /*                                                                          */
    /****************************************************************************/
    void I2CISR(void)
    {
    	volatile unsigned int intCode = 0;
    
    	// 取得中断代码
    	intCode = I2CInterruptVectorGet(savedBase);
    
    	if (intCode == I2C_INTCODE_TX_READY)
    	{
    	  I2CMasterDataPut(savedBase, slaveData[dataIdx]);
    	  dataIdx++;
    	}
    
    	if(intCode == I2C_INTCODE_RX_READY)
    	{
    	  slaveData[dataIdx] = I2CMasterDataGet(savedBase);
    	  dataIdx++;
    	}
    
    	if (intCode == I2C_INTCODE_STOP)
    	{
    	  // 失能中断
    	  I2CMasterIntDisableEx(savedBase, I2C_INT_TRANSMIT_READY
    									   | I2C_INT_DATA_READY);
    	  txCompFlag = 0;
    	}
    
    	if (intCode == I2C_INTCODE_NACK)
    	{
    	 I2CMasterIntDisableEx(SOC_I2C_0_REGS, I2C_INT_TRANSMIT_READY |
    										   I2C_INT_DATA_READY |
    										   I2C_INT_NO_ACK |
    										   I2C_INT_STOP_CONDITION);
    	 // 产生停止位
    	 I2CMasterStop(SOC_I2C_0_REGS);
    
    	 I2CStatusClear(SOC_I2C_0_REGS, I2C_CLEAR_STOP_CONDITION);
    
    	 // 清除中断
    	 IntEventClear(SYS_INT_I2C0_INT);
    	 txCompFlag = 0;
    	}
    
    	intCode = I2CInterruptVectorGet(savedBase);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              写数据到寄存器                                              */
    /*                                                                          */
    /****************************************************************************/
    void I2CRegWrite(unsigned int baseAddr, unsigned char regAddr,
                       unsigned char regData)
    {
        // 发送寄存器地址和数据
        slaveData[0] = regAddr;
        slaveData[1] = regData;
    
        I2CSendBlocking(baseAddr, 2);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              IIC 写两个数据到寄存器                                            */
    /*                                                                          */
    /****************************************************************************/
    void I2CRegWrite3(unsigned int baseAddr, unsigned char regAddr,
                        unsigned char regData, unsigned char regData2)
    {
    	// 发送寄存器地址和数据
        slaveData[0] = regAddr;
        slaveData[1] = regData;
        slaveData[2] = regData2;
    
        I2CSendBlocking(baseAddr, 3);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              读寄存器                                                    */
    /*                                                                          */
    /****************************************************************************/
    unsigned char I2CRegRead(unsigned int baseAddr, unsigned char regAddr)
    {
    	// 发送寄存器地址
        slaveData[0] = regAddr;
        I2CSendBlocking(baseAddr, 1);
    //    I2CCodecSendBlockingNstop(baseAddr, 1);
    
        // 接收寄存器返回数据
        I2CRcvBlocking(baseAddr, 1);
    
        return (slaveData[0]);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              IIC写寄存器的某一bit                                        */
    /*                                                                          */
    /****************************************************************************/
    void I2CRegBitSet(unsigned int baseAddr, unsigned char regAddr,
                        unsigned char bitMask)
    {
    	// 发送寄存器地址
        slaveData[0] = regAddr;
        I2CSendBlocking(baseAddr, 1);
    //    I2CCodecSendBlockingNstop(baseAddr, 1);
      
        // 接收寄存器返回数据
        I2CRcvBlocking(baseAddr, 1);
    
        slaveData[1] =  slaveData[0] | bitMask;
        slaveData[0] = regAddr;
    
        I2CSendBlocking(baseAddr, 2);
    }
    
    /****************************************************************************/
    /*                                                                          */
    /*              IIC 清除寄存器的某一bit                                     */
    /*                                                                          */
    /****************************************************************************/
    void I2CRegBitClr(unsigned int baseAddr, unsigned char regAddr,
                        unsigned char bitMask)
    {
    	// 发送寄存器地址
        slaveData[0] = regAddr;
        I2CSendBlocking(baseAddr, 1);
    //    I2CCodecSendBlockingNstop(baseAddr, 1);
    
        // 接收寄存器返回数据
        I2CRcvBlocking(baseAddr, 1);
    
        slaveData[1] =  slaveData[0] & ~bitMask;
        slaveData[0] = regAddr;
       
        I2CSendBlocking(baseAddr, 2);
    }
    
    /***************************** End Of File ***********************************/
  • 非常感谢 我们的程序是差不多的 但是我的卡在了

    while(txCompFlag);
    我看了时钟脚是有时钟的 感觉像是中断函数没进去 txCompFlag没清零 您遇到过这种问题吗
  • I2C这块基本没有调过,都是现成的代码直接拿过来用的。

  • 请问设置回写和无效cache分别有什么作用?