Line 35... |
Line 35... |
---- ----
|
---- ----
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
|
|
-- CVS Log
|
-- CVS Log
|
--
|
--
|
-- $Id: i2c_master_bit_ctrl.vhd,v 1.14 2006-10-11 12:10:13 rherveille Exp $
|
-- $Id: i2c_master_bit_ctrl.vhd,v 1.15 2009-01-20 10:34:51 rherveille Exp $
|
--
|
--
|
-- $Date: 2006-10-11 12:10:13 $
|
-- $Date: 2009-01-20 10:34:51 $
|
-- $Revision: 1.14 $
|
-- $Revision: 1.15 $
|
-- $Author: rherveille $
|
-- $Author: rherveille $
|
-- $Locker: $
|
-- $Locker: $
|
-- $State: Exp $
|
-- $State: Exp $
|
--
|
--
|
-- Change History:
|
-- Change History:
|
-- $Log: not supported by cvs2svn $
|
-- $Log: not supported by cvs2svn $
|
|
-- Revision 1.14 2006/10/11 12:10:13 rherveille
|
|
-- Added missing semicolons ';' on endif
|
|
--
|
-- Revision 1.13 2006/10/06 10:48:24 rherveille
|
-- Revision 1.13 2006/10/06 10:48:24 rherveille
|
-- fixed short scl high pulse after clock stretch
|
-- fixed short scl high pulse after clock stretch
|
--
|
--
|
-- Revision 1.12 2004/05/07 11:53:31 rherveille
|
-- Revision 1.12 2004/05/07 11:53:31 rherveille
|
-- Fixed previous fix :) Made a variable vs signal mistake.
|
-- Fixed previous fix :) Made a variable vs signal mistake.
|
Line 174... |
Line 177... |
|
|
signal iscl_oen, isda_oen : std_logic; -- internal I2C lines
|
signal iscl_oen, isda_oen : std_logic; -- internal I2C lines
|
signal sda_chk : std_logic; -- check SDA status (multi-master arbitration)
|
signal sda_chk : std_logic; -- check SDA status (multi-master arbitration)
|
signal dscl_oen : std_logic; -- delayed scl_oen signals
|
signal dscl_oen : std_logic; -- delayed scl_oen signals
|
signal sSCL, sSDA : std_logic; -- synchronized SCL and SDA inputs
|
signal sSCL, sSDA : std_logic; -- synchronized SCL and SDA inputs
|
signal clk_en, slave_wait : std_logic; -- clock generation signals
|
signal dSCL, dSDA : std_logic; -- delayed versions ofsSCL and sSDA
|
|
signal clk_en : std_logic; -- statemachine clock enable
|
|
signal scl_sync, slave_wait : std_logic; -- clock generation signals
|
signal ial : std_logic; -- internal arbitration lost signal
|
signal ial : std_logic; -- internal arbitration lost signal
|
-- signal cnt : unsigned(15 downto 0) := clk_cnt; -- clock divider counter (simulation)
|
-- signal cnt : unsigned(15 downto 0) := clk_cnt; -- clock divider counter (simulation)
|
signal cnt : unsigned(15 downto 0); -- clock divider counter (synthesis)
|
signal cnt : unsigned(15 downto 0); -- clock divider counter (synthesis)
|
|
|
begin
|
begin
|
Line 188... |
Line 193... |
begin
|
begin
|
if (clk'event and clk = '1') then
|
if (clk'event and clk = '1') then
|
dscl_oen <= iscl_oen;
|
dscl_oen <= iscl_oen;
|
end if;
|
end if;
|
end process;
|
end process;
|
slave_wait <= dscl_oen and not sSCL;
|
|
|
-- slave_wait is asserted when master wants to drive SCL high, but the slave (another master) pulls it low
|
|
-- slave_wait remains asserted until the slave (other master) releases SCL
|
|
process (clk, nReset)
|
|
begin
|
|
if (nReset = '0') then
|
|
slave_wait <= '0';
|
|
else
|
|
slave_wait <= (scl_oen and not dscl_oen and not sSCL) or (slave_wait and not sSCL);
|
|
end if;
|
|
end process;
|
|
|
|
-- master drives SCL high, but another master pulls it low
|
|
-- master start counting down its low cycle now (clock synchronization)
|
|
scl_sync <= dSCL and not sSCL and scl_oen;
|
|
|
-- generate clk enable signal
|
-- generate clk enable signal
|
gen_clken: process(clk, nReset)
|
gen_clken: process(clk, nReset)
|
begin
|
begin
|
if (nReset = '0') then
|
if (nReset = '0') then
|
Line 200... |
Line 219... |
clk_en <= '1';
|
clk_en <= '1';
|
elsif (clk'event and clk = '1') then
|
elsif (clk'event and clk = '1') then
|
if (rst = '1') then
|
if (rst = '1') then
|
cnt <= (others => '0');
|
cnt <= (others => '0');
|
clk_en <= '1';
|
clk_en <= '1';
|
elsif ( (cnt = 0) or (ena = '0') ) then
|
elsif ( (cnt = 0) or (ena = '0') or (scl_sync = '1') ) then
|
cnt <= clk_cnt;
|
cnt <= clk_cnt;
|
clk_en <= '1';
|
clk_en <= '1';
|
elsif (slave_wait = '1') then
|
elsif (slave_wait = '1') then
|
cnt <= cnt;
|
cnt <= cnt;
|
clk_en <= '0';
|
clk_en <= '0';
|
Line 216... |
Line 235... |
end process gen_clken;
|
end process gen_clken;
|
|
|
|
|
-- generate bus status controller
|
-- generate bus status controller
|
bus_status_ctrl: block
|
bus_status_ctrl: block
|
signal dSCL, dSDA : std_logic; -- delayes sSCL and sSDA
|
|
signal sta_condition : std_logic; -- start detected
|
signal sta_condition : std_logic; -- start detected
|
signal sto_condition : std_logic; -- stop detected
|
signal sto_condition : std_logic; -- stop detected
|
signal cmd_stop : std_logic; -- STOP command
|
signal cmd_stop : std_logic; -- STOP command
|
signal ibusy : std_logic; -- internal busy signal
|
signal ibusy : std_logic; -- internal busy signal
|
begin
|
begin
|