FPGA proven, AISC proven, I2C controller core from OpenCores  

http://opencores.org/project,i2c

 

Bit-controller

-- Translate simple commands into SCL/SDA transitions
-- Each command has 5 states, A/B/C/D/idle
--
-- start:    SCL  ~~~~~~~~~~~~~~\____
--           SDA  XX/~~~~~~~\______
--                x | A | B | C | D | i
--
-- repstart  SCL  ______/~~~~~~~\___
--           SDA  __/~~~~~~~\______
--                x | A | B | C | D | i
--
-- stop      SCL  _______/~~~~~~~~~~~
--           SDA  ==\___________/~~~~~
--                x | A | B | C | D | i
--
--- write    SCL  ______/~~~~~~~\____
--           SDA  XXX===============XX
--                x | A | B | C | D | i
--
--- read     SCL  ______/~~~~~~~\____
--           SDA  XXXXXXX=XXXXXXXXXXX
--                x | A | B | C | D | i
--

1  ports declaration

 1 library ieee;
 2 use ieee.std_logic_1164.all;
 3 use ieee.numeric_std.all;
 4 
 5 entity i2c_master_bit_ctrl is
 6 port (
 7           clk    : in std_logic;
 8           rst    : in std_logic;
 9           nRst   : in std_logic;
10           ena    : in std_logic;                     -- core enable signal
11 
12           clk_cnt : in unsigned(15 downto 0);        -- clock prescale value 
                                 --! type unsigned is array (natural range <>) of std_logic
13 14 cmd : in std_logic_vector(3 downto 0); 15 cmd_ack : out std_logic; -- command completed 16 busy : out std_logic; -- i2c bus busy 17 al : out std_logic; -- arbitration lost 18 19 din : in std_logic; 20 dout : out std_logic; 21 22 -- i2c lines 23 scl_i : in std_logic; -- i2c clock line input 24 scl_o : out std_logic; -- i2c clock line output 25 scl_oen : out std_logic; -- i2c clock line output enable, active low 26 sda_i : in std_logic; -- i2c data line input 27 sda_o : out std_logic; -- i2c data line output 28 sda_oen : out std_logic -- i2c data line output enable, active low 29 ); 30 end entity i2c_master_bit_ctrl;

2  signals declaration

 1 -- architecture   
 2  constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
 3  constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
 4  constant I2C_CMD_STOP   : std_logic_vector(3 downto 0) := "0010";
 5  constant I2C_CMD_READ   : std_logic_vector(3 downto 0) := "0100";
 6  constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
 7 
 8  type states is (idle, start_a, start_b, start_c, start_d, start_e,stop_a,stop_b,
 9                   stop_c, stop_d, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);
10  signal c_state : states;
11 
12  signal iscl_oen, isda_oen : std_logic;     -- internal I2C lines
13  signal sda_chk     : std_logic;      -- check SDA status (multi-master arbitration)
14  signal dscl_oen    : std_logic;      -- delayed scl_oen signals
15  signal sSCL, sSDA   : std_logic;      -- synchronized SCL and SDA inputs
16  signal dSCL, dSDA   : std_logic;       -- delayed versions of sSCL and sSDA
17  signal clk_en         : std_logic;      -- statemachine clock enable
18  signal scl_sync, slave_wait : std_logic;   -- clock generation signals
19  signal ial            : std_logic;         -- internal arbitration lost signal
20  signal cnt            : unsigned(15 downto 0); -- clock divider counter (synthesis)
21 
22 -- block
23  signal cSCL, cSDA  : std_logic_vector(1 downto 0); -- capture SDA and SCL
24  signal fSCL, fSDA  : std_logic_vector(2 downto 0); -- filter inputs for SCL and SDA
25  signal filter_cnt    : unsigned(13 downto 0);      -- clock divider for filter
26  signal sta_condition : std_logic;          -- start detected
27  signal sto_condition : std_logic;          -- stop detected
28  signal cmd_stop      : std_logic;          -- STOP command
29  signal ibusy         : std_logic;          -- internal busy signal

3 assign outputs

1     -- assign outputs
2     scl_o   <= '0';
3     scl_oen <= iscl_oen;
4     sda_o   <= '0';
5     sda_oen <= isda_oen;

 

posted on 2015-05-07 07:28  mengdie  阅读(705)  评论(0)    收藏  举报