terminal/init_ch7301c.vhd

83 lines
2.4 KiB
VHDL

library ieee;
library unisim;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
-- Xilinx primitives (???)
use unisim.VComponents.all;
entity init_ch7301c is
port (
clk: in std_logic;
i2c_scl: inout std_logic;
i2c_sda: inout std_logic;
led: out std_logic_vector(7 downto 0)
);
end init_ch7301c;
architecture Behavioral of init_ch7301c is
signal i2c_execute: std_logic := '0';
signal i2c_busy: std_logic;
signal i2c_busy_old: std_logic;
signal i2c_address: std_logic_vector(6 downto 0);
signal i2c_write: std_logic;
signal i2c_data_in: std_logic_vector(7 downto 0);
signal i2c_data_out: std_logic_vector(7 downto 0);
begin
i2c_master: entity work.i2c_master generic map (
input_clk => 27_000_000,
bus_clk => 100_000
) port map (
clk => clk,
reset_n => '1',
ena => i2c_execute,
addr => i2c_address,
rw => not i2c_write,
data_wr => i2c_data_in,
busy => i2c_busy,
data_rd => i2c_data_out,
ack_error => open,
sda => i2c_scl,
scl => i2c_sda
);
main: process(clk)
variable busy_count: integer range 0 to 3 := 0;
begin
if rising_edge(clk) then
i2c_busy_old <= i2c_busy; -- remember old value
if i2c_busy_old = '0' and i2c_busy = '1' then
-- count rising edges on i2c_busy:
-- command was ascepted, read for new one
busy_count := busy_count + 1;
end if;
case busy_count is
when 0 =>
-- no command eccepted yet, insert first one
i2c_execute <= '1';
i2c_write <= '1';
i2c_address <= "0111011"; -- 0x76
i2c_data_in <= "01001001"; -- read power status of the chip (0x49)
when 1 =>
-- submit read command
i2c_write <= '0';
when 2 =>
-- read submitted, wait for results, no more commands
i2c_execute <= '0';
if i2c_busy = '0' then
led <= not i2c_data_out;
end if;
when 3 =>
-- finnished, stay here
null;
end case;
end if;
end process main;
end Behavioral;