📄 mpc107dma.c
字号:
MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg); /* Release all the Descriptors */ pTempFirstDescriptor = pFirstDescriptorCh1; /* 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)); } } pFirstDescriptorCh1 = NULL; chainedDma1FirstTime = FALSE; } else { errnoSet (EINVAL); return (ERROR); } return (OK); }/***************************************************************************** mpc107DmaBuildDecsriptor - build DMA descriptors** This routine is used for creation of a DMA descriptor required* for chained (periodic or non-periodic) DMA transfers.* Before a chained DMA transfer can be started, a set of descriptors can* be setup by calling this routine as many number of times as required* with the appropriate parameters. The routine mpc107DmaChainedStart should be* called after the descriptors are built.** If a periodic DMA is in progress, then the descriptor cannot be built and* the routine returns an error. If periodic DMA is not in progress then the* descriptor is formed. A periodic chained DMA with a new set of descriptors* can only be started by stopping the chained periodic DMA in progress using* the routine mpc107DmaPeriodicStop.** RETURNS: OK, or ERROR if channel is configured for Periodic DMA or* <numberOfBytes> is zero or channel specified by <channelNumber> is* not valid .*/STATUS mpc107DmaBuildDecsriptor ( UINT32 channelNumber, /* Channel Number */ UCHAR * pSourceAddress, /* Pointer to DMA start Address */ UCHAR * pDestinationAddress, /* Pointer to DMA destination address */ UINT32 transferType, /* specifies whether the transfer */ /* is "PCI to PCI" */ /* or "Memory to Memory" */ /* or "Memory to PCI" */ /* or "Memory to Memory" */ UINT32 numberOfBytes /* Number of bytes to be sent by DMA */ ) { MPC107_DMA_DESCRIPTOR * pTempDescriptor; MPC107_DMA_DESCRIPTOR * pTempFirstDescriptor; ULONG statusOfDmaReg; if (numberOfBytes == 0) /* number of bytes is zero */ { /* if the number of bytes is zero return an error */ errnoSet (EINVAL); return (ERROR); } if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */ { statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0); if ((!(statusOfDmaReg & MPC107_DMA_DMR_CTM) && (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0) { /* This channel is configured for Periodic DMA */ errnoSet (EBUSY); return (ERROR); } semTake (semIdChainDmaCh0, WAIT_FOREVER); /* If Direct DMA is configured */ if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0) { /* Polling to see when the channel is free */ while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB); } /* Flag set to indicate that the descriptors are being built */ dmaBuildDescrInProgCh0 = 1; 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; /* * Disable End of Segment Interrupt & * Disable End of Transfer Interrupt * For each descriptor except the last one */ pTempFirstDescriptor -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *) ((UINT32)pTempFirstDescriptor -> pNextDescriptorAddress & (!((UINT32)MPC107_DMA_NDAR_EOTD) & !((UINT32)MPC107_DMA_NDAR_NDEOSIE))); pTempFirstDescriptor = pTempFirstDescriptor -> pNextDescriptorAddress; } /* Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *) memalign(MPC107_DMA_MEM_ALIGN, sizeof(MPC107_DMA_DESCRIPTOR)); /* Flush the data cache */ cacheFlush (DATA_CACHE, pTempDescriptor -> pNextDescriptorAddress, sizeof(MPC107_DMA_DESCRIPTOR)); /* Source Address for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> pSourceAddress = (UCHAR *)pSourceAddress; /* Destinantion Address for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> pDestinationAddress = (UCHAR *)pDestinationAddress; /* Number of bytes for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> numberOfBytes = numberOfBytes; /* * Disable End of Segment Interrupt & * Enable End of Transfer Interrupt */ pTempDescriptor -> pNextDescriptorAddress -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *) MPC107_DMA_NDAR_EOTD; } else /* Descriptors donot exist */ { /* First Descriptor */ pFirstDescriptorCh0 = (MPC107_DMA_DESCRIPTOR *) memalign(MPC107_DMA_MEM_ALIGN, sizeof(MPC107_DMA_DESCRIPTOR)); /* Flush the data cache */ cacheFlush (DATA_CACHE, pFirstDescriptorCh0, sizeof(MPC107_DMA_DESCRIPTOR)); /* Source Address for the Current Descriptor */ pFirstDescriptorCh0 -> pSourceAddress = (UCHAR *)pSourceAddress; /* Destinantion Address for the Current Descriptor */ pFirstDescriptorCh0 -> pDestinationAddress = (UCHAR *) pDestinationAddress; /* Number of Bytes for the current Descriptor */ pFirstDescriptorCh0 -> numberOfBytes = numberOfBytes; /* * Disable End of Segment Interrupt & * Enable End of Transfer Interrupt */ pFirstDescriptorCh0 -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *)MPC107_DMA_NDAR_EOTD; /* * Set a Global Flag to indicate that the descriptors are being * built afresh again or are being built for the first time */ chainedDma0FirstTime = TRUE; } /* Flag cleared to indicate that the descriptors have been built */ dmaBuildDescrInProgCh0 = 0; semGive (semIdChainDmaCh0); } 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); } semTake (semIdChainDmaCh1, WAIT_FOREVER); /* if Direct DMA is configured */ if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0) { /* Polling to see when the channel is free */ while (MPC107EUMBBARREAD(MPC107_DMA_DSR1) & MPC107_DMA_DSR_CB); } /* Flag set to indicate that the descriptors are being built */ dmaBuildDescrInProgCh1 = 1; pTempFirstDescriptor = pFirstDescriptorCh1; /* If Descriptors Already Exist */ if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0) { while (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != NULL ) { pTempDescriptor = pTempFirstDescriptor; /* * Disable End of Segment Interrupt & * Disable End of Transfer Interrupt * For each descriptor except the last one */ pTempFirstDescriptor -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *) ((UINT32)pTempFirstDescriptor -> pNextDescriptorAddress & (!(UINT32)MPC107_DMA_NDAR_EOTD & (UINT32)MPC107_DMA_NDAR_NDEOSIE)); pTempFirstDescriptor = pTempFirstDescriptor -> pNextDescriptorAddress; } /* Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *)memalign (MPC107_DMA_MEM_ALIGN, sizeof(MPC107_DMA_DESCRIPTOR)); /* Flush the data cache */ cacheFlush (DATA_CACHE, pTempDescriptor -> pNextDescriptorAddress, sizeof(MPC107_DMA_DESCRIPTOR)); /* Source Address for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> pSourceAddress = (UCHAR*)pSourceAddress; /* Destinantion Address for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> pDestinationAddress = (UCHAR*) pDestinationAddress; /* Number of bytes for the Next Descriptor */ pTempDescriptor -> pNextDescriptorAddress -> numberOfBytes = numberOfBytes; /* * Disable End of Segment Interrupt & * Enable End of Transfer Interrupt */ pTempDescriptor -> pNextDescriptorAddress -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR *)MPC107_DMA_NDAR_EOTD; } else /* Descriptors donot exist */ { /* First Descriptor */ pFirstDescriptorCh1 = memalign(MPC107_DMA_MEM_ALIGN, sizeof(MPC107_DMA_DESCRIPTOR)); /* Flush the data cache */ cacheFlush (DATA_CACHE, pFirstDescriptorCh1, sizeof(MPC107_DMA_DESCRIPTOR)); /* Source Address for the Current Descriptor */ pFirstDescriptorCh1 -> pSourceAddress = (UCHAR *)pSourceAddress; /* Destinantion Address for the Current Descriptor */ pFirstDescriptorCh1 -> pDestinationAddress = (UCHAR *)pDestinationAddress; /* Number of Bytes for the current Descriptor */ pFirstDescriptorCh1 -> numberOfBytes = numberOfBytes; /* * Disable End of Segment Interrupt & * Enable End of Transfer Interrupt */ pFirstDescriptorCh1 -> pNextDescriptorAddress = (MPC107_DMA_DESCRIPTOR*)MPC107_DMA_NDAR_EOTD; /* * Set a Global Flag to indicate that the descriptors are being * built afresh again or are being built for the first time */ chainedDma1FirstTime = TRUE; } /* Flag cleared to indicate that the descriptors have been built */ dmaBuildDescrInProgCh1 = 0; semGive (semIdChainDmaCh1); } else { errnoSet (EINVAL); return (ERROR); } return (OK); }/***************************************************************************** mpc107DmaStatus - query DMA status and DMA Transfer Mode** This routine purpose is to query the specified DMA channel for DMA* transfer status and DMA transfer mode.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -