library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library i2c;
library utils;
use work.ssd1306_pkg.all;
entity ssd1306_counter is
generic (
CLK_FREQ : integer := 100000000; -- Input clock frequency
I2C_CLK_FREQ : integer := 10000000; -- 12500000;
COUNT_FREQ : integer := 1;
DELAY : integer := 20;
EXPECT_ACK : std_logic := '1';
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;
state_o : out std_logic_vector(3 downto 0);
substate_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 ssd1306_counter;
architecture a1 of ssd1306_counter is
constant ADDRESS : std_logic_vector(6 downto 0) := "0111100";
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 err_noack_data : std_logic;
signal err_noack_address : std_logic;
signal err_arbitration : std_logic;
signal err_general : std_logic;
signal any_err : std_logic;
signal waiting : std_logic;
signal dev_busy : std_logic;
signal sda, scl : std_logic;
signal sda_enable, scl_enable : std_logic;
constant DIGITS : natural := 3;
signal count : std_logic_vector(DIGITS * 4 - 1 downto 0);
begin -- architecture a+
tx_clear_buffer <= '0';
rw <= '0';
master_run <= '1';
rst_n <= not rst_sync;
waiting_o <= waiting;
dev_busy_o <= dev_busy;
err_noack_data_o <= err_noack_data;
err_noack_address_o <= err_noack_address;
err_arbitration_o <= err_arbitration;
err_general_o <= err_general;
any_err <= err_general or err_arbitration or err_noack_address or err_noack_data;
counter_master_logic: entity work.ssd1306_counter_master_logic
generic map (
DIGITS => DIGITS,
I2C_CLK_FREQ => I2C_CLK_FREQ)
port map (
clk_i => i2c_clk,
rst_in => rst_n,
start_i => start_i,
count_i => count,
tx_valid_o => tx_valid,
tx_ready_i => tx_ready,
tx_data_o => tx_data,
dev_busy_i => dev_busy,
waiting_i => waiting,
any_err_i => any_err,
state_o => state_o,
substate_o => substate_o);
counter: entity utils.counter
generic map (
MAX => 10,
DIGITS => DIGITS,
IN_FREQ => CLK_FREQ,
OUT_FREQ => COUNT_FREQ)
port map (
clk_i => clk_i,
rst_in => rst_n,
value_o => count);
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 => EXPECT_ACK,
--
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,
err_noack_address_o => err_noack_address,
err_arbitration_o => err_arbitration,
err_general_o => err_general,
--
stop_i => master_stop,
start_i => master_start,
run_i => master_run,
rw_i => rw,
--
dev_busy_o => dev_busy,
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);
end architecture a1;