Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

NIOS + IRQ + custom component

Altera_Forum
Honored Contributor II
3,794 Views

Hi, I'm trying to interrupt a Nios Prosessor whit a Custom Component and setup a successful interrupt routine. But I can't Do it.  

 

The problem is that i can't find a complete example of a custom component connected to a NIOS II processor who succesfuly call a ISR.  

 

Can someone help me? 

 

Jairo
0 Kudos
34 Replies
Altera_Forum
Honored Contributor II
1,093 Views

I would start by reading through this section of the handbook and practicing using an input PIO as an interrupt source: 

 

http://www.altera.com/literature/hb/nios2/n2sw_nii52006.pdf 

 

If you need additional help shoot me a pm with your email address and I'll send you a test design that contains a random IRQ generator I created a while back for reasons I can't really remember :)
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Tks, BadOmen, I am reading. 

 

I can't PM, but you can email the example to 

 

frodobolsonxx (at) gmail (dot) com 

 

 

Tks again jairo
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi, 

 

I would appreciate a copy of the example SOPC custom component with IRQ , if available.  

 

please send to: kered95 at gmail dot com 

 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Ok it's sent.

0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Thanks BadOmen, 

 

Much appreciated. 

 

Ken.  

 

:)
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi, 

Please send the example SOPC custom component with IRQ to rgjokerit at gmail dot com. 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi, 

Please send the example SOPC custom component with IRQ to alexandrvb58 at gmail dot com. 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Seems to me that you should be doing your own assignments. 

Remember your tutor will also be reading the forum!
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Sent. <post needs 10+ characters so this is to make the forum happy>

0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi, now I'm also trying to interrupt the CPU with my custom component. 

So my custom component consists of this following blocks : 

1. FIFO, this FIFO receives input from outside SOPC and send the output to DMA 

2. Write_control, to control how the FIFO writes its data  

 

After a certain number of data (for example 10) have been written in the FIFO, the FIFO should send an interrupt signal to CPU. I've provided an irq signal (the interface type is 'interrupt sender', the interrupt signal's width is one clock) and connected it to the CPU's interrupt receiver interface. 

 

My question is in the interrupt sender properties, which Avalon MM slave that I have to assign? Is it the Avalon MM slave of the FIFO output data interface? 

 

I've tried to assign the Avalon MM slave of the FIFO output data in the interrupt sender properties. I also have written the interrupt handler C code like shown in Quartus manual.  

 

However my design didn't work. Does anyone have any suggestion for me? 

Thank you
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

@BadOmen would you send the example SOPC custom component with IRQ to my email ?  

thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi Fightingdreamer, 

 

The IRQ signal needs to be >> 1 clock period wide. The CPU invokes initial processing to ID the interrupt and select the correct handler. Sorry I can post links but google NIOS II Exception Handling by John Loomis and look at alterawiki for IRQ code. In my case I had to make the IRQ pulse 50 clock cyles wide. I presently don't know of any Altera guidelines on this (Is there one?).  

 

I would suggest the interrupt sender should be assigned to the MM slave (a custom CSR interface ??) were you should clear the defined IRQ bit before existing the ISR. 

 

Hope this is helpful. 

 

kohagan.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi Kohagan, 

 

Thanks for your reply. 

 

I've tried to modify and provide an Avalon MM slave, it consists of a 'write' and a 'writedata' signal. This Avalaon MM slave function is to let the CPU send a command to clear the interrupt bit. Then, I assign my interrupt signal in SOPC to this Avalon MM. However, the result is very strange... my program totally doesn't work, even it has hanged in the beginning.... :( I don't know why.., I've set the interrupt priority low enough such that it didn't overlap with previous process. Do you have any suggestion why it happens? 

 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi Fightingdreamer, 

 

Not sure if you are implementing the procedure correctly. Process I implemented was: 

 

1. IRQ signal ( interrupt sender) is generated. This signal needs to have a period of typically 50 clocks wide (wrt Nios Clock).  

 

2. The IRQ signal is used to simultaneously set an IRQ bit in an avalon MM register, i.e. Status reg within your custom component.  

 

Process 1 alerts the NIOS to an interrupt event and points to the entry point of your ISR code. 

 

The ISR code reads and clears the IRQ bit (set in Process 2) before exiting the ISR. 

 

Hope this helps, 

 

Ken.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

I would make the IRQ signal indefinite - ie stay active until the ISR clears the source. 

The IRQ can then be a logical 'or' of all the bits of the MM slave register. You then need to do 'write to clear' on that location from the nios. 

 

The ISR then does: 

1) Read IRQ register 

2) Write the value back to clear the IRQ bits that were present at the time it was read. 

3) Check each IRQ bit in turn (or fifo level (etc)) to actually service the interrupt. 

4) exit from ISR 

 

There are some systems [1] where it is possible to exit the ISR before the write 

(2) has propogated far enough to actually cause the IRQ line to be deasserted. This can cause 'splurious' ISR messages under certain loads. 

 

[1] eg when the write gets 'posted' on some bus, and the check (3) involves looking in shared memory (typical of ethernet receive).
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Oh - you also want to add a 2nd MM slave register so that the nios code can disable interrupts without regard for what the hardware is actually doing. 

This could feed in either side of the 'or' of the multiple IRQ sources.
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Hi dsl, 

 

Thanks for the post.  

 

I can appreciate that your closed loop IRQ process is a better solution as it automatically maintains the required IRQ signal period.  

 

kohagan
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

Dear kohagan & dsl, 

 

Wow...your posts really make my day! :D Now I understand what part that I missed. I thought before that IRQ signal were same as IRQ bit. 

 

Ok, soon I will try your suggestions 

Thanks!
0 Kudos
Altera_Forum
Honored Contributor II
1,093 Views

You need to close the loop with the ISR. 

The nios interrupts are level sensitive, so if the hardware removes the IRQ signal (to the cpu) and the cpu was running with interrupts disabled, then the interrupt wont be detected.
0 Kudos
Altera_Forum
Honored Contributor II
1,006 Views

Dear all, 

 

I have followed your instructions in the previous posts, but it still doesn't work (I think my C-code is wrong) :( 

 

I attach the snapshot of the configuration of my component in SOPC builder. As your suggestions I added an additional Avalon MM slave that is responsible to store the IRQ bit (I named it 'interrupt handler'). This Avalon MM consists of this following signals : 

- IRQ_bit (the register that stores the IRQ bit, the signal type is readdata) 

- READ_IRQ (read signal of the Avalon MM slave to read the IRQ_bit) 

- interrupt (the register that used to set / clear the IRQ_bit) 

- interrupt_en (write signal of the Avalon MM slave to clear the IRQ_bit). 

 

The interrupt sender is assigned to this Avalon MM slave (interrupt handler). 

 

I also attach the verilog code of my component and its testbench. 

 

And here is the snapshot of my C code : 

volatile int fifo_interrupt; # ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT void FIFOinterrupt_handler(void* context) # else void FIFOinterrupt_handler(void* context, alt_u32 id) # endif { INT8U error_code; volatile int* fifo_interrupt_ptr = (volatile int*) context; printf("IRQ bit 1 : %d\n",IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0)); *fifo_interrupt_ptr = IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0); // get the IRQ bit IOWR(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0,0x0); // clear the IRQ bit printf("IRQ bit 2 : %d\n",IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0)); OSSemPost(DMAActvSem); alt_uCOSIIErrorHandler(error_code, 0); IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0); } void main() { ..... ..... void* fifo_interrupt_ptr = (void*) &fifo_interrupt; printf("IRQ bit 0 : %d\n",IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0)); IOWR(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0,0x0); // reset the IRQ bit printf("IRQ bit 0 : %d\n",IORD(FIFIO_DUALWIDE_INTERRUPT_HANDLER_BASE,0)); # ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT alt_ic_isr_register(FIFIO_DUALWIDE_INTERRUPT_HANDLER_IRQ_INTERRUPT_CONTROLLER_ID, FIFIO_DUALWIDE_INTERRUPT_HANDLER_IRQ, FIFOinterrupt_handler, fifo_interrupt_ptr, 0x0); # else alt_irq_register(FIFIO_DUALWIDE_INTERRUPT_HANDLER_IRQ, fifo_interrupt_ptr, FIFOinterrupt_handler); # endif ..... ..... }  

 

When I ran my program, the program didn't recognize the interrupt. The SignalTap showed that when the IRQ signal (wrfinish) was active, the IRQ bit (IRQ_bit) was also active which meant there was no mistake in the hardware (I think..). So the problem should be in my C code... 

 

Would you check my verilog code and the above C code? Hope you can help me to find where the problem is..:( 

 

Thanks a lot
0 Kudos
Reply