Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion sources_1/imports/RTL/edid_rom.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ entity edid_rom is
port ( clk : in std_logic;
sclk_raw : in std_logic;
sdat_raw : inout std_logic := 'Z';
edid_debug : out std_logic_vector(2 downto 0) := (others => '0')
edid_debug : out std_logic_vector(2 downto 0) := (others => '0');
edid_read_detected : out std_logic := '0'
);
end entity;

Expand Down Expand Up @@ -190,6 +191,7 @@ architecture Behavioral of edid_rom is
signal PULL_LOW : std_logic := '0';
signal sdat_input : std_logic := '0';
signal sdat_delay_last : std_logic := '0';
signal edid_read_flag : std_logic := '0';
begin

i_IOBUF: IOBUF
Expand All @@ -205,10 +207,15 @@ i_IOBUF: IOBUF
);
edid_debug(0) <= std_logic(sdat_delay(sdat_delay'high));
edid_debug(1) <= sclk_raw;
edid_read_detected <= edid_read_flag;

process(clk)
begin
if rising_edge(clk) then
-- Clear the flag after one clock cycle
if edid_read_flag = '1' then
edid_read_flag <= '0';
end if;

-- falling edge on SDAT while sclk is held high = START condition
if sclk_delay(1) = '1' and sclk_delay(0) = '1' and sdat_delay_last = '1' and sdat_delay(sdat_delay'high) = '0' then
Expand Down Expand Up @@ -284,6 +291,7 @@ process(clk)

when state_ack_device_read => state <= state_read7;
data_out_sr <= edid_rom(to_integer(addr_reg));
edid_read_flag <= '1';
when state_read7 => state <= state_read6;
when state_read6 => state <= state_read5;
when state_read5 => state <= state_read4;
Expand Down
52 changes: 48 additions & 4 deletions sources_1/imports/RTL/hdmi_io.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ architecture Behavioral of hdmi_io is
port ( clk : in std_logic;
sclk_raw : in std_logic;
sdat_raw : inout std_logic;
edid_debug : out std_logic_vector(2 downto 0));
edid_debug : out std_logic_vector(2 downto 0);
edid_read_detected : out std_logic);
end component;

component hdmi_input is
Expand Down Expand Up @@ -320,11 +321,26 @@ architecture Behavioral of hdmi_io is
signal tmds_out_ch2 : std_logic;
signal counter : std_logic_vector(31 downto 0):=(others => '0');
signal detect_sr : std_logic_vector(7 downto 0) := (others => '0');

-- Automatic mode switching signals
signal edid_read_pulse : std_logic;
signal pixel_clk_watchdog : unsigned(27 downto 0) := (others => '0'); -- ~2.7 seconds at 100MHz
signal pixel_clk_timeout : std_logic := '1';
signal auto_online_mode : std_logic := '0';
signal pixel_clk_edge_detect : std_logic_vector(1 downto 0) := "00";
signal final_online_mode : std_logic;
begin
-- pixel_clk <= pixel_clk_i;
pixel_clk<=oclk;
hdmi_rx_hpa <= '1';
hdmi_rx_cec <= 'Z';

-- Allow manual override: if online='1' (DIP switch ON), use manual mode
-- Otherwise use automatic detection
final_online_mode <= online or auto_online_mode;

-- Export automatic mode status on sel pin (since it's no longer used for original purpose)
sel <= auto_online_mode;

debug(7) <= raw_hsync;
debug(6) <= raw_vsync;
Expand All @@ -341,14 +357,15 @@ i_clk_sel: clk_selector port map(
hdmi_clk5=> pixel_io_clk_x5,
clk73=>clk73, clk367=>clk367,
oclk=>oclk, oclk1=>oclk1, oclk5=>oclk5,
online => online
online => final_online_mode -- Use automatic mode with manual override
);

i_edid_rom: edid_rom port map (
clk => clk100,
sclk_raw => hdmi_rx_scl,
sdat_raw => hdmi_rx_sda,
edid_debug => open);
edid_debug => open,
edid_read_detected => edid_read_pulse);

---------------------
-- Input buffers
Expand Down Expand Up @@ -562,6 +579,33 @@ process(pixel_clk_i)
end if;
end process;


-- Automatic mode switching based on EDID reads and pixel clock presence
process(clk100)
begin
if rising_edge(clk100) then
-- Edge detection for pixel clock
pixel_clk_edge_detect <= pixel_clk_edge_detect(0) & pixel_clk_i;

-- Pixel clock watchdog timer
if pixel_clk_edge_detect = "01" or pixel_clk_edge_detect = "10" then
-- Reset watchdog on any pixel clock edge
pixel_clk_watchdog <= (others => '0');
pixel_clk_timeout <= '0';
elsif pixel_clk_watchdog < x"BEBC200" then -- ~200M cycles = 2 seconds at 100MHz
pixel_clk_watchdog <= pixel_clk_watchdog + 1;
else
pixel_clk_timeout <= '1';
end if;

-- Mode switching logic
if edid_read_pulse = '1' then
-- EDID read detected - switch to online mode
auto_online_mode <= '1';
elsif pixel_clk_timeout = '1' then
-- No pixel clock for 2 seconds - switch to offline mode
auto_online_mode <= '0';
end if;
end if;
end process;

end Behavioral;