Forum Discussion

Alberto_F's avatar
Alberto_F
Icon for New Contributor rankNew Contributor
3 years ago

Cyclone V HPS - I2C1 through FPGA routing

Hello all,

I'm trying to get the I2C1 module on a Cyclone V HPS routed through the FPGA pins on a DE0 Nano board, and I'm confused about the signal naming and purpose. The device is only to be used as master. The I2C0 interface, through Linux, works perfectly well.

The settings on the HPS are as I2C1 mode Full:

The truth is I could not find information how to connect the clocks.

Is there a guide I've missed somewhere on how to use this peripheral as master and route it out through the FPGA?

Any help is appreciated.

Cheers,

Alberto

8 Replies

  • aikeu's avatar
    aikeu
    Icon for Regular Contributor rankRegular Contributor

    Hi Alberto_F,


    I think you can try to connect the i2c1_scl_in on the HPS IP to the Clock IP that provides the main clock source.


    Thanks.

    Regards,

    Aik Eu


  • Alberto_F's avatar
    Alberto_F
    Icon for New Contributor rankNew Contributor

    Hi @aikeu thanks, I will try that. If I understand you correctly, is that the 100MHz clock the system runs at?

    Cheers,

    Alberto

  • aikeu's avatar
    aikeu
    Icon for Regular Contributor rankRegular Contributor

    Hi Alberto_F,


    Ya is the main system clock. The GHRD is using 50Mhz.


    Thanks.

    Regards,

    Aik Eu




  • Alberto_F's avatar
    Alberto_F
    Icon for New Contributor rankNew Contributor

    Hi Aik,

    sorry, I have not been able to get into this further! Last I tried it didn't work. I found some information about having to add ALTIOBUFFERS explicitly, unfortunately I got sidetracked as uboot is not loading the FPGA image any more.

    I will try to get more information next week.

    Cheers,

    Alberto

  • Alberto_F's avatar
    Alberto_F
    Icon for New Contributor rankNew Contributor

    Hi all,

    This is what the data sheet (Reference Manual) shows on I2C:

    And this is the output of the IP platform:

    I find the names a bit confusing to be honest, I think an example would help. I'm still working on this. The datasheet also says:

    So I'm guessing this is the actual I2c clock? There are four signals in total exported from Platform Designer, I suppose they are the four signals that are mentioned in the datasheet?

    This is what I have for now, I will let you all know how it goes.

    Cheers,

    Alberto

    • Alberto_F's avatar
      Alberto_F
      Icon for New Contributor rankNew Contributor

      Ok, I got it running, here it is for future references and as an example to anyone who needs this:

      The above are the four I2C signals used to interface to the FPGA and the output, NOT the 50MHz clock. The project generates the following interface:

      -- I2C2 (FPGA)
      hps_0_i2c2_clk_clk              : out   std_logic; -- I2C SCL Control Signal
      hps_0_i2c2_out_data             : out   std_logic; -- I2C SDA Control Signal
      hps_0_i2c2_sda                  : in    std_logic; -- SDA Input pin
      hps_0_i2c2_scl_in_clk           : in    std_logic; -- SCL Input pin

      The first two signals above are the control for the BUFIO that drives the output, while the signals below are the input signals from the pins. To correctly drive the output and read the signals in, I added the following process:

      i2c2_proc: process(hps_0_i2c2_clk_clk, hps_0_i2c2_out_data)
      begin
      	
      	if(hps_0_i2c2_clk_clk = '1') then
      		I2C2_SCL <= '0';
      	else
      		I2C2_SCL <= 'Z';
      	end if;
      
      	if(hps_0_i2c2_out_data = '1') then
      		I2C2_SDA <= '0';
      	else
      		I2C2_SDA <= 'Z';
      	end if;
      end process;
      
      hps_0_i2c2_scl_in_clk <= I2C2_SCL;
      hps_0_i2c2_sda <= I2C2_SDA;

      The above is the equivalent of the image below, although the naming is confusing.

      Once the project is generated, you MUST re-generate the QTS files, which will effectively set this line "1, /* I2C2USEFPGA */" in pinmux_config.h.

      Also, to make sure your bootloader and Linux system recognise the new module, you need to explicitly add them to the drivers:

      /* UBOOT */
      &i2c2 {
      	status = "okay";
      	clock-frequency = <100000>;
      	compatible = "snps,designware-i2c-17.0", "snps,designware-i2c";
      	clocks = <&l4_sp_clk>;
      	status = "okay"; /* embeddedsw.dts.params.status type STRING */
      	clock-frequency = <100000>;
      	i2c-sda-hold-time-ns = <100>;
      	i2c-sda-falling-time-ns = <100>;
      	i2c-scl-falling-time-ns = <300>;
      };
      /* Linux */
      &i2c2 {
      	status = "okay";
      	clock-frequency = <100000>;
      };

      Recompile and test. Remember to add pullup resistors on the SDA and SCL lines.

      Hope this helps.

      Cheers,

      Alberto

  • aikeu's avatar
    aikeu
    Icon for Regular Contributor rankRegular Contributor

    Hi Alberto_F,


    Glad that you have resolved the issue.

    Thanks for the sharing of your findings, it helps me to understand better.


    Thanks.

    Regards,

    Aik Eu