⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_master_bit_ctrl.vhd

📁 实现基于Avalon总线架构的I2C控制器!可实现OV7620等数字摄像头的配置功能!
💻 VHD
📖 第 1 页 / 共 2 页
字号:
	        ELSIF (Clk'EVENT AND Clk = '1') THEN
	            sta_condition <= ((NOT sSDA) AND dSDA) AND sSCL;--hold '1' for 1 clock
	            sto_condition <= (sSDA AND (NOT dSDA)) AND sSCL;--Slave release the bus
	        END IF;
	    END PROCESS detect_sta_sto;

	    -- generate i2c-bus busy signal
	    gen_busy: process(Clk, Reset_n)
	    BEGIN
	        IF (Reset_n = '0') THEN
	           ibusy <= '0';
	        ELSIF (Clk'EVENT AND Clk = '1') THEN
	           ibusy <= (sta_condition OR ibusy) AND (NOT sto_condition);
	        END IF;
	    END PROCESS gen_busy;
	    busy <= ibusy;


	    -- generate arbitration lost signal
	    -- aribitration lost when:
	    -- 1) master drives SDA high, but the i2c bus is low
	    -- 2) stop detected while not requested (detect during 'idle' state)
--	    gen_al: PROCESS(Clk, Reset_n)
--	    BEGIN
--	      IF (Reset_n = '0') THEN
--	        cmd_stop  <= '0';
--	        ial       <= '0';
--	      ELSIF (Clk'EVENT AND Clk = '1') THEN
--	        IF (clk_en = '1') THEN
--	            IF (cmd = I2C_CMD_STOP) THEN
--	              cmd_stop <= '1';
--	            ELSE
--	              cmd_stop <= '0';
--	            END IF;
--	        END IF;
--	        IF (c_state = idle) THEN
--	            ial <= (sda_chk AND (NOT sSDA) AND isda_oen);
--	        ELSE
--	            ial <= (sda_chk AND (NOT sSDA) AND isda_oen) OR (sto_condition AND (NOT cmd_stop));
--	        END IF;
--	      END IF;
--	    END PROCESS gen_al;
--	    al <= ial;

	    -- generate dout signal, store dout on rising edge of SCL
	    gen_dout: PROCESS(Clk)
	    BEGIN
	      IF (Clk'EVENT AND Clk = '1') THEN
	        IF (sSCL = '1' AND dSCL = '0') THEN
	          dout <= sSDA;
	        ELSE
			  Null;
	        END IF;
	      END IF;
	    END PROCESS gen_dout;
	END BLOCK bus_status_ctrl;


	-- generate statemachine
	nxt_state_decoder : PROCESS (Clk, Reset_n, c_state, cmd)
	BEGIN
	    IF (Reset_n = '0') THEN
	      c_state  <= idle;
	      cmd_ack  <= '0';---
	      --iscl_oen <= '0';---
	      isda_oen <= '0';---
	      iscl_o <= '1';--- reset '1';
	      isda_o <= '1';---
--	      sda_chk  <= '0';
	    ELSIF (Clk'EVENT AND Clk = '1') THEN
--	      IF (ial = '1') THEN
--	        c_state  <= idle;
--	        cmd_ack  <= '0';
--	        iscl_oen <= '1';
--	        isda_oen <= '1';
--	        sda_chk  <= '0';
--	      ELSE
	        cmd_ack <= '0'; -- default no acknowledge

	        IF (clk_en = '1') THEN
	          CASE (c_state) IS
	             -- idle
	             WHEN idle =>
	                CASE cmd IS
	                  WHEN I2C_CMD_START => c_state <= start_a;
	                  WHEN I2C_CMD_STOP  => c_state <= stop_a;
	                  WHEN I2C_CMD_WRITE => c_state <= wr_a;
	                  WHEN I2C_CMD_READ  => c_state <= rd_a;
	                  WHEN others        => c_state <= idle; -- NOP command
	                END CASE;

	                --iscl_oen <= iscl_oen; -- keep SCL in same state
	                isda_oen <= isda_oen; -- keep SDA in same state
	                iscl_o <= iscl_o;---
	                isda_o <= isda_o;---
--	                sda_chk  <= '0';      -- don't check SDA

	             -- start
	             WHEN start_a =>
	                c_state  <= start_b;
	                --iscl_oen <= '0';
	                isda_oen <= '0';
	                iscl_o <= iscl_o; -- keep SCL in same state (for repeated start)
	                isda_o <= '1';      -- set SDA high
--	                sda_chk  <= '0';      -- don't check SDA

	             WHEN start_b =>
	                c_state  <= start_c;
	                --iscl_oen <= '0'; -- set SCL high
	                isda_oen <= '0'; -- keep SDA high
	                iscl_o <= '1';
	                isda_o <= '1';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN start_c =>
	                c_state  <= start_d;
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '0'; -- set SDA low
	                iscl_o <= '1';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN start_d =>
	                c_state  <= start_e;
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '0'; -- keep SDA low
	                iscl_o <= '1';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN start_e =>
	                c_state  <= idle;
	                cmd_ack  <= '1'; -- command completed
	                --iscl_oen <= '0'; -- set SCL low
	                isda_oen <= '0'; -- keep SDA low
	                iscl_o <= '0';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             -- stop
	             WHEN stop_a =>
	                c_state  <= stop_b;
	                --iscl_oen <= '0'; -- keep SCL low
	                isda_oen <= '0'; -- set SDA low
	                iscl_o <= '0';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN stop_b =>
	                c_state  <= stop_c;
	                --iscl_oen <= '0'; -- set SCL high
	                isda_oen <= '0'; -- keep SDA low
	                iscl_o <= '1';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN stop_c =>
	                c_state  <= stop_d;
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '0'; -- keep SDA low
	                iscl_o <= '1';
	                isda_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN stop_d =>
	                c_state  <= idle;
	                cmd_ack  <= '1'; -- command completed
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '0'; -- set SDA high
	                iscl_o <= '1';
	                isda_o <= '1';
	             --   sda_chk  <= '0'; -- don't check SDA

	             -- read
	             WHEN rd_a =>
	                c_state  <= rd_b;
	                --iscl_oen <= '0'; -- keep SCL low
	                isda_oen <= '1'; -- tri-state SDA
	                iscl_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN rd_b =>
	                c_state  <= rd_c;
	                --iscl_oen <= '0'; -- set SCL high
	                isda_oen <= '1'; -- tri-state SDA
	                iscl_o <= '1';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN rd_c =>
	                c_state  <= rd_d;
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '1'; -- tri-state SDA
	                iscl_o <= '1';
	             --   sda_chk  <= '0'; -- don't check SDA

	             WHEN rd_d =>
	                c_state  <= idle;
	                cmd_ack  <= '1'; -- command completed
	                --iscl_oen <= '0'; -- set SCL low
	                isda_oen <= '1'; -- tri-state SDA
	                iscl_o <= '0';
	             --   sda_chk  <= '0'; -- don't check SDA

	             -- write
	             WHEN wr_a =>
	                c_state  <= wr_b;
	                --iscl_oen <= '0'; -- keep SCL low
	                isda_oen <= '0'; -- set SDA
	                iscl_o <= '0';
	                isda_o <= din;
	             --   sda_chk  <= '0'; -- don't check SDA (SCL low)

	             WHEN wr_b =>
	                c_state  <= wr_c;
	                --iscl_oen <= '0'; -- set SCL high
	                isda_oen <= '0'; -- keep SDA
	                iscl_o <= '1';
	                isda_o <= din;
	             --   sda_chk  <= '1'; -- check SDA

	             WHEN wr_c =>
	                c_state  <= wr_d;
	                --iscl_oen <= '0'; -- keep SCL high
	                isda_oen <= '0'; -- keep SDA
	                iscl_o <= '1';
	                isda_o <= din;
	             --   sda_chk  <= '1'; -- check SDA

	             WHEN wr_d =>
	                c_state  <= idle;
	                cmd_ack  <= '1'; -- command completed
	                --iscl_oen <= '0'; -- set SCL low
	                isda_oen <= '0'; -- keep SDA
	                iscl_o <= '0';
	                isda_o <= din;
	            --    sda_chk  <= '0'; -- don't check SDA (SCL low)

	             WHEN OTHERS => NULL;

	          END CASE;
	        END IF;
--	      END IF;
	    END IF;
	END PROCESS nxt_state_decoder;


	-- assign outputs
	scl_o   <= iscl_o;
--	scl_oen <= iscl_oen;
	sda_o   <= isda_o;
	sda_oen <= isda_oen;
END ARCHITECTURE structural;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -