我这里使用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
Shine:
请问是用EDMA传数据的吗?如果跑算法只是有些迟缓功能正常,但cache打开后出现声音断的话,一般是cache一致性的问题。
taoyu:
回复 Shine:
肯定是一致性的问题,关掉就正常了。但是不开的话,算法跑不起来。现在不清楚是需要怎么设置回写和无效cache。
Shine:
回复 taoyu:
你应该用了EDMA吧?
你看一下回写和无效cache放的位置对不对?在CPU读数据前做cache invalid,在CPU写之后做cache writeback。
taoyu:
回复 Shine:
我无效和写回都做了分别是在两个中断里面
接收中断做了无效
/****************************************************************************/
/* *//* 此函数会在接收完成中断里调用 *//* *//****************************************************************************/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));
……
user4557851:
方便发一下完整代码嘛 我这边也是做音频处理但是I2C总线不正常 数据发不出去
taoyu:
回复 user4557851:
不好意思啊,这个是公司的项目不能随意把整个代码铁道论坛上来的。
user4557851:
回复 taoyu:
好的理解 那您能提供以下I2C初始化部分的代码嘛 我这边烧例程都不行
taoyu:
回复 user4557851:
这个只要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引脚PINMUXI2CPinMuxSetup(0);// IIC 复位 / 禁用I2CMasterDisable(baseAddr);// 配置总线速度为 100KHzI2CMasterInitExpClk(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 ***********************************/
user4557851:
回复 taoyu:
非常感谢 我们的程序是差不多的 但是我的卡在了
while(txCompFlag);我看了时钟脚是有时钟的 感觉像是中断函数没进去 txCompFlag没清零 您遇到过这种问题吗