1 ---------------------------------------------------------------------
3 ---- WISHBONE revB2 compl. I2C Master Core; byte-controller ----
6 ---- Author: Richard Herveille ----
7 ---- richard@asics.ws ----
10 ---- Downloaded from: http://www.opencores.org/projects/i2c/ ----
12 ---------------------------------------------------------------------
14 ---- Copyright (C) 2000 Richard Herveille ----
15 ---- richard@asics.ws ----
17 ---- This source file may be used and distributed without ----
18 ---- restriction provided that this copyright statement is not ----
19 ---- removed from the file and that any derivative work contains ----
20 ---- the original copyright notice and the associated disclaimer.----
22 ---- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ----
23 ---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ----
24 ---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ----
25 ---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ----
26 ---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ----
27 ---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ----
28 ---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ----
29 ---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ----
30 ---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ----
31 ---- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ----
32 ---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ----
33 ---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ----
34 ---- POSSIBILITY OF SUCH DAMAGE. ----
36 ---------------------------------------------------------------------
40 -- $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $
42 -- $Date: 2004/02/18 11:41:48 $
44 -- $Author: rherveille $
49 -- $Log: i2c_master_byte_ctrl.vhd,v $
50 -- Revision 1.5 2004/02/18 11:41:48 rherveille
51 -- Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
53 -- Revision 1.4 2003/08/09 07:01:13 rherveille
54 -- Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
55 -- Fixed a potential bug in the byte controller's host-acknowledge generation.
57 -- Revision 1.3 2002/12/26 16:05:47 rherveille
58 -- Core is now a Multimaster I2C controller.
60 -- Revision 1.2 2002/11/30 22:24:37 rherveille
63 -- Revision 1.1 2001/11/05 12:02:33 rherveille
64 -- Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
65 -- Code updated, is now up-to-date to doc. rev.0.4.
73 ------------------------------------------
74 -- Byte controller section
75 ------------------------------------------
78 use ieee.std_logic_1164.all;
79 use ieee.std_logic_arith.all;
81 entity i2c_master_byte_ctrl is
84 rst : in std_logic; -- synchronous active high reset (WISHBONE compatible)
85 nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
86 ena : in std_logic; -- core enable signal
88 clk_cnt : in unsigned(15 downto 0); -- 4x SCL
96 din : in std_logic_vector(7 downto 0);
99 cmd_ack : out std_logic; -- command done
100 ack_out : out std_logic;
101 i2c_busy : out std_logic; -- arbitration lost
102 i2c_al : out std_logic; -- i2c bus busy
103 dout : out std_logic_vector(7 downto 0);
106 scl_i : in std_logic; -- i2c clock line input
107 scl_o : out std_logic; -- i2c clock line output
108 scl_oen : out std_logic; -- i2c clock line output enable, active low
109 sda_i : in std_logic; -- i2c data line input
110 sda_o : out std_logic; -- i2c data line output
111 sda_oen : out std_logic -- i2c data line output enable, active low
113 end entity i2c_master_byte_ctrl;
115 architecture structural of i2c_master_byte_ctrl is
116 component i2c_master_bit_ctrl is
120 nReset : in std_logic;
121 ena : in std_logic; -- core enable signal
123 clk_cnt : in unsigned(15 downto 0); -- clock prescale value
125 cmd : in std_logic_vector(3 downto 0);
126 cmd_ack : out std_logic; -- command done
127 busy : out std_logic; -- i2c bus busy
128 al : out std_logic; -- arbitration lost
131 dout : out std_logic;
134 scl_i : in std_logic; -- i2c clock line input
135 scl_o : out std_logic; -- i2c clock line output
136 scl_oen : out std_logic; -- i2c clock line output enable, active low
137 sda_i : in std_logic; -- i2c data line input
138 sda_o : out std_logic; -- i2c data line output
139 sda_oen : out std_logic -- i2c data line output enable, active low
141 end component i2c_master_bit_ctrl;
143 -- commands for bit_controller block
144 constant I2C_CMD_NOP : std_logic_vector(3 downto 0) := "0000";
145 constant I2C_CMD_START : std_logic_vector(3 downto 0) := "0001";
146 constant I2C_CMD_STOP : std_logic_vector(3 downto 0) := "0010";
147 constant I2C_CMD_READ : std_logic_vector(3 downto 0) := "0100";
148 constant I2C_CMD_WRITE : std_logic_vector(3 downto 0) := "1000";
150 -- signals for bit_controller
151 signal core_cmd : std_logic_vector(3 downto 0);
152 signal core_ack, core_txd, core_rxd : std_logic;
153 signal al : std_logic;
155 -- signals for shift register
156 signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
157 signal shift, ld : std_logic;
159 -- signals for state machine
160 signal go, host_ack : std_logic;
161 signal dcnt : unsigned(2 downto 0); -- data counter
162 signal cnt_done : std_logic;
165 -- hookup bit_controller
166 bit_ctrl: i2c_master_bit_ctrl port map(
187 -- generate host-command-acknowledge
190 -- generate go-signal
191 go <= (read or write or stop) and not host_ack;
193 -- assign Dout output to shift-register
196 -- generate shift register
197 shift_register: process(clk, nReset)
199 if (nReset = '0') then
200 sr <= (others => '0');
201 elsif (clk'event and clk = '1') then
203 sr <= (others => '0');
204 elsif (ld = '1') then
206 elsif (shift = '1') then
207 sr <= (sr(6 downto 0) & core_rxd);
210 end process shift_register;
212 -- generate data-counter
213 data_cnt: process(clk, nReset)
215 if (nReset = '0') then
216 dcnt <= (others => '0');
217 elsif (clk'event and clk = '1') then
219 dcnt <= (others => '0');
220 elsif (ld = '1') then
221 dcnt <= (others => '1'); -- load counter with 7
222 elsif (shift = '1') then
226 end process data_cnt;
228 cnt_done <= '1' when (dcnt = 0) else '0';
234 type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
235 signal c_state : states;
238 -- command interpreter, translate complex commands into simpler I2C commands
240 nxt_state_decoder: process(clk, nReset)
242 if (nReset = '0') then
243 core_cmd <= I2C_CMD_NOP;
250 elsif (clk'event and clk = '1') then
251 if (rst = '1' or al = '1') then
252 core_cmd <= I2C_CMD_NOP;
260 -- initialy reset all signal
269 if (start = '1') then
271 core_cmd <= I2C_CMD_START;
272 elsif (read = '1') then
274 core_cmd <= I2C_CMD_READ;
275 elsif (write = '1') then
277 core_cmd <= I2C_CMD_WRITE;
280 core_cmd <= I2C_CMD_STOP;
287 if (core_ack = '1') then
290 core_cmd <= I2C_CMD_READ;
293 core_cmd <= I2C_CMD_WRITE;
300 if (core_ack = '1') then
301 if (cnt_done = '1') then
303 core_cmd <= I2C_CMD_READ;
305 c_state <= st_write; -- stay in same state
306 core_cmd <= I2C_CMD_WRITE; -- write next bit
312 if (core_ack = '1') then
313 if (cnt_done = '1') then
315 core_cmd <= I2C_CMD_WRITE;
317 c_state <= st_read; -- stay in same state
318 core_cmd <= I2C_CMD_READ; -- read next bit
326 if (core_ack = '1') then
327 -- check for stop; Should a STOP command be generated ?
330 core_cmd <= I2C_CMD_STOP;
333 core_cmd <= I2C_CMD_NOP;
335 -- generate command acknowledge signal
339 -- assign ack_out output to core_rxd (contains last received bit)
348 if (core_ack = '1') then
350 core_cmd <= I2C_CMD_NOP;
352 -- generate command acknowledge signal
356 when others => -- illegal states
358 core_cmd <= I2C_CMD_NOP;
359 report ("Byte controller entered illegal state.");
365 end process nxt_state_decoder;
367 end block statemachine;
369 end architecture structural;