--======================================================================================
-- Design Units	    : control_i2c
--
-- Filename             : DV_pass_thru.vhd
--
-- Purpose              : This module implements a simple I2C control interface to  
--			              the SAA7111A video input processor and SAA7121 digital video 
--                        encoder to load the configuration registers. Once loaded,
--                        digital video data captured by the SAA7111 will be passed
--                        through to the SAA7121 for encoding and output.  This module
--                        performs no data manipulation.
--
-- Notes                : 														   					 
--
-- Limitations          :
--
-- Errors               :
--
-- Library              :
--
-- Dependencies         : IEEE.Std_Logic_1164, IEEE.STD_LOGIC_UNSIGNED, IEEE.STD_LOGIC_ARITH
--
-- Sub Modules          : 

-- Author               : Jim Burnett 
--                        Avnet Design Services
--                        Adapted from I2C code written by Matt Schultz
--
-- Simulator            :  
--
-- Disclaimer           :Avnet, Inc. makes no warranty for the use of this code or design.  
--			             This code is provided  "As Is". Avnet, Inc assumes no responsibility
--                       for any errors, which may appear in this code, nor does it make a
--                       commitment to update the information contained herein. Avnet, Inc
--                       specifically disclaims any implied warranties of fitness for a 
--                       particular purpose.
--
--              	       Copyright (c) 2002 Avnet, Inc.
--               	       All rights reserved.
--
--
------------------------------------------------------------------------------------------
-- Revision list
-- Version		Author		Date				Changes
--
-- 1.0			JRB         11 Dec 02       Initial Release	
--              vjg                         changed i2c clock to output
------------------------------------------------------------------------------------------

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity control_i2c is
    Port (
	 I2C_SDA_I		 : in std_logic;    -- I2C data line (open-drain bidirectional data line)
	 I2C_SDA_O		 : out std_logic;    -- I2C data line (open-drain bidirectional data line)
	 I2C_SDA_T		 : out std_logic;    -- I2C data line (open-drain bidirectional data line)
	 I2C_CLK		 : out std_logic;    -- I2C clock line (100 kHz)
	 CLK_200kHz_out : out   std_logic;    -- continuous clock for logic analyzer
	 CLK			 : in    std_logic;    -- 27MHz
--	 Vin_VPO        : in    std_logic_vector(15 downto 0);
--	 Vin_RES		 : in    std_logic;    -- RESET_N output from SAA7111
--	 Vin_RES_out    : out   std_logic;    -- RESET_N output for logic analyzer trigger
--	 Vin_CE         : out   std_logic;	  -- SAA7111 Chip Enable (active high, low forces RESET_N)
--	 DV_OUT         : out   std_logic_vector(7 downto 0);
--	 DV_OUT_RST_N   : out   std_logic;    -- SAA7121 RESET_N (active low)
	 SWITCH_general : in    std_logic;
	 colorbar_en : in    std_logic;
--	 switch_unlock  : in    std_logic;
--	 SWITCH_7111    : in    std_logic;
--	 SWITCH_7121    : in    std_logic;
--	 LED_out	 	 : out   std_logic_vector(7 downto 0);
	 testpoint	 : out   std_logic
	 );
end control_i2c;

architecture Behavioral of control_i2c is

type I2C_states  is (IDLE, SEND_START, SEND_SLAVE_ADDRESS, SEND_REGISTER_ADDRESS, SEND_DATA,
                     ACK, SEND_STOP, TOGGLE_SCLK, CONTINUE, WAIT_After_STOP);

type REG_DATA_ARRAY is array (0 to 247) of STD_LOGIC_VECTOR(7 downto 0);

signal   I2C_state        : I2C_states;
signal   DATA_ARRAY       : REG_DATA_ARRAY;
signal   CLK_200kHz       : STD_LOGIC;
signal   I2C_state_cnt    : STD_LOGIC_VECTOR(3 downto 0);
signal   state_ID         : STD_LOGIC_VECTOR(3 downto 0);
signal   stop_state       : STD_LOGIC_VECTOR(1 downto 0);
signal   I2C_data         : STD_LOGIC_VECTOR(7 downto 0);
signal   I2C_SDA          : std_logic;
signal   I2C_DATA_EN      : STD_LOGIC;
signal   I2C_CLK_EN_N     : STD_LOGIC;
signal   WAIT_COUNT       : std_logic_vector(3 downto 0);
signal   I2C_address      : STD_LOGIC_VECTOR(7 downto 0);
signal   RESET_N          : STD_LOGIC;
signal   CLK_COUNT        : integer range 0 to 255;

-- I2C Slave Addresses - bit 8 = 0 to signify "write"
constant SAA7111_addr     : STD_LOGIC_VECTOR(7 downto 0) := "01001000";
constant SAA7121_addr     : STD_LOGIC_VECTOR(7 downto 0) := "10001000";

-- Register settings for SAA7111A Video Input Processor
-- NTSC/ITU-R BT.656

-- SAA7111A Register Addresses
constant V_7111_ADR_1    : STD_LOGIC_VECTOR(7 downto 0)  := "00000001";	--*****
constant V_7111_ADR_2    : STD_LOGIC_VECTOR(7 downto 0)  := "00000010";
constant V_7111_ADR_3    : STD_LOGIC_VECTOR(7 downto 0)  := "00000011";
constant V_7111_ADR_4    : STD_LOGIC_VECTOR(7 downto 0)  := "00000100";
constant V_7111_ADR_5    : STD_LOGIC_VECTOR(7 downto 0)  := "00000101";
constant V_7111_ADR_6    : STD_LOGIC_VECTOR(7 downto 0)  := "00000110";
constant V_7111_ADR_7    : STD_LOGIC_VECTOR(7 downto 0)  := "00000111";
constant V_7111_ADR_8    : STD_LOGIC_VECTOR(7 downto 0)  := "00001000";
constant V_7111_ADR_9    : STD_LOGIC_VECTOR(7 downto 0)  := "00001001";
constant V_7111_ADR_A    : STD_LOGIC_VECTOR(7 downto 0)  := "00001010";
constant V_7111_ADR_B    : STD_LOGIC_VECTOR(7 downto 0)  := "00001011";
constant V_7111_ADR_C    : STD_LOGIC_VECTOR(7 downto 0)  := "00001100";
constant V_7111_ADR_D    : STD_LOGIC_VECTOR(7 downto 0)  := "00001101";
constant V_7111_ADR_E    : STD_LOGIC_VECTOR(7 downto 0)  := "00001110";
constant V_7111_ADR_F    : STD_LOGIC_VECTOR(7 downto 0)  := "00001111";	--*****
constant V_7111_ADR_10   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7111_ADR_11   : STD_LOGIC_VECTOR(7 downto 0)  := "00010001";
constant V_7111_ADR_12   : STD_LOGIC_VECTOR(7 downto 0)  := "00010010";
constant V_7111_ADR_13   : STD_LOGIC_VECTOR(7 downto 0)  := "00010011";
constant V_7111_ADR_14   : STD_LOGIC_VECTOR(7 downto 0)  := "00010100";	--*****
constant V_7111_ADR_15   : STD_LOGIC_VECTOR(7 downto 0)  := "00010101";
constant V_7111_ADR_16   : STD_LOGIC_VECTOR(7 downto 0)  := "00010110";
constant V_7111_ADR_17   : STD_LOGIC_VECTOR(7 downto 0)  := "00010111";
constant V_7111_ADR_18   : STD_LOGIC_VECTOR(7 downto 0)  := "00011000";	--*****
constant V_7111_ADR_19   : STD_LOGIC_VECTOR(7 downto 0)  := "00011001";	--*****
constant V_7111_ADR_1D   : STD_LOGIC_VECTOR(7 downto 0)  := "00011101";	--*****
constant V_7111_ADR_1E   : STD_LOGIC_VECTOR(7 downto 0)  := "00011110";	--*****

