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

FPGA to HPS simple communication

Altera_Forum
Honored Contributor II
1,526 Views

Hello,  

 

In advance, sorry for my english (it's not my mother tongue). 

 

I'm a beginner into qsys and linux (1 month). I have experience on microcontrollers without OS. 

I work on a DE1-Soc board (and also a SocKit). The OS used is the linux provided by terasic on their website. 

 

I am trying to make the HPS react to a communication initiated by the FPGA. The piece of information to send from the FPGA to the HPS should be around 200 bits ? 

 

I thougth about two ways to resolve this problem. 

1. Use one of the two IRQ in the HPS IP. When arrived in the interrupt routine, read a reserved part of the FPGA sdram through the h2f_axi bridge (the FPGA put there the right data before sending the interrupt signal). 

 

2. Use the f2h_axi bus to directly transfert the data. 

 

 

I began the first solution. 

I succeed in the h2_f_axi reading but I have big difficulties to understand how the interrupt works. I read a lot on this forum and on rocketboards.org but I think that I miss serious basis in embedded linux development. 

 

I saw that I have to modify the device tree file. I ran sopc2dts.exe (gui mode) on mysystem.sopcinfo. I understood that this device tree makes the correspondence between the hard and the soft. But I couldn't find any trace of "IRQ" or "interrupts = <0 40 1>;" in the dts generated file. 

 

There is my Qsys design in the attached file. (It's a test design, the components I developed have very simple behaviour) 

My interrupt sender simply makes the link between a Key of the board and the interrupt signal. But in the end it will be triggered from a finite state machine. 

 

Is there a tutorial with all the steps requiered to implement interrupt (from Qsys to C program) ? 

Is the interrupt way the simpliest way to achieve my goals (just having a FPGA to HPS communication that trigger a routine) ? 

 

 

I work on a Windows7 computer. As shown in the terasic tutorials, for the moment, I write my C programs in a text editor and compile with a makefile thanks to the "Embedded_command_shell" provided. (Is that a good way ? I saw a lot of people working on DS5) 

 

 

Can someone help me ? 

Thanks
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
608 Views

HI!! 

First, I really think its a better idea to use the DS5!! 

Well for your program you will first need to program a VHDL/Verilog module and add it to QSYS!(connect the irq to hps) 

Add the module in your dts with the reg parameters(memory map parameters) and irq (examplei2c0 irq =>>> interrupts = <0 158 4>; /*0=SPI 1=PPI, Altr_int nr - 32, 4=active High level sensitive GIC_CPU_MASK arm-gic.h (refer @ kernel arm/gic and arm cortex a9 docu 3.1.2)*/) 

Then you need to write a "Linux Kernel Module"!! 

insert the module 

and use it in your program!! 

The whole thing its not a easy task! but thats life! :) 

Here you can find a nice blog!!! 

https://zhehaomao.com/blog/fpga/2014/05/24/sockit-10.html 

bye und viel spass! 

ahh !!  

and dont forget to reserved the memory your writing to! (dts)
0 Kudos
Altera_Forum
Honored Contributor II
608 Views

Thanks for your answer. I'm sorry to reply with such a delay, I didn't received any notification email ... And I started to work on an other part of my system ... Now I will check ever day ;) 

 

Yes I wrote a tiny VHDL module for Qsys : 

library ieee; use ieee.std_logic_1164.all; ENTITY interrupt_generator IS PORT( irq : OUT std_logic; key : IN std_logic ); END interrupt_generator; ARCHITECTURE a_interrupt_generator OF interrupt_generator IS BEGIN irq <= not key; END a_interrupt_generator; 

 

It's plugged in Qsys as you can see in my first post (in the attached file). The conduit signal is directly connected to one of the push-buttons in my top-level VHDL. 

 

I have modified the original dts adding those lines in the soc node 

hps_0_arm_gic_0: intc@fffed000 { compatible = "arm,cortex-a9-gic"; # interrupt-cells = <0x3>; interrupt-controller; reg = <0xfffed000 0x1000 0xfffec100 0x100>; linux,phandle = <0x2>; phandle = <0x2>; }; fpgaint0: fpgaint@0 { compatible = "altr,fpgaint-0.1"; interrupt-parent = < &hps_0_arm_gic_0 >; label = "fpgaint0"; interrupts = <0 40 1>; }; fpgaint1: fpgaint@1 { compatible = "altr,fpgaint-0.1"; interrupt-parent = < &hps_0_arm_gic_0 >; label = "fpgaint1"; interrupts = <0 41 1>; }; fpgaint2: fpgaint@2 { compatible = "altr,fpgaint-0.1"; interrupt-parent = < &hps_0_arm_gic_0 >; label = "fpgaint2"; interrupts = <0 42 1>; }; 

 

I copy-pasted it from one template and different forum's topics. 

I don't understand the values of this line : 

reg = <0xfffed000 0x1000 0xfffec100 0x100>; 

If I think right (is it really <addr value addr value> ?), why the values are 0x1000 and 0x100. In an Altera Document : "Using the ARM Generic Interrupt Controller", the enable bits are shown on bits 0 of ICCICR and ICDDCR, so 0x1 for both. 

To enable my interrupt (the fisrt one) should I add, in the line reg=, 0xfffed108 0x100 (for GIC ID 72) or 0xfffed104 0x100 (ID 40) ? 

 

Now I compile dts with the dtc command, and copy it to the sd card. 

 

Should I be able to see something happenning with cat /proc/stat at this stage (something like a counter incremented every time I hit the push button ?) ? (My complete dts is in the attached file) 

 

I don't understand what you mean by "reserved the memory your writing to! (dts)" 

 

Merci beaucoup
0 Kudos
Reply