/** * * 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 writes the given user data to the Write FIFO in both the * polled mode and the interrupt mode and starts the transfer of the data to * the ICAP device. * * In the polled mode, this function will write the specified number of words * into the FIFO before returning. * * In the interrupt mode, this function will write the words upto the size * of the Write FIFO and starts the transfer, then subsequent transfer of the * data is performed by the interrupt service routine until the entire buffer * has been transferred. The status callback function is called when the entire * buffer has been sent. * In order to use interrupts, it is necessary for the user to connect the driver * interrupt handler, XHwIcap_IntrHandler(), to the interrupt system of * the application and enable the interrupts associated with the Write FIFO. * The user has to enable the interrupts each time this function is called * using the XHwIcap_IntrEnable macro. * * @param InstancePtr is a pointer to the XHwIcap instance. * @param FrameBuffer is a pointer to the data to be written to the * ICAP device. * @param NumWords is the number of words (16 bit for S6 and 32 bit * for all other devices)to write to the ICAP device. * * @return XST_SUCCESS or XST_FAILURE * * @note This function is a blocking for the polled mode of operation * and is non-blocking for the interrupt mode of operation. * Use the function XHwIcap_DeviceWriteFrame for writing a frame * of data to the ICAP device. * *****************************************************************************/ int XHwIcap_DeviceWrite(XHwIcap *InstancePtr, u32 *FrameBuffer, u32 NumWords) { u32 Index; /* Array Index */ #if XPAR_HWICAP_0_ICAP_DWIDTH == 8 u8 Fifo[NumWords*4]; #elif XPAR_HWICAP_0_ICAP_DWIDTH == 16 u16 Fifo[NumWords*2]; #else u32 Fifo[4]; /** Icap Width of 32 does not use Fifo but declared to overcome compilation error. Size of 4 is used to overcome compiler warnings */ #endif #if (XPAR_HWICAP_0_MODE == 0) u32 WrFifoVacancy; u32 IntrStatus; #endif Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(FrameBuffer != NULL); Xil_AssertNonvoid(NumWords > 0); /* * Make sure that the last Read/Write by the driver is complete. */ if (XHwIcap_IsTransferDone(InstancePtr) == FALSE) { return XST_FAILURE; } /* * Check if the ICAP device is Busy with the last Read/Write */ if (XHwIcap_IsDeviceBusy(InstancePtr) == TRUE) { return XST_FAILURE; } /* * Set the flag, which will be cleared when the transfer * is entirely done from the FIFO to the ICAP. */ InstancePtr->IsTransferInProgress = TRUE; /* * Disable the Global Interrupt. */ XHwIcap_IntrGlobalDisable(InstancePtr); #if (XPAR_HWICAP_0_ICAP_DWIDTH == 8) || (XPAR_HWICAP_0_ICAP_DWIDTH == 16) /* 16 bit */ if(InstancePtr->HwIcapConfig.IcapWidth == 16) { for(Index = 0; Index < (NumWords*2); Index = Index + 2) { Fifo[Index + 1] = *FrameBuffer; Fifo[Index] = *FrameBuffer >> 16; FrameBuffer++; } InstancePtr->RequestedWords = NumWords * 2; InstancePtr->RemainingWords = NumWords * 2; InstancePtr->SendBufferPtr = &Fifo[0]; } /* 8 bit */ else { for(Index = 0; Index < (NumWords*4); Index = Index + 4)
/** * * The interrupt handler for HwIcap interrupts. This function must be connected * by the user to an interrupt source. * * @param InstancePtr is a pointer to the XHwIcap instance. * * @return None. * * @note The interrupts are being used only while writing data to the * ICAP device. The reading of the data from the ICAP device is * done in polled mode. * In a worst case scenario the interrupt handler can * be busy writing large amount of data to the Write FIFO. * ******************************************************************************/ void XHwIcap_IntrHandler(void *InstancePtr) { XHwIcap *HwIcapPtr = (XHwIcap *) InstancePtr; u32 IntrStatus; u32 WrFifoVacancy; Xil_AssertVoid(InstancePtr != NULL); /* * Get the Interrupt status. */ IntrStatus = XHwIcap_IntrGetStatus(HwIcapPtr); if (IntrStatus & XHI_IPIXR_WRP_MASK) { /* * A transmit has just completed. Check for more data * to transmit. */ if (HwIcapPtr->RemainingWords > 0) { /* * Fill the FIFO with as many words as it will take (or * as many as we have to write). We can use the Write * FIFO vacancy to know if the device can take more data. */ WrFifoVacancy = XHwIcap_GetWrFifoVacancy(HwIcapPtr); while ((WrFifoVacancy != 0) && (HwIcapPtr->RemainingWords > 0)) { XHwIcap_FifoWrite(HwIcapPtr, *HwIcapPtr->SendBufferPtr); HwIcapPtr->RemainingWords--; WrFifoVacancy--; HwIcapPtr->SendBufferPtr++; } XHwIcap_StartConfig(HwIcapPtr); } else { if (HwIcapPtr->RequestedWords != 0) { /* * No more data to send. Disable the interrupts * by disabling the Global Interrupts. * Inform the upper layer software that the * transfer is done. */ XHwIcap_IntrGlobalDisable(HwIcapPtr); HwIcapPtr->IsTransferInProgress = FALSE; HwIcapPtr->StatusHandler(HwIcapPtr->StatusRef, XST_HWICAP_WRITE_DONE, HwIcapPtr->RequestedWords); } } } /* * Clear the Interrupt status. */ XHwIcap_IntrClear(HwIcapPtr, IntrStatus); }