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

Cyclone V HPS - I2C1 through FPGA routing

Alberto_F
New Contributor I
931 Views

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:

Alberto_F_0-1660791179474.png

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

Alberto_F_1-1660791302435.png

 

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

 

0 Kudos
8 Replies
aikeu
Employee
910 Views

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


0 Kudos
Alberto_F
New Contributor I
889 Views

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

 

Cheers,

 

Alberto

0 Kudos
aikeu
Employee
887 Views

Hi Alberto_F,


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


Thanks.

Regards,

Aik Eu




0 Kudos
aikeu
Employee
864 Views

Hi Alberto_F,


Is there any further question from your side?


Thanks.

Regards,

Aik Eu


0 Kudos
Alberto_F
New Contributor I
859 Views

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

0 Kudos
Alberto_F
New Contributor I
834 Views

Hi all,

 

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

Alberto_F_1-1661745283676.png

 

And this is the output of the IP platform:

Alberto_F_2-1661745298846.png

 

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:

Alberto_F_0-1661745267121.png

 

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

0 Kudos
Alberto_F
New Contributor I
828 Views

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

Alberto_F_0-1661758428308.png

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.

Alberto_F_1-1661758993643.png

 

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

0 Kudos
aikeu
Employee
805 Views

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


0 Kudos
Reply