⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpc107dma.c

📁 VxWorks系统中DMA控制器驱动部分的源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
                               MPC107_DMA_DMR_CS);            }        else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) == 0)            {            /* This channel is configured for Chained DMA */            /* If Chained DMA is already in progress  */            if ((MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB) != 0)                {                /*                 * Set the channel continue bit to in DMA Mode Register 0                 * to start DMA                 */                dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0);                MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |                                   MPC107_DMA_DMR_CC);                }            /*             * If chained DMA is not in progress  and the descriptors are             * built afresh             */            else if ((chainedDma0FirstTime))                {                /* Program the Current Descriptor Address Register 0 */                MPC107EUMBBARWRITE(MPC107_DMA_CDAR0,                                  (UINT32)pFirstDescriptorCh0);                /* Program the DMA Mode Register 0 to start DMA */                dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &                                                 !(MPC107_DMA_DMR_CS) &                                                 !(MPC107_DMA_DMR_CTM);                /*                 * Clear the Channel Start Bit  and  the Channel Transfer Mode                 * to be Chained  DMA                 */                MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);                /* Set the Channel Start Bit to start DMA transfer */                MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |                                  MPC107_DMA_DMR_CS);                }            }        }    else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */        {        statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);        if ( (!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&              (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)            {            /* This channel is configured for Periodic DMA */            errnoSet (EBUSY);            return (ERROR);            }        else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0)            {            /* This channel is configured for Direct DMA */            /* Waiting for the channel to be free */            while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB);            /* Program the Current Descriptor Address Register 1 */            MPC107EUMBBARWRITE(MPC107_DMA_CDAR1, (UINT32)pFirstDescriptorCh1);            /* Program the DMA Mode Register 1 to start DMA */            dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &                           !(MPC107_DMA_DMR_CS) & !(MPC107_DMA_DMR_CTM);            /*             * Clear the Channel Start Bit  and  the Channel Transfer Mode             * to be Chained  DMA             */            MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);            /* Set the Channel Start Bit to start DMA transfer */            MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |                               MPC107_DMA_DMR_CS);            }        else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) == 0)            {            /* This channel is configured for Chained DMA */            /* if Chained DMA is already in progress  */            if ((MPC107EUMBBARREAD(MPC107_DMA_DSR1) & MPC107_DMA_DSR_CB) != 0)                {               /*                * Set the channel continue bit to in DMA Mode Register 1                * to start DMA                */                dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);                MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |                                   MPC107_DMA_DMR_CC);                }            /*             * if chained DMA is not in progress  and the descriptors are             * built afresh             */            else if ((chainedDma1FirstTime))                {                /* Program the Current Descriptor Address Register 1 */                MPC107EUMBBARWRITE(MPC107_DMA_CDAR1,                                  (UINT32)pFirstDescriptorCh1);                /* Program the DMA Mode Register 1 to start DMA */                dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &                                                 !(MPC107_DMA_DMR_CS) &                                                 !(MPC107_DMA_DMR_CTM);                /*                 * Clear the Channel Start Bit  and  the Channel Transfer Mode                 * to be Chained  DMA                 */                MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);                /* Set the Channel Start Bit to start DMA transfer */                MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |                                   MPC107_DMA_DMR_CS);                }            }        }    else        {        errnoSet (EINVAL);        return (ERROR);        }    return (OK);    }/***************************************************************************** mpc107DmaPeriodicStart -  start Periodic Chained DMA** This routine initializes the specified  DMA channel for a  "periodic"* DMA transfer.* This routine is called in the routine mpc107DmaChainedStart() after the* "DMA descriptors" are built using the routine  mpc107DmaBuildDescriptor().* All the descriptors for a "periodic" DMA should be built before starting* the chained DMA transfer. Descriptors  cannot be added while a periodic* DMA transfer is taking place.** RETURNS: OK, or ERROR if the channel specified by <channelNumber> is not a* valid channel or the  channel is already configured for "periodic" DMA .*/LOCAL STATUS mpc107DmaPeriodicStart    (    UINT32	channelNumber,  /* DMA Channel Number */    UINT32	timePeriod      /* Time period */    )    {    UINT32 	tempDataRead;    STATUS 	status;    if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */        {        /* Disable interrupt for the timer */        tempDataRead = MPC107EUMBBARREAD(MPC107_EPIC_TM2_VEC_REG) |                                          MPC107_EPIC_TM_VECREG_INTMASK;        /* Program the count based on time period  and Clear  Count Inhibit */        MPC107EUMBBARWRITE(MPC107_EPIC_TM2_BASE_COUNT_REG,                           timePeriod & ! (MPC107_EPIC_TM_BASE_COUNT_CI));        /* Start Periodic DMA transfer and Set the periodic DMA Enable Bit */        status = mpc107DmaChainStart (channelNumber);        if (status == OK)            {            tempDataRead = MPC107EUMBBARREAD(MPC107_DMA_DMR0) |                                             MPC107_DMA_DMR_PDE;            MPC107EUMBBARWRITE(MPC107_DMA_DMR0, tempDataRead);            }        return (status);        }    else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */        {        /* Disable interrupt for the timer */        tempDataRead = MPC107EUMBBARREAD(MPC107_EPIC_TM3_VEC_REG) |                                          MPC107_EPIC_TM_VECREG_INTMASK;        /* Program the count based on time period  and Clear  Count Inhibit */        MPC107EUMBBARWRITE(MPC107_EPIC_TM3_BASE_COUNT_REG,                           timePeriod & ! (MPC107_EPIC_TM_BASE_COUNT_CI));        /* Start Periodic DMA transfer and Set the periodic DMA Enable Bit */        status = mpc107DmaChainStart (channelNumber);        if (status == OK)            {            tempDataRead = MPC107EUMBBARREAD(MPC107_DMA_DMR1) |                                             MPC107_DMA_DMR_PDE;            MPC107EUMBBARWRITE(MPC107_DMA_DMR1, tempDataRead);            }        return (status);        }    else        {        errnoSet (EINVAL);        return (ERROR);        }    return (OK);    }/***************************************************************************** mpc107DmaChainedStart - start  a  "Chained" (Periodic or Non Periodic) DMA** This routine is used for starting a "chained" (Periodic or Non Periodic)* DMA  transfer.** The <timePeriod> specified should be in microseconds. If a zero <timePeriod>* is specified, a "chained" DMA transfer is started. If a nonzero <timePeriod>* is specified, a "periodic" chained DMA transfer is started. The <timePeriod>* should not be less than the time it takes for the DMA transfer for periodic* DMA transfers.* This routine should be called after the "DMA descriptors" are built using* the routine  mpc107DmaBuildDescriptor().All the descriptors for a "periodic"* DMA should be built before starting the chained DMA transfer. Descriptors* cannot be added while a periodic DMA transfer is taking place.* The routine  mpc107DmaStopPeriodic()  has to be used to stop the on-going* periodic DMA  before a new periodic DMA can be started with a new set of* descriptors.** RETURNS: OK, or ERROR if channel specified by <channelNumber> is not a valid* channel or the channel is already configured for "periodic" DMA .*/STATUS mpc107DmaChainedStart    (    UINT32 	channelNumber, /* DMA Channel Number  */    UINT32 	timePeriod     /* time period for repetition for a periodic */                               /* DMA transfer, zero for chained DMA. */                               /* Time period is specified in  multiples  */                               /* of Microseconds */    )    {    if ((channelNumber == MPC107_DMA_CHANNEL0) ||        (channelNumber == MPC107_DMA_CHANNEL1))        {        if (timePeriod == NULL) /* If time period specified is zero */            {            /* Start Chained DMA */            return (mpc107DmaChainStart (channelNumber));            }        else            {            /* Start Periodic DMA */            return (mpc107DmaPeriodicStart (channelNumber, timePeriod));            }        }    else        {        errnoSet (EINVAL);        return (ERROR);        }   }/***************************************************************************** mpc107DmaPeriodicStop -  stop Periodic DMA** This routine is used for stopping "periodic" chained  DMA transfer for the* specified DMA channel.** RETURNS: OK, or ERROR if specified <channelNumber> is not a valid channel.*/STATUS mpc107DmaPeriodicStop    (    UINT32 	channelNumber  	/* Channel Number  */    )    {    MPC107_DMA_DESCRIPTOR *pTempDescriptor;    MPC107_DMA_DESCRIPTOR *pTempFirstDescriptor;    UINT32 dataReadDmaReg;    if (channelNumber == MPC107_DMA_CHANNEL0)        {        /* Set  Count Inhibit to Inhibit Timer */        MPC107EUMBBARWRITE(MPC107_EPIC_TM2_BASE_COUNT_REG,                           MPC107_EPIC_TM_BASE_COUNT_CI);        /* Disable Periodic DMA by Clearing  the periodic DMA Enable Bit */        dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &                                          !(MPC107_DMA_DMR_PDE);        MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);        /* Release all the Descriptors */        pTempFirstDescriptor = pFirstDescriptorCh0;        /* If Descriptors Already Exist */        if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0)            {            while (((UINT32)pTempFirstDescriptor &                                      MPC107_DMA_NDAR_ADDR_MASK ) != NULL )                {                pTempDescriptor = pTempFirstDescriptor;                pTempFirstDescriptor = pTempFirstDescriptor                                      -> pNextDescriptorAddress;                free ((void *)((UINT32)pTempDescriptor &                                MPC107_DMA_NDAR_ADDR_MASK));                }            }            pFirstDescriptorCh0 = NULL;            chainedDma0FirstTime = FALSE;        }    else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */        {        /* Set  Count Inhibit to Inhibit Timer */        MPC107EUMBBARWRITE(MPC107_EPIC_TM3_BASE_COUNT_REG,                           MPC107_EPIC_TM_BASE_COUNT_CI);        /* Disable Periodic DMA by Clearing  the periodic DMA Enable Bit */        dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &                                          !(MPC107_DMA_DMR_PDE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -