I2C controller core之Bit controller(04)

  4) detect start/stop condition

    START- falling edge on SDA while SCL is high;  STOP -  rising edge on SDA while SCL is high  

 1 -- block

 2  signal sta_condition : std_logic;       -- start detected

 3  signal sto_condition : std_logic;       -- stop detected

 4 

 5 detect_sta_sto: process(clk, nRst)

 6 begin

 7    if (nRst = '0') then

 8        sta_condition <= '0';

 9        sto_condition <= '0';

10    elsif (clk'event and clk = '1') then

11        if (rst = '1') then

12            sta_condition <= '0';

13            sto_condition <= '0';

14        else

15            sta_condition <= (not sSDA and dSDA) and sSCL;

16            sto_condition <= (sSDA and not dSDA) and sSCL;

17        end if;

18    end if;

19 end process detect_sta_sto;

  5)  generate i2c-bus busy signal

 1 -- port

 2  busy    : out std_logic;      -- i2c bus busy

 3 

 4 -- architecture

 5  signal ibusy  : std_logic;    -- internal busy signal

 6 

 7 gen_busy: process(clk, nRst)

 8 begin

 9    if (nRst = '0') then

10        ibusy <= '0';

11    elsif (clk'event and clk = '1') then

12        if (rst = '1') then

13            ibusy <= '0';

14        else

15            ibusy <= (sta_condition or ibusy) and not sto_condition;

16        end if;

17    end if;

18 end process gen_busy;

19 

20 busy <= ibusy;

  6) generate arbitration lost signal 

 0 -- port
1  al  : out std_logic;    -- arbitration lost
1 -- architecture
2 constant I2C_CMD_NOP : std_logic_vector(3 downto 0) := "0000"; 3 constant I2C_CMD_START : std_logic_vector(3 downto 0) := "0001"; 4 constant I2C_CMD_STOP : std_logic_vector(3 downto 0) := "0010"; 5 constant I2C_CMD_READ : std_logic_vector(3 downto 0) := "0100"; 6 constant I2C_CMD_WRITE : std_logic_vector(3 downto 0) := "1000"; 7 8 signal ial : std_logic; -- internal arbitration lost signal 9 signal sda_chk : std_logic; -- check SDA status (multi-master arbitration) 10 11 -- block 12 signal cmd_stop : std_logic; -- STOP command 13 14 -- aribitration lost when: 15 -- 1) master drives SDA high, but the i2c bus is low 16 -- 2) stop detected while not requested (detect during 'idle' state) 17 gen_al: process(clk, nRst) 18 begin 19 if (nRst = '0') then 20 cmd_stop <= '0'; 21 ial <= '0'; 22 elsif (clk'event and clk = '1') then 23 if (rst = '1') then 24 cmd_stop <= '0'; 25 ial <= '0'; 26 else 27 if (clk_en = '1') then 28 if (cmd = I2C_CMD_STOP) then 29 cmd_stop <= '1'; 30 else 31 cmd_stop <= '0'; 32 end if; 33 end if; 34 35 if (c_state = idle) then 36 ial <= (sda_chk and not sSDA and isda_oen) or (sto_condition and not cmd_stop); 37 else 38 ial <= (sda_chk and not sSDA and isda_oen); 39 end if; 40 end if; 41 end if; 42 end process gen_al; 43 al <= ial;

   7) generate dout signal

 1 -- store dout on rising edge of SCL

 2 gen_dout: process(clk, nReset)

 3 begin

 4    if (nReset = '0') then

 5        dout <= '0';

 6    elsif (clk'event and clk = '1') then

 7        if (sSCL = '1' and dSCL = '0') then

 8            dout <= sSDA;

 9        end if;

10    end if;

11 end process gen_dout;

12 end block bus_status_ctrl;

 

你可能感兴趣的:(controller)