Fixup i2c init module
This commit is contained in:
parent
168102e13b
commit
a86cd90384
@ -33,9 +33,6 @@
|
||||
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="65"/>
|
||||
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
|
||||
</file>
|
||||
<file xil_pn:name="main.ucf" xil_pn:type="FILE_UCF">
|
||||
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
|
||||
</file>
|
||||
<file xil_pn:name="ipcore_dir/clock_source.xaw" xil_pn:type="FILE_XAW">
|
||||
<association xil_pn:name="BehavioralSimulation" xil_pn:seqID="106"/>
|
||||
<association xil_pn:name="Implementation" xil_pn:seqID="0"/>
|
||||
@ -377,8 +374,7 @@
|
||||
</properties>
|
||||
|
||||
<bindings>
|
||||
<binding xil_pn:location="/main" xil_pn:name="main.ucf"/>
|
||||
<binding xil_pn:location="/main" xil_pn:name="init_ch7301c.ucf"/>
|
||||
<binding xil_pn:location="/init_ch7301c" xil_pn:name="init_ch7301c.ucf"/>
|
||||
</bindings>
|
||||
|
||||
<libraries/>
|
||||
|
@ -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;
|
||||
|
124
init_ch7301c.vhd
124
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;
|
||||
|
Loading…
Reference in New Issue
Block a user