----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;      
use IEEE.STD_LOGIC_ARITH.ALL;     
use IEEE.STD_LOGIC_UNSIGNED.ALL;
----------------------------------------------------------------------------------
entity SPI_bridge_DAC is
  Port (
    
    CLK48 : in  STD_LOGIC;                    --Interface Clock
	 
    data1A  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 10b  
	 data1B  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 10b
	 
	 data2A  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 10b  
	 data2B  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 10b
	 
	 data3A  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 12b  
	 data3B  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 12b
	 
	 data4A  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 12b  
	 data4B  : in  STD_LOGIC_VECTOR(15 downto 0); -- data must be right aligned 12b
	 
	 wr_en : in  STD_LOGIC; 


    MOSI : out STD_LOGIC := '0';
	 SPI_SCK	: out STD_LOGIC := '0';
	 
	 CS_DAC1 : out  STD_LOGIC := '1'; 
	 CS_DAC2 : out  STD_LOGIC := '1'; 
	 CS_DAC3 : out  STD_LOGIC := '1'; 
	 CS_DAC4 : out  STD_LOGIC := '1'
	 
  );
end SPI_bridge_DAC;
----------------------------------------------------------------------------------
architecture rtl of SPI_bridge_DAC is
 

signal SPI_state_cntr : std_logic_vector(15 downto 0) := X"FFFF"; -- for timing the 3*4 transmissions
signal send : std_logic := '0'; -- send signal to transmitter
signal data : std_logic_vector(15 downto 0) := X"0000"; 
signal CS : std_logic := '0'; -- send signal to transmitter



