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.

AIF2 LteRelayTest example FastCM not working !!!

Other Parts Discussed in Thread: SYSBIOS, TMS320C6670

Hi Ti Folks,

                 I am trying Fast C&M, Vendor Specific information transmission through AIF2 interface. In this regard, i have few questions.

1. I took the LTERelayTestProject, I have c6670 evm board and i am trying loopback within

i set EVM_TYPE =1

       CPRI_RELAY_CONFIG = 2 and

//Enable control words
#define CPRI_FAST_CM 1

volatile unsigned int intLoopback = 1;
volatile unsigned int swSync = 1;

The example works fine for data, but the code flow DOES NOT touch the FAST_CM code at all, i put a break point in the below part of the code, the breakpoint doesn not hit at all. let me know is there any config/setting i need to take care still.[ofcourse, i did tweak the IF loop and make it work, and i did so, though push to Txq is happening, but reception at Rxq is not happening, so i understood that i have disturbed the natural flow,kindly help so that the example will work on its own without any tweaking].

if (CPRI_FAST_CM)
{

//printf("frame %d,aifFsyncEventCount %d \r\n",frameCount,aifFsyncEventCount[1]);

gie = _disable_interrupts();
if (frameCount < aifFsyncEventCount[1])
{
frameCount = aifFsyncEventCount[1];
// pop from control stream free queue
ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqCtrl[0]));
// push control data on tx queue
if (ptrMonoDesc != NULL) Qmss_queuePushDesc(aifObj.pktDmaConfig.txQCtrl[0], (Uint32*)ptrMonoDesc);
// check if new packet available on the receive side
entries = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQCtrl[0]);
if (entries > 0)
{
ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQCtrl[0]));
// recycle control packet on rx free queue
Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqCtrl[0], (Uint32*)ptrMonoDesc);
ctrlPktCount++;
}
}
_restore_interrupts(gie);
}

Thanks

