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

📄 dp_hardware_dispatcher.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		else if ( DP_ReadFieldFromHardware ( sFieldToAdd.pasFieldToWrite ) != sFieldToAdd.ui32ValueToWrite )
		{
			/* The address of the field to add is not currently listed in the buffer			*/
			/* and is not already set to the desired value in memory (in which case we just		*/
			/* ditch the request to change that particular field, as it is already 'changed'.	*/
			/* The hardware should be read and a new memory write added to the buffer.			*/
			
			/* Copy the current value of the memory location into the end of the target buffer	*/
			ui32CurrentQueuedValue = DP_ReadFromMemory ( (sFieldToAdd.pasFieldToWrite)->ui32TargetAddressOffset );

#if defined DP_SIMULATION_MODE

			printf (	"Read value 0x%x from addr 0x%x  \t - Fn. : DP_AddToBuffer') \n", 
						ui32CurrentQueuedValue,	
						(DP_UINT_32) (sFieldToAdd.pasFieldToWrite)->ui32TargetAddressOffset		);

#endif

			/* Add the current value as read from memory to the end of the buffer				*/
			sMemoryWriteToAdd.ui32TargetAddressOffset = (sFieldToAdd.pasFieldToWrite)->ui32TargetAddressOffset;
			sMemoryWriteToAdd.ui32TargetValue = ui32CurrentQueuedValue;

			DP_MEMCPY ( (&(pasBufferToAddTo [ *pui16SizeOfBuffer ])),
						(&sMemoryWriteToAdd),
						sizeof ( DP_QueuedMemoryWrite )	);




			/* Now merge the field to add into the new entry at the end of the buffer			*/
			DP_WriteFieldToAddress (	sFieldToAdd.pasFieldToWrite,
										sFieldToAdd.ui32ValueToWrite,
										&(pasBufferToAddTo [ *pui16SizeOfBuffer ].ui32TargetValue)	);

			/* Now increment the size of the buffer to reflect the newly added memory write		*/
			*pui16SizeOfBuffer += 1;
		
		}
	
	}
																
}

												
/***********************************************************************************************
 * Function Name  : DP_WriteFieldToAddress
 * Inputs         : psTargetField			-	A pointer to the 'DP_FieldTarget' structure
 *												containing details of the field to be written
 *												to.
 *					
 *					ui32SourceData			-	The value to write to the specified field.
 *					
 *					pui32TargetAddress		-	Opportunity to write to somewhere other than 
 *												the field's native address :	  
 *													If this parameter is set to 'DP_NULL', then
 *												the field will be written to at the address
 *												specified in the 'DP_FieldTarget' structure. If
 *												an address is passed in this parameter, then the
 *												field will be written to according to the 
 *												bitfield, mask, etc. specified in the
 *												'DP_FieldTarget', but at the (absolute) address
 *												by this parameter.
 * Outputs        : None.
 * Returns        : Nothing.
 * Globals Used   :	DP_pui32BaseAddress		-	Addresses (specified as offsets) are added to
 *												the base address prior to actual writing to
 *												hardware.
 *
 * Description    : This function takes in a value and places it in the correct bitfield at a 
 *					target address. No checking of DMA engine buffers is conducted - the 
 *					function simply writes to the right	place in hardware. If a target address 
 *					is specified, it will be used as a replacement for the field's normal 
 *					hardware address (for both read and write accesses).					
 *
 ***********************************************************************************************/

DP_VOID		DP_WriteFieldToAddress		(	const DP_FieldTarget *		psTargetField,					
											DP_UINT_32					ui32SourceData,					
											DP_PUINT_32					pui32TargetAddress		 )		

/*	psTargetField		- Field to write to														*/
/*	ui32SourceData		- Value to place in field												*/
/*	pui32TargetAddress	- e 		*/
/*						  		*/

