/**
*
* Run a self-test on the driver/device. The test
*	- Writes to the Interrupt Enable Register and reads it back
*	for comparison.
*
* @param	InstancePtr is a pointer to the XHwIcap instance.
*
* @return
*		- XST_SUCCESS if the value read from the register
*		is the same as the value written.
*		- XST_FAILURE otherwise
*
* @note		None.
*
******************************************************************************/
int XHwIcap_SelfTest(XHwIcap *InstancePtr)
{
	int Status = XST_SUCCESS;
	u32 IeRegister;
	u32 DgieRegister;


	/*
	 * Assert the argument
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	/*
	 * Save a copy of the Global Interrupt Enable Register and Interrupt
	 * Enable Register before writing them so that they can be restored.
	 */
	DgieRegister = XHwIcap_ReadReg(InstancePtr->HwIcapConfig.BaseAddress,
						XHI_GIER_OFFSET);
	IeRegister = XHwIcap_IntrGetEnabled(InstancePtr);

	/*
	 * Disable the Global Interrupt
	 */
	XHwIcap_IntrGlobalDisable(InstancePtr);


	/*
	 * Disable/Enable the interrupts and then verify that the register
	 * is read back correct.
	 */
	XHwIcap_IntrDisable(InstancePtr, XHI_IPIXR_ALL_MASK);
	if (XHwIcap_IntrGetEnabled(InstancePtr) != 0x0) {
		Status = XST_FAILURE;
	}

	XHwIcap_IntrEnable(InstancePtr, (XHI_IPIXR_WEMPTY_MASK |
					XHI_IPIXR_RDP_MASK));
	if (XHwIcap_IntrGetEnabled(InstancePtr) !=
			(XHI_IPIXR_WEMPTY_MASK | XHI_IPIXR_RDP_MASK)) {
		Status |= XST_FAILURE;
	}

	/*
	 * Restore the Interrupt Enable Register to the value before the
	 * test.
	 */
	XHwIcap_IntrDisable(InstancePtr, XHI_IPIXR_ALL_MASK);
	if (IeRegister != 0) {
		XHwIcap_IntrEnable(InstancePtr, IeRegister);
	}


	/*
	 * Restore the Global Interrupt Enable Register to the value
	 * before the test.
	 */
	XHwIcap_WriteReg(InstancePtr->HwIcapConfig.BaseAddress,
				XHI_GIER_OFFSET, DgieRegister);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	return XST_SUCCESS;
}
/**
*
* This function does a minimal test on the HwIcap device and driver as a
* design example. The purpose of this function is to illustrate how to use
* the XHwIcap component using the interrupt mode.
*
* This function sends data and expects to receive the same data.
*
*
* @param	IntcInstancePtr is a pointer to the instance of the INTC component.
* @param	HwIcapInstancePtr is a pointer to the instance of HwIcap component.
* @param	HwIcapDeviceId is the Device ID of the HwIcap Device and is the
*		XPAR_<HWICAP_instance>_DEVICE_ID value from xparameters.h.
* @param	HwIcapIntrId is the interrupt Id and is typically
*		XPAR_<INTC_instance>_<HWICAP_instance>_IP2INTC_IRPT_INTR
*		value from xparameters.h .
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note
*
* This function contains an infinite loop such that if interrupts are not
* working it may never return.
*
******************************************************************************/
int HwIcapIntrExample(XIntc *IntcInstancePtr, XHwIcap *HwIcapInstancePtr,
			u16 HwIcapDeviceId, u16 HwIcapIntrId)
{
	int Status;
	u32 Count;
	u8 Test;
	XHwIcap_Config *ConfigPtr;

	/*
	 * Initialize the HwIcap driver.
	 */
	ConfigPtr = XHwIcap_LookupConfig(HwIcapDeviceId);
	if (ConfigPtr == NULL) {
		return XST_FAILURE;
	}
	Status = XHwIcap_CfgInitialize(HwIcapInstancePtr,
					ConfigPtr,
					ConfigPtr->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Perform a self-test to ensure that the hardware was built correctly.
	 */
	Status = XHwIcap_SelfTest(HwIcapInstancePtr);

	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Connect the HwIcap device to the interrupt subsystem such that
	 * interrupts can occur. This function is application specific.
	 */
	Status = HwIcapSetupInterruptSystem(IntcInstancePtr,
					HwIcapInstancePtr,
					HwIcapIntrId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Setup the handler for the HwIcap that will be called from the
	 * interrupt context when an HwIcap status occurs, specify a pointer
	 * to the HwIcap driver instance as the callback reference so the
	 * handler is able to access the instance data.
	 */
	XHwIcap_SetInterruptHandler(HwIcapInstancePtr, HwIcapInstancePtr,
			 (XHwIcap_StatusHandler)HwIcapIntrHandler);

	/*
	 * Initialize the write buffer with pattern to write.
	 */
	for (Count = 0; Count < TEST_WRITE_BUFFER_SIZE;) {

		WriteBuffer[Count++] = XHI_DUMMY_PACKET;
		WriteBuffer[Count++] = XHI_SYNC_PACKET;
		WriteBuffer[Count++] = XHwIcap_Type1Read(XHI_IDCODE) | 1;
		WriteBuffer[Count++] = XHI_NOOP_PACKET;
		WriteBuffer[Count++] = XHI_NOOP_PACKET;
		WriteBuffer[Count++] = XHI_DUMMY_PACKET;
		WriteBuffer[Count++] = XHI_SYNC_PACKET;
		WriteBuffer[Count++] = XHwIcap_Type1Read(XHI_COR) | 1;
		WriteBuffer[Count++] = XHI_NOOP_PACKET;
		WriteBuffer[Count++] = XHI_NOOP_PACKET;
	}

	/*
	 * Enable the Write FIFO Half Full Interrupt.
	 */
	XHwIcap_IntrEnable(HwIcapInstancePtr, XHI_IPIXR_WRP_MASK);

	/*
	 * Write the the data to the device.
	 */
	TransferInProgress = TRUE;
	Status = XHwIcap_DeviceWrite(HwIcapInstancePtr,
					(u32 *) &WriteBuffer[0],
					TEST_WRITE_BUFFER_SIZE);
	if (Status != XST_SUCCESS)  {
		return XST_FAILURE;
	}

	/*
	 * Wait for the data to be written to the device.
	 */
	while (TransferInProgress);

	return XST_SUCCESS;
}