-- SAA7111A Register Settings
constant V_7111_REG_1    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_2    : STD_LOGIC_VECTOR(7 downto 0)  := "11000000";
constant V_7111_REG_3    : STD_LOGIC_VECTOR(7 downto 0)  := "00110011";
constant V_7111_REG_4    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_5    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_6    : STD_LOGIC_VECTOR(7 downto 0)  := "11101011";
constant V_7111_REG_7    : STD_LOGIC_VECTOR(7 downto 0)  := "11100000";
constant V_7111_REG_8    : STD_LOGIC_VECTOR(7 downto 0)  := "11001000";
constant V_7111_REG_9    : STD_LOGIC_VECTOR(7 downto 0)  := "00010001";
constant V_7111_REG_A    : STD_LOGIC_VECTOR(7 downto 0)  := "10000000";
constant V_7111_REG_B    : STD_LOGIC_VECTOR(7 downto 0)  := "01000111";
constant V_7111_REG_C    : STD_LOGIC_VECTOR(7 downto 0)  := "01000000";
constant V_7111_REG_D    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_E    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_F    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_10   : STD_LOGIC_VECTOR(7 downto 0)  := "11001000";
constant V_7111_REG_11   : STD_LOGIC_VECTOR(7 downto 0)  := "00011100";
constant V_7111_REG_12   : STD_LOGIC_VECTOR(7 downto 0)  := "00100001";
constant V_7111_REG_13   : STD_LOGIC_VECTOR(7 downto 0)  := "01000000";
constant V_7111_REG_14   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_15   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_16   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_17   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7111_REG_18   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_19   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_1D   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****
constant V_7111_REG_1E   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000"; --*****

-- Register settings for SAA7121 Video Output Processor
-- NTSC/ITU-R BT.656 

