xdma_channel.c

来自「适合KS8695X」· C语言 代码 · 共 739 行 · 第 1/2 页

C
739
字号
/******************************************************************************
*
*     Author: Xilinx, Inc.
*
*
*     This program is free software; you can redistribute it and/or modify it
*     under the terms of the GNU General Public License as published by the
*     Free Software Foundation; either version 2 of the License, or (at your
*     option) any later version.
*
*
*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
*     FITNESS FOR A PARTICULAR PURPOSE.
*
*
*     Xilinx hardware products are not intended for use in life support
*     appliances, devices, or systems. Use in such applications is
*     expressly prohibited.
*
*
*     (c) Copyright 2002-2004 Xilinx Inc.
*     All rights reserved.
*
*
*     You should have received a copy of the GNU General Public License along
*     with this program; if not, write to the Free Software Foundation, Inc.,
*     675 Mass Ave, Cambridge, MA 02139, USA.
*
* FILENAME:
*
* xdma_channel.c
*
* DESCRIPTION:
*
* This file contains the DMA channel component. This component supports
* a distributed DMA design in which each device can have it's own dedicated
* DMA channel, as opposed to a centralized DMA design. This component
* performs processing for DMA on all devices.
*
* See xdma_channel.h for more information about this component.
*
* NOTES:
*
* None.
*
******************************************************************************/

/***************************** Include Files *********************************/

#include "xdma_channel.h"
#include "xbasic_types.h"
#include "xio.h"

