Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20704 Discussions

DE0-Nano-SoC: How HPS(ARM) recognizes f2h_irq0 or f2h_irq1 interrupts from FPGA

Altera_Forum
Honored Contributor II
5,240 Views

I designed a block in Verilog. When data processing is finished, this FPGA block sends an interrupt signal to HPS using one of dedicated interrupt line: f2h_irq0 or f2h_irq1. The question is how HPS can recognize that this interrupt is active? Could anybody give an example of C code where HPS reads the interrupt (or decode interrupt vector) from FPGA?

0 Kudos
15 Replies
Altera_Forum
Honored Contributor II
1,814 Views

Hi Sebar,What sofware are you running on your HPS ? Bare metal,RTOS or Linux ?

0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

#include <linux/module.h> 

# include <linux/irq.h> 

# include <linux/interrupt.h> 

# include <linux/kernel.h> 

# include <linux/gpio.h> 

 

static int gpio_number = -1; 

 

irqreturn_t gpio_isr(int this_irq, void *dev_id) 

printk("Interrupt happened at gpio:%d\n", gpio_number); 

return IRQ_HANDLED; 

 

static void __exit gpio_interrupt_exit (void) 

free_irq(gpio_to_irq(gpio_number), 0); 

return; 

 

static int __init gpio_interrupt_init (void) 

int r; 

 

if (gpio_number < 0) { 

printk("Please specify a valid gpio_number\n"); 

return -1; 

 

int irq_number = gpio_to_irq(gpio_number); 

 

r = request_irq(irq_number, gpio_isr, IRQF_DISABLED, 0, 0); 

if (r) { 

printk("failure requesting irq %i\n", irq_number); 

return r; 

return 0; 

 

MODULE_LICENSE("GPL"); 

 

module_param(gpio_number, int, 0); 

 

module_init(gpio_interrupt_init); 

module_exit(gpio_interrupt_exit); 

 

This example code it´s in the SoC EDS installation folder C:\altera\15.1\embedded\examples\software (For Linux )
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Hello Nachodizz990, 

 

Thank you very much for the prompt reply with very concrete code example, which would be very useful in my case.  

Regarding the system on HPS, there is original Linux version 3.13.0-00298-g3c7cbb9-dirty (root@matthew) (gcc version 4.6.3 (Sourcery CodeBench Lite 2012.03-57) ). 

 

Since I am beginner in Cyclone V SoC, nothing was changed on my DE0-Nano-SoC board, I use orginal SW on my board and PC. Therefore, I have additional maybe a silly question to you:confused: about header files used in your C code:  

# include <linux/module.h> 

# include <linux/irq.h> 

# include <linux/interrupt.h> 

# include <linux/kernel.h> 

# include <linux/gpio.h> 

 

I have complete installation of: 

1) Altera 15.1.0.185 Standard Edition, including Quartus Prime and SoC Embedded Design Suite (EDS) 15.1.0.185 under Win7 

2) ARM DS-5 v5.22.0 under Win7, 

However, I cannot find above files: module.h, irq.h, interrupt.h, kernel.h, gpio.h. Where I can find them to install on my PC in order to compile succesfully your C code?
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

C:\altera\15.1\embedded\embeddedsw\socfpga\prebuilt_images\kernel_headers\include\linux 

 

All these files and all you need is inside the EDS suite. 

The nano soc manual shows you how cross compile with the shell but i work and program in ds5 eclipse because you can acces the linux terminal, explore the filesystem and debug the programs 

 

This pic illustrates how i work. 

 

http://s28.postimg.org/g9ussmjml/2016_01_17_10h40_29.png 

 

 

I can guide you to configure the workspace if you want!!
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Dear Nachodizz990, 

 

Thanks for the tips. My status is the following: 

 

  1. I set up Eclipse for DS-5- v5.22.0. 

  2. Remote Systems is set up, so the target’s files are accessible via SFTP and I have contact with my target via Terminal. 

  3. Debug Configuration let me run a simple hello example directly on the target with an access to his registers values using the breakpoints. 

 

 

Now when I set up a new project New -> Project -> C Project with ARM Compiler 5 (DS-5 built –in) as a Toolchain, the new project folder is created with some libraries inside: 

-arm_linux 

-arm_linux_compact 

-rw. 

However there is no linux subfolder with libraries used in given source code above. 

 

For toolchain: GCC 4.x [arm-linux-gnueabihf] (DS-5 built -in), I could find only kernel.h, but not the rest of needed files: # include <linux/module.h># include <linux/irq.h># include <linux/interrupt.h># include <linux/gpio.h> 

 

Can you guide me step by step, which toolchain I should use to find above files?
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

