]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
ADC I2C readout implemented
authorLudwig Maier <lmaier@crius.e12.ph.tum.de>
Tue, 28 Jan 2014 12:17:06 +0000 (13:17 +0100)
committerLudwig Maier <lmaier@crius.e12.ph.tum.de>
Tue, 28 Jan 2014 12:17:20 +0000 (13:17 +0100)
nxyter/source/nx_i2c_master.vhd
nxyter/source/nx_setup.vhd
nxyter/source/nx_trigger_validate.vhd
nxyter/source/registers.txt

index 30ce9f5e629d86e97ab997e27e119d3bfd6c075e..777a7009e92ea4383bbb7e9c41eb0e65d9c1988a 100644 (file)
@@ -449,7 +449,7 @@ begin
   --   D[29:27] RESERVED        set all to '0'
   --   D[26:24] I2C_NUM_BYTES   number of bytes to be read 1..4       
   --   D[23:16] I2C_ADDRESS     address of I2C chip
-  --   D[15:8]  I2C_CMD         command byte for access
+  --   D[15:8]  I2C_REG_ADDRESS command byte for access
   --   D[7:0]   I2C_DATA        data to be written
   --   
   --   Read bit definition
index 269ec217e094966cf874921543cb4eb30216587d..c4f3978daa8a576f669d8d9cca24496d3928e3e6 100644 (file)
@@ -46,6 +46,7 @@ architecture Behavioral of nx_setup is
   signal i2c_lock_1      : std_logic;
   signal i2c_lock_2      : std_logic;
   signal i2c_lock_3      : std_logic;
+  signal i2c_lock_4      : std_logic;
   signal i2c_command     : std_logic_vector(31 downto 0);
   
   -- Send I2C Command
@@ -85,8 +86,8 @@ architecture Behavioral of nx_setup is
   signal ram_write_1             : std_logic;
   signal do_write                : std_logic;
 
-  -- DAC Trim FIFO RAM
-  type dac_ram_t is array(0 to 130) of std_logic_vector(5 downto 0);
+  -- DAC Trim FIFO RAM Handler
+  type dac_ram_t is array(0 to 128) of std_logic_vector(5 downto 0);
   signal dac_ram                 : dac_ram_t;
   signal dac_ram_write_0         : std_logic;
   signal dac_ram_write_1         : std_logic;
@@ -95,7 +96,11 @@ architecture Behavioral of nx_setup is
   signal dac_ram_data_0          : std_logic_vector(5 downto 0);
   signal dac_ram_data_1          : std_logic_vector(5 downto 0);
   signal do_dac_write            : std_logic;
-      
+
+  -- ADC RAM Handler
+  type adc_ram_t is array(0 to 3) of std_logic_vector(15 downto 0);
+  signal adc_ram                 : adc_ram_t;
+  
   -- Token Handler
   signal i2c_read_token          : std_logic_vector(45 downto 0);
   signal i2c_write_token         : std_logic_vector(45 downto 0);
@@ -133,7 +138,6 @@ architecture Behavioral of nx_setup is
                     );
   
   signal DR_STATE, DR_STATE_RETURN : DR_STATES;
-
   
   signal dac_read_i2c_command    : std_logic_vector(31 downto 0);
   signal r_fifo_ctr              : unsigned(7 downto 0);
@@ -155,6 +159,25 @@ architecture Behavioral of nx_setup is
   signal dac_write_token_clear   : std_logic_vector(128 downto 0);
   signal next_token_dac_w        : std_logic;
   signal i2c_lock_2_clear        : std_logic;