-- SAA7121 Register Addresses
constant V_7121_ADR_0    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_ADR_1    : STD_LOGIC_VECTOR(7 downto 0)  := "00000001";
constant V_7121_ADR_2    : STD_LOGIC_VECTOR(7 downto 0)  := "00000010";
constant V_7121_ADR_3    : STD_LOGIC_VECTOR(7 downto 0)  := "00000011";
constant V_7121_ADR_4    : STD_LOGIC_VECTOR(7 downto 0)  := "00000100";
constant V_7121_ADR_5    : STD_LOGIC_VECTOR(7 downto 0)  := "00000101";
constant V_7121_ADR_6    : STD_LOGIC_VECTOR(7 downto 0)  := "00000110";
constant V_7121_ADR_7    : STD_LOGIC_VECTOR(7 downto 0)  := "00000111";
constant V_7121_ADR_8    : STD_LOGIC_VECTOR(7 downto 0)  := "00001000";
constant V_7121_ADR_9    : STD_LOGIC_VECTOR(7 downto 0)  := "00001001";
constant V_7121_ADR_A    : STD_LOGIC_VECTOR(7 downto 0)  := "00001010";
constant V_7121_ADR_B    : STD_LOGIC_VECTOR(7 downto 0)  := "00001011";
constant V_7121_ADR_C    : STD_LOGIC_VECTOR(7 downto 0)  := "00001100";
constant V_7121_ADR_D    : STD_LOGIC_VECTOR(7 downto 0)  := "00001101";
constant V_7121_ADR_E    : STD_LOGIC_VECTOR(7 downto 0)  := "00001110";
constant V_7121_ADR_F    : STD_LOGIC_VECTOR(7 downto 0)  := "00001111";
constant V_7121_ADR_10   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7121_ADR_11   : STD_LOGIC_VECTOR(7 downto 0)  := "00010001";
constant V_7121_ADR_12   : STD_LOGIC_VECTOR(7 downto 0)  := "00010010";
constant V_7121_ADR_13   : STD_LOGIC_VECTOR(7 downto 0)  := "00010011";
constant V_7121_ADR_14   : STD_LOGIC_VECTOR(7 downto 0)  := "00010100";
constant V_7121_ADR_15   : STD_LOGIC_VECTOR(7 downto 0)  := "00010101";
constant V_7121_ADR_16   : STD_LOGIC_VECTOR(7 downto 0)  := "00010110";
constant V_7121_ADR_17   : STD_LOGIC_VECTOR(7 downto 0)  := "00010111";
constant V_7121_ADR_18   : STD_LOGIC_VECTOR(7 downto 0)  := "00011000";
constant V_7121_ADR_19   : STD_LOGIC_VECTOR(7 downto 0)  := "00011001";
constant V_7121_ADR_1A   : STD_LOGIC_VECTOR(7 downto 0)  := "00011010";
constant V_7121_ADR_1B   : STD_LOGIC_VECTOR(7 downto 0)  := "00011011";
constant V_7121_ADR_1C   : STD_LOGIC_VECTOR(7 downto 0)  := "00011100";
constant V_7121_ADR_1D   : STD_LOGIC_VECTOR(7 downto 0)  := "00011101";
constant V_7121_ADR_1E   : STD_LOGIC_VECTOR(7 downto 0)  := "00011110";
constant V_7121_ADR_1F   : STD_LOGIC_VECTOR(7 downto 0)  := "00011111";
constant V_7121_ADR_20   : STD_LOGIC_VECTOR(7 downto 0)  := "00100000";
constant V_7121_ADR_21   : STD_LOGIC_VECTOR(7 downto 0)  := "00100001";
constant V_7121_ADR_22   : STD_LOGIC_VECTOR(7 downto 0)  := "00100010";
constant V_7121_ADR_23   : STD_LOGIC_VECTOR(7 downto 0)  := "00100011";
constant V_7121_ADR_24   : STD_LOGIC_VECTOR(7 downto 0)  := "00100100";
constant V_7121_ADR_25   : STD_LOGIC_VECTOR(7 downto 0)  := "00100101";
constant V_7121_ADR_26   : STD_LOGIC_VECTOR(7 downto 0)  := "00100110";
constant V_7121_ADR_27   : STD_LOGIC_VECTOR(7 downto 0)  := "00100111";
constant V_7121_ADR_28   : STD_LOGIC_VECTOR(7 downto 0)  := "00101000";
constant V_7121_ADR_29   : STD_LOGIC_VECTOR(7 downto 0)  := "00101001";
constant V_7121_ADR_2A   : STD_LOGIC_VECTOR(7 downto 0)  := "00101010";
constant V_7121_ADR_2B   : STD_LOGIC_VECTOR(7 downto 0)  := "00101011";
constant V_7121_ADR_2C   : STD_LOGIC_VECTOR(7 downto 0)  := "00101100";
constant V_7121_ADR_2D   : STD_LOGIC_VECTOR(7 downto 0)  := "00101101";
constant V_7121_ADR_2E   : STD_LOGIC_VECTOR(7 downto 0)  := "00101110";
constant V_7121_ADR_2F   : STD_LOGIC_VECTOR(7 downto 0)  := "00101111";
constant V_7121_ADR_30   : STD_LOGIC_VECTOR(7 downto 0)  := "00110000";
constant V_7121_ADR_31   : STD_LOGIC_VECTOR(7 downto 0)  := "00110001";
constant V_7121_ADR_32   : STD_LOGIC_VECTOR(7 downto 0)  := "00110010";
constant V_7121_ADR_33   : STD_LOGIC_VECTOR(7 downto 0)  := "00110011";
constant V_7121_ADR_34   : STD_LOGIC_VECTOR(7 downto 0)  := "00110100";
constant V_7121_ADR_35   : STD_LOGIC_VECTOR(7 downto 0)  := "00110101";
constant V_7121_ADR_36   : STD_LOGIC_VECTOR(7 downto 0)  := "00110110";
constant V_7121_ADR_37   : STD_LOGIC_VECTOR(7 downto 0)  := "00110111";
constant V_7121_ADR_38   : STD_LOGIC_VECTOR(7 downto 0)  := "00111000";
constant V_7121_ADR_39   : STD_LOGIC_VECTOR(7 downto 0)  := "00111001";
constant V_7121_ADR_3A   : STD_LOGIC_VECTOR(7 downto 0)  := "00111010";
constant V_7121_ADR_5A   : STD_LOGIC_VECTOR(7 downto 0)  := "01011010";
constant V_7121_ADR_5B   : STD_LOGIC_VECTOR(7 downto 0)  := "01011011";
constant V_7121_ADR_5C   : STD_LOGIC_VECTOR(7 downto 0)  := "01011100";
constant V_7121_ADR_5D   : STD_LOGIC_VECTOR(7 downto 0)  := "01011101";
constant V_7121_ADR_5E   : STD_LOGIC_VECTOR(7 downto 0)  := "01011110";
constant V_7121_ADR_5F   : STD_LOGIC_VECTOR(7 downto 0)  := "01011111";
constant V_7121_ADR_60   : STD_LOGIC_VECTOR(7 downto 0)  := "01100000";
constant V_7121_ADR_61   : STD_LOGIC_VECTOR(7 downto 0)  := "01100001";
constant V_7121_ADR_62   : STD_LOGIC_VECTOR(7 downto 0)  := "01100010";
constant V_7121_ADR_63   : STD_LOGIC_VECTOR(7 downto 0)  := "01100011";
constant V_7121_ADR_64   : STD_LOGIC_VECTOR(7 downto 0)  := "01100100";
constant V_7121_ADR_65   : STD_LOGIC_VECTOR(7 downto 0)  := "01100101";
constant V_7121_ADR_66   : STD_LOGIC_VECTOR(7 downto 0)  := "01100110";
constant V_7121_ADR_67   : STD_LOGIC_VECTOR(7 downto 0)  := "01100111";
constant V_7121_ADR_68   : STD_LOGIC_VECTOR(7 downto 0)  := "01101000";
constant V_7121_ADR_69   : STD_LOGIC_VECTOR(7 downto 0)  := "01101001";
constant V_7121_ADR_6A   : STD_LOGIC_VECTOR(7 downto 0)  := "01101010";
constant V_7121_ADR_6B   : STD_LOGIC_VECTOR(7 downto 0)  := "01101011";
constant V_7121_ADR_6C   : STD_LOGIC_VECTOR(7 downto 0)  := "01101100";
constant V_7121_ADR_6D   : STD_LOGIC_VECTOR(7 downto 0)  := "01101101";
constant V_7121_ADR_6E   : STD_LOGIC_VECTOR(7 downto 0)  := "01101110";
constant V_7121_ADR_6F   : STD_LOGIC_VECTOR(7 downto 0)  := "01101111";
constant V_7121_ADR_70   : STD_LOGIC_VECTOR(7 downto 0)  := "01110000";
constant V_7121_ADR_71   : STD_LOGIC_VECTOR(7 downto 0)  := "01110001";
constant V_7121_ADR_72   : STD_LOGIC_VECTOR(7 downto 0)  := "01110010";
constant V_7121_ADR_73   : STD_LOGIC_VECTOR(7 downto 0)  := "01110011";
constant V_7121_ADR_74   : STD_LOGIC_VECTOR(7 downto 0)  := "01110100";
constant V_7121_ADR_75   : STD_LOGIC_VECTOR(7 downto 0)  := "01110101";
constant V_7121_ADR_76   : STD_LOGIC_VECTOR(7 downto 0)  := "01110110";
constant V_7121_ADR_77   : STD_LOGIC_VECTOR(7 downto 0)  := "01110111";
constant V_7121_ADR_78   : STD_LOGIC_VECTOR(7 downto 0)  := "01111000";
constant V_7121_ADR_79   : STD_LOGIC_VECTOR(7 downto 0)  := "01111001";
constant V_7121_ADR_7A   : STD_LOGIC_VECTOR(7 downto 0)  := "01111010";
constant V_7121_ADR_7B   : STD_LOGIC_VECTOR(7 downto 0)  := "01111011";
constant V_7121_ADR_7C   : STD_LOGIC_VECTOR(7 downto 0)  := "01111100";
constant V_7121_ADR_7D   : STD_LOGIC_VECTOR(7 downto 0)  := "01111101";
constant V_7121_ADR_7E   : STD_LOGIC_VECTOR(7 downto 0)  := "01111110";
constant V_7121_ADR_7F   : STD_LOGIC_VECTOR(7 downto 0)  := "01111111";


-- SAA7121 Register Settings
constant V_7121_REG_0    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_3    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_4    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_5    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_6    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_7    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_8    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_9    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_A    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_B    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_C    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_D    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_E    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_F    : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_10   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_11   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_12   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_13   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_14   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_15   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_16   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_17   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_18   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_19   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1A   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1B   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1C   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1D   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1E   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_1F   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_20   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_21   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_22   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_23   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_24   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_25   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_26   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_27   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_28   : STD_LOGIC_VECTOR(7 downto 0)  := "00011001";
constant V_7121_REG_29   : STD_LOGIC_VECTOR(7 downto 0)  := "00011101";
constant V_7121_REG_2A   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2B   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2C   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2D   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2E   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_2F   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_30   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_31   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_32   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_33   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_34   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_35   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_36   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_37   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_38   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_39   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
--constant V_7121_REG_3A   : STD_LOGIC_VECTOR(7 downto 0)  := "00010011";	 -- SET MSB FOR COLOR BARS
constant V_7121_REG_3A   : STD_LOGIC_VECTOR(7 downto 0)  := "10010011";	 -- SET MSB FOR COLOR BARS
constant V_7121_REG_5A   : STD_LOGIC_VECTOR(7 downto 0)  := "10001000";
constant V_7121_REG_5B   : STD_LOGIC_VECTOR(7 downto 0)  := "01110110";
constant V_7121_REG_5C   : STD_LOGIC_VECTOR(7 downto 0)  := "10100101";
constant V_7121_REG_5D   : STD_LOGIC_VECTOR(7 downto 0)  := "00101010";
constant V_7121_REG_5E   : STD_LOGIC_VECTOR(7 downto 0)  := "00101110";
constant V_7121_REG_5F   : STD_LOGIC_VECTOR(7 downto 0)  := "00101110";
constant V_7121_REG_60   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_61   : STD_LOGIC_VECTOR(7 downto 0)  := "00010101";
constant V_7121_REG_62   : STD_LOGIC_VECTOR(7 downto 0)  := "00111111";
constant V_7121_REG_63   : STD_LOGIC_VECTOR(7 downto 0)  := "00011111";
constant V_7121_REG_64   : STD_LOGIC_VECTOR(7 downto 0)  := "01111100";
constant V_7121_REG_65   : STD_LOGIC_VECTOR(7 downto 0)  := "11110000";
constant V_7121_REG_66   : STD_LOGIC_VECTOR(7 downto 0)  := "00100001";
constant V_7121_REG_67   : STD_LOGIC_VECTOR(7 downto 0)  := "01010101";
constant V_7121_REG_68   : STD_LOGIC_VECTOR(7 downto 0)  := "01010110";
constant V_7121_REG_69   : STD_LOGIC_VECTOR(7 downto 0)  := "01100111";
constant V_7121_REG_6A   : STD_LOGIC_VECTOR(7 downto 0)  := "01011000";
constant V_7121_REG_6B   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_6C   : STD_LOGIC_VECTOR(7 downto 0)  := "11111001";
constant V_7121_REG_6D   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_6E   : STD_LOGIC_VECTOR(7 downto 0)  := "10110000";
constant V_7121_REG_6F   : STD_LOGIC_VECTOR(7 downto 0)  := "00010100";
constant V_7121_REG_70   : STD_LOGIC_VECTOR(7 downto 0)  := "10000000";
constant V_7121_REG_71   : STD_LOGIC_VECTOR(7 downto 0)  := "11101000";
constant V_7121_REG_72   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7121_REG_73   : STD_LOGIC_VECTOR(7 downto 0)  := "01010100";
constant V_7121_REG_74   : STD_LOGIC_VECTOR(7 downto 0)  := "00000011";
constant V_7121_REG_75   : STD_LOGIC_VECTOR(7 downto 0)  := "00000011";
constant V_7121_REG_76   : STD_LOGIC_VECTOR(7 downto 0)  := "00000110";
constant V_7121_REG_77   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7121_REG_78   : STD_LOGIC_VECTOR(7 downto 0)  := "00000101";
constant V_7121_REG_79   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7121_REG_7A   : STD_LOGIC_VECTOR(7 downto 0)  := "00011000";
constant V_7121_REG_7B   : STD_LOGIC_VECTOR(7 downto 0)  := "00111000";
constant V_7121_REG_7C   : STD_LOGIC_VECTOR(7 downto 0)  := "00010000";
constant V_7121_REG_7D   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_7E   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";
constant V_7121_REG_7F   : STD_LOGIC_VECTOR(7 downto 0)  := "00000000";

begin
-- SAA7111 Register address/register data area
DATA_ARRAY(0)   <= V_7111_ADR_1; --*****
DATA_ARRAY(1)   <= V_7111_REG_1; --*****
DATA_ARRAY(2)   <= V_7111_ADR_2;
DATA_ARRAY(3)   <= V_7111_REG_2;
DATA_ARRAY(4)   <= V_7111_ADR_3;
DATA_ARRAY(5)   <= V_7111_REG_3;
DATA_ARRAY(6)   <= V_7111_ADR_4;
DATA_ARRAY(7)   <= V_7111_REG_4;
DATA_ARRAY(8)   <= V_7111_ADR_5;
DATA_ARRAY(9)   <= V_7111_REG_5;
DATA_ARRAY(10)  <= V_7111_ADR_6;
DATA_ARRAY(11)  <= V_7111_REG_6;
DATA_ARRAY(12)  <= V_7111_ADR_7;
DATA_ARRAY(13)  <= V_7111_REG_7;
DATA_ARRAY(14)  <= V_7111_ADR_8;
DATA_ARRAY(15)  <= V_7111_REG_8;
DATA_ARRAY(16)  <= V_7111_ADR_9;
DATA_ARRAY(17)  <= V_7111_REG_9;
DATA_ARRAY(18)  <= V_7111_ADR_A;
DATA_ARRAY(19)  <= V_7111_REG_A;
DATA_ARRAY(20)  <= V_7111_ADR_B;
DATA_ARRAY(21)  <= V_7111_REG_B;
DATA_ARRAY(22)  <= V_7111_ADR_C;
DATA_ARRAY(23)  <= V_7111_REG_C;
DATA_ARRAY(24)  <= V_7111_ADR_D;
DATA_ARRAY(25)  <= V_7111_REG_D;
DATA_ARRAY(26)  <= V_7111_ADR_E;
DATA_ARRAY(27)  <= V_7111_REG_E;
DATA_ARRAY(28)  <= V_7111_ADR_F; --*****
DATA_ARRAY(29)  <= V_7111_REG_F; --*****
DATA_ARRAY(30)  <= V_7111_ADR_10;
DATA_ARRAY(31)  <= V_7111_REG_10;
DATA_ARRAY(32)  <= V_7111_ADR_11;
DATA_ARRAY(33)  <= V_7111_REG_11;
DATA_ARRAY(34)  <= V_7111_ADR_12;
DATA_ARRAY(35)  <= V_7111_REG_12;
DATA_ARRAY(36)  <= V_7111_ADR_13;
DATA_ARRAY(37)  <= V_7111_REG_13;
DATA_ARRAY(38)  <= V_7111_ADR_14; --*****
DATA_ARRAY(39)  <= V_7111_REG_14; --*****
DATA_ARRAY(40)  <= V_7111_ADR_15;
DATA_ARRAY(41)  <= V_7111_REG_15;
DATA_ARRAY(42)  <= V_7111_ADR_16;
DATA_ARRAY(43)  <= V_7111_REG_16;
DATA_ARRAY(44)  <= V_7111_ADR_17;
DATA_ARRAY(45)  <= V_7111_REG_17;
DATA_ARRAY(46)  <= V_7111_ADR_18; --*****
DATA_ARRAY(47)  <= V_7111_REG_18; --*****
DATA_ARRAY(48)  <= V_7111_ADR_19; --*****
DATA_ARRAY(49)  <= V_7111_REG_19; --*****
DATA_ARRAY(50)  <= V_7111_ADR_1D; --*****
DATA_ARRAY(51)  <= V_7111_REG_1D; --*****
DATA_ARRAY(52)  <= V_7111_ADR_1E; --*****
DATA_ARRAY(53)  <= V_7111_REG_1E; --*****

