/*
** QDMA Application
*/
void EDMAAppQDMA3Test()
{
    volatile unsigned int index = 0u;
    volatile unsigned int count = 0u;
    EDMA3CCPaRAMEntry paramSet;
    unsigned char data = 0u;
    unsigned int retVal = 0u;
    unsigned int isTestPassed = false;
    unsigned int numEnabled = 0u;
    unsigned int aCount = EDMAAPP_MAX_ACOUNT;
    unsigned int bCount = EDMAAPP_MAX_BCOUNT;
    unsigned int cCount = EDMAAPP_MAX_CCOUNT;
    unsigned int DstBuffAddr = 0u;
    volatile unsigned int opt = 0u;
    unsigned int paramId = 32u;

    /* Initalize source and destination buffers */
    for(count = 0u; count < (aCount * bCount * cCount); count++)
    {
        SrcBuff[count] = data++;
        /*
        ** No need to initialize the destination buffer
        ** as it is being invalidated.
        */
    }

    /* Request DMA channel and TCC */
    retVal = EDMA3RequestChannel(EDMAAPP_EDMACC_BASE_ADDRESS,
                                 EDMAAPP_DMA_CH_TYPE, EDMAAPP_DMA_CH_NUM,
                                 EDMAAPP_DMA_TCC_NUM, EDMAAPP_DMA_EVTQ);

    EDMA3MapQdmaChToPaRAM(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_CH_NUM,
                          &paramId);

    EDMA3SetQdmaTrigWord(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_CH_NUM,
                         EDMA3CC_PARAM_ENTRY_DST);

    /* Registering Callback Function */
    EDMAAppCallbackFxn[EDMAAPP_DMA_TCC_NUM] = &EDMAAppCallback;

    if(TRUE == retVal)
    {
        /* Fill the PaRAM Set with transfer specific information */
        paramSet.srcAddr = (unsigned int)(SrcBuff);
        paramSet.destAddr = (unsigned int)(DstBuff);
        paramSet.aCnt = (unsigned short)aCount;
        paramSet.bCnt = (unsigned short)bCount;
        paramSet.cCnt = (unsigned short)cCount;

        /* Setting up the SRC/DES Index */
        paramSet.srcBIdx = (short)aCount;
        paramSet.destBIdx = (short)aCount;
        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            /* A Sync Transfer Mode */
            paramSet.srcCIdx = (short)aCount;
            paramSet.destCIdx = (short)aCount;
        }
        else
        {
            /* AB Sync Transfer Mode */
            paramSet.srcCIdx = ((short)aCount * (short)bCount);
            paramSet.destCIdx = ((short)aCount * (short)bCount);
        }

        /* Configure the paramset with NULL link */
        paramSet.linkAddr = (unsigned short)0xFFFFu;

        paramSet.bCntReload = (unsigned short)0u;
        paramSet.opt = 0u;

        /* Src & Dest are in INCR modes */
        paramSet.opt &= ~(EDMA3CC_OPT_SAM | EDMA3CC_OPT_DAM);

        /* Program the TCC */
        paramSet.opt |= ((EDMAAPP_DMA_TCC_NUM << EDMA3CC_OPT_TCC_SHIFT)
                         & EDMA3CC_OPT_TCC);

        /* Enable Intermediate & Final transfer completion interrupt */
        paramSet.opt |= (1u << EDMA3CC_OPT_ITCINTEN_SHIFT);
        paramSet.opt |= (1u << EDMA3CC_OPT_TCINTEN_SHIFT);

        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            paramSet.opt &= ~EDMA3CC_OPT_SYNCDIM;
        }
        else
        {
            /* AB Sync Transfer Mode */
            paramSet.opt |= (1u << EDMA3CC_OPT_SYNCDIM_SHIFT);
        }

        opt = paramSet.opt;

        /* Now, write the PaRAM Set. */
        EDMA3QdmaSetPaRAM(EDMAAPP_EDMACC_BASE_ADDRESS, EDMAAPP_DMA_CH_NUM,
                          paramId, &paramSet);
    }

    retVal = EDMA3EnableTransfer(EDMAAPP_EDMACC_BASE_ADDRESS,
                                 EDMAAPP_DMA_CH_NUM, EDMAAPP_DMA_TRIG_MODE);

    /*
    ** Since the transfer is going to happen in Manual mode of EDMA3
    ** operation, we have to 'Enable the Transfer' multiple times.
    ** Number of times depends upon the Mode (A/AB Sync)
    ** and the different counts.
    */
    if(TRUE == retVal)
    {
        /* Need to activate next param */
        if(EDMA3_SYNC_A == EDMAAPP_DMA_SYNC_TYPE)
        {
            numEnabled = bCount * cCount;
        }
        else
        {
            /* AB Sync Transfer Mode */
            numEnabled = cCount;
        }

        for(index = 0u; index < numEnabled; index++)
        {
            IrqRaised = EDMAAPP_IRQ_STATUS_XFER_INPROG;

            if(index == (numEnabled - 1u))
            {
                /**
                ** Since OPT.STATIC field should be SET for isolated QDMA
                ** transfers or for the final transfer in a linked list of QDMA
                ** transfers, do the needful for the last request.
                */
                opt |= EDMA3CC_OPT_STATIC;
                EDMA3QdmaSetPaRAMEntry(EDMAAPP_EDMACC_BASE_ADDRESS, paramId,
                                       EDMA3CC_PARAM_ENTRY_OPT, opt);
            }

            opt |= EDMA3CC_OPT_FWID_8BIT;
            EDMA3QdmaSetPaRAMEntry(EDMAAPP_EDMACC_BASE_ADDRESS, paramId,
                                   EDMA3CC_PARAM_ENTRY_OPT, opt);

            /*
            ** Now trigger the QDMA channel by writing to the Trigger
            ** Word which is set as Destination Address.
            */
            DstBuffAddr = (unsigned int)EDMA3QdmaGetPaRAMEntry(
                 EDMAAPP_EDMACC_BASE_ADDRESS, paramId, EDMA3CC_PARAM_ENTRY_DST);

            EDMA3QdmaSetPaRAMEntry(EDMAAPP_EDMACC_BASE_ADDRESS, paramId,
                                   EDMA3CC_PARAM_ENTRY_DST, DstBuffAddr);

            /* Wait for the Completion ISR. */
            while(EDMAAPP_IRQ_STATUS_XFER_INPROG == IrqRaised)
            {
                /*
                ** Wait for the Completion ISR on Master Channel.
                ** You can insert your code here to do something
                ** meaningful.
                */
            }

            /* Check the status of the completed transfer */
            if(IrqRaised < (int)EDMAAPP_IRQ_STATUS_XFER_INPROG)
            {
                /* Some error occured, break from the FOR loop. */
                ConsoleUtilsPrintf("\r\nQDMA3Test: Event Miss Occured!!!\r\n");

                /* Clear the error bits first */
                EDMA3ClearErrorBits(EDMAAPP_EDMACC_BASE_ADDRESS,
                                    EDMAAPP_DMA_CH_NUM, EDMAAPP_DMA_EVTQ);
                break;
            }
        }
    }

    /* Match the Source and Destination Buffers. */
    if(TRUE == retVal)
    {
        for(index = 0u; index < (aCount * bCount * cCount); index++)
        {
            if(SrcBuff[index] != DstBuff[index])
            {
                isTestPassed = false;
                ConsoleUtilsPrintf("QDMA3Test: Data write-read matching FAILED.\r\n");
                ConsoleUtilsPrintf("The mismatch happened at index : %d\r\n",
                                   ((int)index + 1u));
                break;
            }
        }

        if(index == (aCount * bCount * cCount))
        {
            isTestPassed = true;
            ConsoleUtilsPrintf("QDMA3Test: Data write-read matching PASSED.\r\n");
        }

        /* Free the previously allocated channel. */
        retVal = EDMA3FreeChannel(EDMAAPP_EDMACC_BASE_ADDRESS,
                                  EDMAAPP_DMA_CH_TYPE, EDMAAPP_DMA_CH_NUM,
                                  EDMAAPP_DMA_TRIG_MODE, EDMAAPP_DMA_TCC_NUM,
                                  EDMAAPP_DMA_EVTQ);

        /* Unregister Callback Function */
        EDMAAppCallbackFxn[EDMAAPP_DMA_TCC_NUM] = NULL;

        if(TRUE != retVal)
        {
            ConsoleUtilsPrintf("QDMA3Test: EDMA3_DRV_freeChannel() FAILED.\r\n");
        }
    }

    if(true == isTestPassed)
    {
        ConsoleUtilsPrintf("QDMA3Test PASSED.\r\n");
    }
    else
    {
        ConsoleUtilsPrintf("QDMA3Test FAILED.\r\n");
    }
}
Example #2
0
unsigned int EDMARequestXfer2D( unsigned int trigMode,
                                unsigned int chNum,
                                unsigned int scrAddr,
                                unsigned int dstAddr,
                                unsigned int bnOfScrRow,
                                unsigned int numOfScrColum,
                                unsigned int bnOfDstRow,
                                unsigned int numOfDstColum,
                                unsigned int bnOfRow,
                                unsigned int numOfColum,
                                unsigned int handlerIndex) {

    unsigned int paramid,chtype;

    mdAssert(handlerIndex < 64);
    //scrAddr and destAddr shoud 4bit allign;
    mdAssert((scrAddr&0x3 == 0) && (dstAddr&0x3 == 0));

    if (EDMA3_0_NUM_TC==++evtqueue) {
        evtqueue = 0;
    }

    if (EDMA3_TRIG_MODE_QDMA == trigMode) {
        chtype = EDMA3_CHANNEL_TYPE_QDMA;
        paramid = 64+chNum % 8;
    } else {
        chtype = EDMA3_CHANNEL_TYPE_DMA;
        paramid = chNum;
    }

    EDMA3MapChToEvtQ(EDMA_INST_BASE,chtype,chNum,evtqueue);

    //if QDMA disable the channel to aviod trig when set paRam
    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3DisableTransfer(EDMA_INST_BASE, chNum, EDMA3_TRIG_MODE_IMMEDIATE);
    }

    EDMA3CCPaRAMEntry *paramSet = (EDMA3CCPaRAMEntry *)(EDMA_INST_BASE + EDMA3CC_OPT(paramid));

    paramSet->srcAddr    = (unsigned int)scrAddr;
    paramSet->dstAddr   = dstAddr;

    paramSet->aCnt       = bnOfRow ;
    paramSet->bCnt       = numOfColum;
    paramSet->cCnt       = 1;
    paramSet->opt        = (handlerIndex<<12)|(2 << 8)|(1<<20)|(1<<3)|(1<<2); //set STATIC BIT, A-B SYNC,32BIT WIDTH


    paramSet->srcBIdx    = bnOfScrRow;
    paramSet->srcCIdx    = 0;
    paramSet->destBIdx   = bnOfDstRow;
    paramSet->destCIdx   = 0;
    paramSet->bCntReload = 0x0;
    paramSet->linkAddr   = 0xffff;
    EDMA3EnableTransfer(EDMA_INST_BASE, chNum, trigMode);
    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3SetQdmaTrigWord(EDMA_INST_BASE, chNum, 0);
        paramSet->opt  = paramSet->opt; //trig qdma
    }
    return 1;
}
Example #3
0
/**
 * @brief
 *        在某个固定地址缓冲区和一连续的内存区域间传送数据
 * @param [in] trigMode DMA触发方式
 * -- EDMA3_TRIG_MODE_MANUAL    手动触发
 * -- EDMA3_TRIG_MODE_EVENT     事件出发
 * -- EDMA3_TRIG_MODE_IMMEDIATE  立即出发
 * @param [in] chNum   DMA通道号 \b EDMA3_CHA_XXX
 * @param [in] entryAddr 固定地址缓冲区的地址
 * @param [in] bufAddr   连续的内存区地址
 * @param [in] rwFlag   读写标识
 * -- 1 读
 * -- 0 写
 * @param [in] entryBitWidth 固定缓冲区位宽
 * @param [in] blkSize 每次传送的字节数
 * @param [in] nblks 传送的次数
 * @param [in] handlerIndex
 *        数据传送完成后执行的回调函数索引
 * @return  总是 1
 * @date    2013/6/19
 * @note
 * @code
 * @endcode
 * @pre
 * @see
 */
