Sign In

Don't have a Xilinx account yet?

  • Choose to receive important news and product information
  • Gain access to special content
  • Personalize your web experience on Xilinx.com

Create Account

Username

Password

Forgot your password?
XClose Panel
Xilinx Home
Reply
Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009
0
Accepted Solution

two interrupts from one custom core?

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_IRPT_INTR, (XInterruptHandler)mee_handler, 0);

 

 

How do I separate the two interrupt signals i'm generating to use two handlers?

 

Best,

JM

Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009
0

Re: two interrupts from one custom core?

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

Contributor
aaron_eda
Posts: 29
Registered: ‎05-07-2009
0

Re: two interrupts from one custom core?

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.

 

Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009
0

Re: two interrupts from one custom core?

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

Regular Visitor
thobmei
Posts: 40
Registered: ‎05-28-2010
0

Re: two interrupts from one custom core?

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_OFFSET);
      
    xil_printf("Vector %x\r\n",IpStatus);
    
    //MA_TIMER_DUAL2_mWriteReg(XPAR_MA_TIMER_DUAL2_0_BASEADDR, MA_TIMER_DUAL2_INTR_IPISR_OFFSET, IpStatus);
    
  // If timer caused the interrupt then switch LEDs
 
  Xuint32 status;

  status = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASEADDR, MA_TIMER_DUAL2_INTR_CNTRL_SPACE_OFFSET);
  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_BASEADDR, MA_TIMER_DUAL2_INTR_DIER_OFFSET, 4/*0xFFFFFFFF*/);

  IpStatus = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASEADDR,MA_TIMER_DUAL2_INTR_DIER_OFFSET);
    xil_printf("Enabled REGISTERS %x\r\n",IpStatus);
 
  xil_printf("    SUCCESS!\r\n");
 
  IpStatus = XIntc_mGetIntrStatus(MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
  xil_printf("Vector %x\r\n",IpStatus);
 
  while(1){
  }
}

 

 

 

 

Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009
0

Re: two interrupts from one custom core?

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

 

Regular Visitor
thobmei
Posts: 40
Registered: ‎05-28-2010
0

Re: two interrupts from one custom core?

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_OFFSET);
      
    xil_printf("Vector %x\r\n",IpStatus);
    
    //MA_TIMER_DUAL2_mWriteReg(XPAR_MA_TIMER_DUAL2_0_BASEADDR, MA_TIMER_DUAL2_INTR_IPISR_OFFSET, IpStatus);
    
  // If timer caused the interrupt then switch LEDs
 
  Xuint32 status;

  status = MA_TIMER_DUAL2_mReadReg(XPAR_MA_TIMER_DUAL2_0_BASEADDR, MA_TIMER_DUAL2_INTR_CNTRL_SPACE_OFFSET);
  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

 

Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

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_OFFSET);

 

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.

Regular Visitor
thobmei
Posts: 40
Registered: ‎05-28-2010
0

Re: two interrupts from one custom core?

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){
  }
}

Super Contributor
jmonteiro-dme
Posts: 183
Registered: ‎05-15-2009
0

Re: two interrupts from one custom core?

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