【无标题】vxworks ARM Pl330DMA 数据传输指令流创建

 

/*******************************************************************************
*
* pl330DmaChanMicroCodeCreate - create micro code for dma transfer
*
* This routine create micro code for dma transfer
*
* RETURNS: OK or ERROR if there is an error.
*
* ERRNO: N/A
*/
LOCAL STATUS pl330DmaChanMicroCodeCreate
    (
    VXB_DEVICE_ID       pDev,
    PL330_DMA_CHAN *    pChan
    )
    {
    UINT32                  chan;
    UINT32                  ccr;
    UINT32                  loop0;
    UINT32                  loop1;
    UINT32                  rest;
    UINT8 *                 pBuf;
    UINT32                  loop0Start;
    UINT32                  loop1Start;
    UINT32                  burstSize;
    PL330_DMA_CHAN_PARAM *  pChanParam;

    chan        = pChan->chanNum;
    pChanParam  = pChan->pChanParam;
    pBuf        = pChan->pMicroCodeBuf;
    bzero ((char *)pChan->pMicroCodeBuf, PL330_MICROCODE_SIZE);

    /* switch to 1 byte mode if address not align with burst size */

    if ((pChanParam->srcBurstSize == 1) ||
        (!ALIGNED (pChanParam->srcAddr, pChanParam->srcBurstSize)) ||
        (!ALIGNED (pChanParam->dstAddr, pChanParam->srcBurstSize)))
        {
        burstSize = CCR_BURST_SIZE_1;
        pChanParam->srcBurstSize = 1;
        }
    else if (pChanParam->srcBurstSize == 2)
        {
        burstSize = CCR_BURST_SIZE_2;
        }
    else if (pChanParam->srcBurstSize == 4)
        {
        burstSize = CCR_BURST_SIZE_4;
        }
    else if (pChanParam->srcBurstSize == 8)
        {
        burstSize = CCR_BURST_SIZE_8;
        }
    else if (pChanParam->srcBurstSize == 16)
        {
        burstSize = CCR_BURST_SIZE_16;
        }
    else
        {
        return ERROR;
        }

    ccr = (pChanParam->endianSwapSize |
           CCR_DST_CACHE_CTRL |
           CCR_SRC_CACHE_CTRL |
           CCR_DST_PROT_CTRL |
           CCR_SRC_PROT_CTRL |
           pChanParam->dstInc |
           pChanParam->srcInc |
           CCR_DST_BURST_LEN |
           CCR_SRC_BURST_LEN |
           (burstSize << 15) |
           (burstSize << 1));

    DMAMOV (pBuf, CCR, ccr);                    /* DMAMOV CCR, ccr */
    DMAMOV (pBuf, SAR, pChanParam->srcAddr);    /* DMAMOV SAR, src */
    DMAMOV (pBuf, DAR, pChanParam->dstAddr);    /* DMAMOV DAR, dst */

    loop0 = pChanParam->transferSize / pChanParam->srcBurstSize;

    if (loop0 > MAXLOOP)
        {
        PL330_DMA_DBG_MSG (10, "Too big size! 0x%x\r\n", pChanParam->srcAddr,
                           1, 2, 3, 4, 5);
        return ERROR;
        }
    else
        {
        loop1 = loop0 / 256;
        }

    rest =  pChanParam->transferSize % pChanParam->srcBurstSize;

    if (loop1 > 0)
        {
        DMALP (pBuf, 1, loop1);             /* DMALP loop1 */
        loop1Start = (UINT32)pBuf;
        DMALP (pBuf, 0, 256);               /* DMALP loop0 */
        loop0Start = (UINT32)pBuf;
        if (pChanParam->tansferType != MEM_TO_MEM)
            {
            DMAWFP (pBuf, pChanParam->peripheral);
            }
        DMALD (pBuf);                       /* DMALD */
        DMARMB (pBuf);                      /* DMARMB */
        DMAST (pBuf);                       /* DMAST */
        DMAWMB (pBuf);                      /* DMAWMB */
        DMALPEND (pBuf, 0, loop0Start);     /* DMALPEND loop0 */
        DMALPEND (pBuf, 1, loop1Start);     /* DMALPEND loop1 */
        }

    loop0 = loop0 % 256;
    if (loop0 > 0)
        {
        DMALP (pBuf, 0, loop0);             /* DMALP loop0 */
        loop0Start = (UINT32)pBuf;
        if (pChanParam->tansferType != MEM_TO_MEM)
            {
            DMAWFP (pBuf, pChanParam->peripheral);
            }
        DMALD (pBuf);                       /* DMALD */
        DMARMB (pBuf);                      /* DMARMB */
        DMAST (pBuf);                       /* DMAST */
        DMAWMB (pBuf);                      /* DMAWMB */
        DMALPEND (pBuf, 0, loop0Start);     /* DMALPEND */
        }

    if (rest > 0)
        {
        /* switch to 1 byte mode if transfer size not align with burst size */

        ccr = (pChanParam->endianSwapSize |
               CCR_DST_CACHE_CTRL |
               CCR_SRC_CACHE_CTRL |
               CCR_DST_PROT_CTRL |
               CCR_SRC_PROT_CTRL |
               pChanParam->dstInc |
               pChanParam->srcInc |
               CCR_DST_BURST_LEN |
               CCR_SRC_BURST_LEN |
               (CCR_BURST_SIZE_1 << 15) |
               (CCR_BURST_SIZE_1 << 1));

        DMAMOV (pBuf, CCR, ccr);            /* DMAMOV CCR ccr */
        DMALP (pBuf, 0, rest);              /* DMALP loop0 */
        loop0Start = (UINT32)pBuf;
        if (pChanParam->tansferType != MEM_TO_MEM)
            {
            DMAWFP (pBuf, pChanParam->peripheral);
            }
        DMALD (pBuf);                       /* DMALD */
        DMARMB (pBuf);                      /* DMARMB */
        DMAST (pBuf);                       /* DMAST */
        DMAWMB (pBuf);                      /* DMAWMB */
        DMALPEND (pBuf, 0, loop0Start);     /* DMALPEND */
        }

    DMASEV (pBuf, chan);                    /* DMASEV */
    DMAEND (pBuf);                          /* DMAEND */

    return OK;
    }

                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值