I2C slave

Discussion in 'VHDL' started by Frank Buss, Oct 16, 2006.

  1. Frank Buss

    Frank Buss Guest

    I've written a I2C slave core:

    http://www.frank-buss.de/vhdl/i2c_slave-0.1.zip

    It should work with 100 kB and 400 kB master devices and it supports
    sending and receiving multiple bytes and the repeated start condition.
    Stretching clock cycles is not supported, the host which uses the core must
    be fast enough.

    Currently I've tested it in a simulator, only, maybe someone could test it
    on real hardware, e.g. with the included testdevice and a hardware master,
    like built-in in some microcontrollers.

    I'm not sure about the communication concept: Currently it doesn't use
    handshaking, but the slave entity signals, that a byte was received and
    some cycles later releases this signal. I think it is easier to use, but
    maybe a more standard interface like Wishbone would be better?

    The licence is BSD and if you have bugfixes or other improvments, I'll add
    it and publish it again. When it is mature, I'll plan to submit it to
    opencores.org.

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 16, 2006
    #1
    1. Advertising

  2. Frank Buss

    PeteS Guest

    Frank Buss wrote:
    > I've written a I2C slave core:
    >
    > http://www.frank-buss.de/vhdl/i2c_slave-0.1.zip
    >
    > It should work with 100 kB and 400 kB master devices and it supports
    > sending and receiving multiple bytes and the repeated start condition.
    > Stretching clock cycles is not supported, the host which uses the core must
    > be fast enough.
    >
    > Currently I've tested it in a simulator, only, maybe someone could test it
    > on real hardware, e.g. with the included testdevice and a hardware master,
    > like built-in in some microcontrollers.
    >
    > I'm not sure about the communication concept: Currently it doesn't use
    > handshaking, but the slave entity signals, that a byte was received and
    > some cycles later releases this signal. I think it is easier to use, but
    > maybe a more standard interface like Wishbone would be better?
    >
    > The licence is BSD and if you have bugfixes or other improvments, I'll add
    > it and publish it again. When it is mature, I'll plan to submit it to
    > opencores.org.
    >
    > --
    > Frank Buss,
    > http://www.frank-buss.de, http://www.it4-systems.de


    Hi Frank

    I'll drop it in and test it on real hardware in a couple of weeks (when
    I get the latest and greatest back from fab and stuffing).

    One thing I did note: the SDA output should be either Hi Z or 0 - it
    should never be driven high. The standard actually specifies open
    collector, but Hi Z for high works the same way :)

    Cheers

    PeteS
     
    PeteS, Oct 16, 2006
    #2
    1. Advertising

  3. Frank Buss

    Frank Buss Guest

    PeteS wrote:

    > I'll drop it in and test it on real hardware in a couple of weeks (when
    > I get the latest and greatest back from fab and stuffing).


    Thanks.

    > One thing I did note: the SDA output should be either Hi Z or 0 - it
    > should never be driven high. The standard actually specifies open
    > collector, but Hi Z for high works the same way :)


    I don't see a problem. In the ports section I've defined this:

    sda_io: inout std_logic;

    And then in the architecture this:

    signal sda_o: std_logic := '1';
    signal sda_i: std_logic := '0';

    ....

    begin

    ....

    sda_io <= sda_o when sda_o = '0' else 'Z';
    sda_i <= '1' when sda_io /= '0' else '0';
    read_mode_o <= read_mode;

    At least this worked for my 1-wire implementation with Xilinx (
    http://www.frank-buss.de/vhdl/spartan3e.html ), which I've tested with real
    hardware, so I assume the synthesis tool infers something compatible with
    open collector for it, but I'm a VHDL beginner, so maybe there is a better
    solution.

    BTW: is there any drawback to define "scl_i: in std_logic"? It's a I2C
    slave, only and I don't support clock stretching, so I hope it is ok to
    define it just as input.

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 16, 2006
    #3
  4. Frank Buss

    PeteS Guest

    Frank Buss wrote:
    > PeteS wrote:
    >
    > > I'll drop it in and test it on real hardware in a couple of weeks (when
    > > I get the latest and greatest back from fab and stuffing).

    >
    > Thanks.
    >
    > > One thing I did note: the SDA output should be either Hi Z or 0 - it
    > > should never be driven high. The standard actually specifies open
    > > collector, but Hi Z for high works the same way :)

    >
    > I don't see a problem. In the ports section I've defined this:
    >
    > sda_io: inout std_logic;
    >
    > And then in the architecture this:
    >
    > signal sda_o: std_logic := '1';
    > signal sda_i: std_logic := '0';
    >
    > ...
    >
    > begin
    >
    > ...
    >
    > sda_io <= sda_o when sda_o = '0' else 'Z';
    > sda_i <= '1' when sda_io /= '0' else '0';
    > read_mode_o <= read_mode;
    >
    > At least this worked for my 1-wire implementation with Xilinx (
    > http://www.frank-buss.de/vhdl/spartan3e.html ), which I've tested with real
    > hardware, so I assume the synthesis tool infers something compatible with
    > open collector for it, but I'm a VHDL beginner, so maybe there is a better
    > solution.
    >
    > BTW: is there any drawback to define "scl_i: in std_logic"? It's a I2C
    > slave, only and I don't support clock stretching, so I hope it is ok to
    > define it just as input.
    >
    > --
    > Frank Buss,
    > http://www.frank-buss.de, http://www.it4-systems.de


    Hi Frank
    My oops :)

    I was looking at the logical assignemtns, not the IO assignment at the
    end.

    As to SCL - it should be just an input as you don't support clock
    stretch, and that looks fine to me. Note I am more comfortable in 'that
    other HDL language' but as far as I can see this unit looks good.

    I'll drop it into my design and testbench tonight and see what happens!

    Cheers

    PeteS
     
    PeteS, Oct 16, 2006
    #4
  5. Frank Buss

    PeteS Guest

    PeteS wrote:
    > Frank Buss wrote:
    >
    >>PeteS wrote:
    >>
    >>
    >>>I'll drop it in and test it on real hardware in a couple of weeks (when
    >>>I get the latest and greatest back from fab and stuffing).

    >>
    >>Thanks.
    >>
    >>
    >>>One thing I did note: the SDA output should be either Hi Z or 0 - it
    >>>should never be driven high. The standard actually specifies open
    >>>collector, but Hi Z for high works the same way :)

    >>
    >>I don't see a problem. In the ports section I've defined this:
    >>
    >> sda_io: inout std_logic;
    >>
    >>And then in the architecture this:
    >>
    >> signal sda_o: std_logic := '1';
    >> signal sda_i: std_logic := '0';
    >>
    >>...
    >>
    >>begin
    >>
    >>...
    >>
    >> sda_io <= sda_o when sda_o = '0' else 'Z';
    >> sda_i <= '1' when sda_io /= '0' else '0';
    >> read_mode_o <= read_mode;
    >>
    >>At least this worked for my 1-wire implementation with Xilinx (
    >>http://www.frank-buss.de/vhdl/spartan3e.html ), which I've tested with real
    >>hardware, so I assume the synthesis tool infers something compatible with
    >>open collector for it, but I'm a VHDL beginner, so maybe there is a better
    >>solution.
    >>
    >>BTW: is there any drawback to define "scl_i: in std_logic"? It's a I2C
    >>slave, only and I don't support clock stretching, so I hope it is ok to
    >>define it just as input.
    >>
    >>--
    >>Frank Buss,
    >>http://www.frank-buss.de, http://www.it4-systems.de

    >
    >
    > Hi Frank
    > My oops :)
    >
    > I was looking at the logical assignemtns, not the IO assignment at the
    > end.
    >
    > As to SCL - it should be just an input as you don't support clock
    > stretch, and that looks fine to me. Note I am more comfortable in 'that
    > other HDL language' but as far as I can see this unit looks good.
    >
    > I'll drop it into my design and testbench tonight and see what happens!
    >
    > Cheers
    >
    > PeteS
    >

    I dropped this into a design I am doing (only at simulation stage as of
    yet) and all seems to operate properly.

    The one thing I notice is when I push the speed I get invalid data (but
    that's at a few 10s of Mb/s, which is _way_ beyond the spec). Might be
    useful to set a constraint or two to see if I can get more speed out of
    it. Of course, there's a lot of other stuff in the device I am
    simulating, so that's a pretty common issue.

    I will note that I usually push such things (I2C, SMBus, SPI etc) to at
    least 20x normal speed in simulation to account for PCB capacitance. If
    it still operates Post PAR at that, I know it'll operate properly at
    'normal' rates.

    If you don't mind, I might add some conditionals for SMBus (which has
    timeouts that can be useful in hotswap). I2C can lock up in such
    situations where SMBus can recover.

    Cheers

    PeteS


    Cheers

    PeteS
     
    PeteS, Oct 16, 2006
    #5
  6. Frank Buss

    Frank Buss Guest

    PeteS wrote:

    > The one thing I notice is when I push the speed I get invalid data (but
    > that's at a few 10s of Mb/s, which is _way_ beyond the spec).


    I think you'll get many problems with I2C at this speed, because you need
    very low resistors to load the parasitic capacitance in the open collector
    cicuit, but the I2C spec defines a special HS-mode up to 3.4 Mbit/s and
    gives some advice how to design the circuit for it. But there might be
    still problems if there are not enough FPGA clock cycles per I2C clock
    cycles (e.g. you have to delete the data hold counter section, which is
    needed for low speed, improve the bit and logic level handshaking speed
    etc.).

    > If you don't mind, I might add some conditionals for SMBus (which has
    > timeouts that can be useful in hotswap). I2C can lock up in such
    > situations where SMBus can recover.


    I've read the SMBus specification and looks like it has some advantages,
    e.g. lowest speed is 10 kHz, which allows fast timeouts, so you can add it.

    But I don't think that it is absolute necessary to avoid lock ups, because
    for the slave a start or a stop signal resets the transfer state,
    regardless in which state it is. And for the master the I2C specification
    says, that if it doesn't receive an ACK, it should send a repeated start or
    a stop signal.

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 16, 2006
    #6
  7. Frank Buss

    PeteS Guest

    Frank Buss wrote:
    > PeteS wrote:
    >
    >
    >>The one thing I notice is when I push the speed I get invalid data (but
    >>that's at a few 10s of Mb/s, which is _way_ beyond the spec).

    >
    >
    > I think you'll get many problems with I2C at this speed, because you need
    > very low resistors to load the parasitic capacitance in the open collector
    > cicuit, but the I2C spec defines a special HS-mode up to 3.4 Mbit/s and
    > gives some advice how to design the circuit for it. But there might be
    > still problems if there are not enough FPGA clock cycles per I2C clock
    > cycles (e.g. you have to delete the data hold counter section, which is
    > needed for low speed, improve the bit and logic level handshaking speed
    > etc.).
    >
    >
    >>If you don't mind, I might add some conditionals for SMBus (which has
    >>timeouts that can be useful in hotswap). I2C can lock up in such
    >>situations where SMBus can recover.

    >
    >
    > I've read the SMBus specification and looks like it has some advantages,
    > e.g. lowest speed is 10 kHz, which allows fast timeouts, so you can add it.
    >
    > But I don't think that it is absolute necessary to avoid lock ups, because
    > for the slave a start or a stop signal resets the transfer state,
    > regardless in which state it is. And for the master the I2C specification
    > says, that if it doesn't receive an ACK, it should send a repeated start or
    > a stop signal.
    >

    The issue is that I2C will send the repeated start / stop but never
    return to the idle state without a valid transition. SMBus incorporates
    a timeout to alleviate this issue. I've had to deal with this on real
    boards, so I know it's a real problem.

    I'll do that stuff tomorrow :)

    Cheers

    PeteS
     
    PeteS, Oct 16, 2006
    #7
  8. Frank Buss

    Frank Buss Guest

    Frank Buss wrote:

    > Currently I've tested it in a simulator, only, maybe someone could test it
    > on real hardware, e.g. with the included testdevice and a hardware master,
    > like built-in in some microcontrollers.


    Today I tested it with real hardware and the I2C address was detected with
    a reliability of about 20% only. And I discussed the code with a workmate
    and he excoriate the code, expecially the very long and complicated state
    machines. But don't worry, currently I'm rewriting it with many more simple
    processes instead of two big ones and the address detection works already
    with about 100% reliability :)

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 18, 2006
    #8
  9. Frank Buss

    Guest

    Hi Frank,

    I am trying to simulate it with ModelsimDesigner.

    Where do I get the UNISIM library from ?

    Rgds
    André
     
    , Oct 19, 2006
    #9
  10. Frank Buss

    Frank Buss Guest

    wrote:

    > I am trying to simulate it with ModelsimDesigner.
    >
    > Where do I get the UNISIM library from ?


    You don't need it, this was a copy-and-paste error from another project.

    I've updated the project and I think the code is better now. A non-I2C
    conforming (but useful in real systems) timeout is included, to avoid
    lowering SDA too long. To filter out spikes (the I2C specification says 50
    ns has to be filtered) a 4 bit shift register accumulates SCL and SDA and
    rising and falling edges are detected only, if the shift register contains
    "1100" or "0011". I2C master writing to the slave worked on my new T-Rex.

    For testing writing, reading and combinations with repeated start, I've
    implemented a PCA9555 GPIO in VHDL and enhanced the testbench, which
    worked. Tomorrow I can test it with a hardware master, which already
    communicates with a PCA9555 chip.

    The new version:

    http://www.frank-buss.de/vhdl/i2c_slave-0.2.zip

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 20, 2006
    #10
  11. Frank Buss

    Frank Buss Guest

    Frank Buss wrote:

    > Tomorrow I can test it with a hardware master, which already
    > communicates with a PCA9555 chip.


    There were still some bugs, which I didn't detect with the testbench, but
    now it works with real hardware: I've tested it in fast mode with a master
    of an ARM PXA and in standard mode with a master of a HCS08. The HCS08 test
    program is included, I've organized the directory structure to the
    recommendations of OpenCores, added some documentation with logic analyzer
    samples and commented the VHDL code a bit better. The new version:

    http://www.frank-buss.de/vhdl/i2c_slave-0.3.zip

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 21, 2006
    #11
  12. Frank Buss

    Frank Buss Guest

    A new version:

    http://www.frank-buss.de/vhdl/i2c_slave-0.4.zip

    While integrating it in a production system, I found a bug when the slave
    was sending multiple bytes: only the first data request was signaled by the
    i2c_slave core. After fixing it, sending and receiving 128 bytes in an
    endless loop, together with other devices on the same bus, works without
    problems.

    And I've added and tested a Spartan 3 Start Kit project for the PCA9555
    test implementation.

    Today my OpenCores account was approved, the next release will be at
    www.opencores.org.

    --
    Frank Buss,
    http://www.frank-buss.de, http://www.it4-systems.de
     
    Frank Buss, Oct 28, 2006
    #12
  13. Frank Buss

    erezc

    Joined:
    Aug 14, 2007
    Messages:
    2
    I2C slave - PCA9555 VHDL code.

    Dear Frank,

    could you please send me the PCA9555 final code?
    i can not find it.

     
    erezc, Aug 14, 2007
    #13
  14. Frank Buss

    erezc

    Joined:
    Aug 14, 2007
    Messages:
    2
    Minimal core frequency for PCA955 VHDL.

    Hi all,

    could you please advise the minimal Core frequency i can use in the PCA9555 VHDL code?
     
    erezc, Mar 26, 2008
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Ungerer

    Simple I2C slave model (IO expander)

    Alex Ungerer, Oct 3, 2003, in forum: VHDL
    Replies:
    1
    Views:
    2,791
    Paul Baxter
    Oct 3, 2003
  2. rickman

    Check i2c slave

    rickman, Sep 15, 2004, in forum: VHDL
    Replies:
    2
    Views:
    1,148
    Marcus
    Sep 16, 2004
  3. sudha
    Replies:
    2
    Views:
    13,586
  4. Replies:
    1
    Views:
    1,274
  5. LRCR
    Replies:
    2
    Views:
    7,690
    Konstantin Schmidt
    Jan 3, 2006
Loading...

Share This Page