RC Reddy

  • Hi Ti Folks,

                     Awaiting answer for the above issue.

    Thanks

    RC Reddy

  • Hi,

    I understand you're looking for an example using Lte and Cpri fast c&m. I enclosed one to this answer, that has been built for latest aif2 lld version (1.0.0.6) and tested on C6670 in loopback mode.

    /****************************************************************************\
     *           (C) Copyright 2009, Texas Instruments, Inc.                    *
     *                                                                          *
     *  Redistribution and use in source and binary forms, with or without      *
     *  modification, are permitted provided that the following conditions      *
     *  are met:                                                                *
     *                                                                          *
     *    Redistributions of source code must retain the above copyright        *
     *    notice, this list of conditions and the following disclaimer.         *
     *                                                                          *
     *    Redistributions in binary form must reproduce the above copyright     *
     *    notice, this list of conditions and the following disclaimer in the   *
     *    documentation and/or other materials provided with the                *
     *    distribution.                                                         *
     *                                                                          *
     *    Neither the name of Texas Instruments Incorporated nor the names of   *
     *    its contributors may be used to endorse or promote products derived   *
     *    from this software without specific prior written permission.         *
     *                                                                          *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT       *
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   *
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT    *
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   *
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        *
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,   *
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY   *
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT     *
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    *
     ****************************************************************************
     *                                                                          *
     * Target processors : TMS320C66xx                                          *
     *                                                                          *
    \****************************************************************************/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <c6x.h>
    #include <math.h>
    
    #include <ti/csl/csl.h>
    #include <ti/csl/src/intc/csl_intc.h>
    #include <ti/csl/cslr_tmr.h>
    #include <ti/csl/csl_tmrAux.h>
    #include <ti/csl/csl_aif2HwControlAux.h>
    #include <ti/csl/csl_cache.h>
    #include <ti/csl/csl_cacheAux.h>
    #include <ti/csl/csl_xmcAux.h>
    #include <ti/csl/cslr_cppidma_rx_channel_config.h>
    
    #include <ti/drv/aif2/aif2.h>
    #include <ti/drv/cppi/cppi_drv.h>
    #include <ti/drv/cppi/cppi_desc.h>
    #include <ti/drv/qmss/qmss_drv.h>
    #if EVM_TYPE == 4
    #include <ti/platform/evmc6670l/platform_lib/include/evmc66x_pllc.h>
    #endif
    
    //include for GPIO
    #include <ti/csl/csl_gpio.h>
    #include <ti/csl/csl_gpioAux.h>
    
    
    #include <EVM.h>
    
    #include "cslUtils.h"
    
    #if EVM_TYPE == 5
    #include "appletonScbpSync.h"
    #endif
    
    
    /*
     * This is an AIF2 Single Tone example test for a LTE 10MHz configuration.
     * In this test, the Symbol IQ samples are populated with a sine or cosine wave.
     * The signal is continuous across the 14 symbols of an AxC subframe.
     * This test can be run as a sanity check for the LTE RF DL chain.
     * The test is configured to work at the granularity of a slot.
     * For LTE, AIF2 requires usage of monolithic descriptor packets with a 16-byte header.
     * In the header, a protocol specific word is required to indicate the antenna carrier
     * number, the symbol number and the direction (Ingress/Egress)
     * That means that every 0.5 ms, the test will push and pop from the AIF2 HW queues:
     * 7 symbols * numAxCs per link * numLinks * 2 (for Egress/Ingress traffic)
     * This then makes a total of 56 outstanding monolithic packets in the case of
     * LTE 5MHz / 8 AxCs / 1 Links / both directions
     * When defining a descriptor memory region, the following rules apply:
     * Descriptor size is multiple of 16 bytes, min 32.
     * Descriptor count is a power of 2, minimum 25.
     * Memory region base address must be aligned to a 16-byte address boundary.
     * Here are some considerations regarding PktDMA traffic:
     * 		- For Egress, it is up to the user to insure that DMA data is available prior
     * 		to beginning PE message construction (PE2 event). Breaking real time on DMA has
     * 		similar effects to breaking CorePac MIPS real time. Specifically, AIF2 will fail
     * 		each affected AxC until the beginning of the next radio frame boundary.
     * 		- For Ingress, it is important that DMA is efficient enough that the AIF2 input
     * 		buffers never overflow.
     */
    
    //#define LOOPBACK
    //#define DEBUG_MODE              1
    
    #define     TRIG_TIMER          0
    #define     SYNC_TIMER          5
    
    //Value for Sin calculation
    #define     Q_FACTOR            8191
    #define     SAMP_FREQ_FLOAT     30.72  //sampling frequence is 30.72 for LTE 20 MHz
    #define     PI                  3.14159265358979323846
    
    //define the tone mode, only one of the three patterns can be enable at a time
    #define     SINGLE_TONE         1
    #define     DUAL_TONE_ONE_TWO   0
    #define     DUAL_TONE_FIVE_NINE 0
    //Enable control words
    #define     CPRI_FAST_CM        1
    
    #define		CPRI_FAST_CM_SIZE   704  // every hyperframe or 256 basic frames (BFs), 176 BFs can be used for
    									 // fast C&M. These are BF[20:63], BF[84:127], BF[148:191], BF[212:255]
    									 // in 4x rate, word size is 32 bits. So 176*4 = CPRI_FAST_CM_SIZE bytes.
    
    #if EVM_TYPE == 3 || EVM_TYPE == 4
    #define     NEVER_END_TEST      1     //Enable the infinite loop for SCBP test with spectrum analyzer
    #else
    #define     NEVER_END_TEST      0     //Goes thru packet checking after a certain number of slots
    #endif
    
    #define     TEST_NUM            2
    #define     TEST_ALL            0
    #define 	_CSL_AIF2_DUMP		0     //Enable the DUMP of the AIF configuration
    #define     NBCHANNELPERLINK	2	  //For this test example, you use only 2 AxC on the 4 available.
    #define     NBCHANNELMAXPERLINK 2
    #define     NBCHANNELMAX		(NBCHANNELPERLINK*2) 		                                    // 2-link max for this test
    #define     NBSYMBOL			AIF2_LTE_SYMBOL_NUM											// Number of symbols per slot
    #define		LTESYMBOLSIZE		((AIF2_LTE20_FFT_SIZE+AIF2_LTE20_CYPRENORMAL1_SIZE)*4 + 16)    // 8848: FFT size + CP first
    #define 	LTESYMBOL2SIZE		((AIF2_LTE20_FFT_SIZE+AIF2_LTE20_CYPRENORMAL_SIZE)*4 + 16)     // 8784: FFT size + CP 2nd-6th
    #if EVM_TYPE == 0 || EVM_TYPE == 3 || EVM_TYPE == 4 || EVM_TYPE == 5
    #define     DESCMSM				1					// Lyrtech has no stable DDR, so using MSM and reduing the number of mono desc
    #define		NBDESCMAX			64        			//must be a power of 2, and the test needs 56 at minimum                                                 // Descriptor count rounded to the next power of 2
    													// 7 sym * 2 AxCs * 2 pingpong * 2 directions + 16 control packets
    #else
    #define     DESCMSM				0					// mono desc region going to DDR
    #define		NBDESCMAX			128                 // Descriptor count rounded to the next power of 2
    													// 14 sym * 2 AxCs * 2 pingpong * 2 directions * 2 links
    #endif
    #define		MAX_SLOT				400															// For debug, size of monitoring arrays
    
    // pre-proc constant: EVM_TYPE -> 0 = Lyrtech board, 1 = Advantech board DSP_1, 2 = Advantech setup DSP_2
    #define     CLKIN1_INPUT_KHZ    122880  // the Frequency is based on an external 122.88 MHz clock
    #if EVM_TYPE == 0 || EVM_TYPE == 3 || EVM_TYPE == 4
    #define     SYSCLK_INPUT_KHZ    153600  // on Lyrtech EVM, the Frequency is based on an external 153.60 MHz clock
    #else
    #define     SYSCLK_INPUT_KHZ    122880  // on Advantech EVM , the Frequency is based on an external 122.88 MHz clock
    #endif
    #define     PLLC_PREDIV_CLK   	1       // PLLC_PREDIV_CLK - 1 set to register
    #define     PLLC_PLLM_CLK     	8       // PLLC_PLLM_CLK - 1 set to register (983MHz CPU clock)
    
    // DIO engines are not used in LTE mode - instead PKTDMA and HW queues are used to carry the antenna data from/to AIF2
    #define     DIO_0               CSL_AIF2_DIO_ENGINE_0
    
    volatile unsigned int verbose       = 1;
    volatile unsigned int NB_ITERATIONS = 1;
    volatile unsigned int ntest         = 0;
    volatile unsigned int testcheck     = 1;
    #ifdef LOOPBACK
    volatile unsigned int intLoopback   = 1;
    volatile unsigned int swSync        = 1;
    #else
    volatile unsigned int intLoopback   = 0;
    volatile unsigned int swSync        = 0;
    #endif
    
    volatile unsigned char testEnable[TEST_NUM] =
        {  // Each of those need to be run individually
            0,     // CPRI 4x for LTE 20Mhz - Link 0
            1      // CPRI 4x for LTE 20Mhz - Link 3
        };
    
    typedef struct {
    	Int16 re;
    	Int16 im;
    	} Complex16;
    
    typedef struct {
            // Test name
            const unsigned char name[32];
            //AIF link enable or disable, 1 or 0
            Uint32                   linkEnable[AIF_MAX_NUM_LINKS];
            //AIF link rate (1=1x; 2=2x; 4= 4x).
            Uint32                   linkRate[AIF_MAX_NUM_LINKS];
            //AIF link data type for outbound burst traffic.
            CSL_Aif2LinkDataType     outboundDataType[AIF_MAX_NUM_LINKS];
            //AIF link data width for outbound burst traffic.
            CSL_Aif2DataWidth        outboundDataWidth[AIF_MAX_NUM_LINKS];
            //AIF link data type for inbound burst traffic.
            CSL_Aif2LinkDataType     inboundDataType[AIF_MAX_NUM_LINKS];
            //AIF link data width for inbound burst traffic.
            CSL_Aif2DataWidth        inboundDataWidth[AIF_MAX_NUM_LINKS];
            //AIF link DIO engine used
            CSL_Aif2DioEngineIndex   dioEngine[AIF_MAX_NUM_LINKS];
            } TestObj;
    
    
    //////////////////////
    // Global variables
    AIF_ConfigObj               aifObj;
    AIF_ConfigHandle            hConfigAif = &aifObj;
    
    volatile TestObj                     testObjTab[TEST_NUM] = {
    	{//1st Test - CPRI 4x for LTE 20MHz
    	  "LTE_20MHZ_RF_SINGLE_TONE", // test name
    	 // link0          link1          link2          link3          link4          link5
    	  {1,             0,             0,             0,             0,             0            },  // link enable
    	  {4,             4,             4,             4,             4,             4            },  // link rate
    	  {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // outboundDataType
    	  {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_16, DATA_WIDTH_16},  // outboundDataWidth
    	  {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // inboundDataType
    	  {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_16, DATA_WIDTH_16},  // inboundDataWidth
    	  {DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0},          // not applicable for LTE test
    	},
    	{//1st Test - CPRI 4x for DL LTE 20Mhz - Link
          "LTE_20MHZ_RF_SINGLE_TONE", // test name
       // link0          link1          link2          link3          link4          link5
         {0,             0,             0,             1,             0,             0            },  // link enable
         {4,             4,             4,             4,             4,             4            },  // link rate
         {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // outboundDataType
         {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // outboundDataWidth
         {DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL,  DATA_TYPE_DL },  // inboundDataType
         {DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15, DATA_WIDTH_15},  // inboundDataWidth
    	 {DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0,         DIO_0},          // not applicable for LTE test
        }
       };
    
    
    /* Define Rx queue base index for ingress traffic and the associated Rx free descriptor queue base index */
    #define MONO_RX_FDQ            2012
    #define MONO_RX_Q              1000
    
    /* Monolithic descriptor region for all outstanding symbols in a subframe (1ms)
     * Region base address is 16-byte aligned. (aligning to a L1D 64-byte cache line boundary)
     * The linker will place this >1MBytes buffer in internal shared memory (MSM)
     * symbolcount size is 8.8K bytes for Normal cyclic prefix 20 MHz LTE
     */
    #if DESCMSM == 1
    #pragma DATA_SECTION(mono_region_test,".aifdescmsm");
    #pragma DATA_SECTION(rxBuffer,".aifdescmsm");
    #else
    #pragma DATA_SECTION(mono_region_test,".aifdescddr");
    #pragma DATA_SECTION(rxBuffer,".aifdescddr");
    #endif
    #pragma DATA_ALIGN (mono_region_test, 64);
    Uint8   mono_region_test[NBDESCMAX * LTESYMBOLSIZE * NBCHANNELMAXPERLINK];
    Uint8   rxBuffer[LTESYMBOLSIZE-16];
    
    /*
     * Define an array that can contain all descriptor addresses.
     * This way, all packets can be popped from the FDQ and prepared at once for the purpose of this test.
     */
    Cppi_MonolithicDesc* symbolPkt[NBCHANNELMAXPERLINK][NBSYMBOL*2];
    
    /* Storing first sample of each packet to check packet sequence at runtime */
    Complex16 firstSample[NBCHANNELMAXPERLINK][NBSYMBOL*2];
    
    /* Dummy variables for debug */
    Uint32 nblink            = 1; 				 // default at one but set depending on test
    Uint32 nbchanneltotal    = NBCHANNELPERLINK; // Default for 1 link LTE 10 MHz
    Uint32 nbchannelSuperPacket = 1;             // Default is 1 AxC for super packet
    /*
     * Define Rx flows for AIF2 ingress traffic
     * The flow will tell AIF2 from which FDQ to pop new symbol descriptors
     */
    Cppi_RxFlowCfg rxFlow[AIF_MAX_NUM_LINKS][NBCHANNELMAXPERLINK];
    /* Define Rx flow for control packets */
    Cppi_RxFlowCfg rxFlowCpriCw;
    
    /*
     * Slot and symbolcount counters
     */
    volatile Uint32 slotcount = 0;
    volatile Uint32 symbolcount = 0;
    volatile Uint32 packets_already_pushed = 0;
    volatile Uint32 aif2SymbolEgressCount[MAX_SLOT];
    volatile Uint32 aif2SymbolIngressCount[MAX_SLOT];
    volatile Uint32 getCpuTimestamp[MAX_SLOT];
    volatile Uint32 getPhyTimerFrames[MAX_SLOT];
    volatile Uint32 getPhyTimerClk[MAX_SLOT];
    volatile Uint32 getRxPktCnt[MAX_SLOT]; // for first channel
    volatile Uint32 rxPktCnt[NBCHANNELPERLINK * 2]; // assuming 2 link max
    unsigned char saveDesc[2][14][32];
    
    extern Uint8		   keepAifOff;
    
    /*
     * This flag is used for enabling and printing out exceptions at the end of the test
     */
    Uint32 printexceptions = 1;
    #if _CSL_AIF2_DUMP == 1
    void dump_CSL_Aif2Setup (FILE *output, CSL_Aif2Setup *value);
    #endif
    
    #define SLOT_NUM_FIRST_PUSH	60  // The first push needs to happen on the last subframe before frame boundary
    #define SLOT_NUM_DATA_CHECK	130 // Frame boundary when subframecount = 31, so data can be checked on next subframe so 32
    
    #if EVM_TYPE == 4
    // Fonction that are used to set a 1 Hz pps signal in order to sync with appleton board
    extern void routeTimerLowOutToTimerOut0Pin(void);
    extern int ppsGen (void);
    #endif
    
    Uint32 hfnCount = 0;
    
    /*
     * User Isr that is called from pre-defined Isr in cslUtils.c
     */
    void slotIsr()
    {
    	Int32                i,chan;
    	Uint32               rxSymCnt, payloadLen;
    	Cppi_MonolithicDesc *ptrMonoDesc;
    	Uint32              *payloadPtr;
    	Complex16			*checkPtr;
    
    	slotcount++;
    	getCpuTimestamp[slotcount] 	   = TSCL;
    	getPhyTimerFrames[slotcount]   = aifObj.hCsl->regs->AT_PHYT_FRM_VALUE_LSBS;
    	getPhyTimerClk[slotcount]      = aifObj.hCsl->regs->AT_PHYT_CLKCNT_VALUE;
    
    #if NEVER_END_TEST == 0
    	/*
    	 * Rx packet recycling until final check, we need available descriptors in Rx FDQs when actual data is pushed
    	 */
    	if (slotcount < SLOT_NUM_DATA_CHECK){
    #endif
    	for(chan = 0; chan < nbchannelSuperPacket; chan++)
    	{
    		rxSymCnt = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[chan]);
    
    		for(i=0;i<rxSymCnt;i++)
    		{
    			ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQAxC[chan]));
    			// Invalidate symbol packet header and get the updated payload address + length
    			CACHE_invL1d((void *)ptrMonoDesc, 16, CACHE_WAIT);
    			Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)ptrMonoDesc, (Uint8**)&payloadPtr, &payloadLen);
    
    			if((rxPktCnt[chan]%NBSYMBOL) == 0)
    			{
    				 //check payload length for first symbol
    				if (payloadLen != ((LTESYMBOLSIZE-16)*NBCHANNELMAXPERLINK))
    						printf("unexpected payload length:%d, %d\n",((LTESYMBOLSIZE-16)*NBCHANNELMAXPERLINK),payloadLen);
    			} else {
    				//check payload length for the other 6 symbols
    				if (payloadLen != ((LTESYMBOL2SIZE-16)*NBCHANNELMAXPERLINK))
    						printf("unexpected payload length:%d, %d\n",((LTESYMBOL2SIZE-16)*NBCHANNELMAXPERLINK),payloadLen);
    			}
    			// recycle symbol packet on rx free queue
    			Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqAxC[chan], (Uint32*)ptrMonoDesc);
    			rxPktCnt[chan]++;
    		}
    	}
    #if NEVER_END_TEST == 0
    	}
    #endif
    
    	getRxPktCnt[slotcount]      = rxPktCnt[0];
    
    	/*
    	 * In this Isr, at this slot, push all s7 ymbols for all AxCs, links at once
    	 * It assumes that all symbolPkt were first popped from the FDQs, and properly populated.
    	 * AIF2 will returned them in FDQs following the actual transmission via AIF2 protocol encoder.
    	 * Note that AIF2 Rx PktDMA channels will starve for data checking since we don't perform
    	 * Rx packet recycling at runtime. We don't keep pushing packets beyond a certain slot.
    	 */
    	if (!packets_already_pushed) {
    		/* The first two slots we push the packets that have been initialized and are stored in symbolPkt[][]  */
    		if((slotcount == SLOT_NUM_FIRST_PUSH) || (slotcount == (SLOT_NUM_FIRST_PUSH+1)))
    		{
    			for(i=symbolcount;i<(symbolcount + NBSYMBOL);i++)
    			{
    				for(chan = 0; chan < nbchanneltotal; chan++)
    				{
    					Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)symbolPkt[chan][i], (Uint8**)&payloadPtr, &payloadLen);
    #if DEBUG_MODE == 0
    					checkPtr = (Complex16*)payloadPtr;
    					if ((checkPtr->re != firstSample[chan][i].re) || (checkPtr->im != firstSample[chan][i].im)) {
    						printf("unexpected first sample in this packet\n");
    					}
    #endif
    					Qmss_queuePushDesc((aifObj.pktDmaConfig.txQAxC[chan]), (Uint32*)symbolPkt[chan][i]);
    				}
    			}
    			symbolcount += NBSYMBOL;
    			if (symbolcount == AIF2_LTE_FRAME_SYMBOL_NUM) symbolcount = 0;
    			if (slotcount == (SLOT_NUM_FIRST_PUSH+1)) {
    				packets_already_pushed = 1;
    			}
    		}
    	} else {
    #if NEVER_END_TEST == 0
    		if((slotcount > (SLOT_NUM_FIRST_PUSH+1)) && (slotcount < SLOT_NUM_DATA_CHECK)){
    #endif
    		for(i=symbolcount;i<(symbolcount + NBSYMBOL);i++)
    		{
    			for(chan = 0; chan < nbchanneltotal; chan++)
    			{
    				// pop from AxC Tx free descriptor queue
    				ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqAxC[chan]));
    				// Recreate PS data
    				CACHE_invL1d((void *)ptrMonoDesc, 16, CACHE_WAIT);
    				Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, (Cppi_Desc*)ptrMonoDesc, (Uint8**)&payloadPtr, &payloadLen);
    				payloadPtr[0] = (Uint32 )(0x00008000 + chan + (i << 7));//add symbol number into PS field
    				CACHE_wbL1d((void *)payloadPtr, 4, CACHE_WAIT); // writeback the updated PS data in MSM
    				Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)ptrMonoDesc, (Uint8**)&payloadPtr, &payloadLen);
    #if DEBUG_MODE == 0
    				checkPtr = (Complex16*)payloadPtr;
    				if ((checkPtr->re != firstSample[chan][i%(2*NBSYMBOL)].re) || (checkPtr->im != firstSample[chan][i%(2*NBSYMBOL)].im)) {
    					printf("unexpected first sample in this packet\n");
    				}
    #endif
    				memcpy(&saveDesc[chan][i%(2*NBSYMBOL)][0],ptrMonoDesc,32);
    				Qmss_queuePushDesc((aifObj.pktDmaConfig.txQAxC[chan]), (Uint32*)ptrMonoDesc);
    			}
    		}
    		symbolcount += NBSYMBOL;
    		if (symbolcount == AIF2_LTE_FRAME_SYMBOL_NUM) symbolcount = 0;
    #if NEVER_END_TEST == 0
    		}
    #endif
    	}
    
    	/* PktDMA activity monitoring */
    	aif2SymbolEgressCount[slotcount]  = aifObj.hCsl->regs->DB_EDB_EOP_CNT;
    	aif2SymbolIngressCount[slotcount] = aifObj.hCsl->regs->AD_ISCH_EOP_CNT;
    	// Make sure no overflow occurs on the monitoring arrays
    	if (slotcount == (MAX_SLOT-1)) slotcount = 0;
    }
    
    void getcomplex(Complex16* payload,Uint32 index)
    {
    	float freq;
    	Complex16 x1;
    	Complex16 y;
    #if SINGLE_TONE == 1
                    // 500 KHz signal
                    freq = 0.5;
                    x1.re = (Int16) ( (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    x1.im = (Int16) ( (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    y = x1;
    #elif DUAL_TONE_ONE_TWO == 1
                    Complex16         x2;
                    // 1 MHz signal
                    freq = 1;
                    x1.re = (Int16) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    x1.im = (Int16) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    // 2 MHz signal
                    freq = 2;
                    x2.re = (Int16) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    x2.im = (Int16) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    // dual tone signal
                    y.re = x1.re + x2.re;
                    y.im = x1.im + x2.im;
    #elif DUAL_TONE_FIVE_NINE == 1
                    Complex16         x2;
                    // 5 MHz signal
                    freq = 5;
                    x1.re = (Int16) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    x1.im = (Int16) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    // 9 MHz signal
                    freq = 9;
                    x2.re = (Int16) (0.5 * (cos(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    x2.im = (Int16) (0.5 * (sin(2*PI*freq*(1/SAMP_FREQ_FLOAT)*index)) * Q_FACTOR );
                    // dual tone signal
                    y.re = x1.re + x2.re;
                    y.im = x1.im + x2.im;
    #endif
    
                    payload->re = y.re;
                    payload->im = y.im;
    }
    
    int main(void)
    {
        Uint32               idx, idx1, idx2, i, payloadLen, activeLink;
        Uint16               testpass = 0;
        Uint16               myboard	= EVM_TYPE;
    	Uint32               monoRxCount, monoTxCount;
    #if DEBUG_MODE == 1
    	Uint32               *payloadPtr;
    #else
    	Complex16            *payloadPtr;
    	Complex16			 sampleCheck;
    #endif
    
    	Uint32               chan, rx_count, value;
        Cppi_MonolithicDesc *mono_pkt;
        Qmss_Queue 			 descQueue;
        Cppi_DescTag 		 descTag;
        Uint32              *ctrlCw, ctrlCwLen, frameRun, entries, gie, pktCount;
        Cppi_MonolithicDesc *ptrMonoDesc;
    
        /* Make shared memory (MSM) non cacheable for the purpose of testing */
        CSL_XMC_invalidatePrefetchBuffer();
        CACHE_setMemRegionInfo(12,1,0); // MAR12 - cacheable (always), not prefetchable
        CACHE_setMemRegionInfo(13,1,0); // MAR13 - cacheable (always), not prefetchable
    
        printf("Beginning AIF2 LTE 10 MHz RF tests:\n");
        UTILS_waitForHw(100000);
        
        if (myboard == 0)  UTILS_configMasterSlave();
        else if (EVM_TYPE == 5) DSP_procId = 1;
        else if (myboard <= 2)  DSP_procId = EVM_TYPE; // For Advantech: myboard  = 1 (DSP_1) or 2 (DSP_2)
        else DSP_procId = (Uint8)(EVM_TYPE - 2);       // For SCBP: myboard  = 3 (DSP_1) or 4  (DSP_2)
    
    #if EVM_TYPE == 4
    	UTILS_GPIO8_setup();
    #endif
    
       // AIF2 LLD programs AT event 5 with period 0.5ms in case of LTE
       aif2evt5_userIsr = slotIsr;
    
    	// Take AIF out of power saver
    	AIF_enable();
    
    	// General parameters
    	aifObj.aif2ClkSpeedKhz    = (Uint32)SYSCLK_INPUT_KHZ;
    	aifObj.protocol           = CSL_AIF2_LINK_PROTOCOL_CPRI;
    	aifObj.pktdmaOrDioEngine  = CSL_AIF2_CPPI;
    	aifObj.mode               = AIF_LTE_FDD_MODE;
    	if (swSync == 0)
    		aifObj.aif2TimerSyncSource= CSL_AIF2_PHYT_CMP_SYNC;
    	else
    		aifObj.aif2TimerSyncSource= CSL_AIF2_SW_SYNC;
    
        for(ntest=0;ntest<TEST_NUM;ntest++)
       	{
        	if (testEnable[ntest] == 1 )
        	{
        		chan 	= 0;
        		nblink 	= 0 ;
        		for (i=0;i<AIF_MAX_NUM_LINKS;i++)
        		{
        			if (testObjTab[ntest].linkEnable[i]==1)
        			{
        				nblink++;
        				// PktDma parameters
        				for (idx=0 ; idx<NBCHANNELPERLINK ; idx++)
        				{
        					aifObj.pktDmaConfig.txRegionAxC[chan]   = Qmss_MemRegion_MEMORY_REGION0;
        					aifObj.pktDmaConfig.txNumDescAxC[chan]  = NBSYMBOL*2; // double num of Pkts
        					aifObj.pktDmaConfig.txDescSizeAxC[chan] = LTESYMBOLSIZE;
        					aifObj.pktDmaConfig.rxRegionAxC[chan]   = Qmss_MemRegion_MEMORY_REGION0;
        					aifObj.pktDmaConfig.rxNumDescAxC[chan]  = NBSYMBOL*2; // double num of Pkts
        					aifObj.pktDmaConfig.rxDescSizeAxC[chan] = LTESYMBOLSIZE*NBCHANNELMAXPERLINK;
    
        					memset(&rxFlow[i][idx], 0, sizeof(Cppi_RxFlowCfg));
        					rxFlow[i][idx].rx_dest_qnum     = MONO_RX_Q+chan;
        					rxFlow[i][idx].rx_fdq0_sz0_qnum = MONO_RX_FDQ+chan;
        					rxFlow[i][idx].rx_desc_type     = (Uint8)Cppi_DescType_MONOLITHIC;    // MONO
        					rxFlow[i][idx].rx_fdq1_qnum     = MONO_RX_FDQ+chan;
        					rxFlow[i][idx].rx_fdq2_qnum     = MONO_RX_FDQ+chan;
        					rxFlow[i][idx].rx_fdq3_qnum     = MONO_RX_FDQ+chan;
        					rxFlow[i][idx].rx_sop_offset    = 12+4;   // desc header size for Monolithic packet with PS
    
        					aifObj.pktDmaConfig.hRxFlowAxC[chan]   	= &rxFlow[i][idx];
        					aifObj.pktDmaConfig.hRxFlowCtrl[chan]   = NULL;
        					chan++;
        				}
        			} else {
        				aifObj.pktDmaConfig.hRxFlowAxC[chan]    = NULL;
        			}
        		}
    
    			if (CPRI_FAST_CM) {
    				// PktDma parameters for control words (CPRI control word FastC&M)
    				aifObj.pktDmaConfig.txRegionCtrl[0]   = Qmss_MemRegion_MEMORY_REGION0;
    				aifObj.pktDmaConfig.txNumDescCtrl[0]  = 8;
    				aifObj.pktDmaConfig.txDescSizeCtrl[0] = CPRI_FAST_CM_SIZE;
    				aifObj.pktDmaConfig.rxRegionCtrl[0]   = Qmss_MemRegion_MEMORY_REGION0;
    				aifObj.pktDmaConfig.rxNumDescCtrl[0]  = 8;
    				aifObj.pktDmaConfig.rxDescSizeCtrl[0] = CPRI_FAST_CM_SIZE;
    
    				memset(&rxFlowCpriCw, 0, sizeof(Cppi_RxFlowCfg));
    				rxFlowCpriCw.rx_dest_qnum     = 900;
    				rxFlowCpriCw.rx_fdq0_sz0_qnum = 2001;
    				rxFlowCpriCw.rx_desc_type     = (Uint8)Cppi_DescType_MONOLITHIC;    // monolythic
    				rxFlowCpriCw.rx_sop_offset    = 12;   // desc header size
    
    				aifObj.pktDmaConfig.hRxFlowCtrl[0]    = &rxFlowCpriCw;
    				aifObj.pktDmaConfig.hRxFlowCtrl[1]    = NULL;
    				aifObj.pktDmaConfig.hRxFlowCtrl[2]    = NULL;
    				aifObj.pktDmaConfig.hRxFlowCtrl[3]    = NULL;
        		}
    
        		nbchanneltotal = NBCHANNELPERLINK*nblink;
    
        		memset(mono_region_test, 0, NBDESCMAX * LTESYMBOLSIZE * NBCHANNELMAXPERLINK);
    
        		printf("test: %s\n", testObjTab[ntest].name);
        		// proceed with HW cleanup but may require GEL_AdvancedReset("System Reset") on PreFileLoaded callback for 100% robustness
        		UTILS_doCleanup(&aifObj,TRIG_TIMER);
    
            	for (i=0;i<AIF_MAX_NUM_LINKS;i++)
            	{
    				 aifObj.linkConfig[i].linkEnable         = testObjTab[ntest].linkEnable[i];
    				 aifObj.linkConfig[i].numPeAxC           = NBCHANNELMAXPERLINK;
    				 aifObj.linkConfig[i].numPdAxC           = NBCHANNELMAXPERLINK;
    				 aifObj.linkConfig[i].linkRate           = (CSL_Aif2LinkRate)testObjTab[ntest].linkRate[i];
    				 aifObj.linkConfig[i].sampleRate		 = AIF_SRATE_30P72MHZ;
    				 aifObj.linkConfig[i].outboundDataType   = testObjTab[ntest].outboundDataType[i];
    				 aifObj.linkConfig[i].outboundDataWidth  = testObjTab[ntest].outboundDataWidth[i];
    				 aifObj.linkConfig[i].inboundDataType    = testObjTab[ntest].inboundDataType[i];
    				 aifObj.linkConfig[i].inboundDataWidth   = testObjTab[ntest].inboundDataWidth[i];
    				 aifObj.linkConfig[i].cpriPackMode       = AIF2_LTE_CPRI_8b8;
    				 aifObj.linkConfig[i].psMsgEnable        = CPRI_FAST_CM;
    				 if (intLoopback == 1 ) aifObj.linkConfig[i].comType = AIF2_LOOPBACK;
    				 else	 				aifObj.linkConfig[i].comType = AIF2_2_AIF2;
    				 aifObj.linkConfig[i].dioEngine          = testObjTab[ntest].dioEngine[i]; //NA for pkDMA
                }
    
    	        if (DSP_procId == 1)
    	        {
    	        	printf("test: %s\n", testObjTab[ntest].name);
    				UTILS_printLinkConfig(&aifObj);
    	        }
        		/* For SCBP-Appleton EVM run, we'll now proceed with SW clock sync */
        		if (DSP_procId == 1)
        		{
        			UTILS_initTimer(TRIG_TIMER);
        		}
    
        		// initialization function for the AT timer and EDMA3 ISRs
        		UTILS_aifIntcSetup();
    
    #if EVM_TYPE == 5 // DSP_ProcId = 1
        		UTILS_boardsSync(SYNC_TIMER);
    #endif
    #if EVM_TYPE == 4
        		if(DSP_procId == 2)
        		{
        			UTILS_resetTimer();
        			routeTimerLowOutToTimerOut0Pin(); //choose Timer0 output to generate the 1 Hz pps signal
        			ppsGen();                         //generate the 1 Hz pps signal
        		}
    #endif
    
    			// Compute default AIF2 parameters given this user configuration
    			AIF_calcParameters(&aifObj);
    
    			// initialization function for qmss and cppi low-level drivers
    			UTILS_initQmss((Uint32*)mono_region_test, NBDESCMAX, LTESYMBOLSIZE * NBCHANNELMAXPERLINK);
    
    			// initialization of Pktdma and Qmss resources given this user configuration
    			AIF_initPktDma(&aifObj);
    
    			// Adjust AIF2 timing parameters if calcParameters didn't implement this LTE case or doesn't match the application Tx/Rx delays
    			for (i= 0 ; i<AIF_MAX_NUM_LINKS; i++){
    				if (aifObj.linkConfig[i].linkEnable) {
    					aifObj.linkConfig[i].pe2Offset   = 310;
    					aifObj.linkConfig[i].deltaOffset = aifObj.linkConfig[i].pe2Offset + 70;
    					aifObj.linkConfig[i].piMin       = aifObj.linkConfig[i].pe2Offset + 70;
    					activeLink = i;
    				}
    			}
    
    			// initialization function for the AIF2 H/W CSL structure (can still be overridden afterwards)
    			AIF_initHw(&aifObj);
    
    			/*
    			 *  LTE Tx packet symbol initialization at once
    			 */
    			for(chan = 0;chan < nbchanneltotal;chan++)
    			{
    				idx1=0;
    			    for(idx = 0;idx < (NBSYMBOL*2);idx++)
    			    {
    					symbolPkt[chan][idx] = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqAxC[chan]));
    					mono_pkt = symbolPkt[chan][idx];
    
    					//Create Mono packet
    					Cppi_setDescType((Cppi_Desc *)mono_pkt,Cppi_DescType_MONOLITHIC);
    					Cppi_setPacketType(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,0);
    					Cppi_setDataOffset(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,16);
    
    					if((idx%NBSYMBOL) == 0) {
    						Cppi_setPacketLen(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,(LTESYMBOLSIZE-16));
    					} else {
    						Cppi_setPacketLen(Cppi_DescType_MONOLITHIC, (Cppi_Desc *)mono_pkt,(LTESYMBOL2SIZE-16));
    					}
    
    					Cppi_setPSFlags (Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,1);
    					Cppi_setPSLen(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,4);
    
    					descQueue.qMgr = 0;
    					descQueue.qNum = aifObj.pktDmaConfig.txFqAxC[chan];
    					Cppi_setReturnQueue(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,descQueue);
    
    					descTag.destTagHi = 0;					descTag.destTagLo = 0;
    					descTag.srcTagHi  = 0;					descTag.srcTagLo  = 0;
    					Cppi_setTag(Cppi_DescType_MONOLITHIC,(Cppi_Desc *)mono_pkt,&descTag);
    
    					// Get payload address
    					Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)mono_pkt, (Uint8**)&payloadPtr, &payloadLen);
    
    #if DEBUG_MODE == 1
    					if((idx%NBSYMBOL) == 0)
    					{
    						 //payload data setup(first symbol)
    						for (idx2 = 0; idx2 < (LTESYMBOLSIZE-16)/4; idx2 ++)
    						{
    							payloadPtr[idx2]= idx2 + (chan << 20);
    							idx1++;
    						}
    					} else {
    						//payload data setup(other six symbols)
    						for (idx2 = 0; idx2 < (LTESYMBOL2SIZE-16)/4; idx2 ++)
    						{
    							payloadPtr[idx2]= idx2 + (chan << 20);
    							idx1++;
    						}
    					}
    #else
    					if((idx%NBSYMBOL) == 0)
    					{
    						 //payload data setup(first symbol)
    						for (idx2 = 0; idx2 < (LTESYMBOLSIZE-16)/4; idx2 ++)
    						{
    							getcomplex(&payloadPtr[idx2],idx1);
    							idx1++;
    						}
    					} else {
    						//payload data setup(other six symbols)
    						for (idx2 = 0; idx2 < (LTESYMBOL2SIZE-16)/4; idx2 ++)
    						{
    							getcomplex(&payloadPtr[idx2],idx1);
    							idx1++;
    						}
    					}
    					firstSample[chan][idx].re =  payloadPtr[0].re;
    					firstSample[chan][idx].im =  payloadPtr[0].im;
    #endif
    					//Create PS data
    					Cppi_getPSData (Cppi_DescType_MONOLITHIC, Cppi_PSLoc_PS_IN_DESC, (Cppi_Desc*)mono_pkt, (Uint8**)&payloadPtr, &payloadLen);
    					*((Uint32*)payloadPtr) = (Uint32 )(0x00008000 + chan + (idx << 7));//add symbol number into PS field
    
    					//Tx queue push will be done in slot ISR at the pace of 7 symbols / AxCs
    			    }
    			}
    
      	        if (CPRI_FAST_CM) {
    				/* Init payload for 8 Monolithic packets for CPRI control words (1 packet sent every 10ms) */
    				for (idx = 0; idx < 8; idx ++)
    				{
    					  ctrlCw = (Uint32 *)(mono_region_test + (idx * 720) + 12);
    					  for (i = 0; i< CPRI_FAST_CM_SIZE/4;i++) ctrlCw[i] = i;
    				}
      	        }
    			/*
    			 * Perform block writeback on L1D to make sure all symbol packets are coherent with MSM
    			 */
    			for(idx = 0;idx < (NBDESCMAX * NBCHANNELPERLINK);idx++) {
    				CACHE_wbInvL1d((void *)(mono_region_test+(idx*LTESYMBOLSIZE)), LTESYMBOLSIZE, CACHE_WAIT);
    			}
    
    			// start AIF2 HW and PktDMA and then wait for frame synchronization
    #if _CSL_AIF2_DUMP == 1
    			if (DSP_procId == 1)
    			{
    			   FILE *fout;
    			   fout = fopen("csl_aif2_dump.txt","w");
    			   if (fout)
    			   {
    				   dump_CSL_Aif2Setup(fout,aifObj.hAif2Setup);
    				   fclose(fout);
    			   }
    
    			}
    #endif
    			AIF_startHw(&aifObj);
    
    			monoRxCount = 0;
    			monoTxCount = 0;
    	        monoRxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[0]);
    	        monoTxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txQAxC[0]);
    			if (DSP_procId == 1)
    			{
    				UTILS_triggerFsync(&aifObj);
    			}
    
    			if (printexceptions == 1) {
    				// wait 4 slots and then enable exceptions
    				while (slotcount<= 4);
    					AIF_enableException(&aifObj);
    			}
    
    			monoRxCount = 0;
    			monoTxCount = 0;
    			while(1)
    			{
    				asm (" IDLE");
    				if ((CPRI_FAST_CM) && (slotcount == (SLOT_NUM_DATA_CHECK + 2))) {
    					gie = _disable_interrupts();
    					/*if (frameRun < aifFsyncEventCount[1]) {
    						frameRun = aifFsyncEventCount[1];
    					}*/
    					if (hfnCount != CSL_FEXT(aifObj.hCsl->regs->G_RM_LKS[activeLink].RM_LK_STS3,AIF2_RM_LK_STS3_HFN)) {
    
    						entries = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqCtrl[0]);
    						if (entries > 0) {
    							hfnCount = CSL_FEXT(aifObj.hCsl->regs->G_RM_LKS[activeLink].RM_LK_STS3,AIF2_RM_LK_STS3_HFN);
    							// pop from control stream free queue
    							ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.txFqCtrl[0]));
    							// push control data on tx queue
    							if (ptrMonoDesc != NULL) Qmss_queuePushDesc(aifObj.pktDmaConfig.txQCtrl[0], (Uint32*)ptrMonoDesc);
    							else {
    													 printf("Tx control packet descriptor is NULL\n");
    							}
    						}
    						// check if new packet available on the receive side
    						entries = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQCtrl[0]);
    						if (entries > 0) {
    							while (entries != 0) {
    								entries --;
    								ptrMonoDesc = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQCtrl[0]));
    								if (ptrMonoDesc == NULL) printf("Rx control packet descriptor is NULL\n");
    								else {
    									// Get payload address
    									Cppi_getData (Cppi_DescType_MONOLITHIC, (Cppi_Desc*)ptrMonoDesc, (Uint8**)&ctrlCw, &ctrlCwLen);
    									if (ctrlCwLen == CPRI_FAST_CM_SIZE) {
    										for (i = 0; i< CPRI_FAST_CM_SIZE/4;i++) {
    											if (ctrlCw[i] != i) printf("CPRI CW %d issue on frame %d\n",i,frameRun);
    											else ctrlCw[i] = 0; // reset Rx payload for next validation round
    										}
    									}
    									// recycle control packet on rx free queue
    									Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqCtrl[0], (Uint32*)ptrMonoDesc);
    									pktCount++;
    								}
    							}
    						}
    					}
    					_restore_interrupts(gie);
    				}
    
    
    #if NEVER_END_TEST == 0
    				// wait for one extra slots to run out of Rx free pkts
    				if(slotcount == (SLOT_NUM_DATA_CHECK + 2))
    				{
    					//AT disable all events and halt timer
    					CSR&= 0xFFFFFFFE;
    					//keepAifOff = 1;
    					UTILS_doCleanup(&aifObj,TRIG_TIMER);
    					break;
    				}
    #endif
    			}
    
    
    
    			if (printexceptions == 1) {
    				// disable interrupts before checking for data
    				CSR&= 0xFFFFFFFE;
    			}
    
    			monoRxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[0]); // get number of received packed on first channel
    			monoTxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[0]); // channel 0 only
    			printf(" Number of monolithic packets received in RX queue channel0: %d\n", monoRxCount);
    			printf(" Number of monolithic packets in TX free queue for channel0: %d\n", monoTxCount);
    			monoRxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[1]);
    			monoTxCount = Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[1]);
    			printf(" Number of monolithic packets received in RX queue channel1: %d\n", monoRxCount);
    			printf(" Number of monolithic packets in TX free queue for channel1: %d\n", monoTxCount);
    
    			/* Check received symbol packet data */
    			for(chan =0; chan < nbchannelSuperPacket; chan++)
    			{
    				idx1 = 0;
    				testpass = 1;
    				rx_count = Qmss_getQueueEntryCount((aifObj.pktDmaConfig.rxQAxC[chan]));
    				if (rx_count == 0) testpass =0;
    
    				for (idx = 0; idx < NBSYMBOL*2; idx ++)
    				{
    					symbolPkt[chan][idx] = (Cppi_MonolithicDesc *)QMSS_DESC_PTR(Qmss_queuePop(aifObj.pktDmaConfig.rxQAxC[chan]));
    #if DEBUG_MODE == 1
    					payloadPtr = (Uint32 *)symbolPkt[chan][idx];
    #else
    					payloadPtr = (Complex16 *)symbolPkt[chan][idx];
    #endif
    					payloadPtr += 4; //skip pkt header and PS field (16 bytes)
    					if((idx%NBSYMBOL) == 0)
    					{
    						CACHE_invL1d((void *)rxBuffer, LTESYMBOLSIZE-16, CACHE_WAIT);
    						UTILS_deinterleaveLteSuperPacket((Uint32 *)payloadPtr, (Uint32 *)rxBuffer, \
    								(Uint32) aifObj.linkConfig[activeLink].cpriPackMode, aifObj.linkConfig[activeLink].numPeAxC, LTESYMBOLSIZE-16);
    						//CACHE_invL1d((void *)symbolPkt[chan][idx], LTESYMBOLSIZE, CACHE_WAIT);
    #if DEBUG_MODE == 1
    						payloadPtr = (Uint32 *)rxBuffer;
    						for (idx2 = 0; idx2 < (LTESYMBOLSIZE-16)/4; idx2 ++)
    						{
    							if (payloadPtr[idx2] != idx2 + (chan << 20))
    							{
    								testpass = 0; testcheck++;
    							}
    							idx1++;
    						}
    #else
    						payloadPtr = (Complex16 *)rxBuffer;
    						for (idx2 = 0; idx2 < (LTESYMBOLSIZE-16)/4; idx2 ++)
    						{
    							getcomplex(&sampleCheck,idx1);
    							if ((payloadPtr[idx2].re != sampleCheck.re) || (payloadPtr[idx2].im != sampleCheck.im ))
    							{
    								testpass = 0; testcheck++;
    							}
    							idx1++;
    						}
    #endif
    					} else {
    						CACHE_invL1d((void *)rxBuffer, LTESYMBOL2SIZE-16, CACHE_WAIT);
    						UTILS_deinterleaveLteSuperPacket((Uint32 *)payloadPtr, (Uint32 *)rxBuffer, \
    								(Uint32) aifObj.linkConfig[activeLink].cpriPackMode, aifObj.linkConfig[activeLink].numPeAxC, LTESYMBOL2SIZE-16);
    						//CACHE_invL1d((void *)symbolPkt[chan][idx], LTESYMBOL2SIZE, CACHE_WAIT);
    #if DEBUG_MODE == 1
    						payloadPtr = (Uint32 *)rxBuffer;
    						for (idx2 = 0; idx2 < (LTESYMBOL2SIZE-16)/4; idx2 ++)
    						{
    							if (payloadPtr[idx2] != idx2 + (chan << 20))
    							{
    								testpass = 0; testcheck++;
    							}
    							idx1++;
    						}
    #else
    						payloadPtr = (Complex16 *)rxBuffer;
    						for (idx2 = 0; idx2 < (LTESYMBOL2SIZE-16)/4; idx2 ++)
    						{
    							getcomplex(&sampleCheck,idx1);
    								if ((payloadPtr[idx2].re != sampleCheck.re) || (payloadPtr[idx2].im != sampleCheck.im ))
    							{
    								testpass = 0; testcheck++;
    							}
    							idx1++;
    						}
    #endif
    					}
    					Qmss_queuePushDesc(aifObj.pktDmaConfig.rxFqAxC[chan], (Uint32*) symbolPkt[chan][idx]);
    
    				}
    				printf(" Test a) Monolithic Packet Data Recv: on chan: %d are :%d \n", chan, rx_count);
    			}
    
    			if (testpass == 1) {
    				printf(" Test a) Monolithic Packet Data Send/Recv: PASS on channel: %d \n", chan);
    				//testcheck = 0;
    			} else {
    				printf(" Test a) Monolithic Packet Data Send/Recv: FAIL\n");
    			}
    
    			/* read the descriptor counts of the Monolithic queues. */
    			value =0;
    			for (i =0 ; i< nbchanneltotal; i++) {
    				value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txQAxC[i]);
    			}
    			if (value != 0) printf(" Test b1) Monolithic Packet Tx Descriptor Counts:%d FAIL\n",value);
    			else printf(" Test b1) Monolithic Packet Tx Descriptor Counts:%d PASS\n",value);
    			value =0;
    			for (i =0 ; i< nbchanneltotal; i++) {
    				value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.txFqAxC[i]); // channel0
    			}
    			if (value != nbchanneltotal*NBSYMBOL*2) printf(" Test b2) Monolithic Packet Tx Complete Descriptor Counts:%d FAIL\n",value);
    			else printf(" Test b2) Monolithic Packet Tx Complete Descriptor Counts:%d PASS\n",value);
    			value =0;
    			for (i =0 ; i< nbchannelSuperPacket; i++) {
    				value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxQAxC[i]);
    			}
    			if (value != 0) printf(" Test b3) Monolithic Packet Rx Descriptor Counts:%d FAIL\n",value);
    			else printf(" Test b3) Monolithic Packet Rx Descriptor Counts:%d PASS\n",value);
    			value =0;
    			for (i =0 ; i< nbchannelSuperPacket; i++) {
    				value += Qmss_getQueueEntryCount(aifObj.pktDmaConfig.rxFqAxC[i]);
    			}
    			if (value != nbchannelSuperPacket*NBSYMBOL*2) printf(" Test b4) Monolithic Packet Rx Free Descriptor Counts:%d FAIL\n",value);
    			else printf(" Test b4) Monolithic Packet Rx Free Descriptor Counts:%d PASS\n",value);
    
    			if (pktCount == 0) {
    				printf(" CPRI Fast C&M for WCDMA: FAIL\n");
    				testcheck++;
    			}
    
    			printf("Number of control packets received: %d\n", pktCount);
    
    			UTILS_doCleanup(&aifObj,TRIG_TIMER);
    
    
    
    			if (printexceptions == 1)
    			{
    			   	AIF_printException(&aifObj);
    			}
    
    			printf("\nEnding %s test\n", testObjTab[ntest].name);
     	    }
        }
    
        printf("Test: ending AIF2 LTE 20Mhz RF test \n");
    
        if (testcheck == 1) {
               testcheck = 0;
               printf("All tests have passed\n");
        } else {
               printf("Some tests have failed\n");
        }
    
        return (0);
    }
    
    ////////////
    
    

    Please try to use this one in your environment.

    Best Rgds/Seb.

  • Hi Seb,

                Thanks for reply. I will surely try the file you sent. Wanted to check is there anything missing on my part [configuration/settings/] in getting the original LteRelayTest example FastCM working. Please let me know.

    Thanks

    RC Reddy

  • Hi Seb,

    We're also trying to bring CPRI C&M up and running, in this context, we wanted
    to know where do we get the mentioned aif2 LLD version (1.0.0.6). Currently we
    are working with the latest BIOS MCSDK Build 2.0.9.21 which includes only the
    version 1.0.0.2 of the aif LLD driver.

    kind regards

    Matthias

  • Hi,

    Here is the package 1.0.0.6. You can untar it in .\pdk_C6670_1_0_0_21\packages.
    4075.aif2_C6670_1_0_0_6.tar

    Best Rgds/Seb.

  • Hi,
    Please note we are fixes issues when fastcm is used together with lte traffic.
    Once we are done with this work, I'll push an aif2 lld update.
    Best Rgds/Seb.

  • ok,

         now i understood. So it never even worked for you guys also. basically in simple statement, the project is having bug in it. Thanks for reply.

    Thanks

    RC Reddy

  • Hi,

    We have now published TCI6614 usage note 24 or C6670 usage note 26 describes some hardware (HW) limitation and restriction of the AIF2 Fast Ethernet CPRI control word channel operation. This includes one HW limitation about Fast Ethernet SSD (Start of Stream Delimiter) handling. This usage note also explains the HW restrictions of 4B5B encoded data nibble level swapping, Hyperframe boundary delimitation and Ethernet packet CRC32 usage.

    Here is an AIF2LLD engineering update demoing the SW workarounds for fastCM. The example is located here: .\ti\drv\aif2\test\cprifastcm

    You'll find in this package a README file describing how to update AIF2LLD in your environment and how to generate the test examples: 3247.AIF2LLD_C6670_1_0_0_16_prelim.zip

    The test logs in loopback mode from DSP Core 0 are:

    Beginning AIF2 LTE RF tests:
    test: LTE_20MHZ_FASTCM
    AIF CPRI mode
    link 0 runs at 4x rate
    outbound data type: DL
    outbound data width: 15 bit
    inbound data type: DL
    inbound data width: 15 bit
    link 1 is disabled
    link 2 is disabled
    link 3 is disabled
    link 4 is disabled
    link 5 is disabled
    Sent counter =112 Rcvd Conter =111
    Number of monolithic packets received in RX queue channel0: 14
    Number of monolithic packets in TX free queue for channel0: 14
    Number of monolithic packets received in RX queue channel1: 14
    Number of monolithic packets in TX free queue for channel1: 14
    Test a) Monolithic Packet Data Recv: on chan: 0 are :14
    Test a) Monolithic Packet Data Recv: on chan: 1 are :14
    Test a) Monolithic Packet Data Send/Recv: PASS on channel: 2
    Test b1) Monolithic Packet Tx Descriptor Counts:0 PASS
    Test b2) Monolithic Packet Tx Complete Descriptor Counts:28 PASS
    Test b3) Monolithic Packet Rx Descriptor Counts:0 PASS
    Test b4) Monolithic Packet Rx Free Descriptor Counts:28 PASS
    Number of control packets Fast CM transmitted: 112
    Number of control packets Fast CM received: 111
    Ending LTE_20MHZ_FASTCM test
    Test: ending AIF2 LTE 20Mhz RF test
    All tests have passed
    End of Program!!
  • Hi Seb,

    I was trying to run the above mentioned project and faced the issue when 2 links (LINK 0 , LINK 1) enabled together

    So do I need to do some more configuration in the AIF2 driver for running the two links at 4x CPRI rate for AxC (I/Q) and one channel (Channel No 124) for fast Ethernet CPRI C&M.

    I got the following error when I ran two links (link 0, link 1) together.

    [C66xx_0] Beginning AIF2 LTE RF tests:

    test: LTE_20MHZ_FASTCM

    AIF CPRI mode

    link 0 runs at 4x rate

    outbound data type: DL

    outbound data width: 15 bit

    inbound data type: DL

    inbound data width: 15 bit

    link 1 runs at 4x rate

    outbound data type: DL

    outbound data width: 15 bit

    inbound data type: DL

    inbound data width: 15 bit

    link 2 is disabled

    link 3 is disabled

    link 4 is disabled

    link 5 is disabled

    ti.sysbios.gates.GateMutex: line 97: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details.

    xdc.runtime.Error.raise: terminating execution

    Thanks

    Himanshu 

  • Hi,


    I tried to run CPRI C&M project using and EVM6670/6614 and it worked fine however when i ran it on SCBP SERDES loopback doesn't seem to be working so does SCBP SERDES supports loopback of Control and Data(I/Q) and if it works then what other configuration need to be done?

    I am getting the SOP & EOP error in case of SCBP and not receiving any packet in Rx queue.

    Waiting for your reply.

    Thanks

    Himanshu 

  • Hi,


    I am trying to do the same but without Software workaround as i have PG2.0 Silicon of TMS320C6670 and with 4b5b bit reversal code without any success. Do you have a working example for PG2 that removes software workaround?

    I have pasted code from our example for your reference.

       Uint32 uiPD_LK_PACK_CPRI_REG;

       // Fast C&M Ethernet configuration
    #ifdef FAST_CANDM_WORKAROUND
       PdLinkSetup.CpriEnetStrip = FALSE;        // Enable Ethernet strip for Fast C&M channel
       PdLinkSetup.CpriCwNullDelimitor = 0xFF;    //4B/5B idle character
       PdLinkSetup.CpriCwPktDelimitor[cw_pack_chan] = CSL_AIF2_CW_DELIM_NULLDELM;    //Manual 4B/5B idle
       PdLinkSetup.bEnableCpriCrc[cw_pack_chan] = FALSE;    // Disable CRC for Ethernet
    #else
       PdLinkSetup.CpriEnetStrip = TRUE;    // Enable Ethernet strip for Fast C&M channel
       PdLinkSetup.CpriCwPktDelimitor[cw_pack_chan] = CSL_AIF2_CW_DELIM_4B5B;    //Ethernet 4b/5b
       PdLinkSetup.PdCpriCrcType[cw_pack_chan] = CSL_AIF2_CRC_32BIT;    // Ethernet CRC is 32-bit
       PdLinkSetup.bEnableCpriCrc[cw_pack_chan] = TRUE;    // Enable CRC for Ethernet

       if(gLink == CSL_AIF2_LINK_0)
           uiPD_LK_PACK_CPRI_REG=0x1f60008;
       else if(gLink == CSL_AIF2_LINK_1)
           uiPD_LK_PACK_CPRI_REG=0x1f60808;
       else
           uiPD_LK_PACK_CPRI_REG=0x1f61008;

       *((Uint32 *)uiPD_LK_PACK_CPRI_REG) = (0x11) << cw_pack_chan; // Link2 allow bitswapping prior to and after 4B/5B encode/decode

    Kind Regards,

    Piyush