请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:TMS320C6748 工具/软件:Code Composer Studio
您好!
我正在使用 LCDK 开发音频处理器、目前正在尝试在系统中实现回声效果。 我将 McASP Staterware 示例用作准系统代码、并在其上面添加我自己的代码。 我通过使用数组、存储以前的 rxBuf 值并在给定时间段后重放这些值、成功实现了回显效果。
我的问题是、rxBuf 数据包含明显的噪声量。 将缓冲区值复制到变量(用于操作)并再次复制回时、似乎会产生噪声。 是否有人可以建议我如何消除噪声、或如何更干净地处理缓冲区数据。
/** *\file mcaspPlaybk.c * \brief McASP 示例应用程序。 此应用程序回路输入 * 从 EVM 的 LINE_IN 连接到 EVM 的 LINE_OUT。 */ * *版权所有(C) 2012德州仪器(TI)公司- http://www.ti.com/ * 只要 符合以下条件*、就允许以源代码和二进制形式重新分发和使用*进行修改或不进行修改: * *源代码的重新分发必须保留上述版权 声明*、此条件列表和以下免责声明。 * *二进制形式的再发行必须在 * 发行版随附的*文档和/或其他材料中复制上述版权声明、本条件列表和以下免责声明。 * *未经 事先书面许可、不得使用德州仪器公司的名称或*其贡献者的名称认可或推广从本软件派生的产品*。 * *本软件由版权所有者和贡献者 *按原样"提供、 且不承认任何明示或暗示的保证、包括但不限于*特定用途*的适销性和适用性的暗示保证。 在任何情况下、版权 *所有者或贡献者都不对任何直接、间接、偶然、 *特殊、模范、 或相应的损害(包括但不 限于*采购替代产品或服务;丧失使用、 *数据或利润; 或业务中断)、但出于 任何*责任理论、无论是合同、严格责任还是侵权 行为*(包括疏忽或其他原因)、即使 被告知可能会造成此类损坏、也是出于此类责任理论。 */ #include "edma_event.h" #include "interrupt.h" #include "soc _C6748.h" #include "hw_syscfg0_C6748.h" #include "aic31.c6748.h" #include "codecif.h" #include "mcasp.h" #include "aic31.ma.h" #include "include "include "包含"h.h"#include "#include "h" #include /********* ** 内部宏定义 //* **可配置的值 */* 用于发送/接收数据的插槽大小*/ #define SLOT_SIZE (16U) /*用于发送/接收数据的字大小。 字大小<=插槽大小*/ #define WORD_SIZE (16U) // #define SAMPLING_RATE 将同时用于发送和接收段的采样率 (48000u) /*通道数、L 和 R */ #define NUM_I2S_CHANNELS (2U) /*每个音频缓冲器要使用的样本数*/ #define NUM_SAMESS_PER_AUDIO_BUF (24000u) /*每个 TX/Rx 使用的缓冲器数量*/ #define NUM_BUF (3U) /*每个 TX/Rx 使用的链接参数集数量*/ #define NUM_PAR (2U) /*指定参数集起始位置是*/ #define PAR_ID_START (40U) /*循环缓冲区中的样本数*/ #define NUM_SAMESS_LOOP_BUF (10U) /* AIC3106编解码器地址*/ #define I2C_SLAVE_CODE_AIC31 (0x18u) /*在 AINTC 中映射的中断通道*/ #define INT_CHANNEL_I2C (2U) #define INT_CHANNEL MCASP (2U) #define INT_CHANGE_EMACC (2U) /*用于接收的 McASP 串行器*/ #define MCASP_XSER_RX (14U) /*用于发送的 McASP 串行器*/ #define MCASP_XSER_TX (13U) /* **下面的宏是根据上述输入计算 的*/ #define NUM_TX_SERIALIZERS ((NUM_I2S_CHANNELS >> 1)\ +(NUM_I2S_CHANNELS 和0x01) #define NUM_RX_SERIALIZERS ((NUM_I2S_CHANNELS >> 1)\ +(NUM_I2S_CHANNELS 和0x01) #define I2S_SLOTS ((1 << NUM_I2S_CHANNELS)- 1) #define Bytes_per_sample. ((word_size >> 3)\ * NUM_I2S_CHANNELS) #define AUDIO_BUF_SIZE (num_samples_per_audio_BUF \ * bytes_per_sample) #define TX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET (1)|(1 \ <<EDMA3CC_OPT_TCINTEN 位移)) #define RX_DMA_INT_ENABLE (EDMA3CC_OPT_TCC_SET (0)|(1 \ << EDMA3CC_OPT_TCINTEN 移位)) #define PAR_RX_START (PAR_ID_START) #define PAR_TX_START (PAR_RX_START + NUM_PAR) /* **不可配置的定义 */ #define SIZE_PARAMETERS (32U) #define OPT_FIFO_WIDTH (0x02 <<8u) /********* ** 内部函数原型 / 静态空 McASPErrorIsr (void); 静态空 McASPErrorIntSetup (void); 静态空 AIC31I2SConfigure (void); 静态空 McASPI2SConfigure (void); 静态空 McASPTxDMAComplHandler (void); 静态空 McASPRxDMAInHandler (void); 静态空 EDMA3CCComplisr (void); 静态空 I2SDataTxRxActivate (void); 静态空 I2SDMAParamInit (void); 静态空 ParamTxLoopJobSet (unsigned short parId); 静态空 I2SDMApeSxDMAActivate (void、unsigned Short) unsigned short parToUpdate、 unsigned short linkAddr); static void BufferRxDMAActivate (unsigned int rxBuf、unsigned short parId、 无符号短链接); / ** 内部变量定义 / 静态无符号 char loopBuf[NUM_SAMPS_LOOP_BUF * bytes_per_sample]={0}; /* **发送缓冲区。 如果要添加任何新的缓冲区,请在此处进行定义, 并**更新 NUM_BUF。 // signed char txBuf0[AUDIO_BUF_SIZE]; signed char txBuf1[AUDIO_BUF_SIZE]; signed char txBuf2[AUDIO_BUF_SIZE]; // **接收缓冲器。 如果要添加任何新的缓冲区,请在此处进行定义, 并**更新 NUM_BUF。 // signed char rxBuf0[AUDIO_BUF_SIZE]; signed char rxBuf1[AUDIO_BUF_SIZE]; signed char rxBuf2[AUDIO_BUF_SIZE]; // **下一个用于接收数据的缓冲区。 数据将在此缓冲区中接收。 */ 静态易失性 unsigned int nxtBufToRcv = 0; /* **填充最新版本的 RX 缓冲区。 */ 静态易失性无符号 int lastFullRxBuf = 0; /* **填充最新数据的 PX 缓冲区。 // 静态易失性 unsigned int lastFullPxBuf = NUM_BUF - 1; // **参数 ID 相对于参数集起始位置的偏移量。 */ 静态易失性无符号短整型 parOffRcvd = 0; /* **从参数集开始发送的参数 ID 偏移量。 */ 静态易失性无符号短整型 parOffSent = 0; /* **将从参数集开始发送的参数 ID 的偏移量。 */ 静态易失性无符号短整型 parOffTxToSend = 0; /* **最后发送的发送缓冲区。 */ 静态易失性无符号 int lastSentTxBuf = NUM_BUF - 1; /********* ** 内部 CONSTATNT 定义 // //接收缓冲区指针数组*/ signed int rxBufPtr[NUM_BUF]= { (signed int) rxBuf0、 (签名) rxBuf1 (签名) rxBuf2 }; //发送缓冲区指针数组*/ signed int txBufPtR[NUM_BUF]= { txBuf0、 txBuf1(签名) txBuf2 (签名) }; /* **发送段的默认参数。 这将从 **一个环路缓冲器传输。 */ 静态结构 EDMA3CCPaRAMEntry const txDefaultPar = { (unsigned int)(EDMA3CC_OPT_DAM |(0x02 << 8u))、//选择字段 (unsigned int) loopBuf、//源地址*/ (unsigned short)(bytes_per_sample")、/* aCnt */ (无符号短整型)(NUM_SAMESS_LOOP_BUF)、/* bCnt */ (unsigned int) SOC_MCBSP_0_DATA_regs、/* dest 地址*/ (short)(bytes_per_sample")、/* source bIdx * (短整型)(0)、/* dest bIdx */ (无符号短整型)(PAR_TX_START * SIZE _ParamSet)、/*链接地址*/ (无符号短整型)(0)、/* bcnt reload 值*/ (short)(0)、/*源 cIdx */ (短整型)(0)、/* dest cIdx */ (无符号短整型) 1 /* ccnt */ }; /* **接收部分的默认参数。 */ 静态结构 EDMA3CCPaRAMEntry const rxDefaultPar = { (unsigned int)(EDMA3CC_OPT_SAM |(0x02 << 8u))、/* Opt 字段* (unsigned int) SOC_MCBSP_0_DATA_regs、/*源地址*/ (unsigned short)(bytes_per_sample")、/* aCnt */ (无符号短整型)(1)、/* bcnt */ (unsigned int) rxBuf0、/* dest 地址*/ (短整型)(0)、/*源 bIdx * (short)(bytes_per_sample)、/* dest bIdx */ (无符号短整型)(PAR_RX_START * SIZE _ParamSet)、/*链接地址*/ (无符号短整型)(0)、/* bcnt reload 值*/ (short)(0)、/*源 cIdx */ (短整型)(0)、/* dest cIdx */ (无符号短整型) 1 /* ccnt */ }; / ** 功能定义 // //* **为参数集指派循环作业 */ static void ParamTxLoopJobSet (unsigned short parId) { EDMA3CCPaRAMEntry 参数集; memcpy (&ParamSet、&txDefaultPar、Size_ParamSet - 2); /*将参数链接到自身*/ ParamSet.linkAddr = parId * size_ParamSet; EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、parId、&ParamSet); }/* **初始化 DMA 参数。 ** RX 基本参数集(通道)为0,TX 基本参数集(通道)为1。 ** ** RX 参数集0将被初始化,以在 Rx 缓冲区0中接收数据。 **传输完成中断将不会为参数集0启用; **参数集0将链接到 RX 的链接参数集启动(PAR_RX_START)。 **并且只能通过链接参数集进行进一步的接收。 **例如,如果 PAR_RX_START 值为40,且参数数为2, **接收参数集链接将初始化为0->40->41->40** TX 参数集将初始化为从循环缓冲区传输。 **可以配置循环缓冲区的大小。 **传输完成中断将不会为参数集1启用; **参数集1将链接到 TX 的链接参数集启动(PAR_TX_START)。 **所有其它参数集将链接到自身。 **且仅通过链接参数集进行进一步传输。 **例如,如果 PAR_RX_START 值为42,且参数数为2, **因此传输参数集链接将初始化为1->42->42,43->43。 */ static void I2SDMAParamInit (void) { EDMA3CCPaRAMEntry 参数集; int idx; /*初始化接收的第0个参数集*/ memcpy (&ParamSet、&rxDefaultPar、Size_ParamSet - 2); EDMA3SetPaRAM (SOC_EDMA30CC_0_reg、EDMA3_CHA_McASP0_RX、&ParamSet); /*进一步的参数集,启用中断*/ ParamSet.op= RX_DMA_INT_ENABLE; for (idx = 0;idx < NUM_PAR;idx++) { paramSet.destAddr = rxBufPtr[idx]; ParamSet.linkAddr =(PAR_RX_START +((IDx + 1)% NUM_PAR) *(size_ParamSet); ParamSet.bCnt = NUM_SAMESS_PER_AUDIO_BUF; /* **对于第一个链接参数集,开始接收第二个参数集 **仅限样本,因为中已接收到第一个样本 ** Rx 缓冲器0本身。 * if (0 = idx) { paramSet.destAddr += bytes_per_sample_sample_; ParamSet.bcnt = bytes_per_sample_sample_sample_} EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、(PAR_RX_START + IDx)、&ParamSet); } /*初始化接收所需的变量*/ nxtBufToRcv = idx % NUM_BUF; lastFullRxBuf = NUM_BUF - 1; parOffRcvd = 0; /*初始化传输的第一个参数集*/ memcpy (&ParamSet、&txDefaultPar、Size_ParamSet); EDMA3SetPaRAM (SOC_EDMA30CC_0_reg、EDMA3_CHA_McASP0_TX、&ParamSet); /*参数的其余部分,启用循环作业*/ for (idx = 0;idx < NUM_PAR;idx++) { ParamTxLoopJobSet (PAR_TX_START + IDx); } /*初始化要传输的变量*/ parOffSent = 0; lastSentTxBuf = NUM_BUF - 1; } //*** 用于将编解码器配置为 I2S 模式 的函数*/ static void AIC31I2SConfigure (void) { volatile unsigned int delay = 0xFFF; AIC31Reset (SOC_I2C_0_regs); while (delay--); /*配置数据格式和采样率*/ AIC31DataConfig (SOC_I2C_0_regs、AIC31_datatype_I2S、SLOT_SIZE、0); AIC31SampleRateConfig (SOC_I2C_0_regs、AIC31_mode_both、SAMPLING_RATE); /*初始化 ADC 和 DAC */ AIC31ADCInit (SOC_I2C_0_regs); AIC31DACInit (SOC_I2C_0_regs); }/* **将 McASP 发送部分配置为 I2S 模式。 */ static void McASPI2SConfigure (void) { McASPRxReset (SOC_MCASP_0_CTRL_regs); McASPTxReset (SOC_MCASP_0_CTRL_regs); /*为 DMA 传输启用 FIFO */ McASPReadFifoEnable (SOC_MCASP_0_FIFO_REGS、1、1); McASPWriteFifoEnable (SOC_MCASP_0_FIFO_REGS、1、1); /*以发送器/接收器格式单位设置 I2S 格式*/ McASPRxFmtI2SSet (SOC_MCBSP_0_CTRL_regs、WORD_SIZE、SLOT_SIZE、 McASP_RX_MODE_DMA); McASPTxFmtI2SSet (SOC_MCBSP_0_CTRL_regs、WORD_SIZE、SLOT_SIZE、 McASP_TX_MODE_DMA); /*配置帧同步。 I2S 应采用 TDM 格式、具有2个插槽*/ McASPRxFrameSyncCfg (SOC_MCASP_0_CTRL_regs、2、MCASP_RX_FS_WIDTH_WORD、 McASP_RX_FS_EXT_BEGIN_ON_FALL_EDGE); McASPTxFrameSyncCfg (SOC_MCASP_0_CTRL_regs、2、MCASP_TX_FS_WIDTH_WORD、 McASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE); /*为接收器配置时钟*/ McASPRxClkCfg (SOC_MCASP_0_CTRL_regs、MCASP_RX_CLK_EXTERNAL、0、0); McASPRxClkPolaritySet (SOC_MCASP_0_CTRL_regs、MCASP_RX_CLK_POL_RIS_EDGE); McASPRxClkCheckConfig (SOC_MCASP_0_CTRL_regs、MCASP_RX_CLKCHCK_DIV32、 0x00、0xFF); /*配置发送器的时钟*/ McASPTxClkCfg (SOC_MCASP_0_CTRL_regs、MCASP_TX_CLK_EXTERNAL、0、0); McASPTxClkPolaritySet (SOC_MCASP_0_CTRL_regs、MCASP_TX_CLK_POL_FALL_EDGE); McASPTxClkCheckConfig (SOC_MCASP_0_CTRL_regs、MCASP_TX_CLKCHK_DIV32、 0x00、0xFF); /*启用 RX 和 TX 部分的同步*/ McASPTxRxClkSyncEnable (SOC_MCBSP_0_CTRL_regs); /*启用发送器/接收器插槽。 I2S 使用2个插槽*/ McASPRxTimeSlotSet (SOC_MCBSP_0_CTRL_regs、I2S_SLOTS); McASPTxTimeSlotSet (SOC_MCASP_0_CTRL_regs、I2S_SLOTS); /* **设置串行器,当前只有一个串行器设置为 **发送器和一个串行器作为接收器。 * McASPSerialerRxSet (SOC_MCASP_0_CTRL_regs、MCASP_XSER_RX); McASPSerialerTxSet (SOC_MCASP_0_CTRL_regs、MCASP_XSER_TX); /* **配置 McASP 引脚 **输入-帧同步、时钟和串行器 Rx **输出-串行器 Tx 连接到编解码器的输入 * McASPPinMcASPSet (SOC_MCBSP_0_CTRL_regs、0xFFFFFFFF); McASPPinDirOutputSet (SOC_MCASP_0_CTRL_regs、MCASP_PIN_AXR (MCASP_XSER_TX)); McASPPinDirInputSet (SOC_MCASP_0_CTRL_regs、MCASP_PIN_AFSX | MCASP_PIN_ACLKX | MCASP_PIN_AFSR | MCASP_PIN_ACLKR | MCASP_PIN_AXR (MCASP_XSER_RX); /*为 McASP 启用错误中断*/ McASPTxIntEnable (SOC_MCASP_0_CTRL_regs、MCASP_TX_DMAERROR | MCASP_TX_CLKFAIL | MCASP_TX_SYNCERROR | MCASP_TX_UNDERRUN); McASPRxIntEnable (SOC_MCASP_0_CTRL_regs、MCASP_RX_DMAERROR | MCASP_RX_CLKFAIL | MCASP_RX_SYNCERROR | MCASP_RX_overrun); } /* **在 AINTC 中为 EDMA 设置中断 */ 静态空 EDMA3IntSetup (void) { #ifdef _TMS320C6x IntRegister (C674x_MASK_INT5、EDMA3CCComplisr); IntEventMap (C674x_MASK_INT5、SYS_INT_EDMA3_0_cC0_INT1); IntEnable (C674x_MASK_INT5); #else 内部寄存器(SYS_INT_CCINT0、EDMA3CCComplisr); IntChannelSet (SYS_INT_CCINT0、INT_CHANGE_EMACC); IntSystemEnable (SYS_INT_CCINT0); #endif } // **为 AINTC 中的 McASP 设置错误中断 */ 静态空 McASPErrorIntSetup (void) { #ifdef _TMS320C6x IntRegister (C674x_MASK_INT6、McASPErrorIsr); IntEventMap (C674x_MASK_INT6、SYS_INT_McASP0_INT); IntEnable (C674x_MASK_INT6); #else /*注册 McASP 的错误 ISR */ 内部寄存器(SYS_INT_MCASPINT、McASPErrorIsr); IntChannelSet (SYS_INT_MCASPINT、INT_CHANGE_MCASP); IntSystemEnable (SYS_INT_MCASPINT); #endif } /* **激活数据传输/接收 **调用此函数之前,DMA 参数应准备就绪。 */ static void I2SDataTxRxActivate (void) { /*启动时钟*/ McASPRxClkStart (SOC_MCASP_0_CTRL_regs、MCASP_RX_CLK_external); McASPTxClkStart (SOC_MCASP_0_CTRL_regs、MCASP_TX_CLK_external); /*为传输启用 EDMA */ EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、EDMA3_CHA_McASP0_RX、 EDMA3_TRIG_MODE_EVENT); EDMA3 EnableTransfer (SOC_EDMA30CC_0_regs、 EDMA3_CHA_McASP0_TX、EDMA3_TRIG_MODE_EVENT); /*激活串行器*/ McASPRxSerActivate (SOC_MCBSP_0_CTRL_regs); McASPTxSerActivate (SOC_MCBSP_0_CTRL_regs); /*确保 XDATA 位清零*/ while (McASPTxStatusGet (SOC_MCASP_0_CTRL_regs)和 MCASP_TX_STAT_DATAREADY); /*激活状态机*/ McASPRxEnable (SOC_MCBSP_0_CTRL_regs); McASPTxEnable (SOC_MCASP_0_CTRL_regs); } /* **激活给定缓冲区参数集的 DMA 传输。 // void BufferTxDMAActivate (unsigned int txBuf、unsigned short numSamples、 unsigned short parId、unsigned short linkParar) { EDMA3CCPaRAMEntry 参数集; /*复制默认参数集*/ memcpy (&ParamSet、&txDefaultPar、Size_ParamSet - 2); /*启用完成中断*/ ParamSet.op= TX_DMA_INT_ENABLE; ParamSet.srcAddr = txBufPtr[txBuf]; ParamSet.linkAddr = linkPar * size_ParamSet; ParamSet.bCnt = numSamples; EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、parId、&ParamSet); }/* **主函数。 应用从这里启动。 */ int i、x = 0、y = 0、w = 0、z = 0、 V = 0; signed int Echo1[2 * NUM_SAMESS_PER_AUDIO_BUF]={0};//所有元素0 signed int Echo2[2 * NUM_SAPESS_PER_AUDIO_BUF]={0};//所有元素0 signed int Echo3[2 * NUM_SAPESS_PER_AUDIO_BUF]={0}; //所有元素0 ={0}* void int EchoF[0}/所有元素= 0}* void int void int 3 printf ("音频 buf (字节):%u\n"、AUDIO_BUF_SIZE); 无符号短整型 parToSend; 无符号短整型 parToLink; /*为 I2C 模块0设置引脚多路复用器*/ I2CPinMuxSetup (0); McASPPinMuxSetup(); /*为 McASP 模块加电*/ PSCModuleControl (SOC_PSC_1_regs、HW_PSC_McASP0、PSC_POWERDOMAIN_AYS_ON、 PSC_MDCTL_NEW_ENABLE); /*为 EDMA3CC_0和 EDMA3TC_0加电*/ PSCModuleControl (SOC_PSC_0_regs、HW_PSC_cC0、PSC_POWERDOMAIN_AYS_ON、 PSC_MDCTL_NEW_ENABLE); PSCModuleControl (SOC_PSC_0_regs、HW_PSC_TC0、PSC_POWERDOMAIN_AYST_ON、 PSC_MDCTL_NEW_ENABLE); #ifdef _TMS320C6x //初始化 DSP 中断控制器 IntDSPINTCInit(); #else /*初始化 ARM 中断控制器。*/ IntAINTCInit(); #endif /*初始化编解码器 AIC31的 I2C 0接口*/ I2CCodecIfInit (SOC_I2C_0_regs、INT_CHANNE_I2C、I2C_SLAVE_CODE_AIC31); EDMA3初始(SOC_EDMA30CC_0_regs、0); EDMA3IntSetup(); McASPErrorIntSetup(); #ifdef _TMS320C6x IntGlobalEnable(); #else /*启用全局级别的中断生成*/ IntMasterIRQEnable(); IntGlobalEnable(); IntIRQEnable(); #endif /* **请求 EDMA 通道。 通道0用于接收和 **通道1用于传输 * EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、 EDMA3_CHA_McASP0_TX、EDMA3_CHA_McASP0_TX、0); EDMA3RequestChannel (SOC_EDMA30CC_0_regs、EDMA3_CHANNEL_TYPE_DMA、 EDMA3_CHA_McASP0_RX、EDMA3_CHA_McASP0_RX、0); /*初始化 DMA 参数*/ I2SDMAParamInit(); /*将编解码器配置为 I2S 模式*/ AIC31I2SConfigure(); /*为 I2S 配置 McASP */ McASPI2SConfigure(); /*激活音频传输和接收*/ I2SDataTxRxActivate(); /* **永久循环。 如果接收到一个新的缓冲器、lastFullRxBuf 将为 **在 Rx 完成 ISR 中更新。 如果它不是 lastSentTxBuf、 将发送**缓冲区。 必须将其映射到正确的参数集。 * while (1) { Echo1[0]= 0; Echo2[0]= 0; Echo3[0]= 0; Echo4[0]= 0; Echo1[NUM_SAMESS_PER_AUDIO_BUF]= 0; Echo2[NUM_SAMESS_PER_AUDIO_BUF]= 0; Echo3[NUM_SAMESS_PER_AUDIO_BUF]= 0; Echo4[NUM_SAMESS_PER_AUDIO_BUF]= 0; if (lastFullRxBuf!= lastSentTxBuf) { /* **从链接参数集开始传输。 参数集 ** 1将链接到 PAR_TX_START 处设置的参数。 所以请勿这样做 **更新参数设置1。 * parToSend = PAR_TX_START +(parOffTxToSend % NUM_PAR); parOffTxToSend =(parOffTxToSend + 1)% NUM_PAR; parToLink = PAR_TX_START + parOffTxToSend; lastSentTxBuf =(lastSentTxBuf + 1)% NUM_BUF; 对于(I = 4;I <= AUDIO_BUF_SIZE;I += 4) // AUDIO_BUF_SIZE = 96000 // NUM_SAMESS_PER_AUDIO_BUF = 24000 { Z = 0; if (lastSentTxBuf = 0){ z = rxBuf0[i]+(rxBuf0[i+1]<< 8); Echo4[(I/4)]= Echo3[(I/4)]; Echo3[(I/4)]= Echo2[(I/4)]; Echo2[(I/4)]= Echo1[(I/4)]; Echo1[(I/4)]= z; v = z/5 + Echo1[(I/4)+1]/5 + Echo2[(I/4)+1]/5 + Echo3[(I/4)+1]/5 + Echo4[(I/4)+1]/5; rxBuf0[I-4]= v; rxBuf0[I-3]= v >> 8; } 否则、如果(lastSentTxBuf = 1){ z = rxBuf0[i]+(rxBuf0[i+1]<< 8); Echo4[(I/4)]= Echo3[(I/4)]; Echo3[(I/4)]= Echo2[(I/4)]; Echo2[(I/4)]= Echo1[(I/4)]; Echo1[(I/4)]= z; v = z/5 + Echo1[(I/4)+1]/5 + Echo2[(I/4)+1]/5 + Echo3[(I/4)+1]/5 + Echo4[(I/4)+1]/5; rxBuf1[I-4]= v; rxBuf1[I-3]= v >> 8; } 否则、如果(lastSentTxBuf == 2){ z = rxBuf0[i]+(rxBuf0[i+1]<< 8); Echo4[(I/4)]= Echo3[(I/4)]; Echo3[(I/4)]= Echo2[(I/4)]; Echo2[(I/4)]= Echo1[(I/4)]; Echo1[(I/4)]= z; v = z/5 + Echo1[(I/4)+1]/5 + Echo2[(I/4)+1]/5 + Echo3[(I/4)+1]/5 + Echo4[(I/4)+1]/5; rxBuf2[I-4]= v; rxBuf2[I-3]= v >> 8; } } /*复制缓冲区*/ memcpy ((void *) txBufPtr [lastSentTxBuf]、 (void *) rxBufPtr[lastFullRxBuf]、 AUDIO_BUF_SIZE); /* **通过相应地设置 DMA 参数来发送缓冲区。 **此处要发送的缓冲区和样本数按原样传递 **参数。 这一点很重要、如果只是传输段 **将被使用。 * BufferTxDMAActivate (lastSentTxBuf、NUM_Samples_per_AUDIO_BUF、 (无符号短整型) parToSend、 (无符号短整型) parToLink); } } /* **激活给定缓冲区中参数集的 DMA 传输。 */ static void BufferRxDMAActivate (unsigned int rxBuf、unsigned short parId、 unsigned short parLink) { EDMA3CCPaRAMEntry 参数集; /*复制默认参数集*/ memcpy (&ParamSet、&rxDefaultPar、Size_ParamSet - 2); /*启用完成中断*/ ParamSet.op= RX_DMA_INT_ENABLE; paramSet.destAddr = rxBufPtr[rxBuf]; ParamSet.bCnt = NUM_SAMESS_PER_AUDIO_BUF; ParamSet.linkAddr = parLink * Size_ParamSet; EDMA3SetPaRAM (SOC_EDMA30CC_0_regs、parId、&ParamSet); } // ***一旦接收 DMA 完成 ,将调用此函数*/ 静态空 McASPRxDMAHandler (void) { unsigned short nxtParToUpdate; /* **更新 lastFullRxBuf 以指示新的缓冲区接收 **已完成。 * lastFullRxBuf =(lastFullRxBuf + 1)% NUM_BUF; nxtParToUpdate = PAR_RX_START + parOffRcvd; parOffRcvd =(parOffRcvd + 1)% NUM_PAR; /* **更新要接收的缓冲区的 DMA 参数 **在适当的缓冲区中进一步的数据 * BufferRxDMAActivate (nxtBufToRcv、nxtParToUpdate、 PAR_RX_START + parOffRcvd); /*更新下一个缓冲区以接收数据*/ nxtBufToRcv =(nxtBufToRcv + 1)% NUM_BUF; } // ***此函数将在传输 DMA 完成后调用*/ 静态空 McASPTxDMAComplHandler (void) { ParamTxLoopJobSet ((无符号短整型)(PAR_TX_START + parOffSent)); parOffSent =(parOffSent + 1)% NUM_PAR; } // *** EDMA 传输完成 ISR */ 静态空 EDMA3CCComplisr (void) { #ifdef _TMS320C6x IntEventClear (SYS_INT_EDMA3_0_cC0_INT1); #else IntSystemStatusClear (SYS_INT_CCINT0); #endif /*检查接收 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)) { /*清除第一个通道的中断状态*/ EDMA3ClrIntr (SOC_EDMA30CC_0_regs、EDMA3_CHA_McASP0_TX); McASPTxDMAComplHandler(); } }/* ** McASP 的错误 ISR */ 静态空 McASPErrorIsr (void) { #ifdef _TMS320C6x IntEventClear (SYS_INT_McASP0_INT); #else IntSystemStatusClear (SYS_INT_MCASPINT); #endif ;/*在此执行任何错误处理。*/ }/********* 文件结尾 /