+
+  -- ADC Token Handler
+  signal adc_read_token          : std_logic_vector(3 downto 0);
+
+  -- Read ADC Registers
+  type ADC_STATES is (ADC_IDLE_TOKEN,
+                      ADC_READ_I2C_REGISTER,
+                      ADC_WAIT_I2C_READ_DONE,
+                      ADC_READ_I2C_STORE_MEM,
+                      ADC_NEXT_TOKEN
+                    );
+  
+  signal ADC_STATE : ADC_STATES;
+  
+  signal adc_i2c_command         : std_logic_vector(31 downto 0);
+  signal adc_token_ctr           : unsigned(1 downto 0);
+  signal adc_read_token_clear    : std_logic_vector(3 downto 0);
+  signal next_token_adc          : std_logic;
+  signal i2c_lock_4_clear        : std_logic;
   
   -- I2C Online Check
   type R_STATES is (R_TIMER_RESTART,
@@ -191,6 +214,8 @@ architecture Behavioral of nx_setup is
   signal dac_read_token_r        : std_logic_vector(128 downto 0);
   signal dac_write_token_r       : std_logic_vector(128 downto 0);
 
+  signal adc_read_token_r        : std_logic_vector(3 downto 0);
+  
   signal nxyter_polarity         : std_logic_vector(1 downto 0);  -- 0: negative
   signal nxyter_testpulse        : std_logic_vector(1 downto 0);
   signal nxyter_testtrigger      : std_logic_vector(1 downto 0);
@@ -214,12 +239,12 @@ begin
   DEBUG_OUT(7)            <= i2c_lock_0_clear;
   DEBUG_OUT(8)            <= i2c_lock_1_clear;
   DEBUG_OUT(9)            <= i2c_lock_2_clear;
-  DEBUG_OUT(10)           <= i2c_lock_3_clear;
+  DEBUG_OUT(10)           <= i2c_lock_4_clear;
   DEBUG_OUT(11)           <= i2c_online_o; 
   DEBUG_OUT(12)           <= i2c_lock_0;
   DEBUG_OUT(13)           <= i2c_lock_1;
   DEBUG_OUT(14)           <= i2c_lock_2;
-  DEBUG_OUT(15)           <= i2c_lock_3;
+  DEBUG_OUT(15)           <= i2c_lock_4;
 
   -----------------------------------------------------------------------------
 
@@ -291,11 +316,11 @@ begin
       end if;
     end if;
   end process PROC_DAC_RAM;
-         
+
   -----------------------------------------------------------------------------
 
   PROC_I2C_COMMAND_MULTIPLEXER: process(CLK_IN)
-    variable locks : std_logic_vector(3 downto 0) := (others => '0');
+    variable locks : std_logic_vector(4 downto 0) := (others => '0');
   begin
     if( rising_edge(CLK_IN) ) then
       if( RESET_IN = '1' ) then
@@ -303,10 +328,13 @@ begin
         i2c_lock_1       <= '0';
         i2c_lock_2       <= '0';
         i2c_lock_3       <= '0';
+        i2c_lock_4       <= '0';
         i2c_command      <= (others => '0');
       else
         i2c_command      <= (others => '0');
-        locks := i2c_lock_3 & i2c_lock_2 & i2c_lock_1 & i2c_lock_0;
+        locks            := i2c_lock_4 & i2c_lock_3 &
+                            i2c_lock_2 & i2c_lock_1 &
+                            i2c_lock_0;
         
         -- Clear Locks
         if (i2c_lock_0_clear = '1') then
@@ -321,28 +349,36 @@ begin
         if (i2c_lock_3_clear = '1') then
           i2c_lock_3          <= '0';
         end if;
+        if (i2c_lock_4_clear = '1') then
+          i2c_lock_4          <= '0';
+        end if;
 
         if (i2c_command_busy_o = '0') then
-          if (nx_i2c_command(31)  = '1'      and
-              ((locks and "1110") = "0000")  and
-              i2c_lock_0_clear    = '0') then
+          if (nx_i2c_command(31)   = '1'      and
+              ((locks and "11110") = "00000") and
+              i2c_lock_0_clear     = '0') then
             i2c_command       <= nx_i2c_command;
             i2c_lock_0        <= '1';
-          elsif (dac_write_i2c_command(31) = '1'     and
-                 ((locks and "1011")       = "0000") and
+          elsif (dac_write_i2c_command(31) = '1'      and
+                 ((locks and "11011")      = "00000") and
                  i2c_lock_2_clear          = '0') then
             i2c_command       <= dac_write_i2c_command;
             i2c_lock_2        <= '1';
           elsif (dac_read_i2c_command(31) = '1'      and
-                 ((locks and "1101")      = "0000")  and
+                 ((locks and "11101")     = "00000") and
                  i2c_lock_1_clear         = '0') then
             i2c_command       <= dac_read_i2c_command;
             i2c_lock_1        <= '1';
-          elsif (i2c_online_command(31) = '1'     and
-                 ((locks and "0111")    = "0000") and
+          elsif (i2c_online_command(31) = '1'      and
+                 ((locks and "10111")   = "00000") and
                  i2c_lock_3_clear       = '0') then
             i2c_command       <= i2c_online_command;
             i2c_lock_3        <= '1';
+          elsif (adc_i2c_command(31)  = '1'      and
+                 ((locks and "01111") = "00000") and
+                 i2c_lock_4_clear     = '0') then
+            i2c_command       <= adc_i2c_command;
+            i2c_lock_4        <= '1';
           end if;
         end if;
       end if;
@@ -466,6 +502,25 @@ begin
     end if;
   end process PROC_DAC_TOKEN_HANDLER;
 
+
+  PROC_ADC_TOKEN_HANDLER: process(CLK_IN)
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        adc_read_token      <= (others => '0');
+      else
+        -- Read Token
+        if (i2c_update_memory = '1') then
+          adc_read_token    <= (others => '1');
+        elsif (unsigned(adc_read_token_r) /= 0) then
+          adc_read_token    <= (adc_read_token or adc_read_token_r);
+        elsif (unsigned(adc_read_token_clear) /= 0) then
+          adc_read_token    <= adc_read_token and (not adc_read_token_clear); 
+        end if;
+      end if;
+    end if;
+  end process PROC_ADC_TOKEN_HANDLER;
+    
   -----------------------------------------------------------------------------
   
   PROC_I2C_REGISTERS_HANDLER: process(CLK_IN)
@@ -683,10 +738,10 @@ begin
             w_fifo_ctr                            <= (others => '0');
 
           when DW_REGISTER =>
-            dac_write_i2c_command(31 downto 16) <= x"c108";
-            dac_write_i2c_command(15 downto 8)  <= x"2a";  -- DAC Reg 42
-            dac_write_i2c_command(7 downto 0)   <= (others => '0');
-            dac_write_token_clear(index)        <= '1';
+            dac_write_i2c_command(31 downto 16)   <= x"c108";
+            dac_write_i2c_command(15 downto 8)    <= x"2a";  -- DAC Reg 42
+            dac_write_i2c_command(7 downto 0)     <= (others => '0');
+            dac_write_token_clear(index)          <= '1';
             if (i2c_lock_2 = '0') then
               DW_STATE                            <= DW_REGISTER;
             else
@@ -706,7 +761,7 @@ begin
                                                   
           when DW_NEXT_REGISTER =>                
             if (w_fifo_ctr < x"80") then          
-              w_fifo_ctr                            <= w_fifo_ctr + 1;
+              w_fifo_ctr                          <= w_fifo_ctr + 1;
               next_token_dac_w                    <= '1';
               DW_STATE                            <= DW_REGISTER;
             else                                  
@@ -727,7 +782,82 @@ begin
   end process PROC_WRITE_DAC_REGISTERS;
 
   -----------------------------------------------------------------------------
+
+  PROC_ADC_REGISTERS_HANDLER: process(CLK_IN)
+    variable index  : integer := 0;
+  begin
+    if( rising_edge(CLK_IN) ) then
+      if( RESET_IN = '1' ) then
+        adc_i2c_command          <= (others => '0');
+        adc_token_ctr            <= (others => '0');
+        next_token_adc           <= '0';
+        adc_read_token_clear     <= (others => '0');
+        i2c_lock_4_clear         <= '0';
+        ADC_STATE                <= ADC_IDLE_TOKEN;
+      else
+        index                    := to_integer(unsigned(adc_token_ctr));
+        adc_i2c_command          <= (others => '0');
+        next_token_adc           <= '0';
+        adc_read_token_clear     <= (others => '0');
+        i2c_lock_4_clear         <= '0';
+
+        case ADC_STATE is
+          
+          when ADC_IDLE_TOKEN =>
+            if (adc_read_token(index) = '1') then
+              ADC_STATE                          <= ADC_READ_I2C_REGISTER;
+            else
+              ADC_STATE                          <= ADC_NEXT_TOKEN;
+            end if;
+            
+            -- Read I2C Register
+          when ADC_READ_I2C_REGISTER =>
+            adc_i2c_command(31 downto 16)        <= x"c229";
+            adc_i2c_command(15 downto 14)        <= (others => '0');
+            case adc_token_ctr is
+              when "00" => adc_i2c_command(15 downto  12) <= "0000";
+              when "01" => adc_i2c_command(15 downto  12) <= "0001";
+              when "10" => adc_i2c_command(15 downto  12) <= "0010";
+              when "11" => adc_i2c_command(15 downto  12) <= "0100";
+            end case;
+            adc_i2c_command(11 downto  8)        <= "0000";
+            adc_i2c_command( 7 downto  0)        <= (others => '0');
+            if (i2c_lock_4 = '0') then
+              ADC_STATE                          <= ADC_READ_I2C_REGISTER;
+            else
+              adc_read_token_clear(index)        <= '1';
+              ADC_STATE                          <= ADC_WAIT_I2C_READ_DONE;
+            end if;
+
+          when ADC_WAIT_I2C_READ_DONE =>
+            if (i2c_command_done = '0') then
+              ADC_STATE                          <= ADC_WAIT_I2C_READ_DONE;
+            else
+              ADC_STATE                          <= ADC_READ_I2C_STORE_MEM;
+            end if;
+
+          when ADC_READ_I2C_STORE_MEM =>
+            adc_ram(index)                       <= i2c_data(15 downto 0);
+            i2c_lock_4_clear                     <= '1';
+            ADC_STATE                            <= ADC_NEXT_TOKEN;
+            
+            -- Next Token
+          when ADC_NEXT_TOKEN =>
+            if (adc_token_ctr < "11") then
+              adc_token_ctr                      <= adc_token_ctr + 1;
+            else
+              adc_token_ctr                      <= (others => '0');
+            end if;
+            next_token_adc                       <= '1';
+            ADC_STATE                            <= ADC_IDLE_TOKEN;
+            
+        end case;
+      end if;
+    end if;
+  end process PROC_ADC_REGISTERS_HANDLER;
   
+  -----------------------------------------------------------------------------
+    
   nx_timer_1: nx_timer
     generic map (
       CTR_WIDTH => 32
@@ -889,6 +1019,7 @@ begin
         dac_ram_index_0        <= 0;
         dac_ram_write_0        <= '0';
         dac_read_token_r       <= (others => '0');
+        adc_read_token_r       <= (others => '0');
         i2c_update_memory_r    <= '0';                
         nxyter_clock           <= (others => '0');
         nxyter_polarity        <= (others => '0');
@@ -909,6 +1040,9 @@ begin
         dac_ram_index_0        <= 0;
         dac_ram_write_0        <= '0';
         dac_read_token_r       <= (others => '0');
+
+        adc_read_token_r       <= (others => '0');
+        
         i2c_update_memory_r    <= '0';
         nxyter_clock           <= (others => '0');
         nxyter_polarity        <= (others => '0');
@@ -917,7 +1051,7 @@ begin
         nxyter_testchannels    <= (others => '0');
         
         if (SLV_WRITE_IN  = '1') then
-          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then
+          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then
             index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0)));
             if (i2c_disable_memory = '0') then
               ram_index_0                <= index;
@@ -926,7 +1060,7 @@ begin
             end if;
             slv_ack_o                    <= '1';
                       
-          elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN < x"0181") then
+          elsif (SLV_ADDR_IN >= x"0100" and SLV_ADDR_IN <= x"0180") then
             -- Write value to ram
             index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0)));
             if (i2c_disable_memory = '0') then