/************************** Constant Definitions *****************************/

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_Initialize
*
* DESCRIPTION:
*
* This function initializes a DMA channel.  This function must be called
* prior to using a DMA channel.  Initialization of a channel includes setting
* up the registers base address, and resetting the channel such that it's in a
* known state.  Interrupts for the channel are disabled when the channel is
* reset.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* BaseAddress contains the base address of the registers for the DMA channel.
*
* RETURN VALUE:
*
* XST_SUCCESS indicating initialization was successful.
*
* NOTES:
*
* None.
*
******************************************************************************/
XStatus
XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
{
	/* assert to verify input arguments, don't assert base address */

	XASSERT_NONVOID(InstancePtr != NULL);

	/* setup the base address of the registers for the DMA channel such
	 * that register accesses can be done
	 */
	InstancePtr->RegBaseAddress = BaseAddress;

	/* initialize the scatter gather list such that it indicates it has not
	 * been created yet and the DMA channel is ready to use (initialized)
	 */
	InstancePtr->GetPtr = NULL;
	InstancePtr->PutPtr = NULL;
	InstancePtr->CommitPtr = NULL;
	InstancePtr->LastPtr = NULL;

	InstancePtr->TotalDescriptorCount = 0;
	InstancePtr->ActiveDescriptorCount = 0;
	InstancePtr->IsReady = XCOMPONENT_IS_READY;

	/* initialize the version of the component
	 */
	XVersion_FromString(&InstancePtr->Version, "1.00a");

	/* reset the DMA channel such that it's in a known state and ready
	 * and indicate the initialization occured with no errors, note that
	 * the is ready variable must be set before this call or reset will assert
	 */
	XDmaChannel_Reset(InstancePtr);

	return XST_SUCCESS;
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_IsReady
*
* DESCRIPTION:
*
* This function determines if a DMA channel component has been successfully
* initialized such that it's ready to use.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* RETURN VALUE:
*
* TRUE if the DMA channel component is ready, FALSE otherwise.
*
* NOTES:
*
* None.
*
******************************************************************************/
u32
XDmaChannel_IsReady(XDmaChannel * InstancePtr)
{
	/* assert to verify input arguments used by the base component */

	XASSERT_NONVOID(InstancePtr != NULL);

	return InstancePtr->IsReady == XCOMPONENT_IS_READY;
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_GetVersion
*
* DESCRIPTION:
*
* This function gets the software version for the specified DMA channel
* component.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* RETURN VALUE:
*
* A pointer to the software version of the specified DMA channel.
*
* NOTES:
*
* None.
*
******************************************************************************/
XVersion *
XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
{
	/* assert to verify input arguments */

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* return a pointer to the version of the DMA channel */

	return &InstancePtr->Version;
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_SelfTest
*
* DESCRIPTION:
*
* This function performs a self test on the specified DMA channel.  This self
* test is destructive as the DMA channel is reset and a register default is
* verified.
*
* ARGUMENTS:
*
* InstancePtr is a pointer to the DMA channel to be operated on.
*
* RETURN VALUE:
*
* XST_SUCCESS is returned if the self test is successful, or one of the
* following errors.
*
*	XST_DMA_RESET_REGISTER_ERROR 		Indicates the control register value
*										after a reset was not correct
*
* NOTES:
*
* This test does not performs a DMA transfer to test the channel because the
* DMA hardware will not currently allow a non-local memory transfer to non-local
* memory (memory copy), but only allows a non-local memory to or from the device
* memory (typically a FIFO).
*
******************************************************************************/

#define XDC_CONTROL_REG_RESET_MASK  0x98000000UL	/* control reg reset value */

XStatus
XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
{
	u32 ControlReg;

	/* assert to verify input arguments */

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* reset the DMA channel such that it's in a known state before the test
	 * it resets to no interrupts enabled, the desired state for the test
	 */
	XDmaChannel_Reset(InstancePtr);

	/* this should be the first test to help prevent a lock up with the polling
	 * loop that occurs later in the test, check the reset value of the DMA
	 * control register to make sure it's correct, return with an error if not
	 */
	ControlReg = XDmaChannel_GetControl(InstancePtr);
	if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
		return XST_DMA_RESET_REGISTER_ERROR;
	}

	return XST_SUCCESS;
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_Reset
*
* DESCRIPTION:
*
* This function resets the DMA channel. This is a destructive operation such
* that it should not be done while a channel is being used.  If the DMA channel
* is transferring data into other blocks, such as a FIFO, it may be necessary
* to reset other blocks.  This function does not modify the contents of a
* scatter gather list for a DMA channel such that the user is responsible for
* getting buffer descriptors from the list if necessary.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* RETURN VALUE:
*
* None.
*
* NOTES:
*
* None.
*
******************************************************************************/
void
XDmaChannel_Reset(XDmaChannel * InstancePtr)
{
	/* assert to verify input arguments */

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* reset the DMA channel such that it's in a known state, the reset
	 * register is self clearing such that it only has to be set
	 */
	XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
		  XDC_RESET_MASK);
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_GetControl
*
* DESCRIPTION:
*
* This function gets the control register contents of the DMA channel.
*
* ARGUMENTS:
*
* InstancePtr contains a pointer to the DMA channel to operate on.
*
* RETURN VALUE:
*
* The control register contents of the DMA channel. One or more of the
* following values may be contained the register.  Each of the values are
* unique bit masks.
*
*	XDC_DMACR_SOURCE_INCR_MASK	Increment the source address
*	XDC_DMACR_DEST_INCR_MASK	Increment the destination address
*	XDC_DMACR_SOURCE_LOCAL_MASK Local source address
*	XDC_DMACR_DEST_LOCAL_MASK	Local destination address
*	XDC_DMACR_SG_ENABLE_MASK	Scatter gather enable
*	XDC_DMACR_GEN_BD_INTR_MASK	Individual buffer descriptor interrupt
*	XDC_DMACR_LAST_BD_MASK		Last buffer descriptor in a packet
*
* NOTES:
*
* None.
*
******************************************************************************/
u32
XDmaChannel_GetControl(XDmaChannel * InstancePtr)
{
	/* assert to verify input arguments */

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/* return the contents of the DMA control register */

	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
}

/******************************************************************************
*
* FUNCTION:
*
* XDmaChannel_SetControl
*
* DESCRIPTION:
*
* This function sets the control register of the specified DMA channel.
*
* ARGUMENTS:
*

⌨️ 快捷键说明

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