hey sebar how are you? 

 

In 1 hour i will post here a link to you for download a example  

 

Probably, your problem is with the makefiles. 

 

Before opening the project, ensure you have activated the ds5. 

 

To launch ds5 and opening the project you may open the eds shell,type in eclipse and then press enter, never enter ds5 directly.
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

-Hei sebar, download your ds5 example from here, and follow the instructions, 

place the folder into your DS5 workspace, open ds5 and import the project. 

 

- Watch the project configurations, makefile etc ... 

 

- Make some stupid change into the main.c such as adding a comment and then build all, you must not see any error, warning or file missing. 

 

- If any error occurs you can ask to me for see what it happens. 

 

https://www.sendspace.com/file/okshc0
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Hi Nachodizz990, 

 

Thanks for the link. I successfully imported this project, added my printf’s comments, compiled it, configured Debug Configuration.. 

I don’t have any errors, however nothing is output on Console except my printf comment inserted just after int main (int argc, char **argv). 

After putting some breakpoints and removing “//” before “ printf("DIPSWITCHES => 0X%X\r\n",dipsw_value );”, I see that there might be a problem with code line “dipsw_value = alt_read_word(DIPSWITCH_address);” since uncommented line “printf("DIPSWITCHES => 0X%X\r\n",dipsw_value );” is never executed, the system freezes. Question should I build a system in QSYS first, in order to generate and provide soc_system.h?
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

yes, compile your quartus project, i supose that you have 1 pio for the leds,other pio for the dipswitches, and at the top entity you send the fpga pins to the exported conduits in the qsys top module. 

 

then one compiled you must to create your hps.h, for doing this, after compiling the project copy your sopcinfo to the nios eds shell folder, open the nios 

shell and tipe in sopc-create-header files, you must se your new hps.h file and some .h more 

 

Go to the DS5 proyect, remove all the header files and then paste only your new hps.h 

 

Make some dummy change and then compile, if your quartus system is fine, this should be work (remember ro substitute your PIO names IN THE FNCTIONS I CREATED) 

 

If you have some problems send me the quartus project and i will send you a .rar with both quartus and ds5 projects working
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Sebar, this is a most correct and easier way to map peripherials. 

 

Note the differences with the project i sent you 

 

//LWAXI# define LWAXI_FPGASLAVES_OFST ( 0xFF200000 ) //BASE ADDRES HPS2FPGA LIGHTWEIGHT_AXI# define LWAXI_SPAN ( 0x00200000 ) //IS 2MB WIDE 

 

volatile unsigned long *DIPSWITCH_address=NULL; 

 

//AXI 

//#define AXI_FPGASLAVES_OFST ( 0xC0000000 ) //BASE ADDRES HPS2FPGA AXI INTERFACE 

//#define AXI_SPAN ( 0x3C000000 ) //IS 960MB WIDE 

 

 

int main(int argc, char **argv) { 

 

void *LWAXI_virtual_base; 

//void *AXI_virtual_base; 

 

int fd; 

 

// Open the kernel driver to memory 

if( ( fd = open( "/dev/mem", ( O_RDWR | O_SYNC ) ) ) == -1 ) { 

 

perror( "dev/mem" ); 

return( 1 ); 

 

//Map the physical address of the LIGHTHPS2FPGA AXI INTERFACE from start to end 

LWAXI_virtual_base = mmap( NULL, LWAXI_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, fd, LWAXI_FPGASLAVES_OFST ); 

 

//MAP ERROR 

if( LWAXI_virtual_base == MAP_FAILED ) { 

 

perror( "mmap" ); 

close( fd ); 

return( 1 ); 

 

//Map the DIPSWITHCHES PIO 

DIPSWITCH_address = LWAXI_virtual_base + ( ( unsigned long ) ( DIPSWITCH_BASE) ); 

 

alt_read_word(DIPSWITCH_address); 

 

// UNMAP LIGHTWEIGHT HPS2FPGA AXI 

if( munmap( LWAXI_virtual_base, LWAXI_SPAN ) != 0 ) { 

 

perror( "munmap" ); 

close( fd ); 

return( 1 ); 

 

close( fd ); 

return( 0 ); 

 

 

 

but the best way to do this is in a final application is to make a driver  

 

https://zhehaomao.com/blog/fpga/2013/12/29/sockit-4.html
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Hi Nachodizz990, 

 

Thanks for information. My QSYS system looks as follows: 

 

Apart of standard blocks like: 

-Cyclone V Hard Processor System 

-JTAG to Avalon Master Bridge 

-JTAG UART (connected to f2h_irq0) 

-System ID Peripherial 

-PIO (Parallel I/O – pio_led), 

 

I have the following own blocks in QSYS: 

-SPI Master (Altera’s 3 Wire Serial) 

-SPI Slave (Altera’s 3 Wire Serial) 

-My_counter (modulo 32 bits) 

-Merlin IRQ Fanaout (Altera’s IP) 

 

Merlin IRQ’s Senders are connected to Cyclone_V_Hard_Processor_System’s f2h_irq1 (irq Number=2), and to the LED (to let me see when interrupt is active). Merlin IRQ’s Receiver is supplied by My_counter’s overflow flag. The idea is that after power up the 32-bit counter counts up to maximum and an overflow flag is output to the LED and f2h_irq1. 

 

The second source of interrupts, connected to Cyclone_V_Hard_Processor_System’s f2h_irq1 consists of two blocks: 

- SPI Master (irq Number=1) and 

- SPI Slave (irq Number=0) 

 

Their ports are assigned to FPGA’s GPIOs and the wired on the board level in the way that SPI Master will send the data to SPI Slave and SPI Slave hopefully generates an interrupt. 

 

Whole design was synthesized, and FPGA was programmed successfully by soc_system.sof. I copied soc_system.sopcinfo to Nios Eds Shell folder. Then, in the Nios Eds Shell, I ran sopc-create-header-files command. 

I noticed that the following header files were been generated: 

-fpga_only_master.h 

-hps_0.h 

-hps_0_arm_a9_0.h 

-hps_0_arm_a9_1.h 

-hps_0_bridges.h 

-hps_only_master.h 

-soc_system.h 

I replaced all original header files, in the given example HPS_FPGA_DIPSW_LED/headers, by above newly generated files. However, when I compile main.c, I get the following: 

make all  

arm-linux-gnueabihf-gcc -g -Wall -IC:/altera/15.1/embedded/ip/altera/hps/altera_hps/hwlib/include -Dsoc_cv_av -Dsoc_cv -c main.c -o main.o 

main.c: In function 'main': 

main.c:52:79: error: 'DIPSWITCH_BASE' undeclared (first use in this function) 

DIPSWITCH_address=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + DIPSWITCH_BASE ) & ( unsigned long)( HW_REGS_MASK ) ); 

main.c:52:79: note: each undeclared identifier is reported only once for each function it appears in 

main.c:54:73: error: 'LED_BASE' undeclared (first use in this function) 

LED_address=virtual_base + ( ( unsigned long )( ALT_LWFPGASLVS_OFST + LED_BASE ) & ( unsigned long)( HW_REGS_MASK ) ); 

make: *** [main.o] Error 1 

 

As I guess, the reason is that I don’t use DIPSWITCH_BASE and LED_BASE in my system any more. In main.c, I should replace them by SPI_MASTER_BASE or SPI_SLAVE_BASE found in hps_0.h. 

However, in hps_0.h, I cannot find any Macros for Merlin IRQ Fanout, which suppose to pass the IRQ from My_counter to f2h_irq1 (irq Number=2). Why? Because they don’t have any bus with address space like SPI master and Slave?  

How can I get info that there is an interrupt from f2h_irq1 (irq Number=2) (My_Counter's overflow flag)?
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Hi Nachodizz990, 

 

Finnally, On the ARM console, I successfully got received IRQ from counter implemented in Verilog. I assigned counter's overflow flag (source of IRQ) to PIO. In addtition, I assigned this flag to LED. In C, I have a while loop printing PIO IRQ value on the console. When on the console, displayed PIO's IRQ value changes from 0x0 to 0x1, on the board I see that LED is ON.  

 

Thank you very much for your support:)
0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Can you put that project back up? It's exactly what I'm looking for. Thanks in advance. 

 

 

 

--- Quote Start ---  

-Hei sebar, download your ds5 example from here, and follow the instructions, 

place the folder into your DS5 workspace, open ds5 and import the project. 

 

- Watch the project configurations, makefile etc ... 

 

- Make some stupid change into the main.c such as adding a comment and then build all, you must not see any error, warning or file missing. 

 

- If any error occurs you can ask to me for see what it happens. 

 

https://www.sendspace.com/file/okshc0 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
1,814 Views

Hi there, 

Can you put that project back up? The link has expired. It seems to be exactly what I'm looking for. 

 

Thanks
0 Kudos
vrbavojtech
Novice
1,278 Views

Hello,

I have recently written a simple linux kernel driver for non-blocking (polling) of the interrupts from userspace app:

https://gist.github.com/vrbadev/0850428601283986f27221f16ee5ceba

Hope this helps anyone who seeks answers.

0 Kudos
Reply