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: 
Highlighted
Visitor gameer
Visitor
18,091 Views
Registered: ‎10-27-2014

PL to PS interrupt

Hi Everybody,

 I have the ZYNQ ZC706 evaluation board and I'm trying to design a 32 bit counter on the Programming logic of the Zynq. I would like the PL to couse an interrupt every time the counter is incremented and interrupt the PS so that it calculates the ARCTAN of the counter value then send the result to the PL to be stored in another register for furthur processing.

 

Things I have done so far(Using Vivado v2014.3):

1) created a custom AXI lite IP with my counter design incoporated in it (in AXI_inst vhdl file)

2) Enabled the interrupt support from the IP GUI wizard 

3) Enabled IRQ_F2P interrupt in the PS block

 

What I need help with:

1) How to configure the interrupt in the PL side(Do I need to edit or add anything in AXI_intr_inst vhdl file)?

2) How to configure the interrupt from the PS side in XSDK?

 

Most of the examples I have seen so far use pre-built IPs like Timer AXI or GPIO AXI that have interrupt support.

 

Is there a reference example to show how to create a custom IP with interrupt support and create an interrupt from within the PL to make the PS execute a particular command? 

 

 

Thanks,

 

 

 

 

0 Kudos
11 Replies
Moderator
Moderator
18,071 Views
Registered: ‎04-17-2011

Re: PL to PS interrupt

AR: http://www.xilinx.com/support/answers/60837.html -- shows how to create a custom AXI IP with Interrupt enable and how to use it and verify using SDK
AR: http://www.xilinx.com/support/answers/50572.html -- Generic example for PL based interrupt but using AXI Timer.
I hope the first link would help you.
Regards,
Debraj
----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------
0 Kudos
Visitor gameer
Visitor
18,057 Views
Registered: ‎10-27-2014

Re: PL to PS interrupt

Hi D

Thank you for replying to my post. I'm still struggling to understand the driver and implementation of the interrupt in the PS side. I have successfully edited the driver of my IP and used a similar driver to the one you provided in the first link. 

 

What I still don't know is How do you write an interrupt handler so that when an interrupt generated from the PL occurs the PS jumps to that block of code(basically an Interrupt service routine)?

 

Is enabling the interrupt global register and interrupt enable register using the driver fuctions sufficient to enable the interrupt?

 

 

Thanks,

gameer

0 Kudos
Scholar stephenm
Scholar
18,043 Views
Registered: ‎05-06-2012

Re: PL to PS interrupt

The second link has an application that shows how to enable the interrupt on the GIC on Zynq, and how to register the interrupt handler. You should follow that.

0 Kudos
Visitor gameer
Visitor
18,027 Views
Registered: ‎10-27-2014

Re: PL to PS interrupt

Hi Stephen,

thank you for your reply. I looked at the timer example and i'm going through the code but one thing that I don't understand  in the timer example is the timer instance.

 

For example the timer code uses XSCuGic_connect function and passes in it's parameter firstly a XTmrCtr_InterruptHandler and secondly a XTmrCtr instance (TimerInstancePtr) which are defined in built in include. I included the snippet below for your reference.

 

XScuGic_Connect(&InterruptController,
	XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR,
	(Xil_ExceptionHandler)XTmrCtr_InterruptHandler,
	(void *)TimerInstancePtr);

  Do I have to create my own type instance for my counter IP to make the interrupt setup work and if so are there any special fields that the type should include? An example would be appreciated. 

 

Thanks,

gameer

0 Kudos
Scholar stephenm
Scholar
18,017 Views
Registered: ‎05-06-2012

Re: PL to PS interrupt

I have attached an application that I created for a custom IP with interrupt. You can use this as reference 

 

/*
 * main.c
 *
 *  Created on: 4 Nov 2014
 *      Author: stephenm
 */

/*
 * main.c
 *
 *  Created on: 4 Nov 2014
 *      Author: stephenm
 */


#include <stdio.h>
#include "myip.h"
#include "xil_io.h"
#include "xil_types.h"
#include "xparameters.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"

#define SLCR_CAN_RST_ADDR 0xF8000220
#define SLCR_CAN_RST_VALUE 0xF
#define SLCR_WDT_CLK_SEL (XPS_SYS_CTRL_BASEADDR + 0x304)
#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
#define SLCR_FPGA_RST_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x240)
#define SLCR_LVL_SHFTR_EN_ADDR (XPS_SYS_CTRL_BASEADDR + 0x900)
#define SLCR_LVL_SHFTR_EN_VALUE 0xF
#define SLCR_LOCK_KEY_VALUE 0x767B
#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
#define SLCR_MIO_LOOPBACK (XPS_SYS_CTRL_BASEADDR + 0x804)
#define READ_WRITE_MUL_FACTOR 0x10
#define MYIP_WITH_INTERRUPT 0x43c10000


void MYIP_WITH_INTERRUPT_EnableInterrupt(void * baseaddr_p);
void MYIP_WITH_INTERRUPT_ACK(void * baseaddr_p);


XScuGic InterruptController; /* Instance of the Interrupt Controller */
static XScuGic_Config *GicConfig;/* The configuration parameters of the controller */

void INTERRUPT_Handler(void *baseaddr_p){
 print("interrupt\r\n");

}

 


