library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library i2c; library utils; entity full_on is generic ( CLK_FREQ : integer := 100000000; -- Input clock frequency I2C_CLK_FREQ : integer := 5000000; DELAY : integer := 20; SCL_MIN_STABLE_CYCLES : natural := 50); port ( clk_i : in std_logic; rst_i : in std_logic; start_i : in std_logic; err_noack_data_o : out std_logic; err_noack_address_o : out std_logic; err_arbitration_o : out std_logic; err_general_o : out std_logic; full_on_state_o : out std_logic_vector(2 downto 0); bus_busy_o : out std_logic; dev_busy_o : out std_logic; waiting_o : out std_logic; sda_io : inout std_logic; scl_io : inout std_logic); end entity full_on; architecture a1 of full_on is constant ADDRESS : std_logic_vector(6 downto 0) := "0111100"; type data_arr_t is array (natural range <>) of std_logic_vector(7 downto 0); constant INIT_DATA : data_arr_t := ( X"80", X"A8", X"80", X"3F", X"80", X"D3", X"80", X"00", X"80", X"40", X"80", X"A0", X"80", X"C0", X"80", X"DA", X"80", X"02", X"80", X"81", X"80", X"7F", X"80", X"A4", X"80", X"A6", X"80", X"D5", X"80", X"80", X"80", X"8D", X"80", X"14", X"80", X"AF", -- init done X"80", X"A5" --entire display on ); signal rst_n : std_logic; signal rst_sync : std_logic; signal i2c_clk : std_logic; signal master_start, master_stop, master_run : std_logic; signal rw : std_logic; signal tx_valid, tx_ready, tx_clear_buffer : std_logic; signal tx_data : std_logic_vector(7 downto 0); signal rx_valid, rx_confirm : std_logic; signal rx_data : std_logic_vector(7 downto 0); signal waiting : std_logic; signal sda, scl : std_logic; signal sda_enable, scl_enable : std_logic; signal curr_index : natural; signal next_index : natural; signal go_next : std_logic; type state_t is (IDLE, START, COUNT, STOP, DONE); signal curr_state : state_t; signal next_state : state_t; begin -- architecture a1 tx_clear_buffer <= '0'; master_run <= '1'; rst_n <= not rst_sync; waiting_o <= waiting; -- i2c_clk <= clk_i; rw <= '0'; full_on_state_o <= std_logic_vector(to_unsigned(state_t'pos(curr_state), 3)); next_index <= 0 when curr_state = IDLE else (curr_index + 1) when go_next = '1' else curr_index; go_next <= '1' when tx_ready = '1' and curr_index < INIT_DATA'length and curr_state = COUNT else '0'; tx_valid <= '1' when go_next = '1' else '0'; tx_data <= INIT_DATA(curr_index) when curr_index < INIT_DATA'length else "00000000"; next_state <= START when start_i = '1' and curr_state = IDLE else COUNT when curr_state = START else STOP when curr_state = COUNT and curr_index = INIT_DATA'length and waiting = '1' else DONE when curr_state = STOP else IDLE when curr_state = DONE and start_i = '0' else curr_state; master_start <= '1' when curr_state = START else '0'; master_stop <= '1' when curr_state = STOP else '0'; divider: entity utils.clock_divider generic map ( IN_FREQ => CLK_FREQ, OUT_FREQ => I2C_CLK_FREQ) port map ( clk_i => clk_i, clk_o => i2c_clk); i2c_master: entity i2c.master generic map ( SCL_FALLING_DELAY => DELAY, SCL_MIN_STABLE_CYCLES => SCL_MIN_STABLE_CYCLES) port map ( clk_i => i2c_clk, rst_in => rst_n, -- slave_address_i => ADDRESS, -- generate_ack_i => '1', expect_ack_i => '1', -- rx_valid_o => rx_valid, rx_data_o => rx_data, rx_confirm_i => rx_confirm, -- tx_ready_o => tx_ready, tx_valid_i => tx_valid, tx_data_i => tx_data, tx_clear_buffer_i => tx_clear_buffer, -- err_noack_data_o => err_noack_data_o, err_noack_address_o => err_noack_address_o, err_arbitration_o => err_arbitration_o, err_general_o => err_general_o, -- stop_i => master_stop, start_i => master_start, run_i => master_run, rw_i => rw, -- dev_busy_o => dev_busy_o, bus_busy_o => bus_busy_o, waiting_o => waiting, -- sda_i => sda, scl_i => scl, sda_enable_o => sda_enable, scl_enable_o => scl_enable); sync_reset: entity utils.metastability_filter port map ( clk_i => clk_i, signal_i => rst_i, signal_o => rst_sync); sda_open_buffer: entity utils.open_drain_buffer port map ( pad_io => sda_io, enable_i => sda_enable, state_o => sda); scl_open_buffer: entity utils.open_drain_buffer port map ( pad_io => scl_io, enable_i => scl_enable, state_o => scl); set_regs: process (i2c_clk) is begin -- process set_regs if rising_edge(i2c_clk) then -- rising clock edge if rst_n = '0' then -- synchronous reset (active low) curr_state <= IDLE; curr_index <= 0; else curr_state <= next_state; curr_index <= next_index; end if; end if; end process set_regs; end architecture a1;