- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-07-2009 03:37 AM
Hello,
I have a custom core generating two interrupts, i.e., it drives IP2Bus_IntrEvent(0) andIP2Bus_IntrEvent(1). However, i don't understand how to attribute separate handlers using software. I only see one flag to register the handler in xparameters.h, which is like this:
XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR, XPAR_XPS_INTC_0_UNAV_SW_HW_INTERFACE_0_IP2INTC_IRP
How do I separate the two interrupt signals i'm generating to use two handlers?
Best,
JM
Solved! Go to Solution.
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-08-2009 10:03 AM
I have managed to understand this.
The custom core only provides an interrupt signal to the interrupt controller attached to the PLB, however the IPIF wrapper of the core possesses an interrupt controller which, in turn, has the ip interrupt control status register, acessible by software. Hence, the registered handler must check this register and see what interrupt source has generated the interrupt.
It now works fine.
Best,
JM
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-08-2009 07:29 PM
Hello, JM,
In my XPS project, I add Uart and EMAC to my project by the wizard. I enable all interrupt of these two peripherals. After generate and download bit stream to my board, I run the testapp software. But the testapp_peripheral does not run successfully with the Information which shows on the hyperterminal as follows:
-----------------------
......
Running Interrupt Test for Ethernet_MAC ...
------------------------
I check the port connection in System Assembly View. Uart's interrupt signal requires interrupt process through xps_intc_0. But EMAC's interrupt signal does not connect to PPC.
Is adding two peripeherals with interrupt enabled not unallowed?
How to deal with multiple interrupt sources?
Thank you very much!
Best regards,
Aaron.
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-09-2009 03:19 AM
Hello Aaron,
You can generate multiple interrupts with one peripheral or even multiple interrupts with various peripherals. Make sure you connect their interrupt output to the interrupt controller. You can accomplish this easily within the system assembly view->ports in EDK. The Interrupt controller attached to the PLB is responsible for the interrupt management to the processor, but since it has only one interrupt request line to the processor, it implements a multiplexer to go through all possible interrupt sources connected to it.
If using only one peripheral, you can connect the interrupt signal directly to the processor, however this can't be done when using different hardware interrupt sources.
In your case, if you are not changing anything, it should work by default, unless there is a bug. try to see with XMD where the testapp is stalling. For this, open XMD(Debug->XMD, and then run the software debugger (Debug->Software debugger).
Best,
JM
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 04:13 AM
Im Trying 2 geht tow Different Interrupts from MyIPIF. The Ipif is connected to the INTC_0.
Thats the Way I added the Interrupt souces 2 the IP2Bus_IntrEvent:
IP2Bus_IntrEvent(0) <= temp;
IP2Bus_IntrEvent(1) <= temp1;
both are recognized by the Microblaze but when I try to figgure out wich of them occured I always get the same respone:
- Enabling interrupts
Enabled REGISTERS 4
SUCCESS!
Vector 20E00000
Some interrupt!
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
(...)
So I cant see if temp or temp1 occured,
Thats my C programm:
#include "xparameters.h"
#include "xbasic_types.h"
#include "xstatus.h"
#include "ma_timer_dual2.h"
#include "xintc.h"
Xuint32 my_timer;
unsigned int *my_timer_p =
(unsigned int *) XPAR_MA_TIMER_DUAL2_0_BASEADDR;
//------------------------------------------------
// INTERRUPT HANDLER FUNCTION
//------------------------------------------------
void MA_TIMER_DUAL2_Intr_Handler(void * baseaddr_p)
{
static Xuint32 led_data;
Xuint32 baseaddr;
Xuint32 IpStatus;
baseaddr = (Xuint32) baseaddr_p;
xil_printf("Some interrupt!\r\n");
// Get the timer interrupt status
IpStatus = XIntc_mGetIntrStatus(MA_TIMER_DUAL2_INTR_IPISR_OFF
xil_printf("Vector %x\r\n",IpStatus);
//MA_TIMER_DUAL2_mWriteReg(XPAR_MA_TIMER_DUAL2_0_
// If timer caused the interrupt then switch LEDs
Xuint32 status;
status = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASE
xil_printf("Vector %x\r\n",status);
//
//XIntc_Acknowledge();
if (IpStatus){
}
}
//------------------------------------------------
// MAIN FUNCTION
//------------------------------------------------
int main (void)
{
Xuint32 status;
Xuint32 IpStatus;
//------------------------------------------------
// REGISTER INTERRUPT HANDLER
//------------------------------------------------
xil_printf(" - Registering interrupt handler\r\n");
XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
XPAR_XPS_INTC_0_MA_TIMER_DUAL2_0_IP2INTC_IRPT_INTR
MA_TIMER_DUAL2_Intr_Handler,
(void *)XPAR_MA_TIMER_DUAL2_0_BASEADDR);
//------------------------------------------------
// ENABLE INTERRUPTS
//------------------------------------------------
xil_printf(" - Enabling interrupts\r\n");
// Enable INTC interrupts
XIntc_mMasterEnable(XPAR_XPS_INTC_0_BASEADDR);
XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR,
XPAR_MA_TIMER_DUAL2_0_IP2INTC_IRPT_MASK);
// Enable timer interrupts
MA_TIMER_DUAL2_EnableInterrupt(my_timer_p);
// Enable Microblaze interrupts
microblaze_enable_interrupts();
MA_TIMER_DUAL2_mWriteReg(XPAR_MA_TIMER_DUAL2_0_BAS
IpStatus = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASE
xil_printf("Enabled REGISTERS %x\r\n",IpStatus);
xil_printf(" SUCCESS!\r\n");
IpStatus = XIntc_mGetIntrStatus(MA_TIMER_DUAL2_INTR_IPISR_OFF
xil_printf("Vector %x\r\n",IpStatus);
while(1){
}
}
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 04:45 AM
It seems that your handler is being called in inf loop.
Clear the interrupt at the end of the handler by writing back lpstatus. Ex:
xil_printf("User logic interrupt! \n\r");
IpStatus = FE_CF_INTERFACE_mReadReg(baseaddr, FE_CF_INTERFACE_INTR_IPISR_OFFSET);
FE_CF_INTERFACE_mWriteReg(baseaddr, FE_CF_INTERFACE_INTR_IPISR_OFFSET, IpStatus);
And see if the interrupt status register starts to change.
Best,
JM
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 05:16 AM
thx 4 your help ...
I modified my ISR
but I still geht the same Messages:
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
Some interrupt!
Vector 20E00000
Vector 0
The new ISR:
//------------------------------------------------
// INTERRUPT HANDLER FUNCTION
//------------------------------------------------
void MA_TIMER_DUAL2_Intr_Handler(void * baseaddr_p)
{
static Xuint32 led_data;
Xuint32 baseaddr;
Xuint32 IpStatus;
baseaddr = (Xuint32) baseaddr_p;
xil_printf("Some interrupt!\r\n");
// Get the timer interrupt status
IpStatus = XIntc_mGetIntrStatus(MA_TIMER_DUAL2_INTR_IPISR_OFF
xil_printf("Vector %x\r\n",IpStatus);
//MA_TIMER_DUAL2_mWriteReg(XPAR_MA_TIMER_DUAL2_0_
// If timer caused the interrupt then switch LEDs
Xuint32 status;
status = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASE
xil_printf("Vector %x\r\n",status);
IpStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
MA_TIMER_DUAL2_mWriteReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET, IpStatus);
//
//XIntc_Acknowledge();
if (IpStatus){
}
}
Best,
/me
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 05:56 AM
A couple of things:
1) I'm not sure about XIntc_mGetIntrStatus to read the status register. Use
IpStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
instead of
IpStatus = XIntc_mGetIntrStatus(MA_TIMER_DUAL2_INTR_IPISR_OFF
2) Also i don't see why you read status and lpStatus and print both as Vector XX..
3) Make sure the base address is being passed into the handler.
4) Go into the drivers/your_custom_core/src to get an example on how you can correctly activate and manage interrupts for your custom core. You should use your driver auto-generated functions to correctly initialize the interrputs.
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 08:16 AM
thx ...
the autogenerated handler is quite useful.
I cleand the code acording to your suggestions, but the problem is still the same ... no Difference between the Interrupts.
- Registering interrupt handler
- Enabling interrupts
SUCCESS!
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000
Code:
#include "xparameters.h"
#include "xbasic_types.h"
#include "xstatus.h"
#include "ma_timer_dual2.h"
#include "xintc.h"
//------------------------------------------------
// INTERRUPT HANDLER FUNCTION
//------------------------------------------------
void MA_TIMER_DUAL2_Intr_Handler(void * baseaddr_p)
{
Xuint32 baseaddr;
Xuint32 IntrStatus;
Xuint32 IpStatus;
baseaddr = (Xuint32) baseaddr_p;
/*
* Get status from Device Interrupt Status Register.
*/
IntrStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_DISR_OFFSET);
xil_printf("Device Interrupt! DISR value : 0x%08x \n\r", IntrStatus);
/*
* Verify the source of the interrupt is the user logic and clear the interrupt
* source by toggle write baca to the IP ISR register.
*/
if ( (IntrStatus & INTR_IPIR_MASK) == INTR_IPIR_MASK )
{
xil_printf("User logic interrupt! \n\r");
IpStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
MA_TIMER_DUAL2_mWriteReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET, IpStatus);
}
}
//------------------------------------------------
// MAIN FUNCTION
//------------------------------------------------
int main (void)
{
Xuint32 status;
Xuint32 IpStatus;
//------------------------------------------------
// REGISTER INTERRUPT HANDLER
//------------------------------------------------
xil_printf(" - Registering interrupt handler\r\n");
XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
XPAR_XPS_INTC_0_MA_TIMER_DUAL2_0_IP2INTC_IRPT_INTR
MA_TIMER_DUAL2_Intr_Handler,
(void *)XPAR_MA_TIMER_DUAL2_0_BASEADDR);
//------------------------------------------------
// ENABLE INTERRUPTS
//------------------------------------------------
xil_printf(" - Enabling interrupts\r\n");
// Enable INTC interrupts
XIntc_mMasterEnable(XPAR_XPS_INTC_0_BASEADDR);
XIntc_mEnableIntr(XPAR_XPS_INTC_0_BASEADDR,
XPAR_MA_TIMER_DUAL2_0_IP2INTC_IRPT_MASK);
// Enable timer interrupts
MA_TIMER_DUAL2_EnableInterrupt((void *)XPAR_MA_TIMER_DUAL2_0_BASEADDR);
// Enable Microblaze interrupts
microblaze_enable_interrupts();
xil_printf(" SUCCESS!\r\n");
while(1){
}
}
Re: two interrupts from one custom core?
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
07-14-2010 09:03 AM
In this case you should read from the IPIF wrapper interrupt controller to see what is the source of the core interrupt, not the device interrupt.
Try this:
IntrStatus = XIo_In32(BASE_ADDR + MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
instead of
IntrStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_DISR_OFFSET);
Best,
JM











