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

📄 dp_hardware_dispatcher.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			}


		case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_IMMEDIATE:
		case DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC:

			for ( ui16i = 0; ui16i < ui8LengthOfCommandSequence; ui16i++ )
			{
				DP_AddToBuffer (	DP_asCommandSequence		[ ui16i ],
									&DP_TemporaryDispatchBuffer [0],
									&ui16SizeOfBuffer	);
			}
	
			if	(( eOperation == DP_COMMAND_SEQUENCE_OPERATIONS_SEND_ON_VSYNC ) ||
				( eOperation == DP_COMMAND_SEQUENCE_OPERATIONS_SINGLE_COMMAND_ON_VSYNC ))
				DP_WaitForVSYNC ();		

			for ( ui16i = 0; ui16i < ui16SizeOfBuffer; ui16i++ )
			{		
				DP_WriteToMemory (	DP_TemporaryDispatchBuffer [ ui16i ].ui32TargetAddressOffset,
									DP_TemporaryDispatchBuffer [ ui16i ].ui32TargetValue	);
				
			}

			ui8LengthOfCommandSequence = 0;

		break;

	}

return ui16ReturnValue;
}


/***********************************************************************************************
 *
 * Function Name  : DP_GetField
 * Inputs         : psSourceField				-	A pointer to the 'DP_FieldTarget' structure
 *													which contains details of the field from
 *													which a value is to be read.
 *					
 *					pui16Errors					-	A pointer to a 'DP_UINT_16' which the
 *													function uses to indicate the success of
 *													the function call. This variable is either
 *													filled with one of the two 'success' flags
 *													(depending on whether error checking is
 *													enabled) or with
 *													'DP_ERR_EXCEEDS_CAPABILITIES' if the field
 *													was found not to exist.
 * Outputs        : None.
 * Returns        : DP_UINT_32					-	If successful, returns the value of the
 *													requested field.
 *
 * Globals Used   :	DP_DispatcherBuffers		-	Used to compare against the address stored
 *													in the 'pending' register, in order to
 *													establish whether the requested field should
 *													be read from the hardware itself, or from
 *													the pending buffer.
 *
 *					DP_ui16DispatcherBufferSize-	When using the function DP_SearchBuffer, the
 *													size of the buffer being searched must be
 *													passed. The DP_SearchBuffer function is used
 *													here to see if the requested field is in a
 *													a 'pending' buffer and hence should be
 *													returned from the buffer, rather than from
 *													hardware.
 *
 *					DP_ui8DispatcherBufferOffset-	Any direct reference to the dispatcher buffers
 *													must include their current offset (the 16 bit
 *													word toggle which is flipped every time the
 *													buffer is 'freed').
 *
 * Description    : This function allows the value of a field to be read. The resulting value is 
 *					always returned as a zero bit aligned 32 bit value. The function checks to see 
 *					if the requested field is currently queued in the 'pending' buffer and returns 
 *					the queued value if it is.
 *
 ***********************************************************************************************/

DP_UINT_32	DP_GetField					(	const	DP_FieldTarget	*				psSourceField,
													DP_UINT_16		*				pui16Errors		)
{
DP_pQueuedMemoryWrite		psAddressOfCurrentlyPendingBuffer;
DP_pQueuedMemoryWrite		psAddressOfCurrentStatusBuffer;
DP_BOOL						bCurrentStatusFlag;
DP_INT_8					i8PendingBuffer;
DP_UINT_32					ui32CurrentQueuedValue;
DP_UINT_32					ui32ReturnValue = 0;
DP_BOOL						bIsPending = DP_FALSE;

#if defined DP_SIMULATION_MODE
	printf ( "DP_GetField \n" );
#endif

	/* Start by assuming there are no errors													*/
	if ( pui16Errors != DP_NULL )
		*pui16Errors = DP_STANDARD_CODE_NO_ERROR;

	/* If the field being requested doesn't exist in the hardware, then abandon this request	*/
	/* right now.																				*/
	if ( psSourceField->ui32TargetAddressOffset != DP_NO_REG )
	{

		/* Obtain the latest values for 'Pending buffer', 'Status buffer' and 'Status flag'		*/
		psAddressOfCurrentlyPendingBuffer	= (DP_pQueuedMemoryWrite)	DP_ReadFieldFromHardware ( &DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_PENDING_ADDRESS ] );

		#if defined	PCI_BRIDGE_SIM
			/* Adjust for windows linear address space, by adding the value read from hardware	*/
			/* as an offset to the PCI memory mapped region.									*/
			psAddressOfCurrentlyPendingBuffer = ((DP_pQueuedMemoryWrite) DP_pSharedMemory) + (((DP_UINT_32) psAddressOfCurrentlyPendingBuffer) / sizeof (DP_QueuedMemoryWrite));
		#endif

		psAddressOfCurrentStatusBuffer		= (DP_pQueuedMemoryWrite)	DP_ReadFieldFromHardware ( &DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_STATUS_ADDRESS ] );

		#if defined	PCI_BRIDGE_SIM
			/* Adjust for windows linear address space, by adding the value read from hardware	*/
			/* as an offset to the PCI memory mapped region.									*/
			psAddressOfCurrentStatusBuffer = ((DP_pQueuedMemoryWrite) DP_pSharedMemory) + (((DP_UINT_32) psAddressOfCurrentStatusBuffer) / sizeof (DP_QueuedMemoryWrite));
		#endif

		bCurrentStatusFlag					= (DP_BOOL)					(DP_ReadFieldFromHardware ( &DP_asGlobalFieldTargets [ DP_GLOBAL_FIELD_HARDWARE_DISPATCHER_STATUS_FLAG ] ) & 0x01);

		/* If the pending buffer has already been written to hardware, then just read from		*/
		/* hardware																				*/
		if (!(( psAddressOfCurrentStatusBuffer == psAddressOfCurrentlyPendingBuffer ) && bCurrentStatusFlag ))
		{
			/* It is not the case that the current queue is the same as the one which the		*/
			/* hardware has most recently finished dealing with. As such, all we know is that	*/
			/* the data in the currently pending buffer has yet to 'reach' the hardware proper,	*/
			/* so we should treat any relevant data in that buffer as 'latest'.					*/

			if ( psAddressOfCurrentlyPendingBuffer == &(DP_DispatcherBuffers [DP_ui8DispatcherBufferOffset [0]]) )
			{
				/* Buffer 0 is currently pending												*/
				i8PendingBuffer = 0;
			}
			else if ( psAddressOfCurrentlyPendingBuffer == &(DP_DispatcherBuffers [DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES + DP_ui8DispatcherBufferOffset [1]]) )
			{
				/* Buffer 1 is currently pending												*/
				i8PendingBuffer = 1;
			}
			else
			{
				/* The 'Pending buffer' register isn't pointing to a proper buffer, so just		*/
				/* ignore it.																	*/
				i8PendingBuffer = -1;
			}

			/* If a buffer has been earmarked, then search it to see if the address at which	*/
			/* the desired field arrives is going to be modified in the pending buffer (when it */
			/* gets actioned).																	*/
			if ( i8PendingBuffer != -1 )
			{
				if ( DP_SearchBuffer (	&(DP_DispatcherBuffers [(i8PendingBuffer*DP_SIZE_OF_DISPATCHER_BUFFER_IN_ENTRIES) + DP_ui8DispatcherBufferOffset [i8PendingBuffer]]),
										DP_ui16DispatcherBufferSize [ i8PendingBuffer ],
										psSourceField->ui32TargetAddressOffset, 
										&ui32CurrentQueuedValue, 
										(DP_PUINT_16) DP_NULL )		)
				{
					/* The address does have a pending write. Retrieve and normalise that value		*/
					ui32ReturnValue = ui32CurrentQueuedValue;
					ui32ReturnValue	&= psSourceField->ui32TargetBitfieldMask;
					ui32ReturnValue = ui32ReturnValue >> psSourceField->ui8TargetBitfieldStart;

					bIsPending = DP_TRUE;
				}
			}
		}

		if ( !bIsPending )
		{
			/* The specified address does not have a write pending, so read directly from the 	*/
			/* hardware.																		*/
			ui32ReturnValue = DP_ReadFieldFromHardware ( psSourceField );
		}

	}
	else
	{
		if ( pui16Errors != DP_NULL )
			*pui16Errors = DP_ERR_EXCEEDS_CAPABILITIES;
	}

//	printf ( "DP_GetField returns %x \n\n", ui32ReturnValue );

return	ui32ReturnValue;	
}	/* End of 'DP_GetField' */



/***********************************************************************************************
 *
 * Function Name  : DP_ReadFieldFromHardware
 * Inputs         : psSourceField				-	A pointer to the 'DP_FieldTarget' structure
 *													which provides details of the field to be
 *													read.
 * 
 * Outputs        : None.
 * Returns        : DP_UINT_32					-	The value of the field read.
 * Globals Used   :	None.
 *
 * Description    : This lower level read function returns a field (zero bit aligned), but does 
 *					NOT search to see if the value is currently pending (always reads straight 
 *					from hardware).				
 *
 ***********************************************************************************************/														

DP_UINT_32	DP_ReadFieldFromHardware	(	const DP_FieldTarget *			psSourceField	)			

