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.

TCI6487's EDMA3 copying data error

Hi everybody,

       I'm currently working with the TCI6487. But I have got a problem when using EDMA3 copys WCDMA data from AIF data buffer to L2M.     

      The problem is that every 8th chip is in the wrong location, as follows:

     Data in DSP memory:

      [chip0] [chip1] [chip2] [chip3] [chip4] [chip5] [chip6] [chip7]
      [chip8]..                                                                             [chip15]
      [chip16] ...                                                                         [chip23]
      [chip24] ...                                                                         [chip31]   
      [chip32] ...                                                                         [chip39]

     With the problem, the [chip7] is moving to the [chip39],   [chip15] is appeared at [chip47] ...

     The testing result of self adding stream as follows:

      When this problem happened:

      28443 28444 28445 28446 28447 28448 28449 28418 --
      28451 28452 28453 28454 28455 28456 28457 28426     |
      28459 28460 28461 28462 28463 28464 28465 28434     | Data wrong here
      28467 28468 28469 28470 28471 28472 28473 28442     | 
      28475 28476 28477 28478 28479 28480 28481 28450 <-  
      28483 28484 28485 28486 28487 28488 28489 28458 
      28491 28492 28493 28494 28495 28496 28497 28466 --     
      28499 28500 28501 28502 28503 28504 28505 28474     | 
      28507 28508 28509 28510 28511 28512 28513 28482     | Data wrong here 
      28515 28516 28517 28518 28519 28520 28521 28490     | 
      28523 28524 28525 28526 28527 28528 28529 28498 <-
      28531 28532 28533 28534 28535 28536 28537 28506

     The right condition:

      28443 28444 28445 28446 28447 28448 28449 28450 
      28451 28452 28453 28454 28455 28456 28457 28458 
      28459 28460 28461 28462 28463 28464 28465 28466 
      28467 28468 28469 28470 28471 28472 28473 28474 
      28475 28476 28477 28478 28479 28480 28481 28482 
      28483 28484 28485 28486 28487 28488 28489 28490 
      28491 28492 28493 28494 28495 28496 28497 28498 
      28499 28500 28501 28502 28503 28504 28505 28506 
      28507 28508 28509 28510 28511 28512 28513 28514 
      28515 28516 28517 28518 28519 28520 28521 28522 
      28523 28524 28525 28526 28527 28528 28529 28530 
      28531 28532 28533 28534 28535 28536 28537 28538

     The configuration of EDMA3:

     Working on AB-Mode

      ACNT = 16
      BCNT = 8
      CNT  = 2560/8 = 320
      SrcBidx = 16
      DstBidx = 2560 * 4
      SrcCidx = 4 * 8 * 16
      DstCidx = 16

      The Option configuration see the annex(aif_edma.c ).

     Data in AIF data buf & L2M :

    There are four streams in the aif  data buf, and every stream has two samples.

     

/*
Configure EDMA for CS data for an AIF link specified by linkIndex
EDMA for CS data transfer should be triggered by FSync events and
auto-reloaded based on ping-pong mechnism
every link need two working channels for inbound and outbound CS antenna data
//////firstCsEDMAChannel for outbound CS antenna data
//////firstCsEDMAChannel+1 for inbound CS antenna data
every working channel need two reload PaRAM for ping-pong operation
//////firstReloadPaRAM    for outbound ping reload for CS antenna data
//////firstReloadPaRAM+1  for outbound pong reload for CS antenna data
//////firstReloadPaRAM+2 for inbound ping reload for CS antenna data
//////firstReloadPaRAM+3 for inbound pong reload for CS antenna data
if CPRI control word transfer is enabled, the CS data EDMA will chain to CPRI control EDMA
firstCpriControlEDMAChannel is the outbound CPRI control channel
firstCpriControlEDMAChannel+1 is the inbound CPRI control channel
*/
void ConfigAifCsEdmaChannel(Uint32 linkIndex, Uint32 firstCsEDMAChannel,
                            Uint32 firstCpriControlEDMAChannel, Uint32 firstReloadPaRAM)
{
    Uint32 uiPaRAMBaseAddr= (Uint32)Edma3CcRegs->PARAMSET;
    CSL_Edma3ParamSetup myParamSetup;
    Uint32 outboundEDMAChannel= firstCsEDMAChannel;
    Uint32 inboundEDMAChannel= firstCsEDMAChannel+1;

    /*----inbound EDMA configuration AIF -> DSP ----*/
    //Configure option
    if (CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode&&
            CSL_AIF_LINK_PROTOCOL_CPRI==aifProtocol)
    {
    	  //ZTEsec using this option   ---liwen 
        myParamSetup.option= CSL_EDMA3_OPT_MAKE(
                                 CSL_EDMA3_ITCCH_DIS, 	/*Disable intermediate chaining to trigger CPRI control channel*/
                                 CSL_EDMA3_TCCH_DIS, 	/*Disable final chaining to trigger CPRI control channel*/
                                 CSL_EDMA3_ITCINT_DIS,
                                 CSL_EDMA3_TCINT_EN, 	/*enable interrupt*/
                                 firstCpriControlEDMAChannel+1, 	/*set TCC= CPRI control channel for chaining*/
                                 CSL_EDMA3_TCC_NORMAL,
                                 CSL_EDMA3_FIFOWIDTH_NONE,
                                 CSL_EDMA3_STATIC_DIS,
                                 CSL_EDMA3_SYNC_AB,
                                 CSL_EDMA3_ADDRMODE_INCR,
                                 CSL_EDMA3_ADDRMODE_INCR);
    }
    else
    {
        myParamSetup.option= CSL_EDMA3_OPT_MAKE(
                                 CSL_EDMA3_ITCCH_DIS,
                                 CSL_EDMA3_TCCH_DIS,
                                 CSL_EDMA3_ITCINT_DIS,
                                 CSL_EDMA3_TCINT_EN, 	/*enable interrupt*/
                                 inboundEDMAChannel, 	/*set TCC= own channel number*/
                                 CSL_EDMA3_TCC_NORMAL,
                                 CSL_EDMA3_FIFOWIDTH_NONE,
                                 CSL_EDMA3_STATIC_DIS,
                                 CSL_EDMA3_SYNC_AB,
                                 CSL_EDMA3_ADDRMODE_INCR,
                                 CSL_EDMA3_ADDRMODE_INCR);
    }

    /*calculate the address in AIF RAM for a link, the AIF RAM is orgonized as following
    0xA000_0000 �C 0xA07f_FFFF R/W Inbound Circuit Switched RAM Link 0-1
    0xA080_0000 �C 0xA0FF_FFFF R/W Inbound Circuit Switched RAM Link 2-3
    0xA100_0000 �C 0xA17F_FFFF R/W Inbound Circuit Switched RAM Link 4-5
    0xA180_0000 �C 0xA1FF_FFFF �C Reserved
    0xA200_0000 �C 0xA27F_FFFF R/W Outbound Circuit Switched RAM Link 0-1
    0xA280_0000 �C 0xA2FF_FFFF R/W Outbound Circuit Switched RAM Link 2-3
    0xA300_0000 �C 0xA37F_FFFF R/W Outbound Circuit Switched RAM Link 4-5
    */
    myParamSetup.srcAddr=  CSL_AIF_0_DATA+
                           linkIndex*AIF_CS_DATA_BLOCK_SIZE;

    //ACNT=16 for 4 chips worth of data, BCNT= (burstchips(equal to 8)/4) * (stream numbers) = 8/4 * 4 = 8
    myParamSetup.aCntbCnt= CSL_EDMA3_CNT_MAKE (16,
                           8);//aifConfig[linkIndex].inBurstSizeInChips/4*aifConfig[linkIndex].streamNumber);
    myParamSetup.dstAddr=
        GLOBAL_ADDR(antennaAxcData[0].InboundAntennaPingS0);

    /*
    for DL data type, BINDX should jump to the next stream
    for UL_RSA data type, BINDX should jump to the next sample, and then next stream, sample 0
    store in the first half of the buffer, second sample is stored in the second half of the buffer
    */
    if (CSL_AIF_LINK_DATA_TYPE_DL==aifConfig[linkIndex].inboundDataType)
        //Dest BINDX= ANT_BUF_SIZE_IN_CHIPS*4 jump to next stream
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(16, ANT_BUF_SIZE_IN_CHIPS*4);
    else
        //Dest BINDX= ANT_BUF_SIZE_IN_CHIPS*2 jump to next sample
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(16, (ANT_BUF_SIZE_IN_CHIPS*4));

    //Link working PaRAM -> pong PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+3)<<5),
                                  aifConfig[linkIndex].inBurstSizeInChips/4 * 4);//aifConfig[linkIndex].streamNumber);

    //CINDX should jump to next burst
    myParamSetup.srcDstCidx= CSL_EDMA3_CIDX_MAKE(4* aifConfig[linkIndex].inBurstSizeInChips* 16, 16);

    //CCNT= number of burst
    myParamSetup.cCnt= ANT_BUF_SIZE_IN_CHIPS/aifConfig[linkIndex].inBurstSizeInChips;

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, inboundEDMAChannel);

    //configure inbound reload ping PaRAM, same configuration as working PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+2);

    //configure inbound reload pong PaRAM
    myParamSetup.dstAddr= GLOBAL_ADDR(antennaAxcData[0].InboundAntennaPongS0);

    //Link pong PaRAM -> ping PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+2)<<5),
                                  aifConfig[linkIndex].inBurstSizeInChips/4 * 4);//aifConfig[linkIndex].streamNumber);

    myParamSetup.option= CSL_EDMA3_OPT_MAKE(
                             CSL_EDMA3_ITCCH_DIS, 	/*Disable intermediate chaining to trigger CPRI control channel*/
                             CSL_EDMA3_TCCH_DIS, 	  /*Disable final chaining to trigger CPRI control channel*/
                             CSL_EDMA3_ITCINT_DIS,
                             CSL_EDMA3_TCINT_EN, 	/*enable interrupt*/
                             firstCpriControlEDMAChannel+2, 	/*set TCC= CPRI control channel for chaining*/
                             CSL_EDMA3_TCC_NORMAL,
                             CSL_EDMA3_FIFOWIDTH_NONE,
                             CSL_EDMA3_STATIC_DIS,
                             CSL_EDMA3_SYNC_AB,
                             CSL_EDMA3_ADDRMODE_INCR,
                             CSL_EDMA3_ADDRMODE_INCR);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+3);

    //Enable channel event
    if (inboundEDMAChannel<32) 	//Edma channel is 0~31
        Edma3CcRegs->EESR= (1<<inboundEDMAChannel);
    else 		//Edma channel is 32~63
        Edma3CcRegs->EESRH= (1<<(inboundEDMAChannel-32));

    //Enable channel interrupt
    if (CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode&&
            CSL_AIF_LINK_PROTOCOL_CPRI==aifProtocol)
    {	/*TCC= CPRI control channel for chaining*/
        if ((firstCpriControlEDMAChannel+1)<32)
        { 	//Edma channel is 0~31
            Edma3CcRegs->IESR= (1<<(firstCpriControlEDMAChannel+1));
            Edma3CcRegs->IESR= (1<<(firstCpriControlEDMAChannel+2));
        }
        else 		//Edma channel is 32~63
        {
            Edma3CcRegs->IESRH= (1<<((firstCpriControlEDMAChannel+1)-32));
            Edma3CcRegs->IESRH= (1<<((firstCpriControlEDMAChannel+2)-32));
        }
    }
    else
    {
        if (inboundEDMAChannel<32) 	//Edma channel is 0~31
            Edma3CcRegs->IESR= (1<<inboundEDMAChannel);
        else 		//Edma channel is 32~63
            Edma3CcRegs->IESRH= (1<<(inboundEDMAChannel-32));
    }
}