@@ -1004,7 +1138,7 @@ begin
           end if;
 
         elsif (SLV_READ_IN = '1') then
-          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN < x"002e") then
+          if (SLV_ADDR_IN >= x"0000" and SLV_ADDR_IN <= x"002d") then
             index := to_integer(unsigned(SLV_ADDR_IN(5 downto 0)));
             if (i2c_disable_memory = '0') then
               slv_data_out_o(7 downto 0)      <= i2c_ram(index);
@@ -1022,7 +1156,7 @@ begin
             index := to_integer(unsigned(SLV_ADDR_IN(7 downto 0)));
             if (i2c_disable_memory = '0') then
               slv_data_out_o(5 downto 0)      <= dac_ram(index);
-              slv_data_out_o(31 downto 6)     <= (others => '0');
+              slv_data_out_o(29 downto 6)     <= (others => '0');
               slv_data_out_o(30)              <= dac_read_token(index);
               slv_data_out_o(31)              <= dac_write_token(index);
             else
@@ -1030,6 +1164,18 @@ begin
             end if;  
             slv_ack_o                         <= '1';
 
+          elsif (SLV_ADDR_IN >= x"0080" and SLV_ADDR_IN <= x"0083") then
+            index := to_integer(unsigned(SLV_ADDR_IN(1 downto 0)));
+            if (i2c_disable_memory = '0') then
+              slv_data_out_o(15 downto 0)     <= adc_ram(index);
+              slv_data_out_o(30 downto 16)    <= (others => '0');
+              slv_data_out_o(31)              <= adc_read_token(index);
+              adc_read_token_r(index)         <= '1'; 
+            else
+              slv_data_out_o(31 downto 0)     <= (others => '1');
+            end if;  
+            slv_ack_o                         <= '1';
+            
           else
             case SLV_ADDR_IN is
               when x"0050" =>
index 50cfbb4edc813e36fbbcaf9f0e7621ecb9db2fdb..da864ba316173f41c73a041c1457c3be50d34a2c 100644 (file)
@@ -352,36 +352,56 @@ begin
             end if;
             
             if (store_data = '1') then
+
               case readout_mode(1 downto 0) is              
                 when "00" =>
-                  -- RefValue + TS window filter + ovfl valid + parity valid
+                  -- RefValue + TS window filter + parity valid
+                  if (TIMESTAMP_STATUS_IN(2) = '0') then
+                    d_data_o(10 downto  0)     <= deltaTStore(10 downto  0);
+                    d_data_o(22 downto 11)     <= ADC_DATA_IN;
+                    d_data_o(29 downto 23)     <= CHANNEL_IN;
+                    d_data_o(31 downto 30)     <=
+                      TIMESTAMP_STATUS_IN(1 downto 0);
+                    d_data_clk_o               <= '1';
+                  end if;
+
+                when "01" =>
+                  -- RefValue + TS window filter + pileup and Overflow valid
+                  -- parity valid
                   if (TIMESTAMP_STATUS_IN(2) = '0' and
                       TIMESTAMP_STATUS_IN(0) = '0') then 
-                    d_data_o(11 downto  0)     <= deltaTStore(11 downto  0);
-                    d_data_o(23 downto 12)     <= ADC_DATA_IN;
-                    d_data_o(30 downto 24)     <= CHANNEL_IN;
-                    d_data_o(31)               <= TIMESTAMP_STATUS_IN(1);
+                    d_data_o(10 downto  0)     <= deltaTStore(10 downto  0);
+                    d_data_o(22 downto 11)     <= ADC_DATA_IN;
+                    d_data_o(29 downto 23)     <= CHANNEL_IN;
+                    d_data_o(31 downto 30)     <=
+                      TIMESTAMP_STATUS_IN(1 downto 0);
                     d_data_clk_o               <= '1';
                   end if;
 
-                when "01" =>
-                  -- RefValue + TS window filter + ovfl and pileup valid
-                  -- + parity valid
-                  if (TIMESTAMP_STATUS_IN = "000") then 
-                    d_data_o(11 downto  0)     <= deltaTStore(11 downto  0);
-                    d_data_o(23 downto 12)     <= ADC_DATA_IN;
-                    d_data_o(30 downto 24)     <= CHANNEL_IN;
-                    d_data_o(31)               <= TIMESTAMP_STATUS_IN(1);
+                when "10" =>
+                  -- RefValue + TS window filter + pileup, Overflow and pileup
+                  -- valid
+                  -- parity valid
+                  if (TIMESTAMP_STATUS_IN(2) = '0' and
+                      TIMESTAMP_STATUS_IN(1) = '0' and 
+                      TIMESTAMP_STATUS_IN(0) = '0') then 
+                    d_data_o(10 downto  0)     <= deltaTStore(10 downto  0);
+                    d_data_o(22 downto 11)     <= ADC_DATA_IN;
+                    d_data_o(29 downto 23)     <= CHANNEL_IN;
+                    d_data_o(31 downto 30)     <=
+                      TIMESTAMP_STATUS_IN(1 downto 0);
                     d_data_clk_o               <= '1';
                   end if;
