• 0
Notarobot

Zynq PL-PS Interrupt issue

Question

Hello to al,

The system is built on the Zybo board in standalone mode. So far I had success sending interrupts from PL via GPIO. In order to reduce complexity I decided to try sending interrupts directly as it is shown on the included diagram. The RTL module is a simple counter sending a pulse once in a period of time. ILA confirmed the pulse. The application is supposed to count 50 interrupt events and quit. However, no triggering is happening. Clock freq is 50 MHz and a counter is 16 bit.

The C-code is taken from two sources: Xilinx Timer-interrupt example and Avnet interrupt tutorial controlling brightness with PWM. The issue in my opinion is that I can't find the parameter called INTERRUPT_ID. The file xparameter.h has nothing related to IRQ interrupt or anything else related to the INTERRUPT_ID or INTC_ID. Below is the last used C-code snapshot.

#include <stdio.h>
#include "platform.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xil_printf.h"
#include "xil_exception.h"

#define INTC_INTERRUPT_ID  84  // IRQ [0]
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID  // =0

static INTC Intc;
unsigned int LED = 0;    // Interrupt counter

void PIsr(void *InstancePtr){    // INTERRUPT SERVICE ROUTINE(ISR)
    LED ++;    
}

int SetupInterruptSystem()  {
    int result;
    XScuGic *IntcInstancePtr = &Intc;

    XScuGic_Config *IntcConfig;

    IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    if (IntcConfig == NULL)    {
        return XST_FAILURE;
    }
    result = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,    IntcConfig->CpuBaseAddress);
    if (result != XST_SUCCESS)    {
        return XST_FAILURE;
    }
    /* Connect the interrupt handler */
    result = XScuGic_Connect(IntcInstancePtr, INTC_INTERRUPT_ID, (Xil_ExceptionHandler) PIsr, 0);
    if (result != XST_SUCCESS)    {
        return result;
    }
    /* Enable the interrupt for the controller device. */
    XScuGic_Enable(IntcInstancePtr, INTC_INTERRUPT_ID);

    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
        (Xil_ExceptionHandler)INTC_HANDLER, IntcInstancePtr);

    Xil_ExceptionEnable();    /* Enable non-critical exceptions */

    return XST_SUCCESS;
}

int main(void)  {
    int status = XST_SUCCESS;

    xil_printf("\nLED=%d\n",LED);
    status = SetupInterruptSystem();
    if (status != XST_SUCCESS)   {
           return XST_FAILURE;
    }
    while (LED < 50)    {
    }
    xil_printf("LED=%d",LED);
    return 0;
}

Hope someone could share insights and educate me.

Thank you very much!

CaptureIRQ.PNG

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

@Notarobot

Your analysis sounds correct to me.

I believe that 61 is the default interrupt address for the IRQ_F2P, rather than the 84 in your code. This shows up defined as XPAR_FABRIC_<device>_INTERRUPT_INTR in xparameters.h. For me the interrupt id definitions appear just above the XSCUGIC device defines.

Edit: This can also be determined by re-customizing the Zynq IP and looking at the IRQ_F2P port under the Interrupts tab. The ID field shows "[91:84], [68:61]". Since least significant bit is last, the zeroth interrupt bit has id 61.

 

Hope this helps,

Arthur

Edited by artvvb
Additional Information

Share this post


Link to post
Share on other sites
  • 0

Hi @artvvb

Thank you for your quick response.

I tried ID 61 and it didn't work too. Generated xparameters.h does not have XPAR_FABRIC_<device>_INTERRUPT_INTR definition. I might be wrong but it was my impression that FABRIC is related to the AXI switch which is not a part of this design.

It seems to me that something else is missing for Vivado to recognize this particular IRQ port. 

 

Share this post


Link to post
Share on other sites
  • 0

 

@Notarobot

Classic question, which versions/editions of Vivado and SDK are you using?

I just threw together a test project in stock 2016.4, haven't written C code to do setup the interrupt controller, but I am picking up the interrupt id in xparameters. Screenshots and code attached.

Relevant xparameters lines:

/* Definitions for Fabric interrupts connected to ps7_scugic_0 */
#define XPAR_FABRIC_TEST_0_INTR_INTR 61

Likely irrelevant verilog module (added to block design with right click + add module)

module test(
    input clk,
    output reg intr // the interrupt pin
    );
    parameter COUNT_MAX = 99999999;
    reg [31:0] count;
    always@(posedge clk)
        if (count < COUNT_MAX) begin
            count <= count + 1;
            intr <= 0;
        end else begin
            count <= 0;
            intr <= 1;
        end
endmodule

screenshot of block design:

zynq-intr.thumb.JPG.0091fc3c010a0bb0a0413179ff24971e.JPG

Thanks,

Arthur

Share this post


Link to post
Share on other sites
  • 0

I am using Vivado 2017.1.

Perhaps I need to start from scratch in Vivado 2016.4 and add GPIO to get XPAR_FABRIC. May be GPIO is a required element of the design?

I will let you know about results.

Thank you for your assistance very much. Digilent rocks!

Share this post


Link to post
Share on other sites
  • 0

For what it's worth, the ID is passed properly in this block design as well. The only thing I can think of outside of version differences is some weirdness with the reset block.

zynq-intr.JPG.fbbaef10ca96620a133cd04764d72fa0.JPG

Cheers

Share this post


Link to post
Share on other sites
  • 0

Hi @artvvb,

After adding GPIO and I was able to get XPAR_FABRIC 61 but still no interrupts. Looking at my code for IRQ_F2P interrupt via GPIO module I can see substantial differences but unfortunately it's above my level of API knowledge. It is using functions like:   

XGpio_InterruptEnable(GpioInstancePtr, 1);
XGpio_InterruptGlobalEnable(GpioInstancePtr);

that are not applicable in my case.

Thank you!

Share this post


Link to post
Share on other sites
  • 0

@artvvb

The issue seems to solved after I've added the statement:  XScuGic_SetPriorityTriggerType(IntcInstancePtr, INTC_INTERRUPT_ID,0x00, 0x3);

Now the applications responds and counts interrupt sisgnals coming fro PL.

Regards,

N

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now