📄 xscugic.c
字号:
/* * The Int_Id is used as an index into the table to select the proper * handler */ InstancePtr->Config->HandlerTable[Int_Id].Handler = Handler; InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = CallBackRef; return XST_SUCCESS;}/*****************************************************************************//**** Updates the interrupt table with the Null Handler and NULL arguments at the* location pointed at by the Int_Id. This effectively disconnects that interrupt* source from any handler. The interrupt is disabled also.** @param InstancePtr is a pointer to the XScuGic instance to be worked on.* @param Int_Id contains the ID of the interrupt source and should* be in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1** @return None.** @note None.*****************************************************************************/void XScuGic_Disconnect(XScuGic *InstancePtr, u32 Int_Id){ u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * The Int_Id is used to create the appropriate mask for the * desired bit position. Int_Id currently limited to 0 - 31 */ Mask = 0x00000001 << (Int_Id % 32); /* * 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 */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DISABLE_OFFSET + ((Int_Id / 32) * 4), 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->Config->HandlerTable[Int_Id].Handler = StubHandler; InstancePtr->Config->HandlerTable[Int_Id].CallBackRef = InstancePtr;}/*****************************************************************************//**** Enables the interrupt source provided as the argument Int_Id. Any pending* interrupt condition for the specified Int_Id will occur after this function is* called.** @param InstancePtr is a pointer to the XScuGic instance.* @param Int_Id contains the ID of the interrupt source and should be* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1** @return None.** @note None.*****************************************************************************/void XScuGic_Enable(XScuGic *InstancePtr, u32 Int_Id){ u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * The Int_Id is used to create the appropriate mask for the * desired bit position. Int_Id currently limited to 0 - 31 */ Mask = 0x00000001 << (Int_Id % 32); /* * Enable the selected interrupt source by setting the * corresponding bit in the Enable Set register. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_ENABLE_SET_OFFSET + ((Int_Id / 32) * 4), Mask);}/*****************************************************************************//**** Disables the interrupt source provided as the argument Int_Id such that the* interrupt controller will not cause interrupts for the specified Int_Id. The* interrupt controller will continue to hold an interrupt condition for the* Int_Id, but will not cause an interrupt.** @param InstancePtr is a pointer to the XScuGic instance.* @param Int_Id contains the ID of the interrupt source and should be* in the range of 0 to XSCUGIC_MAX_NUM_INTR_INPUTS - 1** @return None.** @note None.*****************************************************************************/void XScuGic_Disable(XScuGic *InstancePtr, u32 Int_Id){ u32 Mask; /* * Assert the arguments */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * The Int_Id is used to create the appropriate mask for the * desired bit position. Int_Id currently limited to 0 - 31 */ Mask = 0x00000001 << (Int_Id % 32); /* * Disable the selected interrupt source by setting the * corresponding bit in the IDR. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_DISABLE_OFFSET + ((Int_Id / 32) * 4), Mask);}/*****************************************************************************//**** 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. 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 XScuGic instance.* @param Int_Id is the software interrupt ID to simulate an interrupt.* @param Cpu_Id is the list of CPUs to send the interrupt.** @return** XST_SUCCESS if successful, or XST_FAILURE if the interrupt could not be* simulated** @note None.*******************************************************************************/int XScuGic_SoftwareIntr(XScuGic *InstancePtr, u32 Int_Id, u32 Cpu_Id){ u32 Mask; /* * Assert the arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(Int_Id <= 15) ; Xil_AssertNonvoid(Cpu_Id <= 255) ; /* * The Int_Id is used to create the appropriate mask for the * desired interrupt. Int_Id currently limited to 0 - 15 * Use the target list for the Cpu ID. */ Mask = ((Cpu_Id << 16) | Int_Id) & (XSCUGIC_SFI_TRIG_CPU_MASK | XSCUGIC_SFI_TRIG_INTID_MASK); /* * Write to the Software interrupt trigger register. Use the appropriate * CPU Int_Id. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_SFI_TRIG_OFFSET, Mask); /* Indicate the interrupt was successfully simulated */ return XST_SUCCESS;}/*****************************************************************************//**** A stub for the asynchronous callback. The stub is here in case the upper* layers forget to set the handler.** @param CallBackRef is a pointer to the upper layer callback reference** @return None.** @note None.*******************************************************************************/static void StubHandler(void *CallBackRef) { /* * verify that the inputs are valid */ Xil_AssertVoid(CallBackRef != NULL); /* * Indicate another unhandled interrupt for stats */ ((XScuGic *)CallBackRef)->UnhandledInterrupts++;}/****************************************************************************//*** Sets the interrupt priority and trigger type for the specificd IRQ source.** @param InstancePtr is a pointer to the instance to be worked on.* @param Int_Id is the IRQ source number to modify* @param Priority is the new priority for the IRQ source. 0 is highest* priority, 0xFF is lowest.* @param Trigger is the new trigger type for the IRQ source.* Each bit pair describes the configuration for an INT_ID.* SFI Read Only b10 always* PPI Read Only depending on how the PPIs are configured.* b01 Active HIGH level sensitive* b11 Rising edge sensitive* SPI LSB is read only.* b01 Active HIGH level sensitive* b11 Rising edge sensitive/** @return None.** @note None.******************************************************************************/void XScuGic_SetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, u8 Priority, u8 Trigger){ u32 RegValue; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(Trigger <= XSCUGIC_INT_CFG_MASK); /* * Determine the register to write to using the Int_Id. */ RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); /* * Shift and Mask the correct bits for the priority and trigger in the * register */ RegValue &= ~(XSCUGIC_PRIORITY_MASK << ((Int_Id%4)*8)); RegValue |= Priority << ((Int_Id%4)*8); /* * Write the value back to the register. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id), RegValue); /* * Determine the register to write to using the Int_Id. */ RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id)); /* * Shift and Mask the correct bits for the priority and trigger in the * register */ RegValue &= ~(XSCUGIC_INT_CFG_MASK << ((Int_Id%16)*2)); RegValue |= Trigger << ((Int_Id%16)*2); /* * Write the value back to the register. */ XScuGic_DistWriteReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC(Int_Id), RegValue);}/****************************************************************************//*** Gets the interrupt priority and trigger type for the specificd IRQ source.** @param InstancePtr is a pointer to the instance to be worked on.* @param Int_Id is the IRQ source number to modify* @param Priority is a pointer to the value of the priority of the IRQ* source. This is a return value.* @param Trigger is pointer to the value of the trigger of the IRQ* source. This is a return value.** @return None.** @note None******************************************************************************/void XScuGic_GetPriorityTriggerType(XScuGic *InstancePtr, u32 Int_Id, u8 *Priority, u8 *Trigger){ u32 RegValue; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Int_Id < XSCUGIC_MAX_NUM_INTR_INPUTS); Xil_AssertVoid(Priority != NULL); Xil_AssertVoid(Trigger != NULL); /* * Determine the register to read to using the Int_Id. */ RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_PRIORITY_OFFSET_CALC(Int_Id)); /* * Shift and Mask the correct bits for the priority and trigger in the * register */ RegValue = RegValue >> ((Int_Id%4)*8); *Priority = RegValue & XSCUGIC_PRIORITY_MASK; /* * Determine the register to read to using the Int_Id. */ RegValue = XScuGic_DistReadReg(InstancePtr, XSCUGIC_INT_CFG_OFFSET_CALC (Int_Id)); /* * Shift and Mask the correct bits for the priority and trigger in the * register */ RegValue = RegValue >> ((Int_Id%16)*2); *Trigger = RegValue & XSCUGIC_INT_CFG_MASK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -