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

📄 xllp_dmac.c

📁 PXA270硬件测试源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
**
**  COPYRIGHT (C) 2001, 2002 Intel Corporation.
**
**  This software as well as the software described in it is furnished under
**  license and may only be used or copied in accordance with the terms of the
**  license. The information in this file is furnished for informational use
**  only, is subject to change without notice, and should not be construed as
**  a commitment by Intel Corporation. Intel Corporation assumes no
**  responsibility or liability for any errors or inaccuracies that may appear
**  in this document or any software that may be provided in association with
**  this document. 
**  Except as permitted by such license, no part of this document may be 
**  reproduced, stored in a retrieval system, or transmitted in any form or by
**  any means without the express written consent of Intel Corporation. 
**
**  FILENAME:       xllp_dmac.c
**
**  PURPOSE: contains all primitive functions for Bulverde DMA Controller register 
**           access and control
**                  
******************************************************************************/

#include "xllp_dmac.h"    

#define XLLP_DMAC_DDADR_RESERVED_MASK	 0xFFFFFFF0
#define XLLP_DMAC_DRCMR_ENABLE     		 0x80
#define XLLP_DMAC_DRCMR_DISABLE    		 0x00

/**
 * DMA Controller channels
 **/
XLLP_DMAC_CHANNEL_T pArrayChannel[32];

/**
 * Points to shared area with all DMAC registers
 *
 * MUST DO:
 * Modify to reflect the DMAC register block of your operating environment.
 **/
volatile P_XLLP_DMAC_T		pDmacHandle = 0;

/**
 * Channel priority sets
 **/
const XLLP_DMAC_CHANNEL_T aPrioritySetCount = 8;
const XLLP_DMAC_CHANNEL_T ChannelPriorityHigh[]=
{
    XLLP_DMAC_CHANNEL_0,
    XLLP_DMAC_CHANNEL_1,
    XLLP_DMAC_CHANNEL_2,
    XLLP_DMAC_CHANNEL_3,
    XLLP_DMAC_CHANNEL_16,
    XLLP_DMAC_CHANNEL_17,
    XLLP_DMAC_CHANNEL_18,
    XLLP_DMAC_CHANNEL_19
};    
const XLLP_DMAC_CHANNEL_T ChannelPriorityMedium[]=
{
    XLLP_DMAC_CHANNEL_4,
    XLLP_DMAC_CHANNEL_5,
    XLLP_DMAC_CHANNEL_6,
    XLLP_DMAC_CHANNEL_7,
    XLLP_DMAC_CHANNEL_20,
    XLLP_DMAC_CHANNEL_21,
    XLLP_DMAC_CHANNEL_22,
    XLLP_DMAC_CHANNEL_23
};    
const XLLP_DMAC_CHANNEL_T ChannelPriorityLow[]=
{
    XLLP_DMAC_CHANNEL_8,
    XLLP_DMAC_CHANNEL_9,
    XLLP_DMAC_CHANNEL_10,
    XLLP_DMAC_CHANNEL_11,
    XLLP_DMAC_CHANNEL_24,
    XLLP_DMAC_CHANNEL_25,
    XLLP_DMAC_CHANNEL_26,
    XLLP_DMAC_CHANNEL_27
};    
const XLLP_DMAC_CHANNEL_T ChannelPriorityLowest[]=
{
    XLLP_DMAC_CHANNEL_12,
    XLLP_DMAC_CHANNEL_13,
    XLLP_DMAC_CHANNEL_14,
    XLLP_DMAC_CHANNEL_15,
    XLLP_DMAC_CHANNEL_28,
    XLLP_DMAC_CHANNEL_29,
    XLLP_DMAC_CHANNEL_30,
    XLLP_DMAC_CHANNEL_31
};    

// This is only needed when running without the XLLP DMA Engine.
XLLP_STATUS_T XllpDmacInitHandle(P_XLLP_DMAC_T address)
{
	pDmacHandle = address;
	return 0;
}

/******************************************************************************
XLLP_DOC_HDR_BEGIN

  Function Name: XllpDmaAllocChannel

  Description: XllpDmacAllocChannel is used to obtain an available channel in 
  			   the system.  The channel that is allocated must then be used to
  			   bind a service routine to the operating system such that all 
  			   interrupts that occur on the channel will be routed to the bound
  			   service routine.  Once the channel is done transferring data, it
  			   can be freed by using XllpDmacFreeChannel.
  
  Global Registers Modified: None 

  Input Arguments:
	aChannelPriority: Specifies the priority of the channel reqested
		                 
  Output Arguments:
	pChannel: Holds the available DMA channel assigned to the calling device 
			  driver.  DMA channels range is from 0-31.   
  Return Value: 
	XLLP_STATUS_SUCCESS: Returned when a channel is available and assigned to caller
	XLLP_NO_DMA_CHANNELS_AVAILABLE: Returned when there is no available channel
									to be assigned 

XLLP_DOC_HDR_END
*******************************************************************************/
XLLP_STATUS_T XllpDmacAllocChannel(
			   		 			  P_XLLP_DMAC_CHANNEL_T        pChannel,
			     	 			  XLLP_DMAC_CHANNEL_PRIORITY_T aChannelPriority
			     	 			  )
{
	XLLP_DMAC_CHANNEL_T i;
	XLLP_DMAC_CHANNEL_T aChannel;

	switch(aChannelPriority)
	{
		case XLLP_DMAC_CHANNEL_PRIORITY_HIGH:
			{
				for (i=0; i < aPrioritySetCount; i++ )
				{
					aChannel = ChannelPriorityHigh[i];				
					if (pArrayChannel[aChannel] == 0)
					{
						pArrayChannel[aChannel] = 1;   // Set this channel to InUse
						*pChannel = aChannel;
						return (XLLP_STATUS_SUCCESS);        // Return no error
					}
				}	
				break;
			}
		case XLLP_DMAC_CHANNEL_PRIORITY_MEDIUM:
			{
				for (i=0; i < aPrioritySetCount; i++ )
				{
					aChannel = ChannelPriorityMedium[i];				
					if (pArrayChannel[aChannel] == 0)
					{
						pArrayChannel[aChannel] = 1;   // Set this channel to InUse
						*pChannel = aChannel;
						return (XLLP_STATUS_SUCCESS);        // Return no error
					}
				}	
				break;
			}
		case XLLP_DMAC_CHANNEL_PRIORITY_LOW:
			{
				for (i=0; i < aPrioritySetCount; i++ )
				{
					aChannel = ChannelPriorityLow[i];				
					if (pArrayChannel[aChannel] == 0)
					{
						pArrayChannel[aChannel] = 1;   // Set this channel to InUse
						*pChannel = aChannel;
						return (XLLP_STATUS_SUCCESS);        // Return no error
					}
				}	
				break;
			}
		case XLLP_DMAC_CHANNEL_PRIORITY_LOWEST:
			{
				for (i=0; i < aPrioritySetCount; i++ )
				{
					aChannel = ChannelPriorityLowest[i];				
					if (pArrayChannel[aChannel] == 0)
					{
						pArrayChannel[aChannel] = 1;   // Set this channel to InUse
						*pChannel = aChannel;
						return (XLLP_STATUS_SUCCESS);        // Return no error
					}
				}	
				break;
			}
	}

	/*
	 * If we got this far, that means no channel was available for
	 * the specified channel priority set. So look for any available
	 * channel and return it
	 */
	for (i=0; i < XLLP_DMAC_CHANNEL_NUM; i++ )
	{
		if (pArrayChannel[i] == 0)
		{
			pArrayChannel[i] = 1;      // Set this channel to InUse
			*pChannel = i;
			return (XLLP_STATUS_SUCCESS);    // Return no error
		}
	}	
	return XLLP_STATUS_NO_DMA_CHANNEL_AVAILABLE;	// No DMA channel is free
}