constant TimeTrans1a : integer := (16#0000#)/2;
constant TimeTrans1b : integer := (16#0380#)/2; --X"070";
constant TimeTrans1c : integer := (16#0700#)/2; --X"0E0";

constant TimeTrans2a : integer := (16#0D80#)/2; --X"1B0";
constant TimeTrans2b : integer := (16#1100#)/2; --X"220";
constant TimeTrans2c : integer := (16#1480#)/2; --X"290";

constant TimeTrans3a : integer := (16#1B00#)/2; --X"360";
constant TimeTrans3b : integer := (16#1E80#)/2; --X"3D0";
constant TimeTrans3c : integer := (16#2200#)/2; --X"440";

constant TimeTrans4a : integer := (16#2880#)/2; --X"510";
constant TimeTrans4b : integer := (16#2C00#)/2; --X"580";
constant TimeTrans4c : integer := (16#2F80#)/2; --X"5F0";  these are /2 refer to 3MHz  for other timing other divident or multiplicant can be used


constant TransmTime : integer := (16#02A8#)/2; --X"55"

--------------------------
	COMPONENT SPI_transmitter3B
	PORT(
		CLK48 : IN std_logic;
		data : IN std_logic_vector(15 downto 0);
		wr_en : IN std_logic;          
		CS : OUT std_logic;
		MOSI : OUT std_logic;
		SPI_SCK : OUT std_logic	);
	END COMPONENT;
----------------------------------------------------------------------------------
begin
 
SPI_transmitterCHx: SPI_transmitter3B PORT MAP(
		CLK48 => CLK48,
		data => data,
		wr_en => send,
		CS => CS,
		MOSI => MOSI,
		SPI_SCK => SPI_SCK);
--------------------------	
	
process(CLK48)
begin
    if(rising_edge(CLK48)) then
  
    
		
			if (wr_en = '1') then -- if rising edge of send_now
				SPI_state_cntr <= X"0000"; -- startst the sending by nulling this cntr

				
			elsif SPI_state_cntr < TimeTrans4c + TransmTime then -- else if it is the end of counting
				SPI_state_cntr <= SPI_state_cntr + 1;
			end if;
			
			
			
			
			--------------------sending initialization-------------------------------
			--R1 R0 set control = "11"     //     SPD = slow =  0     //  PWR = 0n = 0
			--ref1 ref0 = "01"  1.024 reference *2
			
			
			if (SPI_state_cntr = TimeTrans1a) then 
			 data <= "1001000000000001"; -- R1 SPD PWR R0 xxxxxx Ref1 Ref0
			 send <= '1';
			end if;
			
			if (SPI_state_cntr = TimeTrans1a+1) then
			 send <= '0';
			end if;
			------------------------------------sending data1A ---------------------
			--R1 R0 set DACB = "00"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans1b) then 
			 data <= "0000" & data1A(9 downto 0) & "00"; --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans1b+1) then
			 send <= '0';
			end if;
			
			------------------------------------sending data1B ---------------------
			--R1 R0 set DACA = "10"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans1c) then 
			 data <= "1000" & data1B(9 downto 0) & "00"; --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans1c+1) then 
			 send <= '0';
			end if;
			
			
			
			
			
			
			
			--------------------sending initialization-------------------------------
			--R1 R0 set control = "11"     //     SPD = slow =  0     //  PWR = 0n = 0
			--ref1 ref0 = "01"  1.024 reference *2
			
			
			if (SPI_state_cntr = TimeTrans2a) then 
			 data <= "1001000000000001"; -- R1 SPD PWR R0 xxxxxx Ref1 Ref0
			 send <= '1';
			end if;
			
			if (SPI_state_cntr = TimeTrans2a+1) then
			 send <= '0';
			end if;
			------------------------------------sending data2A ---------------------
			--R1 R0 set DACB = "00"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans2b) then 
			 data <= "0000" & data2A(9 downto 0) & "00"; --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans2b+1) then
			 send <= '0';
			end if;
			
			------------------------------------sending data2B ---------------------
			--R1 R0 set DACA = "10"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans2c) then 
			 data <= "1000" & data2B(9 downto 0) & "00"; --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans2c+1) then 
			 send <= '0';
			end if;
			
			
			
			
			
			--------------------sending initialization-------------------------------
			--R1 R0 set control = "11"     //     SPD = slow =  0     //  PWR = 0n = 0
			--ref1 ref0 = "01"  1.024 reference *2
			
			
			if (SPI_state_cntr = TimeTrans3a) then 
			 data <= "1001000000000001"; -- R1 SPD PWR R0 xxxxxx Ref1 Ref0
			 send <= '1';
			end if;
			
			if (SPI_state_cntr = TimeTrans3a+1) then
			 send <= '0';
			end if;
			------------------------------------sending data3A ---------------------
			--R1 R0 set DACB = "00"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans3b) then 
			 data <= "0000" & data3A(11 downto 0) ; --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans3b+1) then
			 send <= '0';
			end if;
			
			------------------------------------sending data3B ---------------------
			--R1 R0 set DACA = "10"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans3c) then 
			 data <= "1000" & data3B(11 downto 0); --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans3c+1) then 
			 send <= '0';
			end if;
			
			
			
			
			
			--------------------sending initialization-------------------------------
			--R1 R0 set control = "11"     //     SPD = slow =  0     //  PWR = 0n = 0
			--ref1 ref0 = "01"  1.024 reference *2
			
			
			if (SPI_state_cntr = TimeTrans4a) then 
			 data <= "1001000000000001"; -- R1 SPD PWR R0 xxxxxx Ref1 Ref0
			 send <= '1';
			end if;
			
			if (SPI_state_cntr = TimeTrans4a+1) then
			 send <= '0';
			end if;
			------------------------------------sending data4A ---------------------
			--R1 R0 set DACB = "00"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans4b) then 
			 data <= "0000" & data4A(11 downto 0); --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans4b+1) then
			 send <= '0';
			end if;
			
			------------------------------------sending data4B ---------------------
			--R1 R0 set DACA = "10"     //     SPD = slow =  0     //  PWR = 0n = 0
			
			if (SPI_state_cntr = TimeTrans4c) then 
			 data <= "1000" & data4B(11 downto 0); --data shifted by 2 to left
			 send <= '1';
			end if;
			
			
			if (SPI_state_cntr = TimeTrans4c+1) then 
			 send <= '0';
			end if;
			
			
			
			
			
			--------------------------------------------------------------------------
			---------------------------------------finalizing transmission------------
			
		

    end if;
  end process; 
  
  	--------chip selects------------------------------------------------------

  CS_DAC1 <= CS when (SPI_state_cntr >= TimeTrans1a) and (SPI_state_cntr < TimeTrans1c+TransmTime) else '1';
  CS_DAC2 <= CS when (SPI_state_cntr >= TimeTrans2a) and (SPI_state_cntr < TimeTrans2c+TransmTime) else '1';
  CS_DAC3 <= CS when (SPI_state_cntr >= TimeTrans3a) and (SPI_state_cntr < TimeTrans3c+TransmTime) else '1';
  CS_DAC4 <= CS when (SPI_state_cntr >= TimeTrans4a) and (SPI_state_cntr < TimeTrans4c+TransmTime) else '1';
  
end rtl;