-- SAA7121 Register address/register data area
DATA_ARRAY(54)  <= V_7121_ADR_0;
DATA_ARRAY(55)  <= V_7121_REG_0;
DATA_ARRAY(56)  <= V_7121_ADR_1;
DATA_ARRAY(57)  <= V_7121_REG_1;
DATA_ARRAY(58)  <= V_7121_ADR_2;
DATA_ARRAY(59)  <= V_7121_REG_2;
DATA_ARRAY(60)  <= V_7121_ADR_3;
DATA_ARRAY(61)  <= V_7121_REG_3;
DATA_ARRAY(62)  <= V_7121_ADR_4;
DATA_ARRAY(63)  <= V_7121_REG_4;
DATA_ARRAY(64)  <= V_7121_ADR_5;
DATA_ARRAY(65)  <= V_7121_REG_5;
DATA_ARRAY(66)  <= V_7121_ADR_6;
DATA_ARRAY(67)  <= V_7121_REG_6;
DATA_ARRAY(68)  <= V_7121_ADR_7;
DATA_ARRAY(69)  <= V_7121_REG_7;
DATA_ARRAY(70)  <= V_7121_ADR_8;
DATA_ARRAY(71)  <= V_7121_REG_8;
DATA_ARRAY(72)  <= V_7121_ADR_9;
DATA_ARRAY(73)  <= V_7121_REG_9;
DATA_ARRAY(74)  <= V_7121_ADR_A;
DATA_ARRAY(75)  <= V_7121_REG_A;
DATA_ARRAY(76)  <= V_7121_ADR_B;
DATA_ARRAY(77)  <= V_7121_REG_B;
DATA_ARRAY(78)  <= V_7121_ADR_C;
DATA_ARRAY(79)  <= V_7121_REG_C;
DATA_ARRAY(80)  <= V_7121_ADR_D;
DATA_ARRAY(81)  <= V_7121_REG_D;
DATA_ARRAY(82)  <= V_7121_ADR_E;
DATA_ARRAY(83)  <= V_7121_REG_E;
DATA_ARRAY(84)  <= V_7121_ADR_F;
DATA_ARRAY(85)  <= V_7121_REG_F;
DATA_ARRAY(86)  <= V_7121_ADR_10;
DATA_ARRAY(87)  <= V_7121_REG_10;
DATA_ARRAY(88)  <= V_7121_ADR_11;
DATA_ARRAY(89)  <= V_7121_REG_11;
DATA_ARRAY(90)  <= V_7121_ADR_12;
DATA_ARRAY(91)  <= V_7121_REG_12;
DATA_ARRAY(92)  <= V_7121_ADR_13;
DATA_ARRAY(93)  <= V_7121_REG_13;
DATA_ARRAY(94)  <= V_7121_ADR_14;
DATA_ARRAY(95)  <= V_7121_REG_14;
DATA_ARRAY(96)  <= V_7121_ADR_15;
DATA_ARRAY(97)  <= V_7121_REG_15;
DATA_ARRAY(98)  <= V_7121_ADR_16;
DATA_ARRAY(99)  <= V_7121_REG_16;
DATA_ARRAY(100) <= V_7121_ADR_17;
DATA_ARRAY(101) <= V_7121_REG_17;
DATA_ARRAY(102) <= V_7121_ADR_18;
DATA_ARRAY(103) <= V_7121_REG_18;
DATA_ARRAY(104) <= V_7121_ADR_19;
DATA_ARRAY(105) <= V_7121_REG_19;
DATA_ARRAY(106) <= V_7121_ADR_1A;
DATA_ARRAY(107) <= V_7121_REG_1A;
DATA_ARRAY(108) <= V_7121_ADR_1B;
DATA_ARRAY(109) <= V_7121_REG_1B;
DATA_ARRAY(110) <= V_7121_ADR_1C;
DATA_ARRAY(111) <= V_7121_REG_1C;
DATA_ARRAY(112) <= V_7121_ADR_1D;
DATA_ARRAY(113) <= V_7121_REG_1D;
DATA_ARRAY(114) <= V_7121_ADR_1E;
DATA_ARRAY(115) <= V_7121_REG_1E;
DATA_ARRAY(116) <= V_7121_ADR_1F;
DATA_ARRAY(117) <= V_7121_REG_1F;
DATA_ARRAY(118) <= V_7121_ADR_20;
DATA_ARRAY(119) <= V_7121_REG_20;
DATA_ARRAY(120) <= V_7121_ADR_21;
DATA_ARRAY(121) <= V_7121_REG_21;
DATA_ARRAY(122) <= V_7121_ADR_22;
DATA_ARRAY(123) <= V_7121_REG_22;
DATA_ARRAY(124) <= V_7121_ADR_23;
DATA_ARRAY(125) <= V_7121_REG_23;
DATA_ARRAY(126) <= V_7121_ADR_24;
DATA_ARRAY(127) <= V_7121_REG_24;
DATA_ARRAY(128) <= V_7121_ADR_25;
DATA_ARRAY(129) <= V_7121_REG_25;
DATA_ARRAY(130) <= V_7121_ADR_26;
DATA_ARRAY(131) <= V_7121_REG_26;
DATA_ARRAY(132) <= V_7121_ADR_27;
DATA_ARRAY(133) <= V_7121_REG_27;
DATA_ARRAY(134) <= V_7121_ADR_28;
DATA_ARRAY(135) <= V_7121_REG_28;
DATA_ARRAY(136) <= V_7121_ADR_29;
DATA_ARRAY(137) <= V_7121_REG_29;
DATA_ARRAY(138) <= V_7121_ADR_2A;
DATA_ARRAY(139) <= V_7121_REG_2A;
DATA_ARRAY(140) <= V_7121_ADR_2B;
DATA_ARRAY(141) <= V_7121_REG_2B;
DATA_ARRAY(142) <= V_7121_ADR_2C;
DATA_ARRAY(143) <= V_7121_REG_2C;
DATA_ARRAY(144) <= V_7121_ADR_2D;
DATA_ARRAY(145) <= V_7121_REG_2D;
DATA_ARRAY(146) <= V_7121_ADR_2E;
DATA_ARRAY(147) <= V_7121_REG_2E;
DATA_ARRAY(148) <= V_7121_ADR_2F;
DATA_ARRAY(149) <= V_7121_REG_2F;
DATA_ARRAY(150) <= V_7121_ADR_30;
DATA_ARRAY(151) <= V_7121_REG_30;
DATA_ARRAY(152) <= V_7121_ADR_31;
DATA_ARRAY(153) <= V_7121_REG_31;
DATA_ARRAY(154) <= V_7121_ADR_32;
DATA_ARRAY(155) <= V_7121_REG_32;
DATA_ARRAY(156) <= V_7121_ADR_33;
DATA_ARRAY(157) <= V_7121_REG_33;
DATA_ARRAY(158) <= V_7121_ADR_34;
DATA_ARRAY(159) <= V_7121_REG_34;
DATA_ARRAY(160) <= V_7121_ADR_35;
DATA_ARRAY(161) <= V_7121_REG_35;
DATA_ARRAY(162) <= V_7121_ADR_36;
DATA_ARRAY(163) <= V_7121_REG_36;
DATA_ARRAY(164) <= V_7121_ADR_37;
DATA_ARRAY(165) <= V_7121_REG_37;
DATA_ARRAY(166) <= V_7121_ADR_38;
DATA_ARRAY(167) <= V_7121_REG_38;
DATA_ARRAY(168) <= V_7121_ADR_39;
DATA_ARRAY(169) <= V_7121_REG_39;
DATA_ARRAY(170) <= V_7121_ADR_3A;
--DATA_ARRAY(171) <= V_7121_REG_3A;
DATA_ARRAY(171) <= colorbar_en & V_7121_REG_3A(6 downto 0);
DATA_ARRAY(172) <= V_7121_ADR_5A;
DATA_ARRAY(173) <= V_7121_REG_5A;
DATA_ARRAY(174) <= V_7121_ADR_5B;
DATA_ARRAY(175) <= V_7121_REG_5B;
DATA_ARRAY(176) <= V_7121_ADR_5C;
DATA_ARRAY(177) <= V_7121_REG_5C;
DATA_ARRAY(178) <= V_7121_ADR_5D;
DATA_ARRAY(179) <= V_7121_REG_5D;
DATA_ARRAY(180) <= V_7121_ADR_5E;
DATA_ARRAY(181) <= V_7121_REG_5E;
DATA_ARRAY(182) <= V_7121_ADR_5F;
DATA_ARRAY(183) <= V_7121_REG_5F;
DATA_ARRAY(184) <= V_7121_ADR_60;
DATA_ARRAY(185) <= V_7121_REG_60;
DATA_ARRAY(186) <= V_7121_ADR_61;
DATA_ARRAY(187) <= V_7121_REG_61;
DATA_ARRAY(188) <= V_7121_ADR_62;
DATA_ARRAY(189) <= V_7121_REG_62;
DATA_ARRAY(190) <= V_7121_ADR_63;
DATA_ARRAY(191) <= V_7121_REG_63;
DATA_ARRAY(192) <= V_7121_ADR_64;
DATA_ARRAY(193) <= V_7121_REG_64;
DATA_ARRAY(194) <= V_7121_ADR_65;
DATA_ARRAY(195) <= V_7121_REG_65;
DATA_ARRAY(196) <= V_7121_ADR_66;
DATA_ARRAY(197) <= V_7121_REG_66;
DATA_ARRAY(198) <= V_7121_ADR_67;
DATA_ARRAY(199) <= V_7121_REG_67;
DATA_ARRAY(200) <= V_7121_ADR_68;
DATA_ARRAY(201) <= V_7121_REG_68;
DATA_ARRAY(202) <= V_7121_ADR_69;
DATA_ARRAY(203) <= V_7121_REG_69;
DATA_ARRAY(204) <= V_7121_ADR_6A;
DATA_ARRAY(205) <= V_7121_REG_6A;
DATA_ARRAY(206) <= V_7121_ADR_6B;
DATA_ARRAY(207) <= V_7121_REG_6B;
DATA_ARRAY(208) <= V_7121_ADR_6C;
DATA_ARRAY(209) <= V_7121_REG_6C;
DATA_ARRAY(210) <= V_7121_ADR_6D;
DATA_ARRAY(211) <= V_7121_REG_6D;
DATA_ARRAY(212) <= V_7121_ADR_6E;
DATA_ARRAY(213) <= V_7121_REG_6E;
DATA_ARRAY(214) <= V_7121_ADR_6F;
DATA_ARRAY(215) <= V_7121_REG_6F;
DATA_ARRAY(216) <= V_7121_ADR_70;
DATA_ARRAY(217) <= V_7121_REG_70;
DATA_ARRAY(218) <= V_7121_ADR_71;
DATA_ARRAY(219) <= V_7121_REG_71;
DATA_ARRAY(220) <= V_7121_ADR_72;
DATA_ARRAY(221) <= V_7121_REG_72;
DATA_ARRAY(222) <= V_7121_ADR_73;
DATA_ARRAY(223) <= V_7121_REG_73;
DATA_ARRAY(224) <= V_7121_ADR_74;
DATA_ARRAY(225) <= V_7121_REG_74;
DATA_ARRAY(226) <= V_7121_ADR_75;
DATA_ARRAY(227) <= V_7121_REG_75;
DATA_ARRAY(228) <= V_7121_ADR_76;
DATA_ARRAY(229) <= V_7121_REG_76;
DATA_ARRAY(230) <= V_7121_ADR_77;
DATA_ARRAY(231) <= V_7121_REG_77;
DATA_ARRAY(232) <= V_7121_ADR_78;
DATA_ARRAY(233) <= V_7121_REG_78;
DATA_ARRAY(234) <= V_7121_ADR_79;
DATA_ARRAY(235) <= V_7121_REG_79;
DATA_ARRAY(236) <= V_7121_ADR_7A;
DATA_ARRAY(237) <= V_7121_REG_7A;
DATA_ARRAY(238) <= V_7121_ADR_7B;
DATA_ARRAY(239) <= V_7121_REG_7B;
DATA_ARRAY(240) <= V_7121_ADR_7C;
DATA_ARRAY(241) <= V_7121_REG_7C;
DATA_ARRAY(242) <= V_7121_ADR_7D;
DATA_ARRAY(243) <= V_7121_REG_7D;
DATA_ARRAY(244) <= V_7121_ADR_7E;
DATA_ARRAY(245) <= V_7121_REG_7E;
DATA_ARRAY(246) <= V_7121_ADR_7F;
DATA_ARRAY(247) <= V_7121_REG_7F;

