UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
12,353 Views
Registered: ‎05-15-2009

two interrupts from one custom core?

Jump to solution

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

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Explorer
Explorer
15,529 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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

0 Kudos
23 Replies
Highlighted
Explorer
Explorer
15,530 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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

0 Kudos
Participant aaron_eda
Participant
12,318 Views
Registered: ‎05-07-2009

Re: two interrupts from one custom core?

Jump to solution

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.

 

0 Kudos
Explorer
Explorer
12,311 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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

0 Kudos
Observer thobmei
Observer
10,854 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

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

 

 

 

 

0 Kudos
Explorer
Explorer
10,849 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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

 

0 Kudos
Observer thobmei
Observer
10,845 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

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

 

0 Kudos
Explorer
Explorer
10,838 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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.

Observer thobmei
Observer
10,828 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

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

Tags (3)
0 Kudos
Explorer
Explorer
10,821 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

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

0 Kudos
Observer thobmei
Observer
8,024 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

  - Registering interrupt handler
  - Enabling interrupts
    SUCCESS!
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000

 

still the same problem .....

I also tried

 

  IntrStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
    
  //IntrStatus = XIo_In32(baseaddr_p + MA_TIMER_DUAL2_INTR_IPISR_OFFSET);    
  xil_printf("Device Interrupt! DISR value : 0x%08x \n\r", IntrStatus);

 

without succsess.

 

Base and Highadress are the same in Xparameters and in the XPS .......

 

thats the full XPS projekt .....

http://mac.piffpaffpuff.net/timertest.zip

 

Best,

Tobias

0 Kudos
Observer thobmei
Observer
8,022 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

Using the Device ISC is ok?

 

Best

0 Kudos
Explorer
Explorer
8,014 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

No, try as i told you:

 

// Read from the IPIF wrapper interrupt controller to see what is the source of the core interrupt

IpStatus = XIo_In32(BASE_ADDR + UNAV_SW_HW_INTERFACE_INTR_IPISR_OFFSET);

 

where

 

#define BASE_ADDR XPAR_MA_TIMER_DUAL2_0_BASEADDR

 

(Confirm that XPAR_MA_TIMER_DUAL2_0_BASEADDR is the baseaddr on your xparameters.h)

 

lpStatus must not be zero, it has to have the value (1, 2) of the tinterrupt that triggered the ISR. This prompts me that you are not getting the value correctly.

 

 

Best,

JM

0 Kudos
Observer thobmei
Observer
8,011 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

 

 

IntrStatus = XIo_In32(baseaddr_p + MA_TIMER_DUAL2_INTR_IPISR_OFFSET);    
xil_printf("Device Interrupt! DISR value : 0x%08x \n\r", IntrStatus);

 

also returns:

 

  - 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
Device Interrupt! DISR value : 0x00000000

 

Thaks for still helping me JM

 

do you think I should rebuild the Projekt?

 

 

 

C 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_IPISR_OFFSET);
    
  IntrStatus = XIo_In32(baseaddr_p + MA_TIMER_DUAL2_INTR_IPISR_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){
  }
}

 

 

Xparameters:

 

/* Definitions for peripheral MA_TIMER_DUAL2_0 */
#define XPAR_MA_TIMER_DUAL2_0_DEVICE_ID 0
#define XPAR_MA_TIMER_DUAL2_0_BASEADDR 0xC3C00000
#define XPAR_MA_TIMER_DUAL2_0_HIGHADDR 0xC3C0FFFF

Tags (2)
0 Kudos
Explorer
Explorer
8,007 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

Read the posts carefully.

 

It is possible that the base address is not being correctly passed to the handler, so i suggested you to pass it hardcoded:


// Read from the IPIF wrapper interrupt controller to see what is the source of the core interrupt
IpStatus = XIo_In32(BASE_ADDR + UNAV_SW_HW_INTERFACE_INTR_IPISR_OFFSET);

where

#define BASE_ADDR XPAR_MA_TIMER_DUAL2_0_BASEADDR

 

instead of using baseaddr_p. As i said, lpStatus cannot be zero, it is possible that you are not reading this value correctly.

 

Check in xparameters.h if XPAR_MA_TIMER_DUAL2_0_BASEADDR is exactly your base address variable.

 

I also assume that you have these included:

 

// Generic needed libraries
#include "xparameters.h"
#include "xintc_l.h"

 

Best,

JM

0 Kudos
Observer thobmei
Observer
8,002 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

I checked the includes everything seems to be ok there ... 

 

I used

 

  IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL2_0_BASEADDR + MA_TIMER_DUAL2_INTR_IPISR_OFFSET);    
  xil_printf("Device Interrupt! DISR value : 0x%08x \n\r", IntrStatus);

 

But I still get Zerros all the time ..... no other Value ....

 

Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000
Device Interrupt! DISR value : 0x00000000

 

 

 

 

 

 

includes:

 

 

 

 

 

code:

 

(...)

 

* Get status from Device Interrupt Status Register.
   */
  //IntrStatus = MA_TIMER_DUAL2_mReadReg(baseaddr, MA_TIMER_DUAL2_INTR_IPISR_OFFSET);
    
  IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL2_0_BASEADDR + MA_TIMER_DUAL2_INTR_IPISR_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.
   */

0 Kudos
Observer thobmei
Observer
7,965 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

:smileyhappy:

I think I found the Problem .... but now I have another one .....

I made the mistake to tell the XPS in the create peripheral dialoge to pass through the interrupts ....

So everytime I wanted to look @ the interrupt source it was already 0 again.

 

And I dont got an DISR Value. No I get One.....

 

But now im in an Interrupt loop

 

To solve that I tried

 

 

*Using the Default Interrupt Header

and got:

 

User logic interrupt!
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! DISR value : 0x00000004

 

*Hardcode the BASEADDRESS

and got:

 

User logic interrupt!
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! DISR value : 0x00000004

 

 

*Using

IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR + MA_TIMER_DUAL3_INTR_IPISR_OFFSET); 

 

 

instead of  the Default:

 

IntrStatus = MA_TIMER_DUAL3_mReadReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_DISR_OFFSET);

 

and got:

 

Device Interrupt! DISR value : 0x00000003
Device Interrupt! DISR value : 0x00000003
Device Interrupt! DISR value : 0x00000003
Device Interrupt! DISR value : 0x00000003

 

 

*READ OUT DISR and IPISR

 

and got:

 

User logic interrupt!
Device Interrupt! IPISR value : 0x00000002
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! IPISR value : 0x00000002
Device Interrupt! DISR value : 0x00000004

 

*Clear the DISR

 

with  MA_TIMER_DUAL3_mWriteReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_DISR_OFFSET, IntrStatus);

 

But the Register Wont Change .... its still Device Interrupt! DISR value : 0x00000004

 

 

Code Derfault Header:

 

void MA_TIMER_DUAL3_Intr_DefaultHandler(void * baseaddr_p)
{
  Xuint32 baseaddr;
  Xuint32 IntrStatus;
Xuint32 IpStatus;
  baseaddr = (Xuint32) baseaddr_p;

  /*
   * Get status from Device Interrupt Status Register.
   */
  IntrStatus = MA_TIMER_DUAL3_mReadReg(baseaddr, MA_TIMER_DUAL3_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_DUAL3_mReadReg(baseaddr, MA_TIMER_DUAL3_INTR_IPISR_OFFSET);
    MA_TIMER_DUAL3_mWriteReg(baseaddr, MA_TIMER_DUAL3_INTR_IPISR_OFFSET, IpStatus);
  }

}

My last code, Default Header + modifications:

 

 

#include "xparameters.h"
#include "xbasic_types.h"
#include "xstatus.h"
#include "ma_timer_dual3.h"
#include "xintc.h"
#include "xintc_l.h"



//----------------------------------------------------
// INTERRUPT HANDLER FUNCTION
//----------------------------------------------------
void MA_TIMER_DUAL3_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_DUAL3_mReadReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_DISR_OFFSET);
  IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR + MA_TIMER_DUAL3_INTR_IPISR_OFFSET);    
  xil_printf("Device Interrupt! IPISR value : 0x%08x \n\r", IntrStatus);
 
  IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR + MA_TIMER_DUAL3_INTR_DISR_OFFSET);
  xil_printf("Device Interrupt! DISR value : 0x%08x \n\r", IntrStatus);
 
  MA_TIMER_DUAL3_mWriteReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_DISR_OFFSET, 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_DUAL3_mReadReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_IPISR_OFFSET);
    MA_TIMER_DUAL3_mWriteReg(XPAR_MA_TIMER_DUAL3_0_BASEADDR, MA_TIMER_DUAL3_INTR_IPISR_OFFSET, IpStatus);
  }
   IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR + MA_TIMER_DUAL3_INTR_IPISR_OFFSET);
  xil_printf("Device Interrupt! IPISR is now value : 0x%08x \n\r", IntrStatus);
 
     IntrStatus = XIo_In32((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR + MA_TIMER_DUAL3_INTR_DISR_OFFSET);
  xil_printf("Device Interrupt! DISR is now value : 0x%08x \n\r", IntrStatus);
 
}


//----------------------------------------------------
// MAIN FUNCTION
//----------------------------------------------------
int main (void)
{
  Xuint32 status, Status;
  Xuint32 IpStatus;
  XIntc InterruptController;


  //----------------------------------------------------
  // REGISTER INTERRUPT HANDLER
  //----------------------------------------------------
  xil_printf("  - Registering interrupt handler\r\n");
  XIntc_RegisterHandler(XPAR_XPS_INTC_0_BASEADDR,
    XPAR_XPS_INTC_0_MA_TIMER_DUAL3_0_IP2INTC_IRPT_INTR,
    MA_TIMER_DUAL3_Intr_Handler,
    (void *)XPAR_MA_TIMER_DUAL3_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_DUAL3_0_IP2INTC_IRPT_MASK);
 
  // Enable timer interrupts
 
  MA_TIMER_DUAL3_EnableInterrupt((void *)XPAR_MA_TIMER_DUAL3_0_BASEADDR);
 
  // Enable Microblaze interrupts
  microblaze_enable_interrupts();
  xil_printf("    SUCCESS!\r\n");  
  while(1){
  }
}

 

 

 

 

0 Kudos
Observer thobmei
Observer
7,930 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

It looks like an Problem in my userlogic ... I tryed the default template without modifikations and it worked ....

 

But my logic also looks ok in behavoral simulation ....

:smileysad:

0 Kudos
Explorer
Explorer
7,924 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

 

There are vhdl instructions that are not synthesizable but can be simulated. Check your design to see if you are not using some of these.

 

example:

 

x <= '1' after 2ns.

 

 

Best,

JM

0 Kudos
Observer thobmei
Observer
7,895 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

ok i checked this i think my Code is Quite Synthesizable.

 

I created the template with the Priority Encoder Option, the Use Device ISC Option and Rising Edge Detect.

In the Import Dialoge I also choose the Rising Edge Option for my Interrupt Signal (IP2Bus_IntrEvent).

 

Thats the way I modiefied the default Template

 

  ------------------------------------------
  -- Example code to generate user logic interrupts
  --
  -- Note:
  -- The example code presented here is to show you one way of generating
  -- interrupts from the user logic. This code snippet infers a counter
  -- and generate the interrupts whenever the counter rollover (the counter
  -- will rollover ~21 sec @50Mhz).
  ------------------------------------------
  INTR_PROC : process( Bus2IP_Clk ) is
    constant COUNT_SIZE   : integer := 30;
    constant ALL_ONES     : std_logic_vector(0 to COUNT_SIZE-1) := (others => '1');
    variable counter      : std_logic_vector(0 to COUNT_SIZE-1);
  begin

    if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then
      if ( Bus2IP_Reset = '1' ) then
        counter := (others => '0');
        intr_counter <= (others => '0');
      else
        counter := counter + 1;
         if ( counter = ALL_ONES ) then
          temp <= '1';     
         else
          temp <= '0';
        end if;
      end if;
    end if;
      end process INTR_PROC;
    
    INTR_PROC2 : process( Bus2IP_Clk ) is
    constant COUNT_SIZE   : integer := 20;
    constant ALL_ONES     : std_logic_vector(0 to COUNT_SIZE-1) := (others => '1');
    variable counter      : std_logic_vector(0 to COUNT_SIZE-1);
  begin

    if ( Bus2IP_Clk'event and Bus2IP_Clk = '1' ) then
      if ( Bus2IP_Reset = '1' ) then
        counter := (others => '0');
        intr_counter <= (others => '0');
      else
        counter := counter + 1;
         if ( counter = ALL_ONES ) then
          temp1 <= '1';  
         else
          temp1 <= '0';
        end if;
      end if;
    end if;

  end process INTR_PROC2;




  IP2Bus_IntrEvent(0) <= temp;
  IP2Bus_IntrEvent(1) <= temp1;
  IP2Bus_IntrEvent(2 to 4) <= (others => '0');

 

 

but it causes interrupt Looping

User logic interrupt!
Device Interrupt! DISR value : 0x00000004
User logic interrupt!
Device Interrupt! DISR value : 0x00000004

0 Kudos
Explorer
Explorer
5,118 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

Hi,

 

You don't need the device ISC option since all your interrupts pass through the user logic. This can be messing up with your interrupt control register read.

Observer thobmei
Observer
5,103 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

Jear it seems to work now ...

 

Am I just an Idiot? or is really such hard to get into the whole thing?

How to explain some one It took me nearly 2 Weeks to get into the interrupt thing?

 

thx 4 your help ...  

 

0 Kudos
Explorer
Explorer
5,098 Views
Registered: ‎05-15-2009

Re: two interrupts from one custom core?

Jump to solution

 

Nice. No, it is fairly ok to get some time to figure out some things.

 

By the way, was the Device ISC the reason of your last issue?

 

 

 

Best,

JM

 

0 Kudos
Observer thobmei
Observer
5,094 Views
Registered: ‎05-28-2010

Re: two interrupts from one custom core?

Jump to solution

yes ...

 

0 Kudos