/** * * Register a fast handler function for a specific interrupt ID. The handler * function will be called when an interrupt occurs for the given interrupt ID. * * @param BaseAddress is the base address of the interrupt controller * whose vector table will be modified. * @param InterruptId is the interrupt ID to be associated with the input * handler. * @param FastHandler is the function pointer that will be called when * interrupt occurs * * @return None. * * @note * * Note that this function has no effect if the input base address is invalid. * ******************************************************************************/ void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id, XFastInterruptHandler FastHandler) { u32 CurrentIER; u32 Mask; u32 Imr; CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[Id]; if (CurrentIER & Mask) { /* Disable Interrupt if it was enabled */ CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); XIntc_Out32(BaseAddress + XIN_IER_OFFSET,(CurrentIER & ~Mask)); } XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4), (u32) FastHandler); Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET); XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask); /* Enable Interrupt if it was enabled before calling this function */ if (CurrentIER & Mask) { CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); XIntc_Out32(BaseAddress + XIN_IER_OFFSET,(CurrentIER | Mask)); } }
/** * * Acknowledges the interrupt source provided as the argument Id. When the * interrupt is acknowledged, it causes the interrupt controller to clear its * interrupt condition.In Cascade mode, acknowledges corresponding interrupt * source of Slave controllers depending on the Id. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being * the highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Acknowledge(XIntc * InstancePtr, u8 Id) { u32 Mask; XIntc_Config *CfgPtr; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); if (Id > 31) { /* Enable user required Id in Slave controller */ CfgPtr = XIntc_LookupConfig(Id/32); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; XIntc_Out32(CfgPtr->BaseAddress + XIN_IAR_OFFSET, Mask); } else { /* * The Id is used to create the appropriate mask for the * desired bit position. */ Mask = XIntc_BitPosMask[Id]; /* * Acknowledge the selected interrupt source, no read of the * acknowledge register is necessary since only the bits set * in the mask will be affected by the write */ XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Mask); } }
/** * * Updates the interrupt table with the Null Handler and NULL arguments at the * location pointed at by the Id. This effectively disconnects that interrupt * source from any handler. The interrupt is disabled also. In Cascade mode, * disconnects handler from Slave controller handler table depending on the * interrupt Id. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being * the highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Disconnect(XIntc * InstancePtr, u8 Id) { u32 CurrentIER; u32 Mask; XIntc_Config *CfgPtr; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Disable the interrupt such that it won't occur while disconnecting * the handler, only disable the specified interrupt id without * modifying the other interrupt ids */ /* Disconnect Handlers for Slave controllers in Cascade Mode */ if (Id > 31) { CfgPtr = XIntc_LookupConfig(Id/32); CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); /* * Disconnect the handler and connect a stub, the callback * reference must be set to this instance to allow unhandled * interrupts to be tracked */ CfgPtr->HandlerTable[Id%32].Handler = StubHandler; CfgPtr->HandlerTable[Id%32].CallBackRef = InstancePtr; } /* Disconnect Handlers for Master/primary controller */ else { CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[Id]; XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); InstancePtr->CfgPtr->HandlerTable[Id%32].Handler = StubHandler; InstancePtr->CfgPtr->HandlerTable[Id%32].CallBackRef = InstancePtr; } }
/** * * Disables the interrupt source provided as the argument Id such that the * interrupt controller will not cause interrupts for the specified Id. The * interrupt controller will continue to hold an interrupt condition for the * Id, but will not cause an interrupt. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the * highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Disable(XIntc * InstancePtr, u8 Id) { u32 CurrentIER; u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * The Id is used to create the appropriate mask for the * desired bit position. Id currently limited to 0 - 31 */ Mask = XIntc_BitPosMask[Id]; /* * Disable the selected interrupt source by reading the interrupt enable * register and then modifying only the specified interrupt id */ CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); }
/** * * Updates the interrupt table with the Null Handler and NULL arguments at the * location pointed at by the Id. This effectively disconnects that interrupt * source from any handler. The interrupt is disabled also. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the * highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Disconnect(XIntc * InstancePtr, u8 Id) { u32 CurrentIER; u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Disable the interrupt such that it won't occur while disconnecting * the handler, only disable the specified interrupt id without * modifying the other interrupt ids */ CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); Mask = XIntc_BitPosMask[Id];/* convert from integer id to bit mask */ XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); /* * Disconnect the handler and connect a stub, the callback reference * must be set to this instance to allow unhandled interrupts to be * tracked */ InstancePtr->CfgPtr->HandlerTable[Id].Handler = StubHandler; InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; }
/** * * Starts the interrupt controller by enabling the output from the controller * to the processor. Interrupts may be generated by the interrupt controller * after this function is called. * * It is necessary for the caller to connect the interrupt handler of this * component to the proper interrupt source. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Mode determines if software is allowed to simulate interrupts or * real interrupts are allowed to occur. Note that these modes are * mutually exclusive. The interrupt controller hardware resets in * a mode that allows software to simulate interrupts until this * mode is exited. It cannot be reentered once it has been exited. * * One of the following values should be used for the mode. * - XIN_SIMULATION_MODE enables simulation of interrupts only * - XIN_REAL_MODE enables hardware interrupts only * * @return * - XST_SUCCESS if the device was started successfully * - XST_FAILURE if simulation mode was specified and it could not * be set because real mode has already been entered. * * @note Must be called after XIntc initialization is completed. * ******************************************************************************/ int XIntc_Start(XIntc * InstancePtr, u8 Mode) { u32 MasterEnable = XIN_INT_MASTER_ENABLE_MASK; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid((Mode == XIN_SIMULATION_MODE) || (Mode == XIN_REAL_MODE)) Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Check for simulation mode */ if (Mode == XIN_SIMULATION_MODE) { if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) { return XST_FAILURE; } } else { MasterEnable |= XIN_INT_HARDWARE_ENABLE_MASK; } /* * Indicate the instance is ready to be used and is started before we * enable the device. */ InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED; XIntc_Out32(InstancePtr->BaseAddress + XIN_MER_OFFSET, MasterEnable); return XST_SUCCESS; }
/** * * Starts the interrupt controller by enabling the output from the controller * to the processor. Interrupts may be generated by the interrupt controller * after this function is called. * * It is necessary for the caller to connect the interrupt handler of this * component to the proper interrupt source. This function also starts Slave * controllers in Cascade mode. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Mode determines if software is allowed to simulate interrupts or * real interrupts are allowed to occur. Note that these modes are * mutually exclusive. The interrupt controller hardware resets in * a mode that allows software to simulate interrupts until this * mode is exited. It cannot be reentered once it has been exited. * * One of the following values should be used for the mode. * - XIN_SIMULATION_MODE enables simulation of interrupts only * - XIN_REAL_MODE enables hardware interrupts only * * @return * - XST_SUCCESS if the device was started successfully * - XST_FAILURE if simulation mode was specified and it could not * be set because real mode has already been entered. * * @note Must be called after XIntc initialization is completed. * ******************************************************************************/ int XIntc_Start(XIntc * InstancePtr, u8 Mode) { u32 MasterEnable = XIN_INT_MASTER_ENABLE_MASK; XIntc_Config *CfgPtr; int Index; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid((Mode == XIN_SIMULATION_MODE) || (Mode == XIN_REAL_MODE)) Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Check for simulation mode */ if (Mode == XIN_SIMULATION_MODE) { if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) { return XST_FAILURE; } } else { MasterEnable |= XIN_INT_HARDWARE_ENABLE_MASK; } /* * Indicate the instance is ready to be used and is started before we * enable the device. */ InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED; /* Start the Slaves for Cascade Mode */ if (InstancePtr->CfgPtr->IntcType != XIN_INTC_NOCASCADE) { for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1; Index++) { CfgPtr = XIntc_LookupConfig(Index); XIntc_Out32(CfgPtr->BaseAddress + XIN_MER_OFFSET, MasterEnable); } } /* Start the master */ XIntc_Out32(InstancePtr->BaseAddress + XIN_MER_OFFSET, MasterEnable); return XST_SUCCESS; }
/** * * Enables the interrupt source provided as the argument Id. Any pending * interrupt condition for the specified Id will occur after this function is * called. In Cascade mode, enables corresponding interrupt of Slave controllers * depending on the Id. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being * the highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Enable(XIntc * InstancePtr, u8 Id) { u32 CurrentIER; u32 Mask; XIntc_Config *CfgPtr; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); if (Id > 31) { /* Enable user required Id in Slave controller */ CfgPtr = XIntc_LookupConfig(Id/32); CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER | Mask)); } else { /* * The Id is used to create the appropriate mask for the * desired bit position. */ Mask = XIntc_BitPosMask[Id]; /* * Enable the selected interrupt source by reading the * interrupt enable register and then modifying only the * specified interrupt id enable */ CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER | Mask)); } }
/** * * Stops the interrupt controller by disabling the output from the controller * so that no interrupts will be caused by the interrupt controller. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * * @return None. * * @note None. * ******************************************************************************/ void XIntc_Stop(XIntc * InstancePtr) { /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Stop all interrupts from occurring thru the interrupt controller by * disabling all interrupts in the MER register */ XIntc_Out32(InstancePtr->BaseAddress + XIN_MER_OFFSET, 0); InstancePtr->IsStarted = 0; }
/** * * Allows software to simulate an interrupt in the interrupt controller. This * function will only be successful when the interrupt controller has been * started in simulation mode. Once it has been started in real mode, * interrupts cannot be simulated. A simulated interrupt allows the interrupt * controller to be tested without any device to drive an interrupt input * signal into it. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id is the interrupt ID for which to simulate an interrupt. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if the interrupt could not be * simulated because the interrupt controller is or * has previously been in real mode. * * @note None. * ******************************************************************************/ int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id) { u32 Mask; u32 MasterEnable; /* * Assert the arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); /* Get the contents of the master enable register and determine if * hardware interrupts have already been enabled, if so, this is a write * once bit such that simulation can't be done at this point because * the ISR register is no longer writable by software */ MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET); if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) { return XST_FAILURE; } /* * The Id is used to create the appropriate mask for the * desired bit position. Id currently limited to 0 - 31 */ Mask = XIntc_BitPosMask[Id]; /* * Enable the selected interrupt source by reading the interrupt enable * register and then modifying only the specified interrupt id enable */ XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask); /* indicate the interrupt was successfully simulated */ return XST_SUCCESS; }
/** * * Acknowledges the interrupt source provided as the argument Id. When the * interrupt is acknowledged, it causes the interrupt controller to clear its * interrupt condition. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the * highest priority interrupt. * * @return None. * * @note None. * ****************************************************************************/ void XIntc_Acknowledge(XIntc * InstancePtr, u8 Id) { u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * The Id is used to create the appropriate mask for the * desired bit position. Id currently limited to 0 - 31 */ Mask = XIntc_BitPosMask[Id]; /* * Acknowledge the selected interrupt source, no read of the acknowledge * register is necessary since only the bits set in the mask will be * affected by the write */ XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Mask); }
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { unsigned long ulControlReg, ulMask; /* NOTE: The baud rate used by this driver is determined by the hardware parameterization of the UART Lite peripheral, and the baud value passed to this function has no effect. */ /* Create the queues used to hold Rx and Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); if( ( xRxedChars ) && ( xCharsForTx ) ) { /* Disable the interrupt. */ XUartLite_mDisableIntr( XPAR_RS232_UART_BASEADDR ); /* Flush the fifos. */ ulControlReg = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET ); XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_CONTROL_REG_OFFSET, ulControlReg | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET ); /* Enable the interrupt again. The interrupt controller has not yet been initialised so there is no chance of receiving an interrupt until the scheduler has been started. */ XUartLite_mEnableIntr( XPAR_RS232_UART_BASEADDR ); /* Enable the interrupt in the interrupt controller while maintaining all the other bit settings. */ ulMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) ); ulMask |= XPAR_RS232_UART_INTERRUPT_MASK; XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( ulMask ) ); XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 2 ); } return ( xComPortHandle ) 0; }
/** * * Sets the normal interrupt mode for the specified interrupt in the Interrupt * Mode Register. In Cascade mode disconnects handler from corresponding Slave * controller IVAR register depending on the Id and sets all interrupt sources * of the Slave controller as normal interrupts. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the * highest priority interrupt. * * @return None. * * @note * Slave controllers in Cascade Mode should have all as Fast * interrupts or Normal interrupts, mixed interrupts are not * supported * ****************************************************************************/ void XIntc_SetNormalIntrMode(XIntc *InstancePtr, u8 Id) { u32 Imr; u32 CurrentIER; u32 Mask; XIntc_Config *CfgPtr; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(InstancePtr->CfgPtr->FastIntr == TRUE); if (Id > 31) { /* Enable user required Id in Slave controller */ CfgPtr = XIntc_LookupConfig(Id/32); /* Get the Enabled Interrupts */ CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; /* Disable the Interrupt if it was enabled before calling * this function */ if (CurrentIER & Mask) { XIntc_Disable(InstancePtr, Id); } /* Slave controllers in Cascade Mode should have all as Fast * interrupts or Normal interrupts, mixed interrupts are not * supported */ XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0x0); if (CfgPtr->IntVectorAddr == 0x0) { XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), 0x10); } else { XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), CfgPtr->IntVectorAddr); } /* Enable the Interrupt if it was enabled before calling this * function */ if (CurrentIER & Mask) { XIntc_Enable(InstancePtr, Id); } } else { /* Get the Enabled Interrupts */ CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); Mask = XIntc_BitPosMask[Id];/* Convert from integer id to bit mask */ /* Disable the Interrupt if it was enabled before * calling this function */ if (CurrentIER & Mask) { XIntc_Disable(InstancePtr, Id); } /* * Disable the selected interrupt as Fast Interrupt by reading the * interrupt mode register and then modifying only the * specified interrupt id */ Imr = XIntc_In32(InstancePtr->BaseAddress + XIN_IMR_OFFSET); XIntc_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, Imr & ~Mask); if (InstancePtr->CfgPtr->IntVectorAddr == 0x0) { XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), 0x10); } else { XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), InstancePtr->CfgPtr->IntVectorAddr); } /* Enable the Interrupt if it was enabled before * calling this function */ if (CurrentIER & Mask) { XIntc_Enable(InstancePtr, Id); } } }
/** * * Initializes Slave controllers in Cascade mode. The initialization entails: * - Initial vector table with stub function calls * - All interrupt sources are disabled for last controller. * - All interrupt sources are disabled except sources to 31 pin of * primary and secondary controllers * - Interrupt outputs are disabled * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * * @return None * * @note None. * ******************************************************************************/ static void XIntc_InitializeSlaves(XIntc * InstancePtr) { int Index; u32 Mask; XIntc_Config *CfgPtr; int Id; Mask = XIntc_BitPosMask[31]; /* Convert from integer id to bit mask */ /* Enable interrupt id with 31 for Master * interrupt controller */ XIntc_Out32(InstancePtr->CfgPtr->BaseAddress + XIN_IER_OFFSET, Mask); for (Index = 1; Index <= XPAR_XINTC_NUM_INSTANCES - 1; Index++) { CfgPtr = XIntc_LookupConfig(Index); XIntc_Out32(CfgPtr->BaseAddress + XIN_IAR_OFFSET, 0xFFFFFFFF); if (CfgPtr->IntcType != XIN_INTC_LAST) { /* Enable interrupt ids with 31 for secondary * interrupt controllers */ XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, Mask); } else { XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, 0x0); } /* Disable Interrupt output */ XIntc_Out32(CfgPtr->BaseAddress + XIN_MER_OFFSET, 0); /* Set all interrupts as normal mode if Fast Interrupts * are enabled */ if(CfgPtr->FastIntr == TRUE) { XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0); } /* * Initialize all the data needed to perform interrupt * processing for each interrupt ID up to the maximum used */ for (Id = 0; Id < CfgPtr->NumberofIntrs; Id++) { /* * Initalize the handler to point to a stub to handle an * interrupt which has not been connected to a handler. * Only initialize it if the handler is 0 or * XNullHandler, which means it was not initialized * statically by the tools/user.Set the callback * reference to this instance so that unhandled * interrupts can be tracked. */ if ((CfgPtr->HandlerTable[Id].Handler == 0) || (CfgPtr->HandlerTable[Id].Handler == XNullHandler)) { CfgPtr->HandlerTable[Id].Handler = StubHandler; } CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; } } }
/** * * Makes the connection between the Id of the interrupt source and the * associated handler that is to run when the interrupt is recognized.In Cascade * mode, connects handler to corresponding Slave controller IVAR register * depending on the Id and sets all interrupt sources of the Slave controller as * fast interrupts. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being * the highest priority interrupt. * @param Handler to the handler for that interrupt. * * @return * - XST_SUCCESS * * @note * Slave controllers in Cascade Mode should have all as Fast * interrupts or Normal interrupts, mixed interrupts are not * supported * * WARNING: The handler provided as an argument will overwrite any handler * that was previously connected. * ****************************************************************************/ int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id, XFastInterruptHandler Handler) { u32 Imr; u32 CurrentIER; u32 Mask; XIntc_Config *CfgPtr; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); Xil_AssertNonvoid(Handler != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(InstancePtr->CfgPtr->FastIntr == TRUE); if (Id > 31) { /* Enable user required Id in Slave controller */ CfgPtr = XIntc_LookupConfig(Id/32); if (CfgPtr->FastIntr != TRUE) { /*Fast interrupts of slave controller are not enabled*/ return XST_FAILURE; } /* Get the Enabled Interrupts */ CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; /* Disable the Interrupt if it was enabled before calling * this function */ if (CurrentIER & Mask) { XIntc_Disable(InstancePtr, Id); } XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET + ((Id%32) * 4), (u32) Handler); /* Slave controllers in Cascade Mode should have all as Fast * interrupts or Normal interrupts, mixed interrupts are not * supported */ XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF); /* Enable the Interrupt if it was enabled before calling this * function */ if (CurrentIER & Mask) { XIntc_Enable(InstancePtr, Id); } } else { /* Get the Enabled Interrupts */ CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[Id]; /* Disable the Interrupt if it was enabled before calling * this function */ if (CurrentIER & Mask) { XIntc_Disable(InstancePtr, Id); } XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), (u32) Handler); Imr = XIntc_In32(InstancePtr->BaseAddress + XIN_IMR_OFFSET); XIntc_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, Imr | Mask); /* Enable the Interrupt if it was enabled before * calling this function */ if (CurrentIER & Mask) { XIntc_Enable(InstancePtr, Id); } } return XST_SUCCESS; }
/** * * Register a fast handler function for a specific interrupt ID. The handler * function will be called when an interrupt occurs for the given interrupt ID. * In Cascade mode Interrupt Id is used to set Handler for corresponding Slave * Controller * * @param BaseAddress is the base address of the interrupt controller * whose vector table will be modified. * @param InterruptId is the interrupt ID to be associated with the input * handler. * @param FastHandler is the function pointer that will be called when * interrupt occurs * * @return None. * * @note * * Note that this function has no effect if the input base address is invalid. * ******************************************************************************/ void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id, XFastInterruptHandler FastHandler) { u32 CurrentIER; u32 Mask; u32 Imr; XIntc_Config *CfgPtr; if (Id > 31) { /* Enable user required Id in Slave controller */ CfgPtr = XIntc_LookupConfig(Id/32); /* Get the Enabled Interrupts */ CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[(Id%32)]; /* Disable the Interrupt if it was enabled before calling * this function */ if (CurrentIER & Mask) { XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); } XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET + ((Id%32) * 4), (u32) FastHandler); /* Slave controllers in Cascade Mode should have all as Fast * interrupts or Normal interrupts, mixed interrupts are not * supported */ XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF); /* Enable the Interrupt if it was enabled before calling this * function */ if (CurrentIER & Mask) { XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET, (CurrentIER | Mask)); } } else { CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); /* Convert from integer id to bit mask */ Mask = XIntc_BitPosMask[Id]; if (CurrentIER & Mask) { /* Disable Interrupt if it was enabled */ CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); XIntc_Out32(BaseAddress + XIN_IER_OFFSET, (CurrentIER & ~Mask)); } XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4), (u32) FastHandler); Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET); XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask); /* Enable Interrupt if it was enabled before calling * this function */ if (CurrentIER & Mask) { CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET); XIntc_Out32(BaseAddress + XIN_IER_OFFSET, (CurrentIER | Mask)); } } }
/** * * Run a self-test on the driver/device. This is a destructive test. * * This involves forcing interrupts into the controller and verifying that they * are recognized and can be acknowledged. This test will not succeed if the * interrupt controller has been started in real mode such that interrupts * cannot be forced. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * * @return * - XST_SUCCESS if self-test is successful. * - XST_INTC_FAIL_SELFTEST if the Interrupt controller fails the * self-test. It will fail the self test if the device has * previously been started in real mode. * * @note None. * ******************************************************************************/ int XIntc_SelfTest(XIntc * InstancePtr) { u32 CurrentISR; u32 Temp; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Acknowledge all pending interrupts by reading the interrupt status * register and writing the value to the acknowledge register */ Temp = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET); XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Temp); /* * Verify that there are no interrupts by reading the interrupt status */ CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET); /* * ISR should be zero after all interrupts are acknowledged */ if (CurrentISR != 0) { return XST_INTC_FAIL_SELFTEST; } /* * Set a bit in the ISR which simulates an interrupt */ XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, XIN_TEST_MASK); /* * Verify that it was set */ CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET); if (CurrentISR != XIN_TEST_MASK) { return XST_INTC_FAIL_SELFTEST; } /* * Acknowledge the interrupt */ XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, XIN_TEST_MASK); /* * Read back the ISR to verify that the interrupt is gone */ CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET); if (CurrentISR != 0) { return XST_INTC_FAIL_SELFTEST; } return XST_SUCCESS; }
/** * * Allows software to simulate an interrupt in the interrupt controller. This * function will only be successful when the interrupt controller has been * started in simulation mode. Once it has been started in real mode, * interrupts cannot be simulated. A simulated interrupt allows the interrupt * controller to be tested without any device to drive an interrupt input * signal into it. In Cascade mode writes to ISR of appropraite Slave * controller depending on Id. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Id is the interrupt ID for which to simulate an interrupt. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if the interrupt could not be * simulated because the interrupt controller is or * has previously been in real mode. * * @note None. * ******************************************************************************/ int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id) { u32 Mask; u32 MasterEnable; XIntc_Config *CfgPtr; int Index; int DeviceId; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS); /* Get the contents of the master enable register and determine if * hardware interrupts have already been enabled, if so, this is a write * once bit such that simulation can't be done at this point because * the ISR register is no longer writable by software */ MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET); if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) { return XST_FAILURE; } if (Id > 31) { DeviceId = Id/32; CfgPtr = XIntc_LookupConfig(Id/32); Mask = XIntc_BitPosMask[Id%32]; XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET, Mask); /* Generate interrupt for 31 by writing to Interrupt Status * register of parent controllers. Primary controller ISR * will be written last in the loop */ Mask = XIntc_BitPosMask[31]; for (Index = DeviceId - 1; Index >= 0; Index--) { CfgPtr = XIntc_LookupConfig(Index); XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET, Mask); } } else { /* * The Id is used to create the appropriate mask for the * desired bit position. */ Mask = XIntc_BitPosMask[Id]; /* * Enable the selected interrupt source by reading the interrupt * enable register and then modifying only the specified * interrupt id enable */ XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask); } /* indicate the interrupt was successfully simulated */ return XST_SUCCESS; }
/** * * Initialize a specific interrupt controller instance/driver. The * initialization entails: * * - Initialize fields of the XIntc structure * - Initial vector table with stub function calls * - All interrupt sources are disabled * - Interrupt output is disabled * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param DeviceId is the unique id of the device controlled by this XIntc * instance. Passing in a device id associates the generic XIntc * instance to a specific device, as chosen by the caller or * application developer. * * @return * - XST_SUCCESS if initialization was successful * - XST_DEVICE_IS_STARTED if the device has already been started * - XST_DEVICE_NOT_FOUND if device configuration information was * not found for a device with the supplied device ID. * * @note In Cascade mode this function calls XIntc_InitializeSlaves to * initialiaze Slave Interrupt controllers. * ******************************************************************************/ int XIntc_Initialize(XIntc * InstancePtr, u16 DeviceId) { u8 Id; XIntc_Config *CfgPtr; u32 NextBitMask = 1; Xil_AssertNonvoid(InstancePtr != NULL); /* * If the device is started, disallow the initialize and return a status * indicating it is started. This allows the user to stop the device * and reinitialize, but prevents a user from inadvertently initializing */ if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) { return XST_DEVICE_IS_STARTED; } /* * Lookup the device configuration in the CROM table. Use this * configuration info down below when initializing this component. */ CfgPtr = XIntc_LookupConfig(DeviceId); if (CfgPtr == NULL) { return XST_DEVICE_NOT_FOUND; } /* * Set some default values */ InstancePtr->IsReady = 0; InstancePtr->IsStarted = 0; /* not started */ InstancePtr->CfgPtr = CfgPtr; InstancePtr->CfgPtr->Options = XIN_SVC_SGL_ISR_OPTION; InstancePtr->CfgPtr->IntcType = CfgPtr->IntcType; /* * Save the base address pointer such that the registers of the * interrupt can be accessed */ #if (XPAR_XINTC_USE_DCR_BRIDGE != 0) InstancePtr->BaseAddress = ((CfgPtr->BaseAddress >> 2)) & 0xFFF; #else InstancePtr->BaseAddress = CfgPtr->BaseAddress; #endif /* * Initialize all the data needed to perform interrupt processing for * each interrupt ID up to the maximum used */ for (Id = 0; Id < CfgPtr->NumberofIntrs; Id++) { /* * Initalize the handler to point to a stub to handle an * interrupt which has not been connected to a handler. Only * initialize it if the handler is 0 or XNullHandler, which * means it was not initialized statically by the tools/user. * Set the callback reference to this instance so that * unhandled interrupts can be tracked. */ if ((InstancePtr->CfgPtr->HandlerTable[Id].Handler == 0) || (InstancePtr->CfgPtr->HandlerTable[Id].Handler == XNullHandler)) { InstancePtr->CfgPtr->HandlerTable[Id].Handler = StubHandler; } InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; /* * Initialize the bit position mask table such that bit * positions are lookups only for each interrupt id, with 0 * being a special case * (XIntc_BitPosMask[] = { 1, 2, 4, 8, ... }) */ XIntc_BitPosMask[Id] = NextBitMask; NextBitMask *= 2; } /* * Disable IRQ output signal * Disable all interrupt sources * Acknowledge all sources */ XIntc_Out32(InstancePtr->BaseAddress + XIN_MER_OFFSET, 0); XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, 0); XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, 0xFFFFFFFF); /* * If the fast Interrupt mode is enabled then set all the * interrupts as normal mode. */ if(InstancePtr->CfgPtr->FastIntr == TRUE) { XIntc_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, 0); } /* Initialize slaves in Cascade mode*/ if (InstancePtr->CfgPtr->IntcType != XIN_INTC_NOCASCADE) { XIntc_InitializeSlaves(InstancePtr); } /* * Indicate the instance is now ready to use, successfully initialized */ InstancePtr->IsReady = XIL_COMPONENT_IS_READY; return XST_SUCCESS; }