我想尝试实现在一个task里面驱动两个FFTC同时工作,程序跑固定次数后就报错停止,提示semaphore溢出。所使用的工程是根据andy 提供的keystone的例子工程中的FFTC部分修改的,遇到了前面所述的semaphore溢出的错误。
当程序运行了16384次后,控制台输出如下错误信息:
错误之前FFTC open和flow相关的输出都是在初始化时的输出,使用的是andy提供的例子中的相应的初始化的函数,基本没有修改。
程序运行了16384次后,提示semaphore溢出。
程序中对两个FFTC的配置是完全相同的,没有差别,parse对FFTC完成配置。
我的程序的流程如下(程序在最后):
{
初始化:
FFTC_B分配配置变量空间并配置FFTC_B,
配置rxobj并打开接收流
FFTC_A分配配置变量空间并配置FFTC_A,
配置rxobj_A并打开接收流
中断注册FFTC_B
中断注册FFTC_A
Tx配置(使用FFTC_B)并打开发送流
Tx_A配置(使用FFTC_A)并打开发送流
While(1)
{
外部调度
While(pkt)FFTC发送的包的数目,两个FFTC共享
{
getRequestBuffer(FFTC_B)
getRequestBuffer(FFTC_A)
向FFTC_B中的缓存中考入数据
向FFTC_A中的缓存中考入数据
发送FFTC_B的请求
发送FFTC_A的请求
接收FFTC_B的结果rxGetResult函数
接收FFTC_A的结果rxGetResult函数
将FFTC_B的结果拷贝走
将FFTC_A的结果拷贝走
freeResult FFTC_B
freeResult FFTC_B
pkt修改
}
}//end for while(1)
}
下图是我用于观察记录的一些变量
End_time是计算时钟消耗的,其值是TSCL的值作差得到的,timercnt是调度任务的计数器,fftcnt是fft模块的计数器,两个计数器用来统计各个任务的运行次数。
下图是我程序中的semaphore的静态配置,所有semaphore的都在这里。
其中Sem_BCP_2_Schedual暂时没有使用,其他两个semaphore 的Semaphore_post/pend函数都是成对出现的,即觉得这里的semaphore溢出应该不是自己的问题。
我观察了一下semaphore的溢出提示,数字是65535,整好是我的FFTC_task运行次数(16384)的四倍,我的程序中向fftc发送的pkt数目整好也是4个,在想这两个数值之间是否有什么具体的关系?
问题:semaphore的计数器的次数是程序运行次数的4倍,这个怎么理解?错误信息只提供了semaphore溢出作为参考,我应该考虑哪些方向来找到问题所在并修改呢?希望能提供一些debug的思路。还希望各位朋友能给予指点。
以下是我的FFTC_task的主要程序部分:
其中hFFTC_A通过全局变量extern过来的
static Int32 fftc_test_core (Fftc_DrvHandle hFFTC, UInt32 txQNum, Uint8 fftcInstNum)
{
Fftc_RequestHandle hRequestInfo;
Fftc_ResultHandle hResultInfo;
Fftc_TxHandle hTxObj = NULL;
Fftc_RxHandle hRxObj = NULL;
Fftc_TxCfg txCfg;
Fftc_RxCfg rxCfg;
// UInt32 blockExpVal, clipping;
Fftc_BlockInfo blockInfo;
UInt8 *pReqBuffer, *pResultBuffer, *pResultPSInfo, rxFlowId, rxSrcId;
UInt32 maxReqBufferLen, reqBufferLen, resultLen, rxPSInfoLen, txPSInfoLen = 0;
Fftc_Result* pFFTResult = NULL;
Cplx16 *xout, *xoutread;
UInt16 i, j, pktCounter = 0, rxDestnTagInfo;
Int32 retVal;
// UInt32 bIsTestFailed = 0;
FFT_TestCfg* pFFTTestCfg = NULL;
UInt32 blockDataOffset = 0;
UInt32 blockDataOffset_in = 0;
UInt8 coreNum = CSL_chipReadReg (CSL_CHIP_DNUM);
//xm add
Fftc_RequestHandle hRequestInfo_A;
Fftc_ResultHandle hResultInfo_A;
Fftc_TxHandle hTxObj_A = NULL;
Fftc_RxHandle hRxObj_A = NULL;
Fftc_TxCfg txCfg_A;
Fftc_RxCfg rxCfg_A;
FFT_TestCfg* pFFTTestCfg_A = NULL;
Fftc_BlockInfo blockInfo_A;
Int32 retVal_A;
UInt8 *pReqBuffer_A, *pResultBuffer_A, *pResultPSInfo_A, rxFlowId_A, rxSrcId_A;
UInt16 rxDestnTagInfo_A;
Fftc_Result* pFFTResult_A = NULL;
UInt32 maxReqBufferLen_A, reqBufferLen_A, resultLen_A, rxPSInfoLen_A, txPSInfoLen_A = 0;
/* Allocate memory for the test configuration */
if (!(pFFTTestCfg = (FFT_TestCfg *) Fftc_osalMalloc (sizeof (FFT_TestCfg), FALSE)))
{
Fftc_osalLog ("[Core %d]: Error allocating memory for test configuration \n", coreNum);
return -1;
}
/* Read the FFT input vector and configuration for this test
* from the corresponding input configuration file.
* The testCaseId for this test is 6.
*/
if (fftc_parse_testCfg (pFFTTestCfg, &blockInfo) < 0)
{
return -1;
}
/* Setup a Rx flow. This flow will be used to retrieve FFT results
* from a destination queue.
*
* Rx flow Configuration Params:
* -----------------------------
* - Use Host descriptors
* - No PS Info (bPSInfoPresent = 0)
* - Setup Rx object for interrupts + blocking mode
* - Let FFTC driver pick the destination queue (cppiRxQNum = -1)
* - Pick a buffer size big enough to hold the error information and
* FFT result itself.
*/
memset (&rxCfg, 0, sizeof (rxCfg));
rxCfg.useFlowId = -1;
rxCfg.bManageRxFlowCfg = 1;
rxCfg.rxFlowCfg.drvCfg.descType = Cppi_DescType_HOST;
rxCfg.rxFlowCfg.drvCfg.cppiNumDesc = 2;
/* Allocate result buffers big enough to hold:
*
* Per block result = Per block error info (block exp val + clipping detect + srcId + flowId) (16 bytes) +
* block output data (number of samples * sample size)
*/
rxCfg.rxFlowCfg.drvCfg.bufferSize = (pFFTTestCfg->numOutputSamples[0] * FFTC_TEST_SAMPLE_SIZE + 16) * pFFTTestCfg->numBlocks;
rxCfg.rxFlowCfg.drvCfg.bPSInfoPresent = 0;
rxCfg.rxFlowCfg.drvCfg.psLocation = Cppi_PSLoc_PS_IN_DESC;
rxCfg.cppiRxQNum = -1;
rxCfg.bBlockOnResult = 1;
rxCfg.bUseInterrupts = 1;
rxCfg.bManageAccumList = 1; /* Let driver do the Accum Management */
rxCfg.accumCfg.drvCfg.bEnablePacing = 0; /* Disable pacing */
rxCfg.accumCfg.drvCfg.intThreshold = 1; /* Set interrupt threshold to 1 */
Fftc_getDeviceAccumulatorConfig (fftcInstNum, &rxCfg.accumCfg.drvCfg.accChannelNum, &rxCfg.cppiRxQNum);
// Fftc_getDeviceAccumulatorConfig (CSL_FFTC_B, &rxCfg.accumCfg.drvCfg.accChannelNum, &rxCfg.cppiRxQNum);
/* Get a Rx Object Handle */
if ((hRxObj = Fftc_rxOpen (hFFTC, &rxCfg)) == NULL)
{
Fftc_osalLog ("[Core %d]: Rx flow open failed \n", coreNum);
goto error;
}
else
{
Fftc_osalLog ("[Core %d]: Rx Flow %d opened successfully using Rx queue %d \n", coreNum,
Fftc_rxGetFlowId (hRxObj), Fftc_rxGetRxQueueNumber (hRxObj));
}
//xm add
/* Allocate memory for the test configuration */
if (!(pFFTTestCfg_A = (FFT_TestCfg *) Fftc_osalMalloc (sizeof (FFT_TestCfg), FALSE)))
{
Fftc_osalLog ("[Core %d]: Error allocating memory for test configuration FFTC instance 1\n", coreNum);
return -1;
}
/* Read the FFT input vector and configuration for this test
* from the corresponding input configuration file.
* The testCaseId for this test is 6.
*/
if (fftc_parse_testCfg (pFFTTestCfg_A, &blockInfo_A) < 0)
{
return -1;
}
/* Setup a Rx flow. This flow will be used to retrieve FFT results
* from a destination queue.
*
* Rx flow Configuration Params:
* -----------------------------
* - Use Host descriptors
* - No PS Info (bPSInfoPresent = 0)
* - Setup Rx object for interrupts + blocking mode
* - Let FFTC driver pick the destination queue (cppiRxQNum = -1)
* - Pick a buffer size big enough to hold the error information and
* FFT result itself.
*/
memset (&rxCfg_A, 0, sizeof (rxCfg_A));
rxCfg_A.useFlowId = -1;
rxCfg_A.bManageRxFlowCfg = 1;
rxCfg_A.rxFlowCfg.drvCfg.descType = Cppi_DescType_HOST;
rxCfg_A.rxFlowCfg.drvCfg.cppiNumDesc = 2;
/* Allocate result buffers big enough to hold:
*
* Per block result = Per block error info (block exp val + clipping detect + srcId + flowId) (16 bytes) +
* block output data (number of samples * sample size)
*/
rxCfg_A.rxFlowCfg.drvCfg.bufferSize = (pFFTTestCfg_A->numOutputSamples[0] * FFTC_TEST_SAMPLE_SIZE + 16) * pFFTTestCfg_A->numBlocks;
rxCfg_A.rxFlowCfg.drvCfg.bPSInfoPresent = 0;
rxCfg_A.rxFlowCfg.drvCfg.psLocation = Cppi_PSLoc_PS_IN_DESC;
rxCfg_A.cppiRxQNum = -1;
rxCfg_A.bBlockOnResult = 1;
rxCfg_A.bUseInterrupts = 1;
rxCfg_A.bManageAccumList = 1; /* Let driver do the Accum Management */
rxCfg_A.accumCfg.drvCfg.bEnablePacing = 0; /* Disable pacing */
rxCfg_A.accumCfg.drvCfg.intThreshold = 1; /* Set interrupt threshold to 1 */
Fftc_getDeviceAccumulatorConfig (0, &rxCfg_A.accumCfg.drvCfg.accChannelNum, &rxCfg_A.cppiRxQNum);
// Fftc_getDeviceAccumulatorConfig (CSL_FFTC_B, &rxCfg.accumCfg.drvCfg.accChannelNum, &rxCfg.cppiRxQNum);
/* Get a Rx Object Handle */
if ((hRxObj_A = Fftc_rxOpen (hFFTC_A, &rxCfg_A)) == NULL)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Rx flow open failed \n", coreNum);
goto error;
}
else
{
Fftc_osalLog ("[Core %d]: FFTC 0 Rx Flow %d opened successfully using Rx queue %d \n", coreNum,
Fftc_rxGetFlowId (hRxObj_A), Fftc_rxGetRxQueueNumber (hRxObj_A));
}
// register_rx_interrupts (CSL_FFTC_A,hRxObj);
register_rx_interrupts_fftc (fftcInstNum, hRxObj);
//xm register fftc_a
register_rx_interrupts_fftc (0, hRxObj_A);
/* Setup a Tx Object. This object will be used to submit FFT requests.
*
* Tx object Configuration Params:
* -----------------------------
* - Pre-alloc Tx Free Desc (bManageReqBuffers = 1)
* - Use Host descriptors
* - Pick a buffer size big enough to hold all the
* FFT request blocks.
* - No PS Info (bPSInfoPresent = 0)
* - No mixed size DFTs (bEnableDftSizeListCfg = 0)
* - Open queue in shared mode (bSharedMode = 1).
* Enables re-programming queue using CPPI.
*/
memset (&txCfg, 0, sizeof (txCfg));
txCfg.txQNum = (Fftc_QueueId) txQNum;
txCfg.bManageReqBuffers = 1;
txCfg.bEnableDftSizeListCfg = 0;
txCfg.fftQCfg = pFFTTestCfg->fftcQCfg;
txCfg.bSharedMode = 1;
txCfg.descType = Cppi_DescType_HOST;
txCfg.cppiNumDesc = 2;
txCfg.bufferSize = pFFTTestCfg->numInputSamples[0] * FFTC_TEST_SAMPLE_SIZE * pFFTTestCfg->numBlocks;
txCfg.bPSInfoPresent = 0;
/* Get a Tx Object Handle */
if ((hTxObj = Fftc_txOpen (hFFTC, &txCfg)) == NULL)
{
Fftc_osalLog ("[Core %d]: Tx open failed \n", coreNum);
goto error;
}
//xm add
/* Setup a Tx Object. This object will be used to submit FFT requests.
*
* Tx object Configuration Params:
* -----------------------------
* - Pre-alloc Tx Free Desc (bManageReqBuffers = 1)
* - Use Host descriptors
* - Pick a buffer size big enough to hold all the
* FFT request blocks.
* - No PS Info (bPSInfoPresent = 0)
* - No mixed size DFTs (bEnableDftSizeListCfg = 0)
* - Open queue in shared mode (bSharedMode = 1).
* Enables re-programming queue using CPPI.
*/
memset (&txCfg_A, 0, sizeof (txCfg));
txCfg_A.txQNum = (Fftc_QueueId) txQNum;
txCfg_A.bManageReqBuffers = 1;
txCfg_A.bEnableDftSizeListCfg = 0;
txCfg_A.fftQCfg = pFFTTestCfg_A->fftcQCfg;
txCfg_A.bSharedMode = 1;
txCfg_A.descType = Cppi_DescType_HOST;
txCfg_A.cppiNumDesc = 2;
txCfg_A.bufferSize = pFFTTestCfg_A->numInputSamples[0] * FFTC_TEST_SAMPLE_SIZE * pFFTTestCfg_A->numBlocks;
txCfg_A.bPSInfoPresent = 0;
/* Get a Tx Object Handle */
if ((hTxObj_A = Fftc_txOpen (hFFTC_A, &txCfg_A)) == NULL)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Tx open failed \n", coreNum);
goto error;
}
// int count =0;
int pingpong = 0;
//由于循环CP添加必须是4的倍数 而引起的多余循环CP的数位 最后需要去除掉
int CP_more = 0;
//实际需要的CP
int PrefixAddNum = 0;
while(1)
{
Semaphore_pend(Sem_re_2_fftc, BIOS_WAIT_FOREVER);
fftcnt++;
start_time = TSCL;
pingpong = (pingpong+1)%2;
pktCounter = 0;
OutputDataOffset = 0;
OutputDataOffset_A = 0;
blockDataOffset_in = 0;
// if(count %30 ==0)
// OutputDataOffset = 4416*2;
//xm 做4次FFT,分别为1+6+1+6
/*
*这里天线端口数应该和pktConter相关,天线端口数乘以2为pktCounter的值
*因为一个task驱动了两个FFTC,两个共同配合完成FFT的计算
*此处的修改需要在后面继续完善!!!!!!!!!!
*包括端口号与pktCounter的对应关系,以及CPmode的影响
*/
/* Run the test in a loop */
while (pktCounter != 4)//NUM_TEST_PACKETS)
{
/* No PS info */
txPSInfoLen = 0;
/* Initialize the request buffer offset */
blockDataOffset = 0;
// blockDataOffset_in = 0;
if((pktCounter%2)==0)
{
// Get the number of FFT blocks
pFFTTestCfg->numBlocks = 1;
PrefixAddNum = PrefixAddNum_A;
pFFTTestCfg->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum = ((PrefixAddNum_A+3)>>2)*4;
//xm add
pFFTTestCfg_A->numBlocks = 1;
PrefixAddNum = PrefixAddNum_A;
pFFTTestCfg_A->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum = ((PrefixAddNum_A+3)>>2)*4;
}
else
{
// Get the number of FFT blocks
pFFTTestCfg->numBlocks = 6;
PrefixAddNum = PrefixAddNum_B;
pFFTTestCfg->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum = ((PrefixAddNum_B+3)>>2)*4;
//xm add
pFFTTestCfg_A->numBlocks = 6;
PrefixAddNum = PrefixAddNum_B;
pFFTTestCfg_A->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum = ((PrefixAddNum_B+3)>>2)*4;
}
/* Get the input and output data info for each of the blocks now */
for (i = 0; i < pFFTTestCfg->numBlocks; i ++)
{
/* Account for zero pad samples too. */
pFFTTestCfg->numOutputSamples[i] = pFFTTestCfg->numInputSamples[i];
if (pFFTTestCfg->fftcQCfg.controlRegConfig.bZeroPadEnable)
pFFTTestCfg->numOutputSamples[i] += pFFTTestCfg->fftcQCfg.controlRegConfig.zeroPadFactor;
if (pFFTTestCfg->fftcQCfg.cyclicPrefixRegConfig.bCyclicPrefixAddEnable)
pFFTTestCfg->numOutputSamples[i] += pFFTTestCfg->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum;
//xm add
/* Account for zero pad samples too. */
pFFTTestCfg_A->numOutputSamples[i] = pFFTTestCfg_A->numInputSamples[i];
if (pFFTTestCfg_A->fftcQCfg.controlRegConfig.bZeroPadEnable)
pFFTTestCfg_A->numOutputSamples[i] += pFFTTestCfg_A->fftcQCfg.controlRegConfig.zeroPadFactor;
if (pFFTTestCfg_A->fftcQCfg.cyclicPrefixRegConfig.bCyclicPrefixAddEnable)
pFFTTestCfg_A->numOutputSamples[i] += pFFTTestCfg_A->fftcQCfg.cyclicPrefixRegConfig.cyclicPrefixAddNum;
}
/* Get a request buffer */
if (Fftc_txGetRequestBuffer (hTxObj,
&blockInfo,
&pFFTTestCfg->fftcQCfg,
txPSInfoLen,
Fftc_rxGetFlowId (hRxObj),
pktCounter,
&hRequestInfo,
&pReqBuffer,
&maxReqBufferLen) < 0)
{
Fftc_osalLog ("[Core %d]: Unable to get request buffer \n", coreNum);
goto error;
}
//xm add
/* Get a request buffer */
if (Fftc_txGetRequestBuffer (hTxObj_A,
&blockInfo_A,
&pFFTTestCfg_A->fftcQCfg,
txPSInfoLen,
Fftc_rxGetFlowId (hRxObj_A),
pktCounter,
&hRequestInfo_A,
&pReqBuffer_A,
&maxReqBufferLen_A) < 0)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Unable to get request buffer \n", coreNum);
goto error;
}
/* Initialize the whole FFT request buffer */
memset (pReqBuffer, 0, maxReqBufferLen);
//xm add
memset (pReqBuffer_A,0,maxReqBufferLen_A);
/* The request buffer MUST be populated in the following order:
*
* <PS Info to be passed to receiver> then followed by <FFT request data>
*/
/* We have no Protocol Specific Pass through data to pass to receiver in this test.
* So just copy the FFT request data itself into the request buffer, block by block
*/
//xm 这个两个的长度是一样的
reqBufferLen = pFFTTestCfg->numBlocks * pFFTTestCfg->numInputSamples[0] * FFTC_TEST_SAMPLE_SIZE;
for (i = 0; i < pFFTTestCfg->numBlocks; i ++)
{
// Copy the FFT request block A
memcpy ((Ptr) (pReqBuffer + blockDataOffset),//头头对其,所以间隔0byte
(Ptr) (0x0C1DF300+blockDataOffset_in),//RE后的首地址
RE_number*2);
// Fftc_osalLog ("Iput BLocK address:%x \n", (Uint32)(void *)(0x0C1812C0+ inputDataOffset) );
// Copy the FFT request block B
memcpy ((Ptr) (pReqBuffer + blockDataOffset+RE_number*2+4),//前面A的600*=2400,和中间子载波补0,所以间隔2404byte
(Ptr) (0x0C1DF300+RE_number*2+blockDataOffset_in),//B是RE后的首地址加上(RE个数的一半*4)
RE_number*2);
// Fftc_osalLog ("Iput BLocK address:%x \n", (Uint32)(void *)(0x0C1812C0+ inputDataOffset) );
//xm add
memcpy ((Ptr) (pReqBuffer_A + blockDataOffset),//头头对其,所以间隔0byte
(Ptr) (0x0C1EF980+blockDataOffset_in),//RE后的首地址
RE_number*2);
memcpy ((Ptr) (pReqBuffer_A + blockDataOffset+RE_number*2+4),//前面A的600*=2400,和中间子载波补0,所以间隔2404byte
(Ptr) (0x0C1EF980+RE_number*2+blockDataOffset_in),//B是RE后的首地址加上(RE个数的一半*4)
RE_number*2);
//xm 两组数据完全一样,不再做区分
blockDataOffset_in += (4800);//由于输入数组就是按照1200的格式排列的,所以这里的4800在任何带宽下都不变
blockDataOffset += (pFFTTestCfg->numInputSamples[0] * FFTC_TEST_SAMPLE_SIZE);//根据不同带宽而改变
}
#ifdef FFTC_TEST_DEBUG
Fftc_osalLog ("\n[Core %d]: Submitting FFT Request ... \n", coreNum);
#endif
/* Submit the FFT request for processing */
if (Fftc_txSubmitRequest (hTxObj,
hRequestInfo,
reqBufferLen) < 0)
{
Fftc_osalLog ("[Core %d]: Unable to submit request \n", coreNum);
goto error;
}
else
{
#ifdef FFTC_TEST_DEBUG
Fftc_osalLog ("Submitted request %d successfully \n", pktCounter);
#endif
}
//xm add
/* Submit the FFT request for processing */
if (Fftc_txSubmitRequest (hTxObj_A,
hRequestInfo_A,
reqBufferLen) < 0)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Unable to submit request \n", coreNum);
goto error;
}
else
{
#ifdef FFTC_TEST_DEBUG
Fftc_osalLog ("FFTC 0 Submitted request %d successfully \n", pktCounter);
#endif
}
/* -------------------------------------
* Wait on FFT result and verify Result
* -------------------------------------
*/
#ifdef FFTC_TEST_DEBUG
Fftc_osalLog ("\n[Core %d]: Waiting for Result ... \n", coreNum);
#endif
/* Get the raw result from the engine. */
if ((retVal = Fftc_rxGetResult (hRxObj,
&hResultInfo,
&pResultBuffer,
&resultLen,
&pResultPSInfo,
&rxPSInfoLen,
&rxFlowId,
&rxSrcId,
&rxDestnTagInfo
)) != FFTC_RETVAL_SUCCESS)
{
Fftc_osalLog ("[Core %d]: Invalid FFT result : %d \n", coreNum, retVal);
goto error;
}
//xm add
/* Get the raw result from the engine. */
if ((retVal_A = Fftc_rxGetResult (hRxObj_A,
&hResultInfo_A,
&pResultBuffer_A,
&resultLen_A,
&pResultPSInfo_A,
&rxPSInfoLen_A,
&rxFlowId_A,
&rxSrcId_A,
&rxDestnTagInfo_A
)) != FFTC_RETVAL_SUCCESS)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Invalid FFT result : %d \n", coreNum, retVal_A);
goto error;
}
// else
// {
// Fftc_osalLog("[Core %d]: FFTC 0 valid FFT result: %d \n",coreNum,retVal_A);
// }
CP_more = (((PrefixAddNum+3)>>2)*4 -PrefixAddNum)*4;//乘4是因为4byte一个RE
if(CP_more != 0)
{
for (i = 0; i < pFFTTestCfg->numBlocks; i ++)
{
// memcpy((void*)(g_aucsrioBuf+OutputDataOffset+PrefixAddNum+i*(FFTsize+PrefixAddNum)), (void*)(pResultBuffer+CP_more), (FFTsize)*4);
// CP_more += (FFTsize);
memcpy((void*)(g_aucsrioBuf+OutputDataOffset+i*(FFTsize+PrefixAddNum)), (void*)(pResultBuffer+CP_more), (FFTsize+PrefixAddNum)*4);
CP_more += (FFTsize + ((PrefixAddNum+3)>>2)*4)*4;
}
OutputDataOffset = (OutputDataOffset+pFFTTestCfg->numBlocks*(FFTsize+PrefixAddNum));
// CACHE_wbL1d ((void *)g_aucsrioBuf, SRIO_SEND_BUF_MAX_LEN*4, CACHE_WAIT);
// _mfence();
}
else
{
//edma参数设置 挺简单的
vusr_edma_wr_setup_all_payload((Uint32)(pResultBuffer), (Uint32)(void *)(g_aucsrioBuf+OutputDataOffset), resultLen, 8+pktCounter);
// Fftc_osalLog ("BLocK address:%x \n", (Uint32)(void *)(g_aucsrioBuf + OutputDataOffset) );
//edma触发
verify_edma_complete(8+pktCounter);
OutputDataOffset = (OutputDataOffset+resultLen/4);
}
//xm add
CP_more = (((PrefixAddNum+3)>>2)*4 -PrefixAddNum)*4;//乘4是因为4byte一个RE
if(CP_more != 0)
{
for (i = 0; i < pFFTTestCfg_A->numBlocks; i ++)
{
// memcpy((void*)(g_aucsrioBuf+OutputDataOffset+PrefixAddNum+i*(FFTsize+PrefixAddNum)), (void*)(pResultBuffer+CP_more), (FFTsize)*4);
// CP_more += (FFTsize);
memcpy((void*)(g_aucsrioBuf +30720 +OutputDataOffset_A+i*(FFTsize+PrefixAddNum)), (void*)(pResultBuffer_A+CP_more), (FFTsize+PrefixAddNum)*4);
CP_more += (FFTsize + ((PrefixAddNum+3)>>2)*4)*4;
}
OutputDataOffset_A = (OutputDataOffset_A+pFFTTestCfg_A->numBlocks*(FFTsize+PrefixAddNum));
// CACHE_wbL1d ((void *)g_aucsrioBuf, SRIO_SEND_BUF_MAX_LEN*4, CACHE_WAIT);
// _mfence();
}
else
{
//edma参数设置 挺简单的
vusr_edma_wr_setup_all_payload((Uint32)(pResultBuffer_A), (Uint32)(void *)(g_aucsrioBuf +30720 +OutputDataOffset_A), resultLen_A, 12+pktCounter);
// Fftc_osalLog ("BLocK address:%x \n", (Uint32)(void *)(g_aucsrioBuf + OutputDataOffset) );
//edma触发
verify_edma_complete(12+pktCounter);
OutputDataOffset_A = (OutputDataOffset_A+resultLen_A/4);
}
/* Done using the result buffer, return it to the FFTC driver for recycling */
if (Fftc_rxFreeResult (hRxObj,
hResultInfo
) < 0)
{
Fftc_osalLog ("[Core %d]: Error freeing result : %d \n", coreNum, i);
goto error;
}
//xm add
if (Fftc_rxFreeResult (hRxObj_A,
hResultInfo_A
) < 0)
{
Fftc_osalLog ("[Core %d]: FFTC 0 Error freeing result : %d \n", coreNum, i);
goto error;
}
pktCounter ++;
//delete xm 暂不使用srio传输
/* 这部分SRIO的传输可能会带来一定时延,目前需要一个方法来解决*/
if(pktCounter == 2)
{
// complete = 0;
// Srio_SendData((Uint32*)SRC_BASE, (Uint32*)(DST_BASE1), SLOT_SIZE, DEV1_ID);//每次发一个port的端口
// while(complete == 0);
}
else if(pktCounter == 4)
{
// complete = 0;
// Srio_SendData((Uint32*)(SRC_BASE+SLOT_SIZE*1), (Uint32*)(DST_BASE1+SLOT_SIZE*1), SLOT_SIZE, DEV1_ID);
// while(complete == 0);
}
else if(pktCounter == 6)
{
// complete = 0;
// Srio_SendData((Uint32*)(SRC_BASE+SLOT_SIZE*2), (Uint32*)(DST_BASE2), SLOT_SIZE, DEV1_ID);
// while(complete == 0);
}
}
// complete = 0;
// Srio_SendData((Uint32*)(SRC_BASE+SLOT_SIZE*3), (Uint32*)(DST_BASE2+SLOT_SIZE*1), SLOT_SIZE, DEV1_ID);
// while(complete == 0);
// Srio_SendDoorbell(DEV0_INFO, DEV1_ID);
end_time = TSCL - start_time;
// printf("FFTC time used is %d\n",end_time);
// 做完CP166 8次
// Semaphore_post(Sem_BCP_2_Schedual);
}
/* Free the FFT input, output data and test configuration memory allocated */
fftc_clean_testCfg (pFFTTestCfg, &blockInfo);
/* Close all FFTC handles */
if (hRxObj)
Fftc_rxClose (hRxObj);
if (hTxObj)
Fftc_txClose (hTxObj);
//xm add
/* Free the FFT input, output data and test configuration memory allocated */
fftc_clean_testCfg (pFFTTestCfg_A, &blockInfo_A);
/* Close all FFTC handles */
if (hRxObj_A)
Fftc_rxClose (hRxObj_A);
if (hTxObj_A)
Fftc_txClose (hTxObj_A);
/* Return success. */
return 0;
error:
/* Free the FFT result info memory */
if (pFFTResult)
Fftc_osalFree (pFFTResult, sizeof (Fftc_Result), FALSE);
/* Free the FFT input, output data and test configuration memory allocated */
fftc_clean_testCfg (pFFTTestCfg, &blockInfo);
/* Close all FFTC handles */
if (hRxObj)
Fftc_rxClose (hRxObj);
if (hTxObj)
Fftc_txClose (hTxObj);
//xm add
/* Free the FFT result info memory */
if (pFFTResult_A)
Fftc_osalFree (pFFTResult_A, sizeof (Fftc_Result), FALSE);
/* Free the FFT input, output data and test configuration memory allocated */
fftc_clean_testCfg (pFFTTestCfg_A, &blockInfo_A);
/* Close all FFTC handles */
if (hRxObj_A)
Fftc_rxClose (hRxObj_A);
if (hTxObj_A)
Fftc_txClose (hTxObj_A);
/* Return error */
return -1;
}