/*
Configure EDMA for CPRI control words for an AIF link specified by "linkIndex"
EDMA for CPRI control word transfer should be triggered/chained
by the completion event of the EDMA for CS data transfer
every link need two working channels for inbound and outbound CPRI control word
fisrtCpriControlEDMAChannel for outbound CPRI control word
fisrtCpriControlEDMAChannel+1 for inbound CPRI control word
every working channel need 4 reload PaRAM for ping-pong operation for minimum 1x rate
firstReloadPaRAM+0 for outbound ping reload for CPRI control word
firstReloadPaRAM+1 for outbound pong reload for CPRI control word
firstReloadPaRAM+2 for outbound ping reload for CPRI control word
firstReloadPaRAM+3 for outbound pong reload for CPRI control word
firstReloadPaRAM+4 for inbound ping reload for CPRI control word
firstReloadPaRAM+5 for inbound pong reload for CPRI control word
firstReloadPaRAM+6 for inbound ping reload for CPRI control word
firstReloadPaRAM+7 for inbound pong reload for CPRI control word
*/
void ConfigAifCpriControlEdmaChannel(Uint32 linkIndex, Uint32 firstCsEDMAChannel,
                                     Uint32 firstCpriControlEDMAChannel, Uint32 firstReloadPaRAM)
{
    Uint32 uiPaRAMBaseAddr= (Uint32)Edma3CcRegs->PARAMSET;
    Uint32 outboundEdmaSyncMode, inboundEdmaSyncMode;
    Uint16 aCnt, bCnt;
    CSL_Edma3ParamSetup myParamSetup;
    Uint32 outboundCpriControlEDMAChannel= firstCpriControlEDMAChannel;
    Uint32 inboundCpriControlEDMAChannel= firstCpriControlEDMAChannel+1;

    /*----outbound EDMA configuration DSP -> AIF ----*/

    /*since ACNT<=16 for CPRI control word transfer, if burst=8chips and linkrate=4,
    the minimal data unit size is 32 byte, so SYNC_AB should be used under this case*/
    if (8==aifConfig[linkIndex].outBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
        outboundEdmaSyncMode= CSL_EDMA3_SYNC_AB;
    else
        outboundEdmaSyncMode= CSL_EDMA3_SYNC_A;

    //Configure option
    myParamSetup.option= CSL_EDMA3_OPT_MAKE(
                             CSL_EDMA3_ITCCH_DIS,
                             CSL_EDMA3_TCCH_DIS,
                             CSL_EDMA3_ITCINT_DIS,
                             CSL_EDMA3_TCINT_EN, 	/*enable interrupt*/

                             /*normally, TCC = own channel number, but  becasue the TCC number of CS channel= CPRI control channel number
                             for chaining, so, here set the TCC of the CPRI control channel = CS channel number*/
                             firstCsEDMAChannel,
                             CSL_EDMA3_TCC_NORMAL,
                             CSL_EDMA3_FIFOWIDTH_NONE,
                             CSL_EDMA3_STATIC_DIS,
                             outboundEdmaSyncMode,
                             CSL_EDMA3_ADDRMODE_INCR,
                             CSL_EDMA3_ADDRMODE_INCR);

    myParamSetup.srcAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiOutboundCPRIControlPingBuf);


    if (8==aifConfig[linkIndex].outBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        /*ACNT=16, BCNT=2,  because minimal data unit is 32 bytes for burst=8chips and linkrate=4,
        SYNC_AB should be used for this case*/
        aCnt= 16;
        bCnt= 2;
        myParamSetup.aCntbCnt= CSL_EDMA3_CNT_MAKE (16, 2);
    }
    else
    {
        /*SYNC_A should be used for this case, every trigger transfer control word for burst chips, so
        ACNT=burst size * rate; ACNT*BCNT should be 16 bytes*/
        aCnt= aifConfig[linkIndex].outBurstSizeInChips*aifConfig[linkIndex].linkRate;
        bCnt= 16/aCnt;
    }
    myParamSetup.aCntbCnt= CSL_EDMA3_CNT_MAKE (aCnt, bCnt);

    /*calculate the address in AIF control RAM for a link, the AIF control RAM is orgonized as following
    0xA7000000		Outbound CPRI Control Word RAM for link0
    0xA7000800		Outbound CPRI Control Word RAM for link1
    0xA7001000		Outbound CPRI Control Word RAM for link2
    0xA7001800		Outbound CPRI Control Word RAM for link3
    0xA7002000		Outbound CPRI Control Word RAM for link4
    0xA7002800		Outbound CPRI Control Word RAM for link5	*/
    myParamSetup.dstAddr= AIF_CPRI_CONTROL_OUT_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE;

    if (8==aifConfig[linkIndex].outBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        //source BINDX= ACNT= 16, because the memory is linearly accessed
        //dst BINDX= 32, because the CPRI control RAM has only 16 valid byte in every 32 bytes space
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(16, 32);
    }
    else
    {
        //source BINDX= ACNT, because the memory is linearly accessed
        //dst BINDX= ACNT, because ACNT<=16 bytes
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(aCnt, aCnt);
    }

    //Link working PaRAM -> pong PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+1)<<5), bCnt);

    if (8==aifConfig[linkIndex].outBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        //source CINDX= ACNT*BNCT=32, because SYNC_AB is used and the memory is linearly accessed
        //dst CINDX= 64, because the CPRI control RAM has only 16 valid byte in every 32 bytes space
        myParamSetup.srcDstCidx= CSL_EDMA3_CIDX_MAKE(32, 64);
    }
    else
    {
        //source CINDX= ACNT, because SYNC_A is used and the memory is linearly accessed
        //dst CINDX= ACNT+16, because SYNC_A is used and need to skill 16 unused bytes
        myParamSetup.srcDstCidx= CSL_EDMA3_CIDX_MAKE(aCnt, aCnt+16);
    }

    //ACNT*BCNT*CCNT= bytes for one hyper frame (256 chips * linkRate)
    myParamSetup.cCnt= 256*aifConfig[linkIndex].linkRate/(aCnt*bCnt);

    /*because of the 16 bytes re-order of the CPRI control word RAM,
    outbound EDMA may need be advanceed to make sure 16 byte are ready in the RAM.
    Here, make the first DMA transfer less data, thus the following EDMA will be advanceded.
    This result in error data in first control hyper frame, which is neglectable */
    if (aCnt<16)
        myParamSetup.cCnt-=1; /*CCNT-1 to advance following EDMA for 16 bytes*/

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, outboundCpriControlEDMAChannel);

    //ACNT*BCNT*CCNT= bytes for one hyper frame (256 chips * linkRate)
    myParamSetup.cCnt= 256*aifConfig[linkIndex].linkRate/(aCnt*bCnt);

    //configure outbound reload ping PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM);

    //configure outbound reload PaRAM
    //the next transfer souce is the pong buffer in the DSP memory
    myParamSetup.srcAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiOutboundCPRIControlPongBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)
    for 1x rate, the CPRI control RAM contains 4 hyper frame
    for 2x rate, the CPRI control RAM contains 2 hyper frame
    for 4x rate, the CPRI control RAM contains 1 hyper frame
    */
    myParamSetup.dstAddr= AIF_CPRI_CONTROL_OUT_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2)&0x7FF);

    //Link pong PaRAM -> ping PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+2)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+1);

    //configure outbound reload PaRAM
    //the next transfer souce is the ping buffer in the DSP memory
    myParamSetup.srcAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiOutboundCPRIControlPingBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)*/
    myParamSetup.dstAddr= AIF_CPRI_CONTROL_OUT_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2*2)&0x7FF);

    //Link ping PaRAM -> pong PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+3)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+2);

    //configure outbound reload PaRAM
    //the next transfer souce is the pong buffer in the DSP memory
    myParamSetup.srcAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiOutboundCPRIControlPongBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)*/
    myParamSetup.dstAddr= AIF_CPRI_CONTROL_OUT_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2*3)&0x7FF);

    //Link pong PaRAM -> ping PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+3);

    //Enable channel event
    if (outboundCpriControlEDMAChannel<32) 	//Edma channel is 0~31
        Edma3CcRegs->EESR= (1<<outboundCpriControlEDMAChannel);
    else 		//Edma channel is 32~63
        Edma3CcRegs->EESRH= (1<<(outboundCpriControlEDMAChannel-32));

    //Enable channel interrupt
    /*TCC of the CPRI control channel = CS channel number*/
    if (firstCsEDMAChannel<32) 	//Edma channel is 0~31
        Edma3CcRegs->IESR= (1<<firstCsEDMAChannel);
    else 		//Edma channel is 32~63
        Edma3CcRegs->IESRH= (1<<(firstCsEDMAChannel-32));

    /*----inbound EDMA configuration AIF -> DSP ----*/

    /*since ACNT<=16 for CPRI control word transfer, if burst=8chips and linkrate=4,
    the minimal data unit size is 32 byte, so SYNC_AB should be used under this case*/
    if (8==aifConfig[linkIndex].inBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
        inboundEdmaSyncMode= CSL_EDMA3_SYNC_AB;
    else
        inboundEdmaSyncMode= CSL_EDMA3_SYNC_A;

    //Configure option
    myParamSetup.option= CSL_EDMA3_OPT_MAKE(
                             CSL_EDMA3_ITCCH_DIS,
                             CSL_EDMA3_TCCH_DIS,
                             CSL_EDMA3_ITCINT_DIS,
                             CSL_EDMA3_TCINT_EN, 	/*enable interrupt*/

                             /*normally, TCC = own channel number, but  becasue the TCC number of CS channel= CPRI control channel number for chaining,
                             so, here set the TCC of the CPRI control channel = CS channel number*/
                             firstCsEDMAChannel+1,
                             CSL_EDMA3_TCC_NORMAL,
                             CSL_EDMA3_FIFOWIDTH_NONE,
                             CSL_EDMA3_STATIC_DIS,
                             inboundEdmaSyncMode,
                             CSL_EDMA3_ADDRMODE_INCR,
                             CSL_EDMA3_ADDRMODE_INCR);

    myParamSetup.srcAddr= AIF_CPRI_CONTROL_IN_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE;

    if (8==aifConfig[linkIndex].inBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        /*ACNT=16, BCNT=2,  because minimal data unit is 32 bytes for burst=8chips and linkrate=4
        SYNC_AB should be used for this case*/
        aCnt= 16;
        bCnt= 2;
        myParamSetup.aCntbCnt= CSL_EDMA3_CNT_MAKE (16, 2);
    }
    else
    {
        /*SYNC_A should be used for this case, every trigger transfer control word for burst chips, so
        ACNT=burst size * rate; ACNT*BCNT should be 16 bytes, so BCNT= 16/(burst size * rate)*/
        aCnt= aifConfig[linkIndex].inBurstSizeInChips*aifConfig[linkIndex].linkRate;
        bCnt= 16/aCnt;
    }
    myParamSetup.aCntbCnt= CSL_EDMA3_CNT_MAKE (aCnt, bCnt);

    /*calculate the address in CPRI control RAM for a link, the CPRI control RAM is orgonized as following
    0xA6000000		Inbound CPRI Control Word RAM for link0
    0xA6000800		Inbound CPRI Control Word RAM for link1
    0xA6001000		Inbound CPRI Control Word RAM for link2
    0xA6001800		Inbound CPRI Control Word RAM for link3
    0xA6002000		Inbound CPRI Control Word RAM for link4
    0xA6002800		Inbound CPRI Control Word RAM for link5
    */
    myParamSetup.dstAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiInboundCPRIControlPingBuf);

    if (8==aifConfig[linkIndex].inBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        //dst BINDX= ACNT= 16, because the memory is linearly accessed
        //source BINDX= 32, because the CPRI control RAM has only 16 valid byte in every 32 bytes space
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(32, 16);
    }
    else
    {
        //dst BINDX= ACNT, because the memory is linearly accessed
        //source BINDX= ACNT, because ACNT<=16 bytes
        myParamSetup.srcDstBidx= CSL_EDMA3_BIDX_MAKE(aCnt, aCnt);
    }

    //Link working PaRAM -> pong PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+5)<<5), bCnt);

    if (8==aifConfig[linkIndex].inBurstSizeInChips&&4==aifConfig[linkIndex].linkRate)
    {
        //dst CINDX= ACNT*BNCT=32, because SYNC_AB is used and the memory is linearly accessed
        //source CINDX= 64, because the CPRI control RAM has only 16 valid byte in every 32 bytes space
        myParamSetup.srcDstCidx= CSL_EDMA3_CIDX_MAKE(64, 32);
    }
    else
    {
        //dst CINDX= ACNT, because SYNC_A is used and the memory is linearly accessed
        //source CINDX= ACNT+16, because SYNC_A is used and need to skill 16 unused bytes
        myParamSetup.srcDstCidx= CSL_EDMA3_CIDX_MAKE(aCnt+16, aCnt);
    }

    //ACNT*BCNT*CCNT= bytes for one hyper frame (256 chips * linkRate)
    myParamSetup.cCnt= 256*aifConfig[linkIndex].linkRate/(aCnt*bCnt);

    /*because of the 16 bytes re-order of the CPRI control word RAM,
    inbound EDMA may need be delayed to make sure 16 byte are ready in the RAM.
    Here, make the first DMA transfer more dummy data, thus the following EDMA
    will be delayed. 	This result in dummy data to be written into the memory space after
    the CPRI control ping buffer, for this test, the memory space after ping buffer is pong
    buffer, so it is OK.*/
    if (aCnt<16)
        myParamSetup.cCnt+=1; /*CCNT+1 to delay the following EDMA for 16 bytes*/

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, inboundCpriControlEDMAChannel);

    //ACNT*BCNT*CCNT= bytes for one hyper frame (256 chips * linkRate)
    myParamSetup.cCnt= 256*aifConfig[linkIndex].linkRate/(aCnt*bCnt);

    //configure inbound reload ping PaRAM, same configuration as working PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+4);

    //configure inbound reload PaRAM
    //the next transfer souce is the pong buffer in the DSP memory
    myParamSetup.dstAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiInboundCPRIControlPongBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)
    for 1x rate, the CPRI control RAM contains 4 hyper frame
    for 2x rate, the CPRI control RAM contains 2 hyper frame
    for 4x rate, the CPRI control RAM contains 1 hyper frame
    */
    myParamSetup.srcAddr= AIF_CPRI_CONTROL_IN_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2)&0x7FF);

    //Link pong PaRAM -> ping PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+6)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+5);

    //configure inbound reload PaRAM
    //the next transfer souce is the ping buffer in the DSP memory
    myParamSetup.dstAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiInboundCPRIControlPingBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)*/
    myParamSetup.srcAddr= AIF_CPRI_CONTROL_IN_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2*2)&0x7FF);

    //Link ping PaRAM -> pong PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+7)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+6);

    //configure inbound reload PaRAM
    //the next transfer souce is the pong buffer in the DSP memory
    myParamSetup.dstAddr= GLOBAL_ADDR(cpriControlBuffer[linkIndex].uiInboundCPRIControlPongBuf);

    /*the next transfer dst is the next CPRI hyper frame buffer in AIF CPRI control RAM(2KB)*/
    myParamSetup.srcAddr= AIF_CPRI_CONTROL_IN_RAM_ADDR+
                          linkIndex*AIF_CPRI_CONTROL_RAM_BLOCK_SIZE+
                          ((256*aifConfig[linkIndex].linkRate*2*3)&0x7FF);

    //Link pong PaRAM -> ping PaRAM
    myParamSetup.linkBcntrld= CSL_EDMA3_LINKBCNTRLD_MAKE(
                                  uiPaRAMBaseAddr+((firstReloadPaRAM+4)<<5), bCnt);

    //copy the PaRAM configuration structure to the real PaRAM
    edmaParamConfig((Uint32 *)&myParamSetup, firstReloadPaRAM+7);

    //Enable channel event
    if (inboundCpriControlEDMAChannel<32) 	//Edma channel is 0~31
        Edma3CcRegs->EESR= (1<<inboundCpriControlEDMAChannel);
    else 		//Edma channel is 32~63
        Edma3CcRegs->EESRH= (1<<(inboundCpriControlEDMAChannel-32));

    //Enable channel interrupt
    /*TCC of the CPRI control channel = CS channel number*/
    if ((firstCsEDMAChannel+1)<32) 	//Edma channel is 0~31
        Edma3CcRegs->IESR= (1<<(firstCsEDMAChannel+1));
    else 		//Edma channel is 32~63
        Edma3CcRegs->IESRH= (1<<((firstCsEDMAChannel+1)-32));

}

