diff --git a/dvi_test.xise b/dvi_test.xise
index 704573e..50b0201 100644
--- a/dvi_test.xise
+++ b/dvi_test.xise
@@ -33,9 +33,6 @@
-
-
-
@@ -377,8 +374,7 @@
-
-
+
diff --git a/init_ch7301c.ucf b/init_ch7301c.ucf
index 09ff0d3..34d1e65 100644
--- a/init_ch7301c.ucf
+++ b/init_ch7301c.ucf
@@ -1,6 +1,19 @@
+NET "clk" LOC = AG18;
+NET "clk" PERIOD = 27 MHz HIGH 50%;
+NET "reset" LOC = AJ6; # center switch
NET "i2c_scl" LOC = U27;
NET "i2c_sda" LOC = T29;
+NET "dvi_reset" LOC = AK6;
+
+NET "dip(0)" LOC = AC24;
+NET "dip(1)" LOC = AC25;
+NET "dip(2)" LOC = AE26;
+NET "dip(3)" LOC = AE27;
+NET "dip(4)" LOC = AF26;
+NET "dip(5)" LOC = AF25;
+NET "dip(6)" LOC = AG27;
+NET "dip(7)" LOC = U25;
NET "led(0)" LOC = H18;
NET "led(1)" LOC = L18;
@@ -11,5 +24,8 @@ NET "led(5)" LOC = AD25;
NET "led(6)" LOC = AD24;
NET "led(7)" LOC = AE24;
-NET "clk" LOC = AG18;
-NET "clk" PERIOD = 27 MHz HIGH 50%;
+NET "led_n" LOC = AF13;
+NET "led_e" LOC = AG23;
+NET "led_s" LOC = AG12;
+NET "led_w" LOC = AF23;
+NET "led_c" LOC = E8;
diff --git a/init_ch7301c.vhd b/init_ch7301c.vhd
index 0b903dc..6775bb1 100644
--- a/init_ch7301c.vhd
+++ b/init_ch7301c.vhd
@@ -10,15 +10,28 @@ use unisim.VComponents.all;
entity init_ch7301c is
port (
clk: in std_logic;
+ reset: in std_logic;
i2c_scl: inout std_logic;
i2c_sda: inout std_logic;
+ dvi_reset: out std_logic;
- led: out std_logic_vector(7 downto 0)
+ dip: in std_logic_vector(7 downto 0);
+
+ led: out std_logic_vector(7 downto 0);
+
+ led_n: out std_logic;
+ led_e: out std_logic;
+ led_s: out std_logic;
+ led_w: out std_logic;
+ led_c: out std_logic
);
end init_ch7301c;
architecture Behavioral of init_ch7301c is
+ constant i2c_ch7301c: std_logic_vector(6 downto 0) := "1110110"; -- 0x76
+
+ signal i2c_reset: std_logic := '1';
signal i2c_execute: std_logic := '0';
signal i2c_busy: std_logic;
signal i2c_busy_old: std_logic;
@@ -26,6 +39,10 @@ architecture Behavioral of init_ch7301c is
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);
+ signal i2c_error: std_logic;
+
+ type states is (start, init, finished, error);
+ signal state: states := start;
begin
i2c_master: entity work.i2c_master generic map (
@@ -33,47 +50,90 @@ begin
bus_clk => 100_000
) port map (
clk => clk,
- reset_n => '1',
+ reset_n => i2c_reset,
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
+ ack_error => i2c_error,
+ scl => i2c_scl,
+ sda => 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;
+ led_n <= '1' when state = start else '0';
+ led_e <= '1' when state = init else '0';
+ led_s <= '1' when state = finished else '0';
+ led_w <= '1' when state = error else '0';
+ led_c <= reset;
- 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;
+ main: process(clk, reset)
+ variable delay_init: integer range 0 to 10_000 := 0;
+ variable busy_count: integer range 0 to 2 := 0;
+ begin
+ if reset = '1' then
+ busy_count := 0;
+ delay_init := 0;
+ state <= start;
+
+ -- reset components
+ dvi_reset <= '0';
+ i2c_reset <= '0';
+ elsif rising_edge(clk) then
+ case state is
+ when start =>
+ delay_init := delay_init + 1;
+
+ if delay_init = 5_000 then
+ -- start components
+ dvi_reset <= '1';
+ i2c_reset <= '1';
+ elsif delay_init = 10_000 then
+ delay_init := 0;
+ -- start i2c init
+ state <= init;
+ busy_count := 0;
end if;
- when 3 =>
- -- finnished, stay here
+
+ when init =>
+ 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 accepted, ready for new one
+ busy_count := busy_count + 1;
+ end if;
+
+ if i2c_error = '1' then
+ -- abort on error
+ i2c_execute <= '0';
+ state <= error;
+ end if;
+
+ case busy_count is
+ when 0 =>
+ -- no command accepted yet, insert first one
+ i2c_execute <= '1';
+ i2c_write <= '1';
+ i2c_address <= i2c_ch7301c;
+ i2c_data_in <= dip;
+ 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 <= i2c_data_out;
+ busy_count := 0;
+ state <= finished;
+ end if;
+ end case;
+
+ when finished =>
+ null;
+
+ when error =>
null;
end case;
end if;