Jump to content
  • 0

Zynq PL-PS Interrupt issue


Notarobot

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

Link to comment
Share on other sites

7 answers to this question

Recommended Posts

@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

Link to comment
Share on other sites

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. 

 

Link to comment
Share on other sites

 

@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

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...