]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
code for control of ads1018 ADC
authorTobias Weber <toweber86@gmail.com>
Tue, 10 Oct 2017 14:17:37 +0000 (16:17 +0200)
committerTobias Weber <toweber86@gmail.com>
Tue, 10 Oct 2017 14:30:06 +0000 (16:30 +0200)
mupix/Mupix8/sources/ADS1018SPI.vhd
mupix/Mupix8/sources/MupixBoard.vhd
mupix/Mupix8/sources/MupixBoardDAC.vhd
mupix/Mupix8/tb/ADS1018SPITest.vhd [new file with mode: 0644]

index 0af2474cb04b3522da1e4a39d8540e03bb08bd38..8f2ce63d46dcb6cf58cebeede55fb3e4796a10e8 100644 (file)
@@ -14,19 +14,96 @@ entity ADS1018SPI is
                spi_clock_speed  : integer := 1e4
        );
        port(
-               clk   : in std_logic;
-               reset : in std_logic;
-               start_write          : in  std_logic; --start writing data to adc/start conversion
-       config_in            : in  std_logic_vector(15 downto 0); --config data to adc
-       spi_data_from_chip   : in  std_logic; --serial data from dac
-       spi_data_to_chip     : out std_logic; --seral data to dac shift register
-       spi_data_out         : out std_logic_vector(31 downto 0); --conversion data and config readback
-       spi_clk              : out std_logic; --SPI interface clock
-               spi_ld               : out std_logic); --SPI load/chip select
+               clk                : in  std_logic;
+               reset              : in  std_logic;
+               start_write        : in  std_logic; --start writing data to adc/start conversion
+               config_in          : in  std_logic_vector(15 downto 0); --config data to adc
+               spi_data_from_chip : in  std_logic; --serial data from dac
+               spi_data_to_chip   : out std_logic; --seral data to dac shift register
+               spi_data_out       : out std_logic_vector(31 downto 0); --conversion data and config readback
+               spi_clk            : out std_logic; --SPI interface clock
+               spi_cs             : out std_logic); --SPI chip select
 end entity ADS1018SPI;
 
 architecture RTL of ADS1018SPI is
-       
+
+       constant c_div_cnt_max : integer                              := fpga_clock_speed/spi_clock_speed;
+       signal div_cnt         : integer range 0 to c_div_cnt_max - 1 := 0;
+
+       type ads_fsm_type is (idle, cs_low, sendbit1, sendbit2, cs_high);
+       signal ads_fsm_state : ads_fsm_type := idle;
+
+       signal config_index   : integer range 0 to 15         := 15;
+       signal byte_counter   : integer range 0 to 31         := 31;
+       signal spi_data_out_i : std_logic_vector(31 downto 0) := (others => '0');
+
 begin
 
+       spi_proc : process(clk) is
+       begin
+               if rising_edge(clk) then
+                       if reset = '1' then
+                               spi_cs           <= '1';
+                               spi_clk          <= '0';
+                               spi_data_to_chip <= '0';
+                               spi_data_out     <= (others => '0');
+                               div_cnt          <= 0;
+                       else
+                               case ads_fsm_state is
+                                       when idle =>
+                                               spi_cs           <= '1';
+                                               spi_clk          <= '0';
+                                               spi_data_to_chip <= '0';
+                                               div_cnt          <= 0;
+                                               if start_write = '1' then
+                                                       config_index  <= 15;
+                                                       byte_counter  <= 31;
+                                                       spi_cs        <= '0';
+                                                       ads_fsm_state <= cs_low;
+                                               end if;
+                                       when cs_low =>
+                                               div_cnt <= div_cnt + 1;
+                                               if div_cnt = c_div_cnt_max - 1 then
+                                                       div_cnt       <= 0;
+                                                       ads_fsm_state <= sendbit1;
+                                               end if;
+                                       when sendbit1 =>
+                                               spi_clk          <= '1';
+                                               spi_data_to_chip <= config_in(config_index);
+                                               div_cnt          <= div_cnt + 1;
+                                               if div_cnt = c_div_cnt_max/2 then
+                                                       ads_fsm_state  <= sendbit2;
+                                                       spi_data_out_i <= spi_data_out_i(30 downto 0) & spi_data_from_chip;
+                                               end if;
+                                       when sendbit2 =>
+                                               spi_clk <= '0';
+                                               div_cnt <= div_cnt + 1;
+                                               if div_cnt = c_div_cnt_max - 1 then
+                                                       div_cnt      <= 0;
+                                                       byte_counter <= byte_counter - 1;
+                                                       if config_index > 0 then
+                                                               config_index <= config_index - 1;
+                                                       else
+                                                               config_index <= 15;
+                                                       end if;
+                                                       if byte_counter > 0 then
+                                                               byte_counter  <= byte_counter - 1;
+                                                               ads_fsm_state <= sendbit1;
+                                                       else
+                                                               ads_fsm_state <= cs_high;
+                                                       end if;
+                                               end if;
+                                       when cs_high =>
+                                               div_cnt <= div_cnt + 1;
+                                               if div_cnt = c_div_cnt_max - 1 then
+                                                       div_cnt       <= 0;
+                                                       spi_cs        <= '1';
+                                                       ads_fsm_state <= idle;
+                                                       spi_data_out  <= spi_data_out_i;
+                                               end if;
+                               end case;
+                       end if;
+               end if;
+       end process spi_proc;
+
 end architecture RTL;
index c6c44f891dd75a110ba721c7a4aa21ab837029f6..a3c249bd521f1ea222ea44522703e81cc4e7aad4 100644 (file)
@@ -33,7 +33,7 @@ entity MupixBoard is
     spi_clk             :  out std_logic; --serial clock
     spi_din             :  out std_logic; --serial data out
     spi_ld_tmp_dac      :  out std_logic; --load temperature dac 
-    spi_ld_adc          :  out std_logic; --load adc 
+    spi_cs_adc          :  out std_logic; --load adc 
     spi_ld_thres        :  out std_logic; --load threshold and injection dac
     --slow data signals
     hitbus              :  in  std_logic; --hitbus signal
@@ -192,7 +192,7 @@ architecture Behavioral of MupixBoard is
                        spi_din              : out std_logic; --serial data out
                        spi_ld_tmp_dac       : out std_logic; --load temperature dac 
                        spi_ld_thres         : out std_logic; --load threshold and injection dac
-                       spi_ld_adc           : out std_logic; --load adc 
+                       spi_cs_adc           : out std_logic; --load adc 
                        --TRB slow control
                        SLV_READ_IN          : in  std_logic;
                        SLV_WRITE_IN         : in  std_logic;
index 7690f234f44022d806684413bddc37b8b0853938..37a874da300580375b011c3fd69a1ce06fa63f53 100644 (file)
@@ -19,7 +19,7 @@ entity MupixBoardDAC is
        spi_din             :  out std_logic; --serial data out
        spi_ld_tmp_dac      :  out std_logic; --load temperature dac 
        spi_ld_thres        :  out std_logic; --load threshold and injection dac
-       spi_ld_adc          :  out std_logic; --load adc 
+       spi_cs_adc          :  out std_logic; --load adc 
                --TRB slow control
                SLV_READ_IN          : in  std_logic;
                SLV_WRITE_IN         : in  std_logic;
@@ -66,7 +66,7 @@ architecture RTL of MupixBoardDAC is
                        spi_data_to_chip   : out std_logic;
                        spi_data_out       : out std_logic_vector(31 downto 0);
                        spi_clk            : out std_logic;
-                       spi_ld             : out std_logic
+                       spi_cs             : out std_logic
                );
        end component ADS1018SPI;
        
@@ -148,7 +148,7 @@ begin
                                spi_data_to_chip   => spi_data_to_chip_adc,
                                spi_data_out       => spi_data_out_adc,
                                spi_clk            => spi_clk_adc,
-                               spi_ld             => spi_ld_adc
+                               spi_cs             => spi_cs_adc
                        );              
        -----------------------------------------------------------------------------
        --TRB Slave Bus
@@ -159,6 +159,8 @@ begin
        --0x0094: temperature dac
        --0x0095: readback temperature dac
        --0x0096: start write threshold and injection dacs bit
+       --0x0097: write config adc
+       --0x0098: read adc data
        -----------------------------------------------------------------------------
        SLV_BUS_HANDLER : process(clk)
        begin                               -- process SLV_BUS_HANDLER
@@ -168,6 +170,8 @@ begin
                        SLV_UNKNOWN_ADDR_OUT  <= '0';
                        SLV_NO_MORE_DATA_OUT  <= '0';
                        start_write_threshold <= '0';
+                       start_write_temperature <= '0';
+                       start_write_adc       <= '0';
 
                        if SLV_READ_IN = '1' then
                                case SLV_ADDR_IN is
@@ -189,6 +193,12 @@ begin
                                        when x"0095" =>
                                                SLV_DATA_OUT(15 downto 0) <= spi_data_out_temperature;
                                                SLV_ACK_OUT               <= '1';
+                                       when x"0097" =>
+                                               SLV_DATA_OUT(15 downto 0) <= config_adc;
+                                               SLV_ACK_OUT               <= '1';
+                                       when x"0098" =>
+                                               SLV_DATA_OUT              <= spi_data_out_adc;
+                                               SLV_ACK_OUT               <= '1';
                                        when others =>
                                                SLV_UNKNOWN_ADDR_OUT <= '1';
                                end case;
@@ -208,6 +218,10 @@ begin
                                        when x"0096" =>
                                                start_write_threshold <= '1';
                                                SLV_ACK_OUT           <= '1';
+                                       when x"0097" =>
+                                               config_adc            <= SLV_DATA_IN(15 downto 0);
+                                               start_write_adc       <= '1';
+                                               SLV_ACK_OUT           <= '1';
                                        when others =>
                                                SLV_UNKNOWN_ADDR_OUT <= '1';
                                end case;
diff --git a/mupix/Mupix8/tb/ADS1018SPITest.vhd b/mupix/Mupix8/tb/ADS1018SPITest.vhd
new file mode 100644 (file)
index 0000000..5b79f3a
--- /dev/null
@@ -0,0 +1,110 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity ADS1018SPITest is
+end entity ADS1018SPITest;
+architecture sim of ADS1018SPITest is
+       
+       component ADS1018SPI
+               generic(
+                       fpga_clock_speed : integer := 1e8;
+                       spi_clock_speed  : integer := 1e4
+               );
+               port(
+                       clk                : in  std_logic;
+                       reset              : in  std_logic;
+                       start_write        : in  std_logic;
+                       config_in          : in  std_logic_vector(15 downto 0);
+                       spi_data_from_chip : in  std_logic;
+                       spi_data_to_chip   : out std_logic;
+                       spi_data_out       : out std_logic_vector(31 downto 0);
+                       spi_clk            : out std_logic;
+                       spi_cs             : out std_logic
+               );
+       end component ADS1018SPI;
+       
+       constant c_fpga_clock_speed : integer := 1e8;
+       constant c_spi_clock_speed  : integer := 5e6;
+       constant c_clock_period     : time    := 10 ns;
+       --dut interface signals
+       signal clk                  : std_logic;
+       signal reset                : std_logic := '0';
+       signal start_write          : std_logic := '0';
+       signal config_in            : std_logic_vector(15 downto 0) := (others => '0');
+       signal spi_data_from_chip   : std_logic;
+       signal spi_data_to_chip     : std_logic;
+       signal spi_data_out         : std_logic_vector(31 downto 0);
+       signal spi_clk              : std_logic;
+       signal spi_cs               : std_logic;
+       
+       signal config_chip, config_chip_new : std_logic_vector(15 downto 0) := (others => '0');
+       signal data_chip                    : std_logic_vector(15 downto 0) := x"AACC";
+       signal shiftreg_reg                 : std_logic_vector(31 downto 0) := (others => '0');
+               
+begin
+       
+       dut : entity work.ADS1018SPI
+               generic map(
+                       fpga_clock_speed => c_fpga_clock_speed,
+                       spi_clock_speed  => c_spi_clock_speed
+               )
+               port map(
+                       clk                => clk,
+                       reset              => reset,
+                       start_write        => start_write,
+                       config_in          => config_in,
+                       spi_data_from_chip => spi_data_from_chip,
+                       spi_data_to_chip   => spi_data_to_chip,
+                       spi_data_out       => spi_data_out,
+                       spi_clk            => spi_clk,
+                       spi_cs             => spi_cs
+               );
+               
+       ADS_response : process(spi_cs, spi_clk) is
+       begin
+               if spi_cs'event and spi_cs = '0' then
+                       shiftreg_reg   <= data_chip & config_chip after 100 ns;
+               end if;
+               if spi_cs'event and spi_cs = '1' then
+                       config_chip <= config_chip_new;
+               end if;
+               if spi_clk'event and spi_clk = '1' then --on rising clock edge write out new bit
+                       spi_data_from_chip <= shiftreg_reg(shiftreg_reg'length - 1);
+                       shiftreg_reg <= shiftreg_reg(shiftreg_reg'length - 2 downto 0) & '0' after 100 ns;
+               end if;
+               if spi_clk'event and spi_clk = '0' then --on falling clock edge load new data to config bit
+                       config_chip_new <= config_chip_new(config_chip_new'length - 2 downto 0) & spi_data_to_chip;
+               end if;
+       end process ADS_response;
+               
+               
+       clk_generation : process is
+       begin
+               clk <= '1';
+               wait for c_clock_period/2;
+               clk <= '0';
+               wait for c_clock_period/2;
+       end process clk_generation;
+       
+       stimulus : process is
+       begin
+               wait for 100 ns;
+               config_in <= x"BCDB";
+               start_write <= '1';
+               wait for c_clock_period;
+               start_write <= '0';
+               if spi_cs = '0' then
+                       wait until spi_cs = '1';
+               end if;
+               wait for 200*c_clock_period;
+               config_in <= x"BCDB";
+               start_write <= '1';
+               wait for c_clock_period;
+               start_write <= '0';
+               wait;
+       end process stimulus;
+       
+       
+end architecture sim;