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

📄 xdma_channel_sg.c

📁 linux嵌入式系统的dma方式的实现代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        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 + -