Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
10 years ago

FPGA to HPS simple communication

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

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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