Make init_ch7301c generic and prepare for embedding into main
This commit is contained in:
parent
a86cd90384
commit
da4e8230c5
@ -25,7 +25,5 @@ NET "led(6)" LOC = AD24;
|
|||||||
NET "led(7)" LOC = AE24;
|
NET "led(7)" LOC = AE24;
|
||||||
|
|
||||||
NET "led_n" LOC = AF13;
|
NET "led_n" LOC = AF13;
|
||||||
NET "led_e" LOC = AG23;
|
|
||||||
NET "led_s" LOC = AG12;
|
NET "led_s" LOC = AG12;
|
||||||
NET "led_w" LOC = AF23;
|
|
||||||
NET "led_c" LOC = E8;
|
NET "led_c" LOC = E8;
|
||||||
|
138
init_ch7301c.vhd
138
init_ch7301c.vhd
@ -4,33 +4,33 @@ library unisim;
|
|||||||
use ieee.std_logic_1164.all;
|
use ieee.std_logic_1164.all;
|
||||||
use ieee.std_logic_unsigned.all;
|
use ieee.std_logic_unsigned.all;
|
||||||
use ieee.numeric_std.all;
|
use ieee.numeric_std.all;
|
||||||
-- Xilinx primitives (???)
|
|
||||||
use unisim.VComponents.all;
|
|
||||||
|
|
||||||
entity init_ch7301c is
|
entity init_ch7301c is
|
||||||
|
generic (
|
||||||
|
input_clk: integer := 27_000_000;
|
||||||
|
address: std_logic_vector(6 downto 0) := "1110110" -- 0x76
|
||||||
|
);
|
||||||
port (
|
port (
|
||||||
clk: in std_logic;
|
clk: in std_logic;
|
||||||
reset: in std_logic;
|
reset: in std_logic;
|
||||||
|
|
||||||
|
finished: buffer std_logic;
|
||||||
|
error: buffer std_logic;
|
||||||
|
|
||||||
i2c_scl: inout std_logic;
|
i2c_scl: inout std_logic;
|
||||||
i2c_sda: inout std_logic;
|
i2c_sda: inout std_logic;
|
||||||
|
|
||||||
|
-- tmp
|
||||||
dvi_reset: out std_logic;
|
dvi_reset: out std_logic;
|
||||||
|
|
||||||
dip: in std_logic_vector(7 downto 0);
|
|
||||||
|
|
||||||
led: out std_logic_vector(7 downto 0);
|
led: out std_logic_vector(7 downto 0);
|
||||||
|
dip: in std_logic_vector(7 downto 0);
|
||||||
led_n: out std_logic;
|
led_n: out std_logic;
|
||||||
led_e: out std_logic;
|
|
||||||
led_s: out std_logic;
|
led_s: out std_logic;
|
||||||
led_w: out std_logic;
|
|
||||||
led_c: out std_logic
|
led_c: out std_logic
|
||||||
);
|
);
|
||||||
end init_ch7301c;
|
end init_ch7301c;
|
||||||
|
|
||||||
architecture Behavioral of init_ch7301c is
|
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_reset: std_logic := '1';
|
||||||
signal i2c_execute: std_logic := '0';
|
signal i2c_execute: std_logic := '0';
|
||||||
signal i2c_busy: std_logic;
|
signal i2c_busy: std_logic;
|
||||||
@ -40,13 +40,10 @@ architecture Behavioral of init_ch7301c is
|
|||||||
signal i2c_data_in: std_logic_vector(7 downto 0);
|
signal i2c_data_in: std_logic_vector(7 downto 0);
|
||||||
signal i2c_data_out: std_logic_vector(7 downto 0);
|
signal i2c_data_out: std_logic_vector(7 downto 0);
|
||||||
signal i2c_error: std_logic;
|
signal i2c_error: std_logic;
|
||||||
|
|
||||||
type states is (start, init, finished, error);
|
|
||||||
signal state: states := start;
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
i2c_master: entity work.i2c_master generic map (
|
i2c_master: entity work.i2c_master generic map (
|
||||||
input_clk => 27_000_000,
|
input_clk => input_clk,
|
||||||
bus_clk => 100_000
|
bus_clk => 100_000
|
||||||
) port map (
|
) port map (
|
||||||
clk => clk,
|
clk => clk,
|
||||||
@ -62,80 +59,71 @@ begin
|
|||||||
sda => i2c_sda
|
sda => i2c_sda
|
||||||
);
|
);
|
||||||
|
|
||||||
led_n <= '1' when state = start else '0';
|
led_n <= error;
|
||||||
led_e <= '1' when state = init else '0';
|
led_s <= finished;
|
||||||
led_s <= '1' when state = finished else '0';
|
|
||||||
led_w <= '1' when state = error else '0';
|
|
||||||
led_c <= reset;
|
led_c <= reset;
|
||||||
|
|
||||||
main: process(clk, reset)
|
main: process(clk, reset)
|
||||||
variable delay_init: integer range 0 to 10_000 := 0;
|
-- ch7301c needs some time (>2µs) to init its i2c port after reset
|
||||||
variable busy_count: integer range 0 to 2 := 0;
|
constant max_delay: integer := input_clk / 200_000; -- 5µs
|
||||||
|
variable delay: integer range 0 to max_delay := 0;
|
||||||
|
variable busy_count: integer range 0 to 3 := 0;
|
||||||
begin
|
begin
|
||||||
if reset = '1' then
|
if reset = '1' then
|
||||||
|
delay := 0;
|
||||||
busy_count := 0;
|
busy_count := 0;
|
||||||
delay_init := 0;
|
finished <= '0';
|
||||||
state <= start;
|
error <= '0';
|
||||||
|
|
||||||
-- reset components
|
-- reset components
|
||||||
dvi_reset <= '0';
|
dvi_reset <= '0';
|
||||||
|
i2c_execute <= '0';
|
||||||
i2c_reset <= '0';
|
i2c_reset <= '0';
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
case state is
|
if delay = 5 then
|
||||||
when start =>
|
-- init components
|
||||||
delay_init := delay_init + 1;
|
dvi_reset <= '1';
|
||||||
|
i2c_reset <= '1';
|
||||||
|
delay := delay + 1;
|
||||||
|
elsif delay = max_delay 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 accepted, ready for new one
|
||||||
|
busy_count := busy_count + 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
if delay_init = 5_000 then
|
if i2c_error = '1' then
|
||||||
-- start components
|
-- abort on error
|
||||||
dvi_reset <= '1';
|
i2c_execute <= '0';
|
||||||
i2c_reset <= '1';
|
error <= '1';
|
||||||
elsif delay_init = 10_000 then
|
busy_count := 3;
|
||||||
delay_init := 0;
|
end if;
|
||||||
-- start i2c init
|
|
||||||
state <= init;
|
|
||||||
busy_count := 0;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
when init =>
|
case busy_count is
|
||||||
i2c_busy_old <= i2c_busy; -- remember old value
|
when 0 =>
|
||||||
if i2c_busy_old = '0' and i2c_busy = '1' then
|
-- no command accepted yet, insert first one
|
||||||
-- count rising edges on i2c_busy:
|
i2c_execute <= '1';
|
||||||
-- command was accepted, ready for new one
|
i2c_write <= '1';
|
||||||
busy_count := busy_count + 1;
|
i2c_address <= address;
|
||||||
end if;
|
i2c_data_in <= dip;
|
||||||
|
when 1 =>
|
||||||
if i2c_error = '1' then
|
-- submit read command
|
||||||
-- abort on error
|
i2c_write <= '0';
|
||||||
|
when 2 =>
|
||||||
|
-- read submitted, wait for results, no more commands
|
||||||
i2c_execute <= '0';
|
i2c_execute <= '0';
|
||||||
state <= error;
|
if i2c_busy = '0' then
|
||||||
end if;
|
led <= i2c_data_out;
|
||||||
|
busy_count := 3;
|
||||||
case busy_count is
|
end if;
|
||||||
when 0 =>
|
when 3 =>
|
||||||
-- no command accepted yet, insert first one
|
-- finished!
|
||||||
i2c_execute <= '1';
|
finished <= '1';
|
||||||
i2c_write <= '1';
|
null;
|
||||||
i2c_address <= i2c_ch7301c;
|
end case;
|
||||||
i2c_data_in <= dip;
|
else
|
||||||
when 1 =>
|
delay := delay + 1;
|
||||||
-- submit read command
|
end if;
|
||||||
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;
|
end if;
|
||||||
end process main;
|
end process main;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user