📄 xdma_channel_sg.c
字号:
InstancePtr->TotalDescriptorCount++; UsedByteCount += sizeof(XBufDescriptor); } /* connect the last buffer descriptor created and inserted in the list * to the first such that a ring buffer is created */ XBufDescriptor_SetNextPtr(BufferDescriptorPtr, StartOfListPtr); /* initialize the ring buffer to indicate that there are no * buffer descriptors in the list which point to valid data buffers */ InstancePtr->PutPtr = BufferDescriptorPtr; InstancePtr->GetPtr = BufferDescriptorPtr; InstancePtr->CommitPtr = XNULL; InstancePtr->LastPtr = BufferDescriptorPtr; InstancePtr->ActiveDescriptorCount = 0; InstancePtr->ActivePacketCount = 0; InstancePtr->Committed = XFALSE; /* indicate the scatter gather list was successfully created */ return XST_SUCCESS;}/*****************************************************************************//**** This function determines if the scatter gather list of a DMA channel is* empty with regard to buffer descriptors which are pointing to buffers to be* used for scatter gather operations.** @param** InstancePtr contains a pointer to the DMA channel to operate on. The DMA* channel should be configured to use scatter gather in order for this function* to be called.** @return** A value of XTRUE if the scatter gather list is empty, otherwise a value of* XFALSE.** @note** None.*******************************************************************************/Xboolean XDmaChannel_IsSgListEmpty(XDmaChannel *InstancePtr){ /* assert to verify valid input arguments */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* if the number of descriptors which are being used in the list is zero * then the list is empty */ return (InstancePtr->ActiveDescriptorCount == 0);}/*****************************************************************************//**** This function puts a buffer descriptor into the DMA channel scatter* gather list. A DMA channel maintains a list of buffer descriptors which are* to be processed. This function puts the specified buffer descriptor* at the next location in the list. Note that since the list is already intact,* the information in the parameter is copied into the list (rather than modify* list pointers on the fly).** After buffer descriptors are put into the list, they must also be committed* by calling another function. This allows multiple buffer descriptors which* span a single packet to be put into the list while preventing the hardware* from starting the first buffer descriptor of the packet.** @param** InstancePtr contains a pointer to the DMA channel to operate on. The DMA* channel should be configured to use scatter gather in order for this function* to be called.** @param** BufferDescriptorPtr is a pointer to the buffer descriptor to be put into* the next available location of the scatter gather list.** @return* - A status which indicates XST_SUCCESS if the buffer descriptor was* successfully put into the scatter gather list.* <br><br>* - A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not* been created.* <br><br>* - A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not* put into the list because the list was full.* <br><br>* - A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not* put into the list because the buffer descriptor in the list which is to* be overwritten was locked. A locked buffer descriptor indicates the higher* layered software is still using the buffer descriptor.** @note** It is necessary to create a scatter gather list for a DMA channel before* putting buffer descriptors into it.*******************************************************************************/XStatus XDmaChannel_PutDescriptor(XDmaChannel *InstancePtr, XBufDescriptor *BufferDescriptorPtr){ Xuint32 Control; /* assert to verify valid input arguments and alignment for those * arguments that have alignment restrictions */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(BufferDescriptorPtr != XNULL); XASSERT_NONVOID(((Xuint32)BufferDescriptorPtr & 3) == 0); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* if a scatter gather list has not been created yet, return a status */ if (InstancePtr->TotalDescriptorCount == 0) { return XST_DMA_SG_NO_LIST; } /* if the list is full because all descriptors are pointing to valid * buffers, then indicate an error, this code assumes no list or an * empty list is detected above */ if (InstancePtr->ActiveDescriptorCount == InstancePtr->TotalDescriptorCount) { return XST_DMA_SG_LIST_FULL; } /* if the buffer descriptor in the list which is to be overwritten is * locked, then don't overwrite it and return a status */ if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) { return XST_DMA_SG_BD_LOCKED; } /* set the scatter gather stop bit in the control word of the descriptor * to cause the hw to stop after it processes this descriptor since it * will be the last in the list */ Control = XBufDescriptor_GetControl(BufferDescriptorPtr); XBufDescriptor_SetControl(BufferDescriptorPtr, Control | XDC_DMACR_SG_DISABLE_MASK); /* set both statuses in the descriptor so we tell if they are updated with * the status of the transfer, the hardware should change the busy in the * DMA status to be false when it completes */ XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK); XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0); /* copy the descriptor into the next position in the list so it's ready to * be used by the hw, this assumes the descriptor in the list prior to this * one still has the stop bit in the control word set such that the hw * use this one yet */ CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr); /* End of a packet is reached. Bump the packet counter */ if (XBufDescriptor_IsLastControl(InstancePtr->PutPtr)) { InstancePtr->ActivePacketCount++; } /* only the last in the list and the one to be committed have scatter gather * disabled in the control word, a commit requires only one descriptor * to be changed, when # of descriptors to commit > 2 all others except the * 1st and last have scatter gather enabled */ if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) && (InstancePtr->CommitPtr != XNULL)) { Control = XBufDescriptor_GetControl(InstancePtr->LastPtr); XBufDescriptor_SetControl(InstancePtr->LastPtr, Control & ~XDC_DMACR_SG_DISABLE_MASK); } /* update the list data based upon putting a descriptor into the list, * these operations must be last */ InstancePtr->ActiveDescriptorCount++; /* only update the commit pointer if it is not already active, this allows * it to be deactivated after every commit such that a single descriptor * which is committed does not appear to be waiting to be committed */ if (InstancePtr->CommitPtr == XNULL) { InstancePtr->CommitPtr = InstancePtr->LastPtr; } /* these updates MUST BE LAST after the commit pointer update in order for * the commit pointer to track the correct descriptor to be committed */ InstancePtr->LastPtr = InstancePtr->PutPtr; InstancePtr->PutPtr = XBufDescriptor_GetNextPtr(InstancePtr->PutPtr); return XST_SUCCESS;}/*****************************************************************************//**** This function commits the buffer descriptors which have been put into the* scatter list for the DMA channel since the last commit operation was* performed. This enables the calling functions to put several buffer* descriptors into the list (e.g.,a packet's worth) before allowing the scatter* gather operations to start. This prevents the DMA channel hardware from* starting to use the buffer descriptors in the list before they are ready* to be used (multiple buffer descriptors for a single packet).** @param** InstancePtr contains a pointer to the DMA channel to operate on. The DMA* channel should be configured to use scatter gather in order for this function* to be called.** @return* - A status indicating XST_SUCCESS if the buffer descriptors of the list were* successfully committed.* <br><br>* - A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors* were not committed because there was nothing to commit in the list. All the* buffer descriptors which are in the list are committed.** @note** None.*******************************************************************************/XStatus XDmaChannel_CommitPuts(XDmaChannel *InstancePtr){ /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* if the buffer descriptor to be committed is already committed or * the list is empty (none have been put in), then indicate an error */ if ((InstancePtr->CommitPtr == XNULL) || XDmaChannel_IsSgListEmpty(InstancePtr)) { return XST_DMA_SG_NOTHING_TO_COMMIT; } /* last descriptor in the list must have scatter gather disabled so the end * of the list is hit by hw, if descriptor to commit is not last in list, * commit descriptors by enabling scatter gather in the descriptor */ if (InstancePtr->CommitPtr != InstancePtr->LastPtr) { Xuint32 Control; Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr); XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control & ~XDC_DMACR_SG_DISABLE_MASK); } /* Buffer Descriptors are committed. DMA is ready to be enabled */ InstancePtr->Committed = XTRUE; /* Update the commit pointer to indicate that there is nothing to be * committed, this state is used by start processing to know that the * buffer descriptor to start is not waiting to be committed */ InstancePtr->CommitPtr = XNULL; return XST_SUCCESS;}/*****************************************************************************//**** This function gets a buffer descriptor from the scatter gather list of the* DMA channel. The buffer descriptor is retrieved from the scatter gather list* and the scatter gather list is updated to not include the retrieved buffer* descriptor. This is typically done after a scatter gather operation* completes indicating that a data buffer has been successfully sent or data* has been received into the data buffer. The purpose of this function is to* allow the device using the scatter gather operation to get the results of the* operation.** @param** InstancePtr contains a pointer to the DMA channel to operate on. The DMA* channel should be configured to use scatter gather in order for this function* to be called.** @param** BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which* was retrieved from the list. The buffer descriptor is not really removed* from the list, but it is changed to a state such that the hardware will not* use it again until it is put into the scatter gather list of the DMA channel.** @return* - A status indicating XST_SUCCESS if a buffer descriptor was retrieved from* the scatter gather list of the DMA channel.* <br><br>* - A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not* been created.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -