From: Tobias Weber Date: Tue, 10 Oct 2017 14:17:37 +0000 (+0200) Subject: code for control of ads1018 ADC X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=382b151d8ba067b8eb9bf8af3d16270da00e1274;p=trb3.git code for control of ads1018 ADC --- diff --git a/mupix/Mupix8/sources/ADS1018SPI.vhd b/mupix/Mupix8/sources/ADS1018SPI.vhd index 0af2474..8f2ce63 100644 --- a/mupix/Mupix8/sources/ADS1018SPI.vhd +++ b/mupix/Mupix8/sources/ADS1018SPI.vhd @@ -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; diff --git a/mupix/Mupix8/sources/MupixBoard.vhd b/mupix/Mupix8/sources/MupixBoard.vhd index c6c44f8..a3c249b 100644 --- a/mupix/Mupix8/sources/MupixBoard.vhd +++ b/mupix/Mupix8/sources/MupixBoard.vhd @@ -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; diff --git a/mupix/Mupix8/sources/MupixBoardDAC.vhd b/mupix/Mupix8/sources/MupixBoardDAC.vhd index 7690f23..37a874d 100644 --- a/mupix/Mupix8/sources/MupixBoardDAC.vhd +++ b/mupix/Mupix8/sources/MupixBoardDAC.vhd @@ -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 index 0000000..5b79f3a --- /dev/null +++ b/mupix/Mupix8/tb/ADS1018SPITest.vhd @@ -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;