UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
1,431 Views
Registered: ‎04-02-2015

i2c signal bypass fpga

Jump to solution

Hi everyone,

 

Currently,Our hardware board have a I2C host controller  with 1.8v standard i2c signal(sdc1.8,sda1.8), and a I2C slave memory device(sdc3.3,sda3.3) with 3.3v standard signal.We connected sdc1.8,sda1.8,sdc3.3,sda3.3 to FPGA banks.

And I configure FPGA pins sdc1.8 as input LVCMOS18,sda1.8 as inout LVCMOS1.8,sdc3.3 as output LVCMOS33,sda3.3 as inout LVCMOS33. Actually, FPGA as a Voltage converter,sda and sdc bypass fpga logic.

I don't know if it's right.I am not sure i2c be able to work either. anyone knows?

0 Kudos
1 Solution

Accepted Solutions
1,568 Views
Registered: ‎01-22-2015

Re: i2c signal bypass fpga

Jump to solution

Here’s my submission for “most expensive I2C-bypass circuit” … and it may even work.

 

I have shown only the bidirectional sda-line, but the same circuit could be used for a bidirectional scl-line. Note that I2C clock speeds are typically well below 1 MHz.

 

i2c_bypass.jpg

 

CTRL_LOGIC: process(clk100)
begin
    if rising_edge(clk100) then
        if(rst100 = '1') then  
            O1 <= '0';
            O2 <= '0';
            i2c_state <= s0;                         
        else  
            case i2c_state is
                when s0 =>          --s0: wait for I1 or I2 to be pulled low
                    T1 <= '1';          --both OBUFT in high-impedance state
                    T2 <= '1';
                    if(I1 = '0') then 
                        T2 <= '0';      --sda driven by O2 is now low                 
                        i2c_state <= s1; 
                    elsif(I2 = '0') then
                        T1 <= '0';      --sda driven by O1 is now low                  
                        i2c_state <= s2;                     
                    else
                        i2c_state <= s0;
                    end if;
                                  
                when s1 =>          --s1: wait for I1 to go high
                    if(I1 = '1') then
                        i2c_state <= s0;
                    else
                        i2c_state <= s1;           
                    end if;
                    
                when s2 =>          --s2: wait for I2 to go high
                    if(I2 = '1') then
                        i2c_state <= s0;
                    else
                        i2c_state <= s2;           
                    end if;

                when others =>      --others: bad state
                    i2c_state <= s0;    
            end case; 
        end if;  
    end if;
end process CTRL_LOGIC;
7 Replies
Moderator
Moderator
1,397 Views
Registered: ‎04-18-2011

Re: i2c signal bypass fpga

Jump to solution

maybe draw us a high level diagram of it. 

My main concern is the propagation delay added by this route through you have in the FPGA. 

 

 

-------------------------------------------------------------------------
Don’t forget to reply, kudo, and accept as solution.
-------------------------------------------------------------------------
0 Kudos
1,369 Views
Registered: ‎01-22-2015

Re: i2c signal bypass fpga

Jump to solution

-also, using IOBUF for the bidirectional data (sda) line will be a problem since you have no easy way to control the 3-state-input, T, of the IOBUF.

IOBUF.jpg

0 Kudos
Scholar u4223374
Scholar
1,324 Views
Registered: ‎04-26-2015

Re: i2c signal bypass fpga

Jump to solution

I don't think you can do an I2C passthrough. Say a device at the 1.8V end pulls the bus down. Then the correct reaction from the FPGA is to pull the 3.3V side of the bus down too. Since the 3.3V side is now low (and the FPGA has no way to know whether this is just because it's pulling down, or because a 3.3V device is also pulling the bus down) the correct action is to pull the 1.8V side down too. The result is that the FPGA ends up permanently holding both sides low, so nobody can talk. Very fancy systems can pull the bus down to maybe 0.5V instead of 0V, so then they can detect when something else is holding the bus too - but FPGAs don't have that sort of output buffer, nor do they have ADCs on every pin to detect the difference.

 

Realistically, if you want I2C level translation, there are far better ways to do it. There's a single-MOSFET version (well, one MOSFET per line, so two for I2C) that works nicely. Or there are a range of "smart" level shifters that hold the bus with a very low current (ie microamps) so that any input can overpower them.

0 Kudos
1,297 Views
Registered: ‎04-02-2015

Re: i2c signal bypass fpga

Jump to solution

top.PNG

I think FPGA can convert 1.8v input to 3.3v output. But I'm not sure about Bi-directional I2C signal could bypass through FPGA.

0 Kudos
1,294 Views
Registered: ‎04-02-2015

Re: i2c signal bypass fpga

Jump to solution

Hi,

 Your are right. It's too hard to control 3-state-input,T,of IOBUF.After implement,I noticed there are not any IOBUF insert to sda18 and sda33 IO in FPGA. sda.PNG

0 Kudos
1,291 Views
Registered: ‎04-02-2015

Re: i2c signal bypass fpga

Jump to solution

Hi,

Thanks for you replay. We insert MOSFET to I2C signal and works nicely before. Now, we want remove MOSFET and relpaced by FPGA.

0 Kudos
1,569 Views
Registered: ‎01-22-2015

Re: i2c signal bypass fpga

Jump to solution

Here’s my submission for “most expensive I2C-bypass circuit” … and it may even work.

 

I have shown only the bidirectional sda-line, but the same circuit could be used for a bidirectional scl-line. Note that I2C clock speeds are typically well below 1 MHz.

 

i2c_bypass.jpg

 

CTRL_LOGIC: process(clk100)
begin
    if rising_edge(clk100) then
        if(rst100 = '1') then  
            O1 <= '0';
            O2 <= '0';
            i2c_state <= s0;                         
        else  
            case i2c_state is
                when s0 =>          --s0: wait for I1 or I2 to be pulled low
                    T1 <= '1';          --both OBUFT in high-impedance state
                    T2 <= '1';
                    if(I1 = '0') then 
                        T2 <= '0';      --sda driven by O2 is now low                 
                        i2c_state <= s1; 
                    elsif(I2 = '0') then
                        T1 <= '0';      --sda driven by O1 is now low                  
                        i2c_state <= s2;                     
                    else
                        i2c_state <= s0;
                    end if;
                                  
                when s1 =>          --s1: wait for I1 to go high
                    if(I1 = '1') then
                        i2c_state <= s0;
                    else
                        i2c_state <= s1;           
                    end if;
                    
                when s2 =>          --s2: wait for I2 to go high
                    if(I2 = '1') then
                        i2c_state <= s0;
                    else
                        i2c_state <= s2;           
                    end if;

                when others =>      --others: bad state
                    i2c_state <= s0;    
            end case; 
        end if;  
    end if;
end process CTRL_LOGIC;