📄 mpc107dma.c
字号:
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 + -