{
DP_UINT_32	ui32ValueToWrite;
DP_UINT_32	ui32CurrentValueOfMemoryLocation;
DP_UINT_32	ui32CompletedWriteValue;

	/* Check that the field to be written actually exists										*/
	if ( psTargetField->ui32TargetAddressOffset != DP_NO_REG )
	{

		/* Step 1 - Remove any redundant bits of source data as indicated by 'Read from' value	*/
		/*			of target field																*/
		if ( psTargetField->ui8TargetBitfieldStart > psTargetField->ui8SourceBitfieldStart )
		{
			/* As the target field is further left than the start of the source field (in bits)	*/
			/* a shift left is needed to place the valid data in the correct position			*/

			ui32ValueToWrite = ui32SourceData << ( psTargetField->ui8TargetBitfieldStart - psTargetField->ui8SourceBitfieldStart );
		}
		else if ( psTargetField->ui8TargetBitfieldStart < psTargetField->ui8SourceBitfieldStart )
		{
			/* As the target field is further right than the start of the source field (in		*/
			/* bits) a shift right is needed to place the valid data in the correct position	*/

			ui32ValueToWrite = ui32SourceData >> ( psTargetField->ui8SourceBitfieldStart - psTargetField->ui8TargetBitfieldStart );
		}
		else
		{
			/* The target and source fields are already aligned.								*/
			ui32ValueToWrite = ui32SourceData;
		}
	
		/* Now that the source data is in position, remove all redundant information			*/
		ui32ValueToWrite &= psTargetField->ui32TargetBitfieldMask;


		/* Step 2 - Obtain the current value of the field's memory location	and clear the		*/
		/*			bitfield to be used by the target field.									*/

		if ( pui32TargetAddress == NULL )
		{

			ui32CurrentValueOfMemoryLocation = *(volatile DP_UINT_32 *)( DP_pui32BaseAddress + (psTargetField->ui32TargetAddressOffset / sizeof (DP_UINT_32)) );

#if defined DP_SIMULATION_MODE

			printf (	"Read value 0x%x from addr 0x%x  \t - Fn. : WriteFieldToAddress') \n",
						ui32CurrentValueOfMemoryLocation,
						(DP_UINT_32) psTargetField->ui32TargetAddressOffset );

#endif

		}
		else
		{
			/* Read from the specified address, instread of the field's native position			*/
			ui32CurrentValueOfMemoryLocation = *((DP_PUINT_32) pui32TargetAddress);
		}

		/* Clear the bitfield for subsequent insertion of new field data						*/
		ui32CompletedWriteValue = ui32CurrentValueOfMemoryLocation & ~(psTargetField->ui32TargetBitfieldMask); 


		/* Step 3 - Place the new data into the cleared bitfield								*/
		ui32CompletedWriteValue |= ui32ValueToWrite;


		/* Step 4 - Write the prepared data into memory											*/
		if ( pui32TargetAddress == DP_NULL )
		{
			
			DP_WriteToMemory ( psTargetField->ui32TargetAddressOffset, ui32CompletedWriteValue );

		}
		else
		{	
			/* Write to the specified address, rather than using the field's native position	*/
			*((DP_PUINT_32) pui32TargetAddress) = ui32CompletedWriteValue;
		}

	} /* if */

}


/***********************************************************************************************
 * Function Name  : DP_ReadFromMemory
 * Inputs         : ui32AddressToReadFrom	-	The offset address (from the global base
 *												address) which is to be read.
 * Outputs        :	None.
 * Returns        : DP_UINT_32				-	The value read from the specified address.
 * Globals Used   :	DP_pui32BaseAddress		-	Addresses (specified as offsets) are added to
 *												the base address prior to actual reading from
 *												hardware.
 *
 * Description    :	This function simply reads from a specified memory address - a function is
 *					used so as to provide as few actual hardware access points as possible.
 *
 ***********************************************************************************************/

DP_UINT_32	DP_ReadFromMemory ( DP_UINT_32	ui32AddressToReadFrom )
{
DP_UINT_32	ui32ReturnValue	= 0;
DP_PUINT_32	pui32AddressToReadFrom;

	pui32AddressToReadFrom = DP_pui32BaseAddress + (ui32AddressToReadFrom / sizeof (DP_UINT_32));

	ui32ReturnValue = *(volatile DP_UINT_32*)pui32AddressToReadFrom;

	#if defined DP_SIMULATION_MODE
	printf (	"Read value 0x%x from addr 0x%x  \t - Fn. : ReadFromMemory') \n",
				ui32ReturnValue,
				ui32AddressToReadFrom );
	#endif
return	ui32ReturnValue;
}

void ConvertCToT(TCHAR* pszDest, const IMG_CHAR* pszSrc)
{
    unsigned i;
	for(i = 0; i <= strlen(pszSrc); i++)
        pszDest[i] = (TCHAR) pszSrc[i];
}

/***********************************************************************************************
 * Function Name  : DP_WriteToMemory
 * Inputs         : ui32AddressToWriteTo	-	The offset (from the global base address) of the
 *												address to be written to.
 *					
 *					ui32ValueToWrite		-	The value to be written to the specified address.
 * Outputs        : None.
 * Returns        : None
 * Globals Used   :	DP_pui32BaseAddress		-	Addresses (specified as offsets) are added to
 *												the base address prior to actual writing to
 *												hardware.
 *
 * Description    : This function simply writes to a specified memory address - a function is
 *					used so as to provide as few actual hardware access points as possible.
 *
 ***********************************************************************************************/

