📄 i2c_main_blk.vhd
字号:
end if;
end process;
I2C_Load_SR_Process:process(MPU_CLK, Reset, load,shift)
begin
if(Reset = '0') then
Trans_Buffer_SR <= "00000000";
Value <= '0';
elsif(rising_edge(MPU_CLK)) then
case load is
when "01" =>
Trans_Buffer_SR(7 downto 0) <= Low_Address_Reg(6 downto 0) & Low_Address_Reg(7);
Value <= Low_Address_Reg(7); --write out msb to lsb
when "10" =>
Trans_Buffer_SR(7 downto 0) <= Trans_Buffer(6 downto 0) & Trans_Buffer(7);
Value <= Trans_Buffer(7);
when "11" =>
if(shift = '0') then
Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(7 downto 0);
Value <= Value;
else
Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(6 downto 0) & Trans_Buffer_SR(7);
Value <= Trans_Buffer_SR(7); --write out msb to lsb
end if;
when others =>
Trans_Buffer_SR(7 downto 0) <= Trans_Buffer_SR(7 downto 0);
Value <= Value;
end case;
end if;
end process;
I2C_drive_sda_Process:process(MPU_CLK, MCS(0),MCS(1),WCS(2),WCS(3),WCS(4),Bit_Cnt_Flag,Reset, value)
begin
if(Reset = '0') then
SDA_EN1 <= '0';
elsif(rising_edge(MPU_CLK)) then
if(RCS(4) = '1') then
SDA_EN1 <= '1';
elsif(det_low = '1') then
if(MCS(0) = '1' or MCS(1) = '1' or
((WCS(2) = '1' or WCS(3) = '1' or WCS(4) = '1') and Bit_Cnt_Flag = '1')) then
SDA_EN1 <= '0';
else
if(Value = '1') then -- Write out MSB to LSB and address first
SDA_EN1 <= '0'; -- write out high
else
SDA_EN1 <= '1'; -- write out low
end if;
end if;
end if; --want the data to stay the same until next low scl or sclh
end if;
end process;
I2C_Write_Process:process(MPU_CLK, Reset,MCS(2),MCS(3),WCS(0), Bit_Count, det_low)
begin
if(Reset = '0') then
load <= "11";
shift <= '0';
elsif(rising_edge(MPU_CLK)) then
if((MCS(2) = '1') and (WCS(0) = '1') and (Bit_Count = "000") and (det_low = '1')) then
load <= "01";
shift <= '0';
elsif((MCS(3) = '1') and (WCS(0) = '1') and (Bit_Count = "000") and (det_low = '1')) then
load <= "10";
shift <= '0';
elsif((MCS(2) = '1' or MCS(3) = '1') and (Bit_Count = "000") and (det_low = '1') ) then
load <= load;
shift <= '0';
elsif((MCS(2) = '1' or MCS(3) = '1') and (WCS(0) = '1') and (det_low = '1') ) then
load <= "11";
shift <= '1';
else --do nothing
load <= load;
shift <= '0';
end if;
end if;
end process;
I2C_Read_Process:process(MPU_CLK, Reset, Bit_Count, det_high, RCS, SDA)
begin
if(Reset = '0') then
Read_SR <= "00000000";
elsif(rising_edge(MPU_CLK)) then
if(MCS(4) = '1' and RCS(0) = '1' and Bit_Count = "001" and det_high = '1') then
if(SDA = '1') then
Read_SR <= "0000000" & '1';
else
Read_SR <= "00000000";
end if;
elsif(MCS(4) = '1' and (RCS(0) = '1' or RCS(2) = '1') and det_high = '1') then
if(SDA = '1') then
Read_SR <= Read_SR(6 downto 0) & '1';
else
Read_SR <= Read_SR(6 downto 0) & '0';
end if;
else
Read_SR <= Read_SR;
end if;
end if;
end process;
I2C_WSM: process(MPU_CLK, Reset,Next_WCS)
begin
if(Reset = '0') then
WCS <= Write_State;
elsif(rising_edge(MPU_CLK)) then
WCS <= Next_WCS;
end if;
end process;
I2C_WSM_Process: process(WCS, det_low, det_high, Lost_Arb, Bit_Cnt_Flag, MCS_Write_Flag, SDA)
begin
case WCS is
when Write_State =>
if(Lost_Arb = '0') then
if(det_low = '1' and MCS_Write_Flag = '1') then
Next_WCS <= Delay_Write_State; -- wait for the SCLH clock to transition one cycle
-- and write out next bit
else
Next_WCS <= Write_State;
end if;
else
Next_WCS <= Error_Write_State;
end if;
when Delay_Write_State =>
if(det_high = '1' and Bit_Cnt_Flag = '1') then -- wait for the clock to go high again
Next_WCS <= Delay_Ack_Write_State; -- if bit_count is up goto ack state
elsif(det_high = '1' and Bit_Cnt_Flag = '0') then
Next_WCS <= Write_State;
else
Next_WCS <= Delay_Write_State;
end if;
when Delay_Ack_Write_State =>
if(det_low = '1') then
Next_WCS <= Ack_Write_State;
else
Next_WCS <= Delay_Ack_Write_State;
end if;
when Ack_Write_State =>
if(det_high = '1') then
if(SDA = '0') then -- acknowlege recieved /A
Next_WCS <= Write_State;
else --failed ack
Next_WCS <= Error_Write_State;
end if;
else
Next_WCS <= Ack_Write_State; -- wait for the SCL or SCLH clock to go high, thus data is stable
end if;
when Error_Write_State =>
Next_WCS <= Error_Write_State;
when others =>
Next_WCS <= Write_State;
end case;
end process;
I2C_RSM: process(MPU_CLK, Reset,Next_RCS)
begin
if(Reset = '0') then
RCS <= Read_State;
elsif(rising_edge(MPU_CLK)) then
RCS <= Next_RCS;
end if;
end process;
I2C_RSM_Process: process(RCS, Lost_Arb, Bit_Cnt_Flag,
det_low, SDA, det_high, MCS_Read_Flag)
begin
case RCS is
when Read_State =>
if(Lost_Arb = '0') then
if(det_high = '1' and MCS_Read_Flag = '1') then
Next_RCS <= Delay_Read_State; -- wait for the SCLH clock to transition one cycle
-- and read in next bit
else
Next_RCS <= Read_State;
end if;
else -- lost arb
Next_RCS <= Error_Read_State;
end if;
when Delay_Read_State =>
if(det_low = '1') then -- wait for the clock to go high again
if(Bit_Cnt_Flag = '1') then
Next_RCS <= Delay_Ack_Read_State; -- done reading byte
else
Next_RCS <= Read_State; -- wait for the SCLH clock to transition one cycle
-- and read in next bit
end if;
else
Next_RCS <= Delay_Read_State;
end if;
when Delay_Ack_Read_State =>
if(det_high = '1') then
Next_RCS <= Delay_Ack_Read_State2;
else
Next_RCS <= Delay_Ack_Read_State;
end if;
when Delay_Ack_Read_State2 =>
if(det_low = '1') then
Next_RCS <= Ack_Read_State;
else
Next_RCS <= Delay_Ack_Read_State2;
end if;
when Ack_Read_State =>
if(det_high = '1') then
if(SDA = '0') then -- acknowlege recieved /A
Next_RCS <= Read_State;
else --failed ack
Next_RCS <= Error_Read_State;
end if;
else
Next_RCS <= Ack_Read_State; -- wait for the SCL or SCLH clock to go high, thus data is stable
end if;
when Error_Read_State =>
Next_RCS <= Error_Read_State;
when others =>
Next_RCS <= Read_State;
end case;
end process;
I2C_MSM_Process: process(MPU_CLK, Reset, MCS,Byte_Cnt_Flag, I2C_RW_Bit,
SCL, Start_Det, go)
begin
if(Reset = '0') then
MCS <= Idle_State;
elsif(rising_edge(MPU_CLK)) then
case MCS is
when Idle_State =>
if(I2C_Bus_Busy = '0' and go = '1') then
if(SCL = '1') then
MCS <= Delay_Start_EN_State;
else
MCS <= Idle_State;
end if;
else
MCS <= Idle_State;
end if;
when Delay_Start_EN_State =>
if(Start_Det = '1') then
MCS <= Write_Slv_Addr_State;
else
MCS <= Delay_Start_EN_State;
end if;
when Write_Slv_Addr_State =>
if(WCS(3) = '1' ) then -- ack state in write sm
if(I2C_RW_Bit = '0') then
MCS <= Main_Write_State;
else
MCS <= Main_Read_State;
end if;
else
MCS <= Write_Slv_Addr_State; -- wait for write sm to finish
end if;
when Main_Write_State =>
if(Byte_Cnt_Flag = '1' and WCS(3) = '1') then -- continue writing until transaction complete
MCS <= Idle_State;
else
MCS <= Main_Write_State;
end if;
when Main_Read_State =>
if(Byte_Cnt_Flag = '1') then -- continue reading until transaction complete
MCS <= Idle_State;
else
MCS <= Main_Read_State;
end if;
when others =>
MCS <= Idle_State;
end case;
end if;
end process;
end I2C_Main_Behave;
--------------------------------- E O F --------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -