\r
entity i2c_gstart2 is\r
port(\r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
+ CLOCK : in std_logic;\r
+ RESET : in std_logic;\r
START_IN : in std_logic;\r
DOSTART_IN : in std_logic;\r
I2C_SPEED_IN : in std_logic_vector(8 downto 0);\r
begin\r
\r
-- Countdown for one half of SCL (adjustable clock width)\r
-THE_CYC_CTR_PROC: process( clk_in )\r
+THE_CYC_CTR_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
cctr <= (others => '0');\r
elsif( load_cyc = '1' ) then\r
cctr <= i2c_speed_in;\r
\r
-- The main state machine\r
-- State memory process\r
-STATE_MEM: process( clk_in )\r
+STATE_MEM: process( CLOCK )\r
begin\r
- if ( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if ( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
CURRENT_STATE <= SLEEP;\r
load_cyc <= '0';\r
dec_cyc <= '0';\r
s_scl_x <= '0';\r
case CURRENT_STATE is\r
when SLEEP => \r
- if ( (dostart_in = '1') and (start_in = '1') ) then\r
- NEXT_STATE <= S_CHK0; -- generate a start condition\r
- load_cyc_x <= '1';\r
- elsif( (dostart_in = '1') and (start_in = '0') ) then\r
- NEXT_STATE <= WCTR2; -- generate a stop condition\r
- load_cyc_x <= '1';\r
- else\r
- NEXT_STATE <= SLEEP;\r
--- load_cyc_x <= '1';\r
- end if;\r
+ if ( (dostart_in = '1') and (start_in = '1') ) then\r
+ NEXT_STATE <= S_CHK0; -- generate a start condition\r
+ load_cyc_x <= '1';\r
+ elsif( (dostart_in = '1') and (start_in = '0') ) then\r
+ NEXT_STATE <= WCTR2; -- generate a stop condition\r
+ load_cyc_x <= '1';\r
+ else\r
+ NEXT_STATE <= SLEEP;\r
+-- load_cyc_x <= '1';\r
+ end if;\r
when WCTR2 =>\r
- if( (cycdone = '1') ) then\r
- NEXT_STATE <= P_SCL;\r
- load_cyc_x <= '1';\r
- s_scl_x <= '1';\r
- else\r
- NEXT_STATE <= WCTR2;\r
- dec_cyc_x <= '1';\r
- end if;\r
- when P_SCL => \r
- NEXT_STATE <= WCTR0;\r
+ if( (cycdone = '1') ) then\r
+ NEXT_STATE <= P_SCL;\r
+ load_cyc_x <= '1';\r
+ s_scl_x <= '1';\r
+ else\r
+ NEXT_STATE <= WCTR2;\r
dec_cyc_x <= '1';\r
+ end if;\r
+ when P_SCL => \r
+ NEXT_STATE <= WCTR0;\r
+ dec_cyc_x <= '1';\r
when S_CHK0 =>\r
- if( (sda_in = '1') and (scl_in = '1') ) then\r
- NEXT_STATE <= RS_SDA;\r
- r_sda_x <= '1';\r
- else\r
- NEXT_STATE <= ERROR;\r
- sok_x <= '0';\r
- end if;\r
+ if( (sda_in = '1') and (scl_in = '1') ) then\r
+ NEXT_STATE <= RS_SDA;\r
+ r_sda_x <= '1';\r
+ else\r
+ NEXT_STATE <= ERROR;\r
+ sok_x <= '0';\r
+ end if;\r
when RS_SDA =>\r
+ NEXT_STATE <= WCTR0;\r
+ dec_cyc_x <= '1';\r
+ when WCTR0 =>\r
+ if ( (cycdone = '1') and (start_in = '1') ) then\r
+ NEXT_STATE <= S_CHK1;\r
+ elsif( (cycdone = '1') and (start_in = '0') ) then\r
+ NEXT_STATE <= P_SDA;\r
+ load_cyc_x <= '1';\r
+ s_sda_x <= '1';\r
+ else\r
NEXT_STATE <= WCTR0;\r
dec_cyc_x <= '1';\r
- when WCTR0 =>\r
- if ( (cycdone = '1') and (start_in = '1') ) then\r
- NEXT_STATE <= S_CHK1;\r
- elsif( (cycdone = '1') and (start_in = '0') ) then\r
- NEXT_STATE <= P_SDA;\r
- load_cyc_x <= '1';\r
- s_sda_x <= '1';\r
- else\r
- NEXT_STATE <= WCTR0;\r
- dec_cyc_x <= '1';\r
- end if;\r
+ end if;\r
when S_CHK1 =>\r
- if( (sda_in = '0') and (scl_in = '1') ) then\r
- NEXT_STATE <= DONE;\r
- else\r
- NEXT_STATE <= ERROR;\r
- sok_x <= '0';\r
- end if;\r
+ if( (sda_in = '0') and (scl_in = '1') ) then\r
+ NEXT_STATE <= DONE;\r
+ else\r
+ NEXT_STATE <= ERROR;\r
+ sok_x <= '0';\r
+ end if;\r
when P_SDA =>\r
+ NEXT_STATE <= WCTR1;\r
+ dec_cyc_x <= '1';\r
+ when WCTR1 =>\r
+ if( (cycdone = '1') ) then\r
+ NEXT_STATE <= P_CHK;\r
+ else\r
NEXT_STATE <= WCTR1;\r
dec_cyc_x <= '1';\r
- when WCTR1 =>\r
- if( (cycdone = '1') ) then\r
- NEXT_STATE <= P_CHK;\r
- else\r
- NEXT_STATE <= WCTR1;\r
- dec_cyc_x <= '1';\r
- end if;\r
+ end if;\r
when P_CHK =>\r
- if( (sda_in = '1') and (scl_in = '1') ) then\r
- NEXT_STATE <= DONE;\r
- sdone_x <= '1';\r
- else\r
- NEXT_STATE <= ERROR;\r
- sok_x <= '0';\r
- end if;\r
+ if( (sda_in = '1') and (scl_in = '1') ) then\r
+ NEXT_STATE <= DONE;\r
+ sdone_x <= '1';\r
+ else\r
+ NEXT_STATE <= ERROR;\r
+ sok_x <= '0';\r
+ end if;\r
when ERROR =>\r
- if( dostart_in = '0' ) then\r
- NEXT_STATE <= SLEEP;\r
- else\r
- NEXT_STATE <= ERROR;\r
- sdone_x <= '1';\r
- sok_x <= '0';\r
- end if;\r
+ if( dostart_in = '0' ) then\r
+ NEXT_STATE <= SLEEP;\r
+ else\r
+ NEXT_STATE <= ERROR;\r
+ sdone_x <= '1';\r
+ sok_x <= '0';\r
+ end if;\r
when DONE =>\r
- if( dostart_in = '0' ) then\r
- NEXT_STATE <= SLEEP;\r
- else\r
- NEXT_STATE <= DONE;\r
- sdone_x <= '1';\r
- end if;\r
- when others =>\r
+ if( dostart_in = '0' ) then\r
NEXT_STATE <= SLEEP;\r
+ else\r
+ NEXT_STATE <= DONE;\r
+ sdone_x <= '1';\r
+ end if;\r
+ when others =>\r
+ NEXT_STATE <= SLEEP;\r
end case;\r
end process TRANSFORM;\r
\r
\r
entity i2c_sendb2 is\r
port(\r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
+ CLOCK : in std_logic;\r
+ RESET : in std_logic;\r
DOBYTE_IN : in std_logic;\r
I2C_SPEED_IN : in std_logic_vector(8 downto 0);\r
I2C_BYTE_IN : in std_logic_vector(8 downto 0);\r
SDA_IN : in std_logic;\r
R_SDA_OUT : out std_logic;\r
S_SDA_OUT : out std_logic;\r
--- SCL_IN : in std_logic;\r
+ SCL_IN : in std_logic;\r
R_SCL_OUT : out std_logic;\r
S_SCL_OUT : out std_logic;\r
BDONE_OUT : out std_logic;\r
signal rst_bit : std_logic; -- reset bit counter for byte to send\r
signal load_cyc_x : std_logic;\r
signal load_cyc : std_logic; -- load cycle counter (SCL length)\r
-signal dec_cyc_x : std_logic;\r
-signal dec_cyc : std_logic; -- decrement cycle counter (SCL length)\r
signal load_sr_x : std_logic;\r
signal load_sr : std_logic; -- load output shift register\r
signal shift_o_x : std_logic;\r
begin\r
\r
-- Bit counter (for byte to send)\r
-THE_BIT_CTR_PROC: process( clk_in )\r
+THE_BIT_CTR_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
bctr <= (others => '0');\r
elsif( rst_bit = '1' ) then\r
bctr <= (others => '0');\r
bytedone <= '1' when (bctr = x"9") else '0';\r
\r
-- Countdown for one half of SCL (adjustable clock width)\r
-THE_CYC_CTR_PROC: process( clk_in )\r
+THE_CYC_CTR_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
cctr <= (others => '0');\r
elsif( load_cyc = '1' ) then\r
cctr <= i2c_speed_in;\r
- elsif( dec_cyc = '1' ) then\r
+ elsif( cycdone = '0' ) then\r
cctr <= cctr - 1;\r
end if;\r
end if;\r
cycdone <= '1' when (cctr = x"00") else '0';\r
\r
-- Bit output\r
-THE_BIT_OUT_PROC: process( clk_in )\r
+THE_BIT_OUT_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
out_sr <= (others => '0');\r
i2c_d <= '1';\r
elsif( load_sr = '1' ) then\r
end process THE_BIT_OUT_PROC;\r
\r
-- Bit input\r
-THE_BIT_IN_PROC: process( clk_in )\r
+THE_BIT_IN_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if ( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if ( RESET = '1' ) then\r
in_sr <= (others => '1');\r
elsif( shift_o = '1' ) then\r
in_sr(8 downto 1) <= in_sr(7 downto 0);\r
end process THE_BIT_IN_PROC;\r
\r
-- Output register for readback data (could be reduced to SR_IN_INT)\r
-THE_I2C_BACK_PROC: process( clk_in )\r
+THE_I2C_BACK_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
i2c_back <= (others => '1');\r
elsif( shift_i = '1' ) then\r
i2c_back(8 downto 1) <= in_sr(7 downto 0);\r
\r
-- The main state machine\r
-- State memory process\r
-STATE_MEM: process( clk_in )\r
+STATE_MEM: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1') then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1') then\r
CURRENT_STATE <= SLEEP;\r
inc_bit <= '0';\r
rst_bit <= '0';\r
load_cyc <= '0';\r
- dec_cyc <= '0';\r
load_sr <= '0';\r
shift_o <= '0';\r
shift_i <= '0';\r
inc_bit <= inc_bit_x;\r
rst_bit <= rst_bit_x;\r
load_cyc <= load_cyc_x;\r
- dec_cyc <= dec_cyc_x;\r
load_sr <= load_sr_x;\r
shift_o <= shift_o_x;\r
shift_i <= shift_i_x;\r
inc_bit_x <= '0';\r
rst_bit_x <= '0';\r
load_cyc_x <= '0';\r
- dec_cyc_x <= '0';\r
load_sr_x <= '0';\r
shift_o_x <= '0';\r
shift_i_x <= '0';\r
r_scl_x <= '0';\r
s_scl_x <= '0';\r
case CURRENT_STATE is\r
- when SLEEP => if( dobyte_in = '1' ) then\r
- NEXT_STATE <= LCL;\r
- inc_bit_x <= '1';\r
- load_cyc_x <= '1';\r
- shift_o_x <= '1';\r
- r_scl_x <= '1';\r
- else\r
- NEXT_STATE <= SLEEP;\r
- load_sr_x <= '1';\r
- end if;\r
- when LCL => NEXT_STATE <= WCL;\r
- dec_cyc_x <= '1';\r
- when WCL => if( cycdone = '1' ) then\r
- NEXT_STATE <= LCH;\r
- load_cyc_x <= '1';\r
- s_scl_x <= '1';\r
- else\r
- NEXT_STATE <= WCL;\r
- dec_cyc_x <= '1';\r
- end if;\r
- when LCH => NEXT_STATE <= WCH;\r
- dec_cyc_x <= '1';\r
- when WCH => if ( (cycdone = '1') and (bytedone = '0') ) then\r
- NEXT_STATE <= LCL;\r
- inc_bit_x <= '1';\r
- load_cyc_x <= '1';\r
- shift_o_x <= '1';\r
- r_scl_x <= '1';\r
- elsif( (cycdone = '1') and (bytedone = '1') ) then\r
- NEXT_STATE <= FREE;\r
- shift_o_x <= '1';\r
- shift_i_x <= '1';\r
- r_scl_x <= '1';\r
- else\r
- NEXT_STATE <= WCH;\r
- dec_cyc_x <= '1';\r
- end if;\r
- when FREE => NEXT_STATE <= DONE;\r
- rst_bit_x <= '1';\r
- bdone_x <= '1';\r
- when DONE => if( dobyte_in = '0' ) then\r
- NEXT_STATE <= SLEEP;\r
- else\r
- NEXT_STATE <= DONE;\r
- rst_bit_x <= '1';\r
- bdone_x <= '1';\r
- end if;\r
- -- Just in case...\r
- when others => NEXT_STATE <= SLEEP;\r
+ when SLEEP => \r
+ if( dobyte_in = '1' ) then\r
+ NEXT_STATE <= LCL;\r
+ inc_bit_x <= '1';\r
+ load_cyc_x <= '1';\r
+ shift_o_x <= '1';\r
+ r_scl_x <= '1';\r
+ else\r
+ NEXT_STATE <= SLEEP;\r
+ load_sr_x <= '1';\r
+ end if;\r
+ when LCL => \r
+ NEXT_STATE <= WCL;\r
+ when WCL => \r
+ if( cycdone = '1' ) then\r
+ NEXT_STATE <= LCH;\r
+ load_cyc_x <= '1';\r
+ s_scl_x <= '1';\r
+ else\r
+ NEXT_STATE <= WCL;\r
+ end if;\r
+ when LCH => \r
+ NEXT_STATE <= WCH;\r
+ when WCH => \r
+ if ( (cycdone = '1') and (bytedone = '0') ) then\r
+ NEXT_STATE <= LCL;\r
+ inc_bit_x <= '1';\r
+ load_cyc_x <= '1';\r
+ shift_o_x <= '1';\r
+ r_scl_x <= '1';\r
+ elsif( (cycdone = '1') and (bytedone = '1') ) then\r
+ NEXT_STATE <= FREE;\r
+ shift_o_x <= '1';\r
+ shift_i_x <= '1';\r
+ r_scl_x <= '1';\r
+ else\r
+ NEXT_STATE <= WCH;\r
+ end if;\r
+ when FREE => \r
+ NEXT_STATE <= DONE;\r
+ rst_bit_x <= '1';\r
+ bdone_x <= '1';\r
+ when DONE => \r
+ if( dobyte_in = '0' ) then\r
+ NEXT_STATE <= SLEEP;\r
+ else\r
+ NEXT_STATE <= DONE;\r
+ rst_bit_x <= '1';\r
+ bdone_x <= '1';\r
+ end if;\r
+ -- Just in case...\r
+ when others => \r
+ NEXT_STATE <= SLEEP;\r
end case;\r
end process TRANSFORM;\r
\r
end process DECODE;\r
\r
-- SCL and SDA output pulses\r
-THE_SDA_OUT_PROC: process( clk_in )\r
+THE_SDA_OUT_PROC: process( CLOCK )\r
begin\r
- if( rising_edge(clk_in) ) then\r
- if( reset_in = '1' ) then\r
+ if( rising_edge(CLOCK) ) then\r
+ if( RESET = '1' ) then\r
load <= '0'; -- was a bug, found 081008\r
r_sda <= '0';\r
s_sda <= '0';\r
\r
signal i2c_speed : std_logic_vector(8 downto 0);\r
\r
-signal error_bits : std_logic_vector(7 downto 0);\r
+signal errors_x : std_logic_vector(7 downto 0) := x"00";\r
+signal save_x : std_logic;\r
+signal error_bits : std_logic_vector(7 downto 0) := x"00";\r
\r
-- Components\r
component i2c_gstart2 is\r
port( \r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
+ CLOCK : in std_logic;\r
+ RESET : in std_logic;\r
START_IN : in std_logic;\r
DOSTART_IN : in std_logic;\r
I2C_SPEED_IN : in std_logic_vector(8 downto 0);\r
\r
component i2c_sendb2 is\r
port( \r
- CLK_IN : in std_logic;\r
- RESET_IN : in std_logic;\r
+ CLOCK : in std_logic;\r
+ RESET : in std_logic;\r
DOBYTE_IN : in std_logic;\r
I2C_SPEED_IN : in std_logic_vector(8 downto 0);\r
I2C_BYTE_IN : in std_logic_vector(8 downto 0);\r
SDA_IN : in std_logic;\r
R_SDA_OUT : out std_logic;\r
S_SDA_OUT : out std_logic;\r
--- SCL_IN : in std_logic;\r
+ SCL_IN : in std_logic;\r
R_SCL_OUT : out std_logic;\r
S_SCL_OUT : out std_logic;\r
BDONE_OUT : out std_logic;\r
load_dh_x <= '0';\r
load_dl_x <= '0';\r
valid_x <= '0';\r
+ errors_x <= x"00";\r
+ save_x <= '0';\r
case CURRENT_STATE is\r
when SLEEP => \r
if( i2c_go_in = '1' ) then\r
NEXT_STATE <= LOADA;\r
- error_bits <= x"00";\r
+ save_x <= '1';\r
else\r
NEXT_STATE <= SLEEP;\r
running_x <= '0';\r
dobyte_x <= '1';\r
elsif( (sdone = '1') and (sok = '0') and (phase = '0') ) then\r
NEXT_STATE <= FAILED; -- first START condition failed\r
- error_bits <= x"80";\r
+ errors_x <= x"80";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
elsif( (sdone = '1') and (sok = '0') and (phase = '1') ) then\r
NEXT_STATE <= FAILED; -- second START condition failed\r
- error_bits <= x"40";\r
+ errors_x <= x"40";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
else\r
NEXT_STATE <= GSTART; -- wait for START generation ending\r
NEXT_STATE <= LOADD; -- I2C read, send 0xff dummy byte\r
elsif( (bdone = '1') and (bok = '0') and (phase = '0') ) then\r
NEXT_STATE <= FAILED; -- first address phase failed\r
- error_bits <= x"20";\r
+ errors_x <= x"20";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
elsif( (bdone = '1') and (bok = '0') and (phase = '1') ) then\r
NEXT_STATE <= FAILED; -- second address phase failed\r
- error_bits <= x"10";\r
+ errors_x <= x"10";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
else\r
NEXT_STATE <= SENDA; -- wait for send address ending\r
dostart_x <= '1';\r
elsif( (bdone = '1') and (bok = '0') ) then\r
NEXT_STATE <= FAILED; -- command phase failed\r
- error_bits <= x"08";\r
+ errors_x <= x"08";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
else\r
NEXT_STATE <= SENDC; -- wait for send command ending\r
load_dh_x <= '1';\r
elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
NEXT_STATE <= FAILED; -- I2C write, first data phase failed\r
- error_bits <= x"04";\r
+ errors_x <= x"04";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
else\r
NEXT_STATE <= SENDD; -- wait for send data ending\r
load_dl_x <= '1';\r
elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
NEXT_STATE <= FAILED; -- I2C write, data phase failed\r
- error_bits <= x"02";\r
+ errors_x <= x"02";\r
+ save_x <= '1';\r
dostart_x <= '1';\r
else\r
NEXT_STATE <= SENDD2;\r
end case;\r
end process TRANSFORM;\r
\r
+-- Error bits\r
+THE_ERROR_PROC: process( CLOCK )\r
+begin\r
+ if( rising_edge(CLOCK) ) then\r
+ if( save_x = '1' ) then\r
+ error_bits <= errors_x;\r
+ end if;\r
+ end if;\r
+end process THE_ERROR_PROC;\r
+\r
-- Output decoding\r
DECODE: process(CURRENT_STATE)\r
begin\r
-- The SendByte module\r
THE_I2C_SENDB: i2c_sendb2\r
port map(\r
- CLK_IN => CLOCK,\r
- RESET_IN => RESET,\r
+ CLOCK => CLOCK,\r
+ RESET => RESET,\r
DOBYTE_IN => dobyte,\r
I2C_SPEED_IN => i2c_speed,\r
I2C_BYTE_IN => i2c_byte,\r
I2C_BACK_OUT => i2c_dr,\r
- SDA_IN => sda_q(2), -- changed\r
+ SDA_IN => sda_q(2),\r
R_SDA_OUT => r_sda_sb,\r
S_SDA_OUT => s_sda_sb,\r
--- SCL_IN => scl_q(2), -- changes\r
+ SCL_IN => scl_q(2),\r
R_SCL_OUT => r_scl_sb,\r
S_SCL_OUT => s_scl_sb,\r
BDONE_OUT => bdone,\r
-- The GenStart module\r
THE_I2C_GSTART: i2c_gstart2\r
port map(\r
- CLK_IN => CLOCK,\r
- RESET_IN => RESET,\r
+ CLOCK => CLOCK,\r
+ RESET => RESET,\r
START_IN => start,\r
DOSTART_IN => dostart,\r
I2C_SPEED_IN => i2c_speed,\r
SDONE_OUT => sdone,\r
SOK_OUT => sok,\r
- SDA_IN => sda_q(2), -- changed\r
- SCL_IN => scl_q(2), -- changed\r
+ SDA_IN => sda_q(2),\r
+ SCL_IN => scl_q(2),\r
R_SCL_OUT => r_scl_gs,\r
S_SCL_OUT => s_scl_gs,\r
R_SDA_OUT => r_sda_gs,\r