{
DP_UINT_32		ui32DataAsRead;

	/* Abandon the request if the specified field doesn't exist									*/
	if ( psSourceField->ui32TargetAddressOffset != DP_NO_REG )
	{
			
		/* Step 1 - Read all data from the address at which the specified field is resident		*/
		ui32DataAsRead = DP_ReadFromMemory ( psSourceField->ui32TargetAddressOffset );

		/* Step 2 - Remove all non-field specific data from the read value						*/
		ui32DataAsRead &= psSourceField->ui32TargetBitfieldMask;

		/* Step 3 - Normalise the read value (align it at bit 0)								*/
		ui32DataAsRead = ui32DataAsRead >> psSourceField->ui8TargetBitfieldStart;

		/* Step 4 - If we truncated this field prior to storage in hardware (using the			*/
		/*			'read from' field, then correct for this.									*/
		ui32DataAsRead = ui32DataAsRead << psSourceField->ui8SourceBitfieldStart;
	}


#if defined DP_SIMULATION_MODE

	printf (	"Read field value 0x%x from addr 0x%x  \t - Fn. : ReadFieldFromHardware') \n",
				ui32DataAsRead,
				(DP_UINT_32) psSourceField->ui32TargetAddressOffset );

#endif


return ui32DataAsRead;
}


/***********************************************************************************************
 *
 * Function Name  : DP_SearchBuffer
 * Inputs         : pasBufferToSearch			-	Pointer to the first 'DP_pQueuedMemoryWrite'
 *													in the list of memory writes to be searched.
 *
 *					ui16SizeOfBuffer			-	The number of 'DP_pQueuedMemoryWrite'
 *													structures in the list to be searched.
 *
 *					ui32AddressToSearchFor		-	The target offset to be searched for in the
 *													provided list.
 *
 *					pui32ValueOfQueuedWrite		-	The value to be searched for in the
 *													provided list.
 *					
 *					pui16PositionOfQueuedWrite	-	A pointer to the 'DP_UINT_16' which the
 *													function will fill with the position of the
 *													structure in the provided list which
 *													matched both the specified offset and value.
 *													This value is only filled if the function
 *													indicates success - see below.
 *					
 * Outputs        : pui16PositionOfQueuedWrite	-	See above.
 *
 * Returns        : DP_BOOL						-	A flag indicating whether the specified 
 *													target offset and value were found in any
 *													of the structures in the provided list. If
 *													the function returns 'DP_TRUE' then the 
 *													offset and value were found. If the function
 *													returns 'DP_FALSE', then the search was not
 *													successful.
 * Globals Used   :	None.
 * Description    : This function is used to search through one of the dispatcher buffers for a 
 *					queued write to a specified address. If a write to the specified address is 
 *					found in the indicated queue, the function returns the value which is to be 
 *					written and the offset into the buffer at which the value was found.																
 *
 ***********************************************************************************************/

DP_BOOL		DP_SearchBuffer				(	DP_pQueuedMemoryWrite		pasBufferToSearch,
											DP_UINT_16					ui16SizeOfBuffer,
											DP_UINT_32					ui32AddressToSearchFor,
											DP_PUINT_32					pui32ValueOfQueuedWrite,
											DP_PUINT_16					pui16PositionOfQueuedWrite	)
{
DP_UINT_16	ui16i;
DP_BOOL		bFoundIt = DP_FALSE;

	for ( ui16i = 0; ui16i < ui16SizeOfBuffer; ui16i++ )
	{
		if ( pasBufferToSearch [ ui16i ].ui32TargetAddressOffset == ui32AddressToSearchFor )
		{
			*pui32ValueOfQueuedWrite = pasBufferToSearch [ ui16i ].ui32TargetValue;
			bFoundIt = DP_TRUE;
			if ( pui16PositionOfQueuedWrite != DP_NULL)
				*pui16PositionOfQueuedWrite = ui16i;
			break;
		}
	}

return	bFoundIt;
}


/***********************************************************************************************
 *
 * Function Name  : DP_QueueNewDMABuffer
 * Inputs         : pasQueueToSubmit			-	A pointer to the first 'DP_pQueuedFieldWrite'
 *													structure in a list to be submitted to the 
 *													DMA engine.
 *					
 *					ui8LengthOfQueue			-	The number of 'DP_pQueuedFieldWrite'
 *													structures in the list to be submitted.
 * Outputs        : None.
 * Returns        : Nothing.
 * Globals Used   :	DP_DispatcherBuffers		-	Used variously to establish the current
 *													states of the dispatcher buffers (by
 *													comparison of the buffers' addresses with the
 *													values held in the 'pending' and 'status'
 *													registers. Also used when copying between
 *													buffers, populating buffers and when filling
 *													the 'pending' register with the address of
 *													a buffer being queued.
 *
 *					DP_ui16DispatcherBufferSize-	The size of the dipatcher buffers is used here
 *													in a variety of contexts, when reading from
 *													buffers and when adjusting the size of a
 *													buffer by writing to it.
 *
 *					DP_eBufferStates			-	The decision on where to place the new data
 *													to be queued is based on the current state of
 *													of the two dispatcher buffers. The states are
 *													also modified here, as (a.) the result of 

⌨️ 快捷键说明

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