/*Reset, clear all PaRAM and registers*/
void ResetEDMA(void)
{
    Uint32 i;
    Uint32 * uiPaRAMBaseAddr= (Uint32 *)Edma3CcRegs->PARAMSET;

    //Clear 64 PaRAM entries, every entry has 8 word
    for (i=0; i<64*8; i++)
        *uiPaRAMBaseAddr++= 0;

    //Clear interrupts and events
    Edma3CcRegs->ECR= 0xFFFFFFFF;
    Edma3CcRegs->ECRH= 0xFFFFFFFF;
    Edma3CcRegs->EECR= 0xFFFFFFFF;
    Edma3CcRegs->EECRH= 0xFFFFFFFF;
    Edma3CcRegs->EMCR = 0xffffffff;
    Edma3CcRegs->EMCRH = 0xffffffff;
    Edma3CcRegs->SECR = 0xffffffff;
    Edma3CcRegs->SECRH = 0xffffffff;
    Edma3CcRegs->ICR= 0xFFFFFFFF;
    Edma3CcRegs->ICRH= 0xFFFFFFFF;
    Edma3CcRegs->IECR= 0xFFFFFFFF;
    Edma3CcRegs->IECRH= 0xFFFFFFFF;

    //Clear EDMA interrupt counter
    for (i=0; i<64; i++)
        EdmaIntCount[i]=0;
}

//Set mask of a EDMA region for "channelNumber" channels from "firstChannel"
void maskRegion(CSL_Edma3CmdDrae* regionMask, Uint32 firstChannel, Uint32 channelNumber)
{
    if (firstChannel+ channelNumber<32)
    {
        regionMask->drae = _set(0, firstChannel,
                                firstChannel+ 	channelNumber-1) ;
        regionMask->draeh = 0;
    }
    else if (firstChannel>=32)
    {
        regionMask->drae = 0 ;
        regionMask->draeh = _set(0, firstChannel-32,
                                 firstChannel+ channelNumber-32-1) ;
    }
    else
    {
        regionMask->drae = _set(0, firstChannel, 31) ;
        regionMask->draeh = _set(0, 0, firstChannel+ channelNumber-32-1) ;
    }

}


/* Setup the EDMA3 module */
void ConfigAifEdma(AifConfig * aifConfig)
{
    int i;
    CSL_Status edmaStat;
    CSL_Edma3CmdDrae            regionMask;

    /*Reset, clear all PaRAM and registers*/
    //ResetEDMA();

    // Module Initialization
    CSL_edma3Init(&Edmacontext);

    // Module Level Open
    hEdmaModule = CSL_edma3Open(&edmaObj,CSL_EDMA3,NULL,&edmaStat);

    /* Module Setup */
    //balance the load between EDMA TC3 ,TC4 and TC5
    for (i= FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA; i< FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA+
            EDMA_CHANNEL_USED_FOR_AIF_CS_DATA; i++)
        dmahwSetup[i].que=(CSL_Edma3Que)(CSL_EDMA3_QUE_0+ i&1); 		//use TC3/TC4 for all CS AIF transfer
    if (CSL_AIF_LINK_PROTOCOL_OBSAI==aifProtocol) 	//configure EDMA for OBSAI PS data
    {
        for (i= FIRST_EDMA_CHANNEL_FOR_AIF_PS_OUT_DATA;
                i< FIRST_EDMA_CHANNEL_FOR_AIF_PS_OUT_DATA+ CSL_AIF_MAX_NUM_LINKS; i++)
            dmahwSetup[i].que= CSL_EDMA3_QUE_5; 		//use TC5 for all PS AIF transfer
        for (i= FIRST_EDMA_CHANNEL_FOR_AIF_PS_IN_DATA;
                i< FIRST_EDMA_CHANNEL_FOR_AIF_PS_IN_DATA+ EDMA_CHANNEL_USED_FOR_AIF_PS_IN_DATA; i++)
            dmahwSetup[i].que= CSL_EDMA3_QUE_5; 		//use TC5 for all PS AIF transfer
    }
    else if (CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode)
    {		//configure EDMA for CPRI control words
        for (i= FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL;
                i< FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL+ EDMA_CHANNEL_USED_FOR_CPRI_CONTROL; i++)
            dmahwSetup[i].que= CSL_EDMA3_QUE_2; 		//use TC5 for CPRI control words AIF transfer
    }
    hwSetup.dmaChaSetup  = &dmahwSetup[0];
    hwSetup.qdmaChaSetup = &qdmahwSetup[0];
    CSL_edma3HwSetup(hEdmaModule, &hwSetup);

    /*normally, TCC = own channel number, but when CPRI control word transfer is enbaled,
    the TCC of CS channel= CPRI control channel number for chaining,
    so, this test sets the TCC of the CPRI control channel = CS channel number*/
    if (CSL_AIF_LINK_PROTOCOL_CPRI==aifProtocol&&
            CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode)
    {
        firstCsTccNumber= FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL;
        firstCpriControlTccNumber= FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA;
    }
    else
    {
        firstCsTccNumber= FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA;
        firstCpriControlTccNumber= FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL;
    }

    /* Setup seperated EDMA interrupt region for AIF CS transfer,
    thus, isolate the EDMA ISR for CS and PS transfer*/
    regionMask.region = CSL_EDMA3_REGION_0 ;
    maskRegion(&regionMask, firstCsTccNumber,
               EDMA_CHANNEL_USED_FOR_AIF_CS_DATA);
    CSL_edma3HwControl(hEdmaModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionMask);

    if (CSL_AIF_LINK_PROTOCOL_OBSAI==aifProtocol) 	//configure EDMA for OBSAI PS data
    {
        /* Setup seperated EDMA interrupt region for AIF PS inbound transfer,
        thus, isolate the EDMA ISR for CS and PS transfer*/
        regionMask.region = CSL_EDMA3_REGION_1 ;
        maskRegion(&regionMask, FIRST_EDMA_CHANNEL_FOR_AIF_PS_IN_DATA,
                   EDMA_CHANNEL_USED_FOR_AIF_PS_IN_DATA);
        CSL_edma3HwControl(hEdmaModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionMask);
    }
    else if (CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode)
    {
        /* Setup seperated EDMA interrupt region for CPRI control words transfer,
        thus, isolate the EDMA ISR for CS,PS and CPRI control words transfer*/
        regionMask.region = CSL_EDMA3_REGION_1 ;
        maskRegion(&regionMask, firstCpriControlTccNumber,
                   EDMA_CHANNEL_USED_FOR_CPRI_CONTROL);
        CSL_edma3HwControl(hEdmaModule,CSL_EDMA3_CMD_DMAREGION_ENABLE, &regionMask);
    }

    //Configure EDMA channel for link 0~5
    for (i=0; i<6; i++)
    {
        if (0==aifConfig[i].linkEnable)
            continue;

        //CS data transfer for every link need two working channel and 4 reloading PaRAM
        ConfigAifCsEdmaChannel(i, FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA+i*2,
                               FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL+i*2 ,FIRST_RELOAD_PaRAM_FOR_AIF+i*4);

        if (CSL_AIF_LINK_PROTOCOL_OBSAI==aifProtocol)
        {
            /*Removed by liwen 2012-05-17*/
#if 0
            //PS outbound EDMA configuration for every link
            ConfigAifPsOutboundEdmaChannel(i, FIRST_EDMA_CHANNEL_FOR_AIF_PS_OUT_DATA+i);
#endif
        }
        else if (CSL_AIF_CPRI_CTRL_WORD_READ_FROM_RAM==cpriCtrlWordMode)
        {
            //CPRI control word transfer for every link need two working channel and maximum 8 reloading PaRAM
            ConfigAifCpriControlEdmaChannel(i, FIRST_EDMA_CHANNEL_FOR_AIF_CS_DATA+i*2,
                                            FIRST_EDMA_CHANNEL_FOR_CPRI_CONTROL+i*2 ,FIRST_RELOAD_PaRAM_FOR_AIF+24+i*8);
        }
    }
    if (CSL_AIF_LINK_PROTOCOL_OBSAI==aifProtocol)
    {
        //Configure EDMA channel for inbound PS (packet-switched) data FIFO 0~2
        for (i=0; i<3; i++)
        {
            /*Removed by liwen 2012-05-17*/
#if 0
            //PS inbound EDMA configuration for every FIFO, need one working channel and two reloading PaRAM
            ConfigAifPsInboundEdmaChannel(i, FIRST_EDMA_CHANNEL_FOR_AIF_PS_IN_DATA+i,
                                          FIRST_RELOAD_PaRAM_FOR_AIF+24+i*2);
#endif
        }
    }
}

   

  • Have you looked at the AIF Data Buffer? 

    Also, have you tried butting a different buffer in memory and tested your EDMA PaRAM configuration?  I don't think anything is wrong with the EDMA configuration but that would simply leave the AIF buffer being incorrect.

    Best Regards,

    Chad