-                    
+                  
                 when others =>
+                  d_data_o(10 downto  0)     <= deltaTStore(10 downto  0);
+                  d_data_o(22 downto 11)     <= ADC_DATA_IN;
+                  d_data_o(29 downto 23)     <= CHANNEL_IN;
+                  d_data_o(31 downto 30)     <=
+                    TIMESTAMP_STATUS_IN(1 downto 0);
+                  d_data_clk_o               <= '1';
                   -- RefValue + ignore status
-                  d_data_o(11 downto  0)       <= deltaTStore(11 downto  0);
-                  d_data_o(23 downto 12)       <= ADC_DATA_IN;
-                  d_data_o(30 downto 24)       <= CHANNEL_IN;
-                  d_data_o(31)                 <= TIMESTAMP_STATUS_IN(1);
-                  d_data_clk_o                 <= '1';
+                  
               end case;
             end if;
 
index 07d260c7da08ef40d75cd84952cc5e9e09055698..b72180af4d10465b1484b0d02c9c818dd2e7ba3b 100644 (file)
@@ -19,7 +19,8 @@
 0x810c :  r    All ERROR Flags (8 Bit)
 
 -- NX I2C Setup Handler
-0x8200 : r/w   I2C Memeory Register (Depth: 0 - 45 ... 0x822c) 
+0x8200 : r/w   I2C Memory Register (Depth: 0 - 45 ... 0x822c) 
+0x8280 : r     ADC Memory Register (Depth: 0 - 3  ... 0x8283) 
 0x8300 : r/w   DAC Register Memory (Depth: 0 - 128 ... 0x82e0) 
 0x8250 : r/w   Enable Nxyter Clock 
 0x8251 : r/w   Nxyter Polarity
 0x8060 :       Access to SPI Interface
 
 -- Histogram Handler
-0x8800 :  r/w  r: Read Channel Statistic (128 channel in a row)
-               w: reset all Histograms
-0x8880 :  r    Read Channel Trigger Rate (128 channel in a row, 1/s)
-0x8900 :  r    Read Channel ADC Value    (128 channel in a row)
+0x8800 :  r/w  r: Read Channel HIt Statistic (128 channel in a row)
+0x8900 :  r    Read Channel Trigger Rate (128 channel in a row, 1/s)
+0x8a00 :  r    Read Channel averaged ADC Value (128 channel in a row)
+0x8b00 :  r    Read Channel PileUp Rate (128 channel in a row, 1/s)
+
+0x8880 :  r/w  Hit Rate num averages (3 Bit)
+0x8881 :  r/w  Hit Rate average enable 
+0x8980 :  r/w  ADC num averages (3 Bit)
+0x8981 :  r/w  ADC average enable 
+0x8a80 :  r/w  PileUp Rate num averages (3 Bit)
+0x8a81 :  r/w  PileUp Rate average enable 
+0x8b80 :  r/w  Overflow Rate num averages (3 Bit)
+0x8b81 :  r/w  Overflow Rate average enable 
 
 -- Debug Multiplexer
 0x8020 :  r/w   Select Debug Entity