Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,392 Views

IRQ not working

Hello i have a DE2-115, i am trying to generate an IRQ from a button press. 

I've mapped the button in the pin planner, connected to the system template instance generated by QSys and my software has this code 

 

static void handle_mutex_interrupts() { legal = 1; } static void init_mutex_pio() { void *edge_capture_ptr; edge_capture_ptr = (void*) &edge_capture; // cast edge_capture pointer to match alt_ic_isr_register() prototype // Enable all 4 button interrupts. IOWR_ALTERA_AVALON_PIO_IRQ_MASK(INPUT_IRQ_BASE, 0x1); // Reset the edge capture register. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0xf); // Register the interrupt handler. alt_ic_isr_register( INPUT_IRQ_IRQ_INTERRUPT_CONTROLLER_ID, INPUT_IRQ_IRQ, handle_mutex_interrupts, edge_capture_ptr, 0x0); alt_ic_irq_enabler( INPUT_IRQ_IRQ_INTERRUPT_CONTROLLER_ID, INPUT_IRQ_IRQ); }I've configured my button as a PIO input at QSys then i configured it to generate an IRQ, edge level capture, synchronize capture and enable edge reset register. 

 

But it doesnt work. Why? My main code has a infinite loop reading the value of "legal" that should change to 1 when the IRQ happens
0 Kudos
8 Replies
Altera_Forum
Honored Contributor I
111 Views

Is 'legal' defined as volatile? 

(a function call (to an external function) inside the loop would have the same effect)
Altera_Forum
Honored Contributor I
111 Views

Moreover I think you must reset the edge capture register in the isr, otherwise the interrupt will keep on retriggering.

Altera_Forum
Honored Contributor I
111 Views

I've done volatile int legal declarating and i've changed my isr function to reset the register as shown below 

 

static void handle_mutex_interrupts(void* context, alt_u32 id) { volatile int* edge_capture_ptr = (volatile int*) context; /* Store the value in the Button's edge capture register in *context. */ *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE); // Reset the Buttons edge capture register. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0); legal = 1; } 

 

Still nothing.
Altera_Forum
Honored Contributor I
111 Views

Quite possibly since, IIRQ, the interrupts to the nios itself are level sensitive. 

I'd guess that you need to read the edge capture register to find which bits have changed, then write back the same value to clear the bits. 

 

It might be easier to see how the hardware registers work if you use a program loop instead of the interrupt. A first cut would be to loop for about a second, read and print the registers, then repeat. Once that is working just look for changes. Then try using the isr.
Altera_Forum
Honored Contributor I
111 Views

As dsl said, you must write 1 to the irq bits to reset them. 

Writing 0 won't reset anything. 

You can use 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0xf); 

if you don't mind to reset all bits and not only the one which caused the interrupt to be serviced.
Altera_Forum
Honored Contributor I
111 Views

It works with pooling i've tried it; The hardware register is a 32bits guy.. it's a simple button connected to a PIO. 

 

When i did  

 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0x0); The program wouldnt even printf my "hello" that is in my main 

When i changed to 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0xf); It printed "hello" but the IRQ is still not working. 

 

I connected the IRQ on Qsys bus with priority of 2, my timer is 0(sys_clk_timer on BSP) and my jtag is 1. 

 

Am i missing something
Altera_Forum
Honored Contributor I
111 Views

It worked my problem was that in my ISR function i was reseting with 0x0 instead of 0xf 

 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(INPUT_IRQ_BASE, 0xf); (in the ISR functions) 

 

now it works.
Altera_Forum
Honored Contributor I
111 Views

You only want to clear the bits that you've read as being the cause(s) of the current interrupt. Clearing all the sources will lead to you losing interrupts. 

(Consider what happens if a second button is pressed while the ISR is running just before the register is cleared.)
Reply