-- drive RESET_N from dip switch 0
 RESET_N          <= SWITCH_general;
--Vin_CE         <= SWITCH_7111;             -- SAA7111 has its own POR
--DV_OUT_RST_N   <= SWITCH_7121;  -- put SAA7121 in RESET_N
CLK_200kHz_out <= CLK_200kHz;

-- RESET_N function - SWITCH_general drives RESET_N and RESET_N is latched
-- to get around switch bounce.  Switch_unlock forces RESET_N to zero.
--process (SWITCH_general, switch_unlock)
--variable RESET_lock : integer range 0 to 1 := 0;
--begin
--	if SWITCH_general = '0' and RESET_lock = 0 then
--	  RESET_N      <= '0';
--	elsif switch_unlock = '1' then
--	  RESET_lock   := 0;
--	  RESET_N      <= '0';
--	else
--	  RESET_lock   := 1;
--	  RESET_N      <= '1';
--	end if;
--end process;

--Clock Divider: I2C clock
process (CLK)
begin
  if RESET_N = '0' then
	 CLK_200kHz <= '0';
  elsif (CLK'event and CLK = '1') then       --Use counter to divide CLK by 136
	   if CLK_COUNT  = 136 then
	     CLK_COUNT  <= 0;
	     CLK_200kHz <= not CLK_200kHz;     --CLK (27 MHz) / 136 = CLK_200kHz 
	   else                                 --             (actually 198.5kHz)
	     CLK_COUNT  <= CLK_COUNT + 1;
 	   end if;
  end if;
end process;

-- Following code changes made by VG @ ADS for Microblaze OPB peripheral requirements of bidirectional I/O

I2C_SDA   <= I2C_SDA_I;
--I2C_SDA_T <= I2C_DATA_EN;
I2C_SDA_O <= '0';
---- SDA output control
process (CLK_200kHz, I2C_DATA_EN)
begin
  if (CLK_200kHz'event and CLK_200kHz = '0') then
	if I2C_DATA_EN = '0' then
	   I2C_SDA_T <= '0';
	else
	   I2C_SDA_T <= '1'; -- SDA line is pulled high externally
	end if;
  end if;
end process;

--process (CLK_200kHz, I2C_DATA_EN)
--begin
--  if (CLK_200kHz'event and CLK_200kHz = '0') then
--	if I2C_DATA_EN = '0' then
--	   I2C_SDA <= '0';
--	else
--	   I2C_SDA <= 'Z'; -- SDA line is pulled high externally
--	end if;
--  end if;
--end process;

--testpoint	<= I2C_SDA;
	 
-- pass the ITU-R BT.601 8-bit video data
--  from the SAA7111 to the SAA7121
--DV_OUT(7 downto 0) <= Vin_VPO(15 downto 8);

-- Debug code
--LED_out(0)          <= I2C_CLK;
--LED_out(1)          <= I2C_SDA;
--LED_out(2)          <= RESET_N; 
--LED_out(3)          <= Vin_RES;
--LED_out(7 downto 4) <= state_ID;

------------------------------------------------------------------------------------------
--
-- I2C Communication Protocol:
--
-- The Master (FPGA) begins the communication by issuing the "Start" condition and then
-- continues by sending a unique 7-bit slave device address (MSB first).  The eighth bit
-- after the "Start" specifies whether the slave is to receive (0) or to transmit (1) data.
-- This is followed by an "ACK" issued by the receiver to acknowledge receipt of the previous
-- byte.  The transmitter then transmits a byte of data (MSB first) and the receiver issues
-- an "ACK" upon receipt of the entire byte.  This data/ACK pattern is repeated if there are
-- more bytes to transmit.
--
-- In a write transaction (slave device receiving), when the master is done transmitting
-- it monitors the last "ACK" and then issues the "Stop" condition.  In a read transaction
-- (slave device transmitting), the master does not acknowledge the final byte and issues
-- the "Stop" condition.
--
-- Note that this implementation only transmits initialization data to the SAA7111 and 
-- SAA7121, and does not attempt to read from the these devices.  Each I2C transaction
-- will take the form of START, 7-bit I2C address (ACK), 8-bit register address (ACK),
-- 8-bit data (ACK), STOP, with this sequence repeated until all registers in the SAA7111
-- and SAA7121 have been loaded.  A NACK (instead of an ACK) returned by the addressed slave
-- will result in a STOP condition being generated and the above sequence repeated.
--
-- I2c addresses are: SAA7111 48h write, 49h read (7-bit addressing)
--                    SAA7121 88h write, 89h read (7-bit addressing)
--
------------------------------------------------------------------------------------------
	  
--I2C state machine
process (CLK_200kHz, RESET_N, DATA_ARRAY)
variable bfr_pntr  : integer range 0 to 247 := 0;
variable BIT_COUNT : integer range 0 to 8   := 0;
begin
	if RESET_N = '0' then
    -- Initialize
       I2C_CLK       <= '1';	                                 -- SCK = 1
	  I2C_DATA_EN   <= '1';                                   -- SDA = Z
       state_ID      <= "0001";
       I2C_state_cnt <= "0000";
	  bfr_pntr      := 0; 
	  WAIT_COUNT    <= "0000";
	  I2C_data      <= DATA_ARRAY(0)(7 downto 0); -- load 1st register address
	  I2C_state     <= IDLE;         -- set Idle state as next
	else
	  if (CLK_200kHz'event and CLK_200kHz = '1') then
	    if 247 >= bfr_pntr then
		  case I2C_state is
			when IDLE =>
                 state_ID      <= "0010";
			  I2C_state_cnt <= "0000";
	            I2C_CLK       <= '1';	                        -- SCK = 1
			  I2C_DATA_EN   <= '1';	                        -- SDA = Z
			  I2C_state     <= SEND_START;

		   -- I2C "Start" condition requires a high-to-low transition of
		   --  the data (SDA) line while the clock (SCL) is held high
		   when SEND_START =>
                 state_ID      <= "0011";
		       I2C_state_cnt <= "0001";      -- send slave address
                 I2C_CLK       <= '1';                         -- SCK = 1
                 I2C_DATA_EN   <= '0';                         -- SDA = 0
		       if bfr_pntr < 40 then
			    I2C_address <= SAA7111_addr;
		   	  else		 
			    I2C_address <= SAA7121_addr;
			  end if;
			   I2C_state    <= TOGGLE_SCLK; -- go to transition SDA low
		   
		   -- Send a 7-bit address and "write" indication (bit #8 = 0)
		   when SEND_SLAVE_ADDRESS =>
               state_ID      <= "0100";
			   I2C_state_cnt <= "0010";			 	
			   if BIT_COUNT = 8 then   -- 7-bit address sent, check ACK
	               I2C_CLK     <= '0';                        -- SCK = 0
			     BIT_COUNT   := 0;
			     I2C_state   <= ACK;
			   else
	               I2C_CLK     <= '0';	                       -- SCK = 0
			     I2C_DATA_EN <= I2C_address(7 - BIT_COUNT); -- SDA = data
			     BIT_COUNT   := BIT_COUNT + 1;
			     I2C_state   <= TOGGLE_SCLK;
			   end if;

			  -- send 8-bit register address
			when SEND_REGISTER_ADDRESS =>
                   state_ID        <= "0101";
			    I2C_state_cnt   <= "0101";
			    if BIT_COUNT = 8 then
	                 I2C_CLK       <= '0';                       -- SCK = 0
				  BIT_COUNT     := 0;
				  if bfr_pntr < 247 then
                        bfr_pntr    := bfr_pntr + 1; -- increment the buffer pointer
				  end if;
				  I2C_state     <= ACK;
			    else
	                 I2C_CLK <= '0';                             -- SCK = 0
				  I2C_DATA_EN   <= I2C_data(7 - BIT_COUNT);   -- SDA = data
				  BIT_COUNT     := BIT_COUNT + 1;
				  I2C_state     <= TOGGLE_SCLK;
			    end if;				
				
			    -- Send_Data will transmit an 8-bit quantity to the addressed slave device;
			    --  the 1st byte sent will be the register address, the 2nd byte data			
			when SEND_DATA =>
                   state_ID        <= "0110";
			    I2C_state_cnt   <= "0110";
			    if BIT_COUNT = 8 then
	                I2C_CLK       <= '0';                       -- SCK = 0
			      BIT_COUNT     := 0;
				  if bfr_pntr < 247 then
                       bfr_pntr    := bfr_pntr + 1; -- increment the buffer pointer
				 end if;
				 I2C_state     <= ACK;
			    else
	                I2C_CLK       <= '0';                       -- SCK = 0
				 I2C_DATA_EN   <= I2C_data(7 - BIT_COUNT);   -- SDA = data
				 BIT_COUNT     := BIT_COUNT + 1;
				 I2C_state     <= TOGGLE_SCLK;
			    end if;  					

			   when ACK =>
                    state_ID      <= "1000";
	               I2C_CLK       <= '1';                        -- SCK = 1
			     I2C_DATA_EN   <= '1';                        -- SDA = Z
--				  I2C_DATA_EN   <= '0'; --***********FOR SIMULATION ONLY**********
				I2C_state     <= CONTINUE; -- go to check for SDA low
					
			   -- SCK is high, check for SDA pulled low (ACK)
			   when CONTINUE =>
	                 I2C_CLK <= '0';                          -- SCK = 0
			       if I2C_SDA = '0' then	 -- ACK
				    I2C_DATA_EN <= '0';                        -- SDA = 0
                        state_ID    <= "1001";
				  case I2C_state_cnt is
                          when "0010" => -- SEND_SLAVE_ADDRESS
				   	    I2C_data    <= DATA_ARRAY(bfr_pntr);--(7 downto 0); -- load Reg. address
                             I2C_state   <= Send_Register_Address;
				      when "0101" => --SEND_REGISTER_ADDRESS
					     I2C_data      <= DATA_ARRAY(bfr_pntr);--(7 downto 0); -- load Reg. data
					     I2C_state     <= SEND_DATA;					 
				      when "0110" => --SEND_DATA
					     if bfr_pntr < 40 then
					       I2C_address <= SAA7111_addr;
					     else
					       I2C_address <= SAA7121_addr;
				         end if;
					     I2C_state     <= SEND_STOP;					   
				      when others =>
					     I2C_state <= IDLE;					 
				    end case;
		          else   -- NACK
                       state_ID        <= "1010";
				   case I2C_state_cnt is
			           when "0010" =>  -- NACK following Slave Address
				 	     I2C_data  <= DATA_ARRAY(bfr_pntr); -- load Reg. address
                              I2C_state <= Send_Register_Address;
				      when "0101" =>  -- NACK following Register Address
				          bfr_pntr   := bfr_pntr - 1;     -- decrement loop counter by 1
				          I2C_state  <= WAIT_After_STOP;
				      when "0110" =>  -- NACK following Data byte
				          bfr_pntr   := bfr_pntr - 2;     -- decrement loop counter by 2				
				          I2C_state  <= WAIT_After_STOP;
				      when others =>
			              I2C_state  <= WAIT_After_STOP;
			        end case;
                       I2C_state_cnt <= "0111";	   -- set state to drive STOP
	                  I2C_CLK       <= '1';		               -- SCK = 1
				   I2C_DATA_EN   <= '0';	                    -- SDA = 0
				   I2C_state     <= TOGGLE_SCLK; -- send Stop;
			     end if;
				
               -- I2C "Stop" condition requires a low-to-high transition of
			   --  the data (SDA) line while the clock (SCL) is held high
			   when SEND_STOP =>
                    state_ID      <= "0111";
                    I2C_state_cnt <= "0111";
	               I2C_CLK       <= '1';	                    -- SCK = 1
			     I2C_DATA_EN   <= '1';                        -- SDA = Z
			     I2C_state     <= TOGGLE_SCLK;
				
			   -- waste some time after a STOP is sent
			   when WAIT_After_STOP =>
                    state_ID      <= "1011";
			     I2C_CLK       <= '1';                            -- SCK = 1
                    I2C_DATA_EN   <= '1';                            -- SDA = Z
			     if WAIT_COUNT  = "1010" then
			       WAIT_COUNT  <= "0000";
			       if bfr_pntr < 247 then
			         I2C_state <= SEND_START;
			       else
			         I2C_state <= WAIT_After_STOP;
			       end if;
		          else
			       WAIT_COUNT <= WAIT_COUNT + "0001";
			       I2C_state  <= WAIT_After_STOP;
		          end if;
				
			   when TOGGLE_SCLK =>
                     state_ID           <= "1100";
				 case I2C_state_cnt is
				   when "0000" =>
					 I2C_state     <= IDLE;
				   when "0001" =>  -- Send_Start
					 I2C_DATA_EN   <= '0';                      -- SDA= 0
					 I2C_state     <= SEND_SLAVE_ADDRESS;
				   when "0010" =>  -- Send_Slave_Address
	                     I2C_CLK       <= '1';                      -- SCK = 1
					 I2C_state     <= SEND_SLAVE_ADDRESS;						
				   when "0101" =>  -- Send_Register_Address
	                     I2C_CLK       <= '1';                      -- SCK = 1
					 I2C_state     <= SEND_REGISTER_ADDRESS;	
				   when "0110" =>  -- Send_Data
	                     I2C_CLK       <= '1';                      -- SCK = 1
					 I2C_state     <= SEND_DATA;
				   when "0111" =>  -- Send_Stop
					 I2C_DATA_EN   <= '1';                      -- SDA = Z
					 I2C_state     <= WAIT_After_STOP;
				   when others =>
					 I2C_state     <= IDLE;
				 end case;
	      end case;
        else
	      I2C_state <= SEND_STOP;
	    end if;
       end if;
	end if;
end process;
end Behavioral;