unsigned int EDMARequestXferWithBufferEntry(unsigned int trigMode,
        unsigned int chNum,
        unsigned int entryAddr,
        unsigned int bufAddr,
        unsigned int rwFlag,
        unsigned int entryBitWidth,
        unsigned int blkSize,
        unsigned int nblks,
        unsigned int handlerIndex) {
    unsigned int paramid, chtype;
    volatile EDMA3CCPaRAMEntry *paramSet;

    mdAssert(handlerIndex < 64);
    //entryAddr should 5bit allign;
    mdAssert((entryAddr&0x1fUL) == 0);
    mdAssert((entryBitWidth == 8) || (entryBitWidth == 16) || (entryBitWidth == 32));
    mdAssert(blkSize%(entryBitWidth/8)==0);

    if (EDMA3_0_NUM_TC == ++evtqueue) {
        evtqueue = 0;
    }

    if (EDMA3_TRIG_MODE_QDMA == trigMode) {
        chtype = EDMA3_CHANNEL_TYPE_QDMA;
        paramid = 64+chNum % 8;
    } else {
        chtype = EDMA3_CHANNEL_TYPE_DMA;
        paramid = chNum;
    }

    EDMA3MapChToEvtQ(EDMA_INST_BASE, chtype, chNum, evtqueue);

    /*if QDMA disable the channel to aviod trig when set paRam*/
    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3DisableTransfer(EDMA_INST_BASE, chNum, EDMA3_TRIG_MODE_IMMEDIATE);
    }

    paramSet = (EDMA3CCPaRAMEntry *)(EDMA_INST_BASE + EDMA3CC_OPT(paramid));

    paramSet->srcAddr    = rwFlag ? entryAddr : bufAddr;
    paramSet->dstAddr    = rwFlag ? bufAddr:  entryAddr;

    unsigned int nbyte = entryBitWidth / 8;
    paramSet->aCnt       = nbyte;
    paramSet->bCnt       = (unsigned short)blkSize / nbyte;
    paramSet->cCnt       = nblks;
    paramSet->opt        = (handlerIndex << 12) |(numberToFwid(entryBitWidth) << 8) |
                           (1 << 20) | (1 << !rwFlag) |(1 << 2); // A-B SYNC,ENABLE INT,32BIT WIDTH

    paramSet->srcBIdx    = rwFlag ? 0 : nbyte;
    paramSet->srcCIdx    = rwFlag ? 0 : (unsigned short)blkSize;
    paramSet->destBIdx   = rwFlag ? nbyte : 0;
    paramSet->destCIdx   = rwFlag ? (unsigned short)blkSize : 0;
    paramSet->bCntReload = 0x0;
    paramSet->linkAddr   = 0xffff;

    EDMA3EnableTransfer(EDMA_INST_BASE, chNum, trigMode);

    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3SetQdmaTrigWord(EDMA_INST_BASE, chNum, 0);
        paramSet->opt  = paramSet->opt; //trig qdma
    }

    return 1;
}
Example #4
0
unsigned int EDMARequestXferArray(unsigned int trigMode,
                                  unsigned int chNum,
                                  unsigned int scrAddr,
                                  unsigned int dstAddr,
                                  unsigned int bytenumber,
                                  unsigned int handleIndex) {
    unsigned int synctype ,paramid,chtype;
    volatile EDMA3CCPaRAMEntry *paramSet;

    mdAssert(handleIndex < 64);
    //scrAddr and destAddr shoud 4bit allign;
    mdAssert((scrAddr&0x3 == 0) && (dstAddr&0x3 == 0));

    if (EDMA3_0_NUM_TC == ++evtqueue) {
        evtqueue = 0;
    }

    if (EDMA3_TRIG_MODE_QDMA == trigMode) {
        chtype = EDMA3_CHANNEL_TYPE_QDMA;
        paramid = 64 + chNum % 8;
    } else {
        chtype = EDMA3_CHANNEL_TYPE_DMA;
        paramid  = chNum;
    }

    EDMA3MapChToEvtQ(EDMA_INST_BASE,chtype,chNum,evtqueue);

    paramSet = (EDMA3CCPaRAMEntry *)(EDMA_INST_BASE + EDMA3CC_OPT(paramid));

    if (bytenumber <= 0xffff) {
        synctype = 0;
    } else {
        synctype = 1;
    }
    if ((1==synctype)&&((bytenumber & 0x3ff)!=0)) {
        return 0; //if bytenumber>0xffff, bytenumber should be multiple of 1k;
    }

    //if QDMA disable the channel to aviod trig when set paRam
    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3DisableTransfer(EDMA_INST_BASE, chNum, EDMA3_TRIG_MODE_IMMEDIATE);
    }

    paramSet->srcAddr    = (unsigned int)scrAddr;
    paramSet->dstAddr   = dstAddr;
    if (0==synctype) {
        paramSet->aCnt      = bytenumber;
        paramSet->bCnt      = 1;
        paramSet->cCnt      = 1;
        paramSet->opt       = (handleIndex<<12)|(2 << 8)|(1<<20)|(1<<3); // set STATIC BIT,A SYNC
        paramSet->srcBIdx   = 0;
        paramSet->destBIdx   = 0;
    } else {
        paramSet->aCnt       = 1024 ;
        paramSet->bCnt       = bytenumber/1024;
        paramSet->cCnt       = 1;
        paramSet->opt        = (handleIndex<<12)|(2 << 8)|(1<<20)|(1<<3)|(1<<2); //set STATIC BIT, A-B SYNC,ENABLE INT,32BIT WIDTH
        paramSet->srcBIdx    = 1024;
        paramSet->destBIdx   = 1024;
    }

    paramSet->srcCIdx    = 0;
    paramSet->destCIdx   = 0;

    paramSet->bCntReload = 0x0;
    paramSet->linkAddr   = 0xffff;

    EDMA3EnableTransfer(EDMA_INST_BASE, chNum, trigMode);

    if (EDMA3_TRIG_MODE_IMMEDIATE == trigMode) {
        EDMA3SetQdmaTrigWord(EDMA_INST_BASE,chNum,0);
        paramSet->opt  = paramSet->opt; //trig qdma
    }
    return 1;
}