/******************************************************************************
XLLP_DOC_HDR_BEGIN

  Function Name: XllpDmacFreeChannel

  Description: XllpDmacFreeChannel is used to free a previously obtained channel
  			   back into the free channels pool in the system.  A channel that 
  			   is freed automatically becomes available for allocation when needed,
  			   and all interrupts that were previously being generated to this 
  			   channel will be disconnected.  
  			   
  Global Registers Modified: 
  	DMA request to channel map register, DRCMRx 

  Input Arguments:
	aChannel: Channel to be freed and made available for other users.
	aDeviceDrcmr: Specifies the device that was using the channel to be freed.  Valid
			 	  inputs are elements of type XLLP_DMAC_DRCMR_T, otherwise is invalid.
	                 
  Output Arguments:
  	None
  Return Value: 
	None 

XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacFreeChannel(
						XLLP_DMAC_CHANNEL_T       aChannel,
						XLLP_DMAC_DRCMR_T         aDeviceDrcmr
					    )
{
	/* Verify if channel is currently set as InUse */
	if (pArrayChannel[aChannel] == 1)
	{
		pArrayChannel[aChannel] = (XLLP_DMAC_CHANNEL_T)0; /* Free this channel*/
	
		/* UnMap device from channel */
		if (aDeviceDrcmr != XLLP_DMAC_MEM2MEM_MOVE)
		{
			XllpDmacUnMapDeviceToChannel(aDeviceDrcmr, aChannel);
		}
	}
}

/******************************************************************************
XLLP_DOC_HDR_BEGIN

  Function Name: XllpDmacFillLinkedDesc

  Description: XllpDmacFillLinkedDesc is used to setup a descriptor or chained 
  			   descriptors for DMA transfer operations. To setup a descriptor 
  			   (ie. no chaining), the pointer to the next descriptor pNextDesc 
  			   is expected to be zero, otherwise pNextDesc expected to be a 
  			   valid descriptor pointer.  Users wanting to chain multiple 
  			   descriptors will call this function to accomplish that task.
  			   
  Global Registers Modified: 
	None
		
  Input Arguments:
	pDesc: Hold the pointer to the descriptor to be configured, cannot be a 
		   null pointer.
	pNextDesc: Holds the pointer to the next descriptor used in the DMA transfer
			   process after completely transferring data in the current descriptor
			   pDesc if the channel is not programmed to be stop.  pNextDesc can 
			   be a null pointer only if this descriptor is not meant to be chained.
	aStopContinue:  Specifies whether or not to configure this descriptor to stop
				    the channel after completely transferring data in this descriptor.
	aBranch: Specifies whether to configure this descriptor to enable or disable 
			 the descriptor branching mechanism.  Valid values are element of type
			 XLLP_DMAC_DESC_BRANCH_T (1 or 0).
	aSrcAddr: Holds the source address for this descriptor, cannot be null.
	aTargetAddr: Holds the target address for this descriptor, cannot be null.
	pCmd: Holds the commands for this descriptor.  Users are required to initialize 
		  the various fields of pCmd data structure before making this call.
	                 
  Output Arguments:
  	None
  Return Value: 
	None 

XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacFillLinkedDesc(
						   P_XLLP_DMAC_DESCRIPTOR_T pDesc,
						   P_XLLP_DMAC_DESCRIPTOR_T pNextDescPhyAddr,
						   XLLP_DMAC_DESC_ENABLE_T  aStopContinue,
						   XLLP_DMAC_DESC_BRANCH_T  aBranch,
						   XLLP_UINT32_T            aSrcAddr,
						   XLLP_UINT32_T            aTargetAddr,
						   XLLP_DMAC_COMMAND_T*     pCmd
						  )
{
	XLLP_VUINT32_T aTargetValue;
	

⌨️ 快捷键说明

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