int ScuGicInterrupt_Init()
{
 int Status;
 /*
  * Initialize the interrupt controller driver so that it is ready to
  * use.
  * */
 Xil_ExceptionInit();

 GicConfig = XScuGic_LookupConfig(XPAR_PS7_SCUGIC_0_DEVICE_ID);
 if (NULL == GicConfig) {
  return XST_FAILURE;
 }

 Status = XScuGic_CfgInitialize(&InterruptController, GicConfig,
   GicConfig->CpuBaseAddress);

 if (Status != XST_SUCCESS) {
  return XST_FAILURE;
 }

 /*
  * Setup the Interrupt System
  * */

 /*
  * Connect the interrupt controller interrupt handler to the hardware
  * interrupt handling logic in the ARM processor.
  */
 Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
   (Xil_ExceptionHandler) XScuGic_InterruptHandler,
   (void *) &InterruptController);


 /*
  * Connect a device driver handler that will be called when an
  * interrupt for the device occurs, the device driver handler performs
  * the specific interrupt processing for the device
  */
 Status = XScuGic_Connect(&InterruptController,61,
   (Xil_ExceptionHandler)INTERRUPT_Handler,
   (void *)&InterruptController);


 XScuGic_Enable(&InterruptController, 61);


 /*
  * Enable interrupts in the ARM
  */
 Xil_ExceptionEnable();

 //Only used for edge sensitive Interrupts
 XScuGic_SetPriorityTriggerType(&InterruptController, 61,
      0xa0, 3);

 MYIP_WITH_INTERRUPT_EnableInterrupt(MYIP_WITH_INTERRUPT);


 if (Status != XST_SUCCESS) {
  return XST_FAILURE;
 }

 return XST_SUCCESS;
}


int main()
{
 int xstatus;

 /* SLCR unlock */
 Xil_Out32(SLCR_UNLOCK_ADDR, SLCR_UNLOCK_KEY_VALUE);

    /* SLCR Enabling Level shifting */
    Xil_Out32(SLCR_LVL_SHFTR_EN_ADDR, SLCR_LVL_SHFTR_EN_VALUE);
    /* SLCR clearing PL Reset */
    Xil_Out32(SLCR_FPGA_RST_CTRL_ADDR, 0x0);
    Xil_Out32(SLCR_FPGA_RST_CTRL_ADDR, 0xf);
    Xil_Out32(SLCR_FPGA_RST_CTRL_ADDR, 0x0);

    /* SLCR lock */
    Xil_Out32(SLCR_LOCK_ADDR, SLCR_LOCK_KEY_VALUE);

 

      /*
       * Interrupt Test
      */


 xstatus = ScuGicInterrupt_Init();

 if (xstatus != XST_SUCCESS) {
  return XST_FAILURE;
 }

 //Wait For interrupt;

 print("Wait for the interrupt to trigger \r\n");
 print("########################################\r\n");
 print(" \r\n");

 while(1)
 {
 }

 return 0;
}


void MYIP_WITH_INTERRUPT_EnableInterrupt(void * baseaddr_p)
{
  u32 baseaddr;
  baseaddr = (u32) baseaddr_p;
  /*
   * Enable all interrupt source from user logic.
   */
  MYIP_mWriteReg(baseaddr, 0x4, 0x1);
  /*
   * Set global interrupt enable.
   */
  MYIP_mWriteReg(baseaddr, 0x0, 0x1);
}


void MYIP_WITH_INTERRUPT_ACK(void * baseaddr_p)
{
  u32 baseaddr;
  baseaddr = (u32) baseaddr_p;

  /*
  * ACK interrupts on MYIP_WITH_INTERRUPTS.
  */
  MYIP_mWriteReg(baseaddr, 0xc, 0x1);
}

 

 

 

0 Kudos
Visitor sx1302088
Visitor
16,548 Views
Registered: ‎05-29-2015

Re: PL to PS interrupt

hello,can you tell me that your IP is the same as the first link you give?what's more,what is the sclr?  

0 Kudos
Visitor mihai.coca
Visitor
8,804 Views
Registered: ‎05-19-2017

Re: PL to PS interrupt

Hi @stephenm

 

   I just wanted to try your code but it didn't show any interrupt.
I think you have to call the ACK function in your interrupt_handler.

Regards,
Mihai

 

0 Kudos
Observer mohamd17
Observer
6,148 Views
Registered: ‎01-14-2017

Re: PL to PS interrupt

Hi @mihai.coca

 

 
You finally display an interruption with this application ?
 
I start fro axi lite with the interrupt enabled i connected to the PS(IRQ_F2P) so i want to display a interruption in bare metal.
 
Regards
mohamd
0 Kudos
Participant sruthi@1
Participant
2,775 Views
Registered: ‎06-13-2018

Re: PL to PS interrupt

Hi, where can I find "myip.h" ?
0 Kudos
Moderator
Moderator
2,447 Views
Registered: ‎07-31-2012

Re: PL to PS interrupt

Hi sruthi@1,

 

its "myip_with_interrupt.h" in https://www.xilinx.com/support/answers/60837.html if you follow the steps.

 

Regards

Praveen


-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
Participant sruthi@1
Participant
2,406 Views
Registered: ‎06-13-2018

Re: PL to PS interrupt

hi Praveen,
what all functions are defined in "myip_with_interrupt.h"?

Thanks & Regards,
Sruthi
0 Kudos