📄 i2c.txt
字号:
stm_mstr <= mstr_rd_wait_half;
end if;
--------------------
when mstr_rd_wait_half =>
i_scl_mstr <= '1';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_rd_wait_half;
else
i_scl_cntr <= 0;
i_mstr_rd_data <= i_mstr_rd_data( 6 downto 0 ) & sda;
stm_mstr <= mstr_rd_read;
end if;
---------------------
when mstr_rd_read =>
i_scl_mstr <= '1';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_rd_read;
else
i_scl_cntr <= 0;
if ( i_bit_cntr_mstr > 0 ) then
i_bit_cntr_mstr <= i_bit_cntr_mstr - 1;
i_scl_mstr <= '0';
stm_mstr <= mstr_rd_wait_low;
else
i_mstr_ad <= ( others => '0' );
mstr_dout <= i_mstr_rd_data;
stm_mstr <= mstr_rd_wait_ack;
end if;
end if;
---------------------
--#######################
--### SEND ACKNOWELEDGE #
--#######################
when mstr_rd_wait_ack =>
i_scl_mstr <= '0';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_rd_wait_ack;
else
i_scl_cntr <= 0;
i_sda_mstr <= not send_ack;
stm_mstr <= mstr_rd_get_ack;
end if;
----------------------
when mstr_rd_get_ack =>
i_scl_mstr <= '0';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_rd_get_ack;
else
i_scl_cntr <= 0;
--i_ack_mstr <= sda;
stm_mstr <= mstr_rd_wait_last_half;
end if;
----------------------
when mstr_rd_wait_last_half =>
i_scl_mstr <= '1';
if ( i_scl_cntr < FULL_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_rd_wait_last_half;
else
i_scl_cntr <= 0;
stm_mstr <= mstr_active;
end if;
----------------------
--######################
--######## STOP ########
--######################
when mstr_stop =>
i_scl_mstr <= '1';
i_sda_mstr <= '0';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_stop;
else
i_scl_cntr <= 0;
i_sda_mstr <= '1';
stm_mstr <= mstr_gap;
end if;
---------------------
when mstr_gap =>
if ( i_scl_cntr < GAP_WIDTH ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_gap;
else
i_scl_cntr <= 0;
stm_mstr <= mstr_idle;
end if;
--#####################
--###### RESTART ######
--#####################
when mstr_restart =>
i_scl_mstr <= '1';
i_sda_mstr <= '0';
if ( i_scl_cntr < HALF_BIT ) then
i_scl_cntr <= i_scl_cntr + 1;
stm_mstr <= mstr_restart;
else
i_scl_cntr <= 0;
i_sda_mstr <= '1';
stm_mstr <= mstr_start_cnt;
end if;
when others => stm_mstr <= mstr_idle;
end case;
end if;
end if;
end process i2c_master;
--##############################################
--##############################################
--##############################################
--##############################################
--##############################################
--##############################################
slv_dout <= i_slv_dout;
i2c_slave:
process( sys_clk , sys_rst )
begin
if ( sys_rst = '1' ) then
stm_slv <= slv_idle;
slv_busy <= '0';
i_slv_bit_cnt <= 0;
i_slv_addr <= ( others => '0' );
i_sda_slv <= 'Z';
i_slv_reg_addr <= ( others => '0' );
i_slv_data <= ( others => '0' );
slv_read <= '0';
slv_write <= '0';
i_slv_dout <= ( others => '0' );
elsif rising_edge( sys_clk ) then
case stm_slv is
----------------------
when slv_idle =>
slv_busy <= '0';
i_sda_slv <= 'Z';
i_slv_bit_cnt <= 0;
if ( i_mstr_slv = '0' ) and ( i_slv_strt_bit = '1' ) then
stm_slv <= slv_get_addr;
slv_busy <= '1';
else
stm_slv <= slv_idle;
end if;
----------------------
when slv_get_addr =>
i_sda_slv <= 'Z';
if ( i_slv_stop_bit = '0' ) then
if ( i_slv_scl_rise = '1' ) then
if ( i_slv_bit_cnt < 8 ) then
i_slv_addr <= i_slv_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= i_slv_bit_cnt + 1;
stm_slv <= slv_get_addr;
elsif( i_slv_bit_cnt = 8 ) then
i_slv_addr <= i_slv_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= 0;
stm_slv <= slv_send_addr_ack;
end if;
elsif ( i_slv_scl_fall = '1' ) and ( i_slv_bit_cnt = 8 ) then
stm_slv <= slv_send_addr_ack;
i_slv_bit_cnt <= 0;
else
stm_slv <= slv_get_addr;
end if;
else
stm_slv <= slv_idle;
end if;
-----------------------
when slv_send_addr_ack =>
if ( i_slv_addr( 7 downto 1 ) = SLAVE_ADDR ) then
if ( i_slv_scl_rise = '1' ) then
i_sda_slv <= '0';
stm_slv <= slv_wait_ack;
end if;
else
stm_slv <= slv_idle;
end if;
-----------------------
when slv_wait_ack =>
if ( i_slv_scl_fall = '1' ) then
if ( reg_exist = '1' ) then
stm_slv <= slv_read_reg_addr;
elsif ( i_slv_addr( 0 ) = '0' ) then
stm_slv <= slv_write_data;
slv_read <= '1';
elsif ( i_slv_addr( 0 ) = '1' ) then
stm_slv <= slv_read_reg_addr;
end if;
else
stm_slv <= slv_wait_ack;
end if;
-----------------------
when slv_rd_wr =>
i_sda_slv <= 'Z';
i_slv_data <= slv_din;
i_slv_dout <= i_slv_reg_addr;
if ( i_slv_addr( 0 ) = '1' ) then
slv_write <= '1';
stm_slv <= slv_read_data;
else
stm_slv <= slv_write_data;
slv_read <= '1';
end if;
-----------------------
when slv_read_reg_addr =>
slv_write <= '0';
i_sda_slv <= 'Z';
if ( i_slv_stop_bit = '0' ) then
if ( i_slv_scl_rise = '1' ) then
if ( i_slv_bit_cnt < 7 ) then
i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= i_slv_bit_cnt + 1;
stm_slv <= slv_read_reg_addr;
elsif ( i_slv_bit_cnt = 7 ) then
i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= 0;
stm_slv <= slv_send_data_ack;
end if;
else
stm_slv <= slv_read_reg_addr;
end if;
else
stm_slv <= slv_idle;
end if;
-----------------------
when slv_send_data_ack =>
if ( i_slv_scl_rise = '1' ) then
i_sda_slv <= '0';
stm_slv <= slv_wait_data_ack;
end if;
-----------------------
when slv_wait_data_ack =>
if ( i_slv_scl_fall = '1' ) then
stm_slv <= slv_rd_wr;
else
stm_slv <= slv_wait_data_ack;
end if;
-----------------------
when slv_write_data =>
slv_read <= '0';
if ( i_slv_stop_bit = '0' ) then
i_sda_slv <= i_slv_data( 7 );
if ( i_slv_scl_fall = '1' ) then
if ( i_slv_bit_cnt < 7 ) then
-- i_sda_slv <= i_slv_data( 7 );
i_slv_data <= i_slv_data( 6 downto 0 ) & '0';
i_slv_bit_cnt <= i_slv_bit_cnt + 1;
stm_slv <= slv_write_data;
elsif ( i_slv_bit_cnt = 7 ) then
i_sda_slv <= i_slv_data( 7 );
i_slv_bit_cnt <= 0;
stm_slv <= slv_get_wait_data_ack;
end if;
end if;
else
stm_slv <= slv_idle;
end if;
-----------------------
when slv_get_wait_data_ack =>
i_sda_slv <= 'Z';
if ( i_slv_scl_rise = '1' ) then
stm_slv <= slv_get_data_ack;
else
stm_slv <= slv_get_wait_data_ack;
end if;
-----------------------
when slv_get_data_ack =>
i_sda_slv <= 'Z';
if ( i_slv_scl_fall = '1' ) then
if ( sda = '0' ) and ( i_slv_sda_fall = '0' ) then
stm_slv <= slv_rd_wr;
else
stm_slv <= slv_idle;
end if;
else
stm_slv <= slv_get_data_ack;
end if;
------------------------
when slv_read_data =>
slv_write <= '0';
if ( i_slv_stop_bit = '1' ) then
stm_slv <= slv_idle;
else
if ( i_slv_scl_rise = '1' ) then
if ( i_slv_bit_cnt < 7 ) then
i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= i_slv_bit_cnt + 1;
stm_slv <= slv_read_data;
elsif ( i_slv_bit_cnt = 7 ) then
i_slv_reg_addr <= i_slv_reg_addr( 6 downto 0 ) & sda;
i_slv_bit_cnt <= 0;
stm_slv <= slv_send_data_ack;
end if;
else
stm_slv <= slv_read_data;
end if;
end if;
-------------------------
when others => stm_slv <= slv_idle;
end case;
end if;
end process i2c_slave;
END ARCHITECTURE arc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -