Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - qnx zynq interrupt handling: (13 Items)
   
qnx zynq interrupt handling  
Hi QNX,
                qnx Momentics 6.5.0SP1, bsp-xilinx-zynq7000-zc702-650sp1, Xilinx zc702 evaluation board

I have a zc702 evaluation board at hand, and download the BSP from the following link

http://community.qnx.com/sf/wiki/do/viewPage/projects.bsp/wiki/XilinxZc702

In Xilinx vivado diagram, I added a PL-PS Interrupt Port, selecting from IRQ_F2P[15:0]. xparameters.h tells me the IRQ 
number is 61.

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

However, QNX InterruptAttach always returns -1.

        int irq  = 61;
    	uintptr_t gpio_base = mmap_device_io(0x10000, XPAR_GPIO_0_BASEADDR);
    	int result = InterruptAttach( irq, &handler, &gpio_base, 0x10000, _NTO_INTR_FLAGS_PROCESS);
 
Please advise how to implement zynq  PL-PS Interrupt in QNX, thanks in advance.

Mike
Re: qnx zynq interrupt handling  
Hi MIke,

the "&" in "&gpio_base" looks strange to me...

Cheers,
-- ar
Re: qnx zynq interrupt handling  
I used "&gpio_base" on beaglebone black with other post in this forum 

http://community.qnx.com/sf/discussion/do/listPosts/projects.core_os/discussion.newcode.topc27325

If I delete &, there will be a warning "passing argument 3 of 'InterruptAttach' makes pointer from integer without a 
cast"

either way, I tried 

              int result = InterruptAttach( irq, &handler, gpio_base, 0x1000, _NTO_INTR_FLAGS_PROCESS);

return value of result = -1 .

Please help , thanks in advance
Re: qnx zynq interrupt handling  
Just to be sure... did you call ThreadCtl(_NTO_TCTL_IO) prior to InterruptAttach()? What does errno say when 
InterruptAttach() fails?
Re: qnx zynq interrupt handling  
Hi Thomas, 

Thank you for the advice,

I did missed ThreadCtl(_NTO_TCTL_IO) , now I added following lines in the main() function.

	if (ThreadCtl(_NTO_TCTL_IO, 0) == -1) {
		printf("ThreadCtl\r\n");
		return (!EOK);
	}

return result =5. 

However, I still didn't get interrupt yet. Exact same thing happened as previous post on beaglebone black, i.e., gpio 
pin bears correct value when button pushed, however, the program never enters interrupt handler.

http://community.qnx.com/sf/discussion/do/listPosts/projects.core_os/discussion.newcode.topc27325

My question is whether this IRQ number 61 is acknowledged by QNX when I used InterruptAttach, or QNX tends to assign its
 own IRQ number.

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

Please advise, thanks in advance

Mike
Re: qnx zynq interrupt handling  
Hi QNX,

I made more progress, but still not there yet. Now, the program will hang whenever I push the button. Below is the 
source code,


#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
#include <sys/mman.h>
#include <hw/inout.h>
#include <hw/gpio.h>

#define XPAR_GPIO_0_BASEADDR 0x41200000		// buttons

int irq  = 61;
static uint32_t irqcount = 0;

static void Delay1(volatile unsigned int count)
{
    while(count--);
}

static const struct sigevent *handler(void *area, int id)
{
	irqcount++;
	return NULL;
}


int main(int argc, char *argv[])
{
	if (ThreadCtl(_NTO_TCTL_IO, 0) == -1) {
		printf("ThreadCtl\r\n");
		return (!EOK);
	}

    	// pin configuration ...
    	uintptr_t gpio_base = mmap_device_io(0x10000, XPAR_GPIO_0_BASEADDR);
        if(gpio_base == MAP_DEVICE_FAILED)
        {
            perror("Can't map device I/O");
            return 0;
        }

        out32(gpio_base + 0x4, 0xFF); 			// 1 as inputs.
        out32(gpio_base + 0x0128, 0x1); 		        // IP IER: channel 1 enable
        out32(gpio_base + 0x011C, 0x80000000);     // GIER global enable

//        InterruptEnable();

    	int result = InterruptAttach( irq, &handler, &gpio_base, 0x10000, _NTO_INTR_FLAGS_PROCESS);
    	if(result == -1)
    	{
    		printf("InterruptAttach wrong\r\n");
    	}
    	else
    	{
    		printf("Attached IRQ ID0 = %d\r\n", result);
    	}

    	while(1)
    	{
            Delay1(0xFFFFFF);
            Delay1(0xFFFFFF);
            Delay1(0xFFFFFF);
            Delay1(0xFFFFFF);

	    printf("connected %u\n", irqcount);

    	}

    munmap_device_io(gpio_base, 0x10000);

    return 1;
}

