|
---------------------------------------------------------------------------
|
|
-- (c) 2017 mark watson
|
|
-- I am happy for anyone to use this for non-commercial use.
|
|
-- If my vhdl files are used commercially or otherwise sold,
|
|
-- please contact me for explicit permission at scrameta (gmail).
|
|
-- This applies for source and binary form and derived works.
|
|
---------------------------------------------------------------------------
|
|
LIBRARY ieee;
|
|
USE ieee.std_logic_1164.all;
|
|
use ieee.numeric_std.all;
|
|
use IEEE.STD_LOGIC_MISC.all;
|
|
|
|
-- 3.2MHz to 8 MHz, rather thsn 400KHz...
|
|
-- Different data in and data in - is it still i2c?
|
|
-- Write data in 16 cycles -> clocked in on rising edge
|
|
-- Result in out -> clocked on failling edge
|
|
--
|
|
-- 16 cycle process
|
|
-- data_in is ctrl7,ctrl6,ctrl5,ctrl4,ctrl3,ctrl2,ctrl1,ctrl0,na*8
|
|
-- data_out is l,l,l,l,d7,d6,d5,d4,d3,d2,d1,d0,l,l,l,l,l
|
|
-- cs-> low, 4 clock cycles then data
|
|
|
|
ENTITY adc084 IS
|
|
PORT
|
|
(
|
|
CLK : IN STD_LOGIC; -- about 58MHz...
|
|
RESET_N : IN STD_LOGIC;
|
|
|
|
-- ADC side
|
|
CS : OUT STD_LOGIC;
|
|
SCLK : OUT STD_LOGIC;
|
|
DOUT : IN STD_LOGIC;
|
|
DIN : OUT STD_LOGIC;
|
|
|
|
-- SAMPLED side
|
|
CH1OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
|
|
CH2OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
|
|
CH3OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
|
|
CH4OUT : OUT STD_LOGIC_VECTOR(7 downto 0)
|
|
);
|
|
END adc084;
|
|
|
|
ARCHITECTURE vhdl OF adc084 IS
|
|
signal cycle_next : std_logic_vector(21 downto 0);
|
|
signal cycle_reg : STD_LOGIC_VECTOR(21 DOWNTO 0);
|
|
|
|
signal channel_next : std_logic_vector(1 downto 0);
|
|
signal channel_reg : std_logic_vector(1 downto 0);
|
|
|
|
signal sclk_next : std_logic;
|
|
signal sclk_reg : std_logic;
|
|
|
|
signal alt_next : std_logic;
|
|
signal alt_reg : std_logic;
|
|
|
|
signal din_next : std_logic;
|
|
signal din_reg : std_logic;
|
|
|
|
signal cs_reg : std_logic;
|
|
signal cs_next : std_logic;
|
|
|
|
signal enable : std_logic;
|
|
|
|
signal cap_next : std_logic_vector(7 downto 0);
|
|
signal cap_reg : std_logic_vector(7 downto 0);
|
|
|
|
signal ch1_next : std_logic_vector(7 downto 0);
|
|
signal ch2_next : std_logic_vector(7 downto 0);
|
|
signal ch3_next : std_logic_vector(7 downto 0);
|
|
signal ch4_next : std_logic_vector(7 downto 0);
|
|
|
|
signal ch1_reg : std_logic_vector(7 downto 0);
|
|
signal ch2_reg : std_logic_vector(7 downto 0);
|
|
signal ch3_reg : std_logic_vector(7 downto 0);
|
|
signal ch4_reg : std_logic_vector(7 downto 0);
|
|
|
|
signal store : std_logic;
|
|
BEGIN
|
|
-- regs
|
|
process(clk, reset_n)
|
|
begin
|
|
if (reset_n='0') then
|
|
cycle_reg <= "0000000000000000000001";
|
|
channel_reg <= "01";
|
|
ch1_reg <= (others=>'0');
|
|
ch2_reg <= (others=>'0');
|
|
ch3_reg <= (others=>'0');
|
|
ch4_reg <= (others=>'0');
|
|
cap_reg <= (others=>'0');
|
|
sclk_reg <= '1';
|
|
din_reg <= '0';
|
|
cs_reg <= '1';
|
|
alt_reg <= '1';
|
|
elsif (clk'event and clk='1') then
|
|
cycle_reg <= cycle_next;
|
|
channel_reg <= channel_next;
|
|
ch1_reg <= ch1_next;
|
|
ch2_reg <= ch2_next;
|
|
ch3_reg <= ch3_next;
|
|
ch4_reg <= ch4_next;
|
|
cap_reg <= cap_next;
|
|
sclk_reg <= sclk_next;
|
|
din_reg <= din_next;
|
|
cs_reg <= cs_next;
|
|
alt_reg <= alt_next;
|
|
end if;
|
|
end process;
|
|
|
|
enable_div_clk : entity work.enable_divider
|
|
generic map (COUNT=>8) -- cycle_length
|
|
port map(clk=>clk,reset_n=>reset_n,enable_in=>'1',enable_out=>enable);
|
|
|
|
-- main coms engine
|
|
process(enable,cycle_reg,cap_reg,din_reg,alt_reg,sclk_reg,cs_reg,channel_reg,dout)
|
|
begin
|
|
cycle_next <= cycle_reg;
|
|
cap_next <= cap_reg;
|
|
sclk_next <= sclk_reg;
|
|
alt_next <= alt_reg;
|
|
cs_next <= cs_reg;
|
|
|
|
din_next <= din_reg;
|
|
store <= '0';
|
|
|
|
if (enable='1') then
|
|
sclk_next <= or_reduce(not(sclk_reg)&cycle_reg(21 downto 16));
|
|
cs_next <= or_reduce(cycle_reg(20 downto 17));
|
|
alt_next <= not(alt_reg);
|
|
if (alt_reg = '1') then -- was 1, next is 0 -> falling edge
|
|
din_next <= (channel_reg(1) and cycle_reg(3)) or (channel_reg(0) and cycle_reg(4));
|
|
end if;
|
|
|
|
if (alt_reg = '0') then -- was 0, next is 1 -> rising edge
|
|
cycle_next <= cycle_reg(20 downto 0)&cycle_reg(21);
|
|
cap_next(0) <= dout;
|
|
|
|
cap_next(7 downto 1) <= cap_reg(6 downto 0);
|
|
-- signal cap_next : std_logic_vector(7 downto 0);
|
|
-- signal cap_reg : std_logic_vector(7 downto 0);
|
|
|
|
store <= cycle_reg(12);
|
|
end if;
|
|
end if;
|
|
end process;
|
|
|
|
-- store channel
|
|
process(store,channel_reg,cap_reg,ch1_reg,ch2_reg,ch3_reg,ch4_reg)
|
|
begin
|
|
channel_next <= channel_reg;
|
|
ch1_next <= ch1_reg;
|
|
ch2_next <= ch2_reg;
|
|
ch3_next <= ch3_reg;
|
|
ch4_next <= ch4_reg;
|
|
|
|
if (store = '1') then
|
|
channel_next <= std_logic_vector(unsigned(channel_reg) + 1);
|
|
--channel_next <= "01";
|
|
--ch2_next <= cap_reg;
|
|
|
|
case channel_reg is
|
|
when "00" =>
|
|
ch4_next <= cap_reg;
|
|
when "01" =>
|
|
ch1_next <= cap_reg;
|
|
when "10" =>
|
|
ch2_next <= cap_reg;
|
|
when "11" =>
|
|
ch3_next <= cap_reg;
|
|
when others =>
|
|
end case;
|
|
end if;
|
|
end process;
|
|
|
|
sclk <= sclk_reg;
|
|
din <= din_reg;
|
|
cs <= cs_reg;
|
|
ch1out <= ch1_reg;
|
|
ch2out <= ch2_reg;
|
|
ch3out <= ch3_reg;
|
|
ch4out <= ch4_reg;
|
|
|
|
END vhdl;
|