DP_VOID	DP_WriteToMemory	(	DP_UINT_32	ui32AddressToWriteTo,	
								DP_UINT_32	ui32ValueToWrite	)
{
volatile	DP_UINT_32	*	pui32PhysicalAddress;
#ifdef PRINTMESSAGE
char buffer[256];
	TCHAR unicode[256];

	sprintf(buffer,"Reg 0x%04x = 0x%08x\n",ui32AddressToWriteTo,ui32ValueToWrite);
	ConvertCToT(unicode, buffer);
	OutputDebugString(unicode);
#endif

	pui32PhysicalAddress = DP_pui32BaseAddress + (ui32AddressToWriteTo / sizeof ( DP_UINT_32 ) );

	*(pui32PhysicalAddress) = ui32ValueToWrite;
	#ifdef PDPPDUMP
	PDUMPREG(PDUMPTAGS_REG_PDP,(WORD)ui32AddressToWriteTo,ui32ValueToWrite);
	#endif

	#if defined DP_SIMULATION_MODE

	printf (	"Wrote value 0x%x to addr 0x%x  \t - Fn. : DP_WriteToMemory) \n", 
				(DP_UINT_32) ui32ValueToWrite,
				(DP_UINT_32) ui32AddressToWriteTo	);

	#if !defined SHOW_DMA_INTERFACE_OUTPUT
	if (	(ui32AddressToWriteTo != DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_PENDING_ADDRESS ].ui32TargetAddressOffset) &&
			(ui32AddressToWriteTo != DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_STATUS_ADDRESS ].ui32TargetAddressOffset) &&
			(ui32AddressToWriteTo != DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_STATUS_FLAG ].ui32TargetAddressOffset) &&
			(ui32AddressToWriteTo != DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_LENGTH_OF_PENDING_BUFFER ].ui32TargetAddressOffset)	)
	{
	#endif

		/* The field being written has nothing to do with the DMA Engine, so dump it to			*/
		/* the simulator file.																	*/
		#ifdef PDPPDUMP
		PDUMPREG ( PDUMPTAGS_REG_PDP, ui32AddressToWriteTo, ui32ValueToWrite );
		#endif

	#if !defined SHOW_DMA_INTERFACE_OUTPUT
	}
	#endif

#endif

}


												
#if defined DP_SIMULATION_MODE


/***********************************************************************************************
 * Function Name  : DP_SimulateDMAEngine
 * Inputs         : eSimulatorMode			-	The manner in which the simulation shoudl
 *												proceed.
 * Outputs        : None.
 * Returns        : Nothing.
 * Globals Used   :	DP_pui32BaseAddress		-	Addresses (specified as offsets) are added to
 *												the base address prior to actual writing to
 *												hardware.
 *
 * Description    :	This function simulates a single DMA Engine 'event'. The function can be 
 *					told to	start the DMA Engine's cycle, and then later to stop it, or just to 
 *					simulate an entire cycle instantly.
 *
 ***********************************************************************************************/

void	DP_SimulateDMAEngine	( DP_DMAEngineSimulatorModes	eSimulatorMode )
{
static	DP_PUINT_32		pui32PendingAddress;
static	DP_PUINT_32		pui32StatusAddress;
		DP_UINT_8		ui8i;
static	DP_UINT_8		ui8LengthOfCurrentStatusBuffer = 0;
static	DP_BOOL			bCycleProceeding = DP_FALSE;
		DP_BOOL			bCurrentValidFlag;


	printf ( "DP_SimulateDMAEngine \n" );

	if	( eSimulatorMode == DP_DMA_ENGINE_SIMULATOR_INITIALISE )
	{
		/* This is a one time only call which sets the initial state of the DMA Engine.			*/
		/* The 'completed' flag is set, so that the DMA Engine knows upon startup that it is	*/
		/* not currently processing a buffer.													*/

		#if defined SHOW_DMA_INTERFACE_OUTPUT
		PDumpComment ( "DEL" );
		#endif
		DP_WriteFieldToAddress (	&(DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_STATUS_FLAG ]),
									(DP_UINT_32) DP_TRUE,
									NULL	);


		#if defined SHOW_DMA_INTERFACE_OUTPUT
		PDumpComment ( "DEL" );
		#endif
		/* Clear the 'valid' flag																*/
		DP_WriteFieldToAddress (	&(DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_PENDING_ADDRESS_VALID_FLAG ]),
									(DP_UINT_32) DP_FALSE,
									DP_NULL		);

	}


	/* The DMA cycle can be split into three sections :											*/
	/*	1)	Establish whether there is a buffer pending. If there is, and it's not the same 

⌨️ 快捷键说明

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