Line 72... |
Line 72... |
|
|
-- control reg bits --
|
-- control reg bits --
|
constant ctrl_twi_en_c : natural := 0; -- r/w: TWI enable
|
constant ctrl_twi_en_c : natural := 0; -- r/w: TWI enable
|
constant ctrl_twi_start_c : natural := 1; -- -/w: Generate START condition
|
constant ctrl_twi_start_c : natural := 1; -- -/w: Generate START condition
|
constant ctrl_twi_stop_c : natural := 2; -- -/w: Generate STOP condition
|
constant ctrl_twi_stop_c : natural := 2; -- -/w: Generate STOP condition
|
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: transmission done interrupt
|
constant ctrl_twi_irq_en_c : natural := 3; -- r/w: Enable transmission done interrupt
|
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0
|
constant ctrl_twi_prsc0_c : natural := 4; -- r/w: CLK prsc bit 0
|
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1
|
constant ctrl_twi_prsc1_c : natural := 5; -- r/w: CLK prsc bit 1
|
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2
|
constant ctrl_twi_prsc2_c : natural := 6; -- r/w: CLK prsc bit 2
|
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission
|
constant ctrl_twi_mack_c : natural := 7; -- r/w: generate ACK by controller for transmission
|
|
constant ctrl_twi_cksten_c : natural := 8; -- r/w: enable clock stretching by peripheral
|
--
|
--
|
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received
|
constant ctrl_twi_ack_c : natural := 30; -- r/-: Set if ACK received
|
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy
|
constant ctrl_twi_busy_c : natural := 31; -- r/-: Set if TWI unit is busy
|
|
|
-- access control --
|
-- access control --
|
Line 96... |
Line 97... |
|
|
-- twi clock stretching --
|
-- twi clock stretching --
|
signal twi_clk_halt : std_ulogic;
|
signal twi_clk_halt : std_ulogic;
|
|
|
-- twi transceiver core --
|
-- twi transceiver core --
|
signal ctrl : std_ulogic_vector(7 downto 0); -- unit's control register
|
signal ctrl : std_ulogic_vector(8 downto 0); -- unit's control register
|
signal arbiter : std_ulogic_vector(2 downto 0);
|
signal arbiter : std_ulogic_vector(2 downto 0);
|
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
|
signal twi_bitcnt : std_ulogic_vector(3 downto 0);
|
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
|
signal twi_rtx_sreg : std_ulogic_vector(8 downto 0); -- main rx/tx shift reg
|
|
|
-- tri-state I/O --
|
-- tri-state I/O --
|
Line 139... |
Line 140... |
data_o(ctrl_twi_irq_en_c) <= ctrl(ctrl_twi_irq_en_c);
|
data_o(ctrl_twi_irq_en_c) <= ctrl(ctrl_twi_irq_en_c);
|
data_o(ctrl_twi_prsc0_c) <= ctrl(ctrl_twi_prsc0_c);
|
data_o(ctrl_twi_prsc0_c) <= ctrl(ctrl_twi_prsc0_c);
|
data_o(ctrl_twi_prsc1_c) <= ctrl(ctrl_twi_prsc1_c);
|
data_o(ctrl_twi_prsc1_c) <= ctrl(ctrl_twi_prsc1_c);
|
data_o(ctrl_twi_prsc2_c) <= ctrl(ctrl_twi_prsc2_c);
|
data_o(ctrl_twi_prsc2_c) <= ctrl(ctrl_twi_prsc2_c);
|
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
|
data_o(ctrl_twi_mack_c) <= ctrl(ctrl_twi_mack_c);
|
|
data_o(ctrl_twi_cksten_c) <= ctrl(ctrl_twi_cksten_c);
|
--
|
--
|
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
|
data_o(ctrl_twi_ack_c) <= not twi_rtx_sreg(0);
|
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
|
data_o(ctrl_twi_busy_c) <= arbiter(1) or arbiter(0);
|
else -- twi_rtx_addr_c =>
|
else -- twi_rtx_addr_c =>
|
data_o(7 downto 0) <= twi_rtx_sreg(8 downto 1);
|
data_o(7 downto 0) <= twi_rtx_sreg(8 downto 1);
|
Line 270... |
Line 272... |
end process twi_rtx_unit;
|
end process twi_rtx_unit;
|
|
|
|
|
-- Clock Stretching Detector --------------------------------------------------------------
|
-- Clock Stretching Detector --------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
clock_stretching: process(arbiter, twi_scl_o, twi_scl_i_ff1)
|
clock_stretching: process(ctrl, arbiter, twi_scl_o, twi_scl_i_ff1)
|
begin
|
begin
|
-- clock stretching by the peripheral can happen at "any time"
|
-- clock stretching by the peripheral can happen at "any time"
|
if (arbiter(2) = '1') and -- module enabled
|
if (arbiter(2) = '1') and -- module enabled
|
|
(ctrl(ctrl_twi_cksten_c) = '1') and -- clock stretching enabled
|
(twi_scl_o = '1') and -- controller wants to pull scl high
|
(twi_scl_o = '1') and -- controller wants to pull scl high
|
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
|
(twi_scl_i_ff1 = '0') then -- but scl is pulled low by peripheral
|
twi_clk_halt <= '1';
|
twi_clk_halt <= '1';
|
else
|
else
|
twi_clk_halt <= '0';
|
twi_clk_halt <= '0';
|