Please advise, thanks in advance

Mike

Re: qnx zynq interrupt handling  
I'm not sure, I do not known the Zynq, but but maybe You have to clear the GPIO interrupt manually in the Isr :
It shold be that is not done automatically by bsp Isr handler ....
Eventually, try with InterruptAttachEvent instate of InterruptAttach: its is much easy to debug.
mario

Re: qnx zynq interrupt handling  
Hi mario sangalli,

thank you for the nice suggestions.

I tried InterruptAttach, the interrupt only occurred once, then program hung.

Attached IRQ ID0 = 5
Interrupt 1

add source code like follows,

        struct sigevent event;
        event.sigev_notify = SIGEV_INTR;
        int result = InterruptAttachEvent( irq, &event, 0 );
    	if(result == -1)
    	{
    		printf("InterruptAttach wrong\r\n");
    	}
    	else
    	{
    		printf("Attached IRQ ID0 = %d\r\n", result);
    	}
    	while(1)
    	{
			InterruptWait( 0, NULL );
			InterruptMask( irq, result );
			     irqcount++;
			     printf("Interrupt %d\n", irqcount);
			InterruptUnmask( irq, result );
    	}

If removing  InterruptMask( irq, result ); then the interrupt will never stop even with one-time button push. Results 
like below,

Attached IRQ ID0 = 5
Interrupt 1
.....
Interrupt 4984
Interrupt 4985
Interrupt 4986
Interrupt 4987
Interrupt 4988
Interrupt 4989
Interrupt 4990
Interrupt 4991
Interrupt 49
....

Please advise, thanks in advance,

Mike
Re: qnx zynq interrupt handling  
Mike, You haven't to do the InterruptMask!  interrupt is already masked, You have only to
unmask it when done with your stuffs.
Before unmask interrupt, during debug, You can look at  GPIO registers and checks what's
wrong (ie: interrupt not clear or some other GPIO interrupt pending ...)

Anyway, I've downloaded the bsp just for curiosity: I've found in an interesting gpio library 
You can look at the gpio lib sources, see xzynq_gpio.c  and the xzynq_gpio_irq_clear(int pin)  function. 
It sound a usefull one: maybe You have to add the xzynq_gpio_irq_clear to Your code....

BTW, I've read in the Qnx 6.6 bsp release notes that gpio library has been fixed for some bugs: 
maybe You can switch to 6.6 or You have to patch the 6.5 files using 6.6 one and recompile the 
gpio lib (libgpio-xzync.a)

mario


Re: qnx zynq interrupt handling  
Hi mario, 

Thank you for the timely support.

The gpio lib sources in BSP package are for PS-GPIO. I have already successfully implemented PS-GPIO (arm side) 
interrupt in early March, and recorded a previous post in this forum http://community.qnx.com/sf/discussion/do/listPosts
/projects.core_os/discussion.newcode.topc27341

What I am doing now is AXI-GPIO interrupt, which is implemented by FPGA, and could register interrupt through PL-PS 
Interrupt Port, selecting from IRQ_F2P[15:0]. i.e., irq # =[61~68 | 84~91] 

Xilinx product guide, Page 10, table 2-4 shows the register space (which is different from PS-GPIO). 
https://www.xilinx.com/support/documentation/ip_documentation/axi_gpio/v2_0/pg144-axi-gpio.pdf

Please advise, thanks in advance

Mike
Re: qnx zynq interrupt handling  
Mike,sorry,  I've never used the zynq, I'm a bit confused about PS-GPIO and AXI GPIO :-) 
Anyway, if the AXI GPIO are  not equal to PS-GPIO, You have to add the support for the interrupt handling in the 
init_intrinfo.c creating one or more entry and add the specific function to mask, unmask,  eoi etc....  
If the AXI GPIO requires a different way (or simply have a different base address) to handle mask, unmask and 
eoi , You code will crash just after the interrupt assertion :-)
Maybe You can change the callout_interrupt_xzynq_gpio.s to adapt to AXI registers layout.


mario

Re: qnx zynq interrupt handling  
Hi mario,

Thanks for the advice, though it sounds of lots of workload, I will try at later time.

Best

Mike
Re: qnx zynq interrupt handling  
follow another post in this forum, https://openqnx.com/phpbbforum/viewtopic.php?t=7263

I added _NTO_INTR_FLAGS_TRK_MSK to InterruptAttachEvent, but did not make any difference.

        int result = InterruptAttachEvent( irq, &event, _NTO_INTR_FLAGS_TRK_MSK );

Please advise, thanks in advance