Index: firmware/FTU/rs485/FTU_rs485_control.vhd
===================================================================
--- firmware/FTU/rs485/FTU_rs485_control.vhd	(revision 10047)
+++ firmware/FTU/rs485/FTU_rs485_control.vhd	(revision 10050)
@@ -89,4 +89,28 @@
 
   signal txcnt : integer range 0 to (RS485_BLOCK_WIDTH / 8) := 0;  -- count 28 1-byte frames 
+
+  signal reset_crc_sig     : std_logic := '0';
+  signal crc_enable_sig    : std_logic := '0';
+  signal crc_input_sig     : std_logic_vector(RS485_BLOCK_WIDTH - 9 downto 0) := (others => '0');
+  signal crc_sig           : std_logic_vector(CRC_POLYNOMIAL'length - 1 downto 0) := (others => '0');
+  signal crc_sig_inv       : std_logic_vector(CRC_POLYNOMIAL'length - 1 downto 0) := (others => '0');
+  signal crc_error_cnt_sig : integer range 0 to 255 := 0;
+
+  component ucrc_par
+    generic(
+      POLYNOMIAL : std_logic_vector;
+      INIT_VALUE : std_logic_vector;
+      DATA_WIDTH : integer range 2 to 256;
+      SYNC_RESET : integer range 0 to 1
+    );
+    port(
+      clk_i   : in  std_logic;
+      rst_i   : in  std_logic;
+      clken_i : in  std_logic;
+      data_i  : in  std_logic_vector(DATA_WIDTH - 1 downto 0);
+      match_o : out std_logic;
+      crc_o   : out std_logic_vector(POLYNOMIAL'length - 1 downto 0)
+    );
+  end component;
   
   component FTU_rs485_receiver
@@ -107,4 +131,5 @@
       block_valid            : IN  std_logic;
       brd_add                : IN  std_logic_vector(5 downto 0);
+      crc_error_cnt          : OUT integer range 0 to 255;
       int_new_DACs           : OUT std_logic;
       int_new_enables        : OUT std_logic;
@@ -139,7 +164,9 @@
   end component;
 
-  type FTU_rs485_control_StateType is (RECEIVE,
+  type FTU_rs485_control_StateType is (INIT, RECEIVE,
                                        READ_RATES_WAIT, READ_DAC_WAIT, READ_ENABLE_WAIT, READ_PRESCALING_WAIT,
-                                       SET_DAC_WAIT, SET_ENABLE_WAIT, SET_PRESCALING_WAIT, PING_PONG_WAIT,
+                                       READ_RATES_WAIT_2, READ_DAC_WAIT_2, READ_ENABLE_WAIT_2, READ_PRESCALING_WAIT_2,
+                                       SET_DAC_WAIT, SET_ENABLE_WAIT, SET_PRESCALING_WAIT, PING_PONG_WAIT,                                       
+                                       SET_DAC_WAIT_2, SET_ENABLE_WAIT_2, SET_PRESCALING_WAIT_2, PING_PONG_WAIT_2,
                                        READ_RATES_TRANSMIT, READ_DAC_TRANSMIT, READ_ENABLE_TRANSMIT, READ_PRESCALING_TRANSMIT,
                                        SET_DAC_TRANSMIT, SET_ENABLE_TRANSMIT, SET_PRESCALING_TRANSMIT, PING_PONG_TRANSMIT);
@@ -147,4 +174,22 @@
   
 begin
+
+  crc_sig <= crc_sig_inv(0) & crc_sig_inv(1) & crc_sig_inv(2) & crc_sig_inv(3) & crc_sig_inv(4) & crc_sig_inv(5) & crc_sig_inv(6) & crc_sig_inv(7);
+  
+  Inst_ucrc_par : ucrc_par
+    generic map(
+      POLYNOMIAL => CRC_POLYNOMIAL,
+      INIT_VALUE => CRC_INIT_VALUE,
+      DATA_WIDTH => 216,
+      SYNC_RESET => 1
+    )
+    port map(
+      clk_i   => main_clk,
+      rst_i   => reset_crc_sig,
+      clken_i => crc_enable_sig,
+      data_i  => crc_input_sig,
+      match_o => open,
+      crc_o   => crc_sig_inv
+    );
   
   Inst_FTU_rs485_receiver : FTU_rs485_receiver
@@ -164,4 +209,5 @@
       block_valid            => block_valid_sig,
       brd_add                => brd_add,
+      crc_error_cnt          => crc_error_cnt_sig,
       int_new_DACs           => int_new_DACs_sig,
       int_new_enables        => int_new_enables_sig,
@@ -200,6 +246,12 @@
     if Rising_edge(main_clk) then
       case FTU_rs485_control_State is
+
+        when INIT =>
+          reset_crc_sig <= '1';
+          FTU_rs485_control_State <= RECEIVE;
         
-        when RECEIVE =>  -- default state, receiver on, no transmission          
+        when RECEIVE =>  -- default state, receiver on, no transmission
+          reset_crc_sig <= '0';
+          crc_enable_sig <= '0';
           tx_start_sig <= '0';
           if (int_new_DACs_sig = '1') then
@@ -304,5 +356,16 @@
           if (DACs_ready = '1') then
             new_DACs <= '0';
-            FTU_rs485_control_State <= SET_DAC_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000"
+                             & conv_std_logic_vector(dac_array_rs485_in(7),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(7),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(3),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(3),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(2),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(2),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(1),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(1),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(0),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(0),16)(7 downto 0) & "00000000"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= SET_DAC_WAIT_2;
           else
             new_DACs <= '1';
@@ -310,8 +373,22 @@
           end if;
 
+        when SET_DAC_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= SET_DAC_TRANSMIT;
+          
         when SET_ENABLE_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (enables_ready = '1') then
             new_enables <= '0';
-            FTU_rs485_control_State <= SET_ENABLE_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" 
+                             & enable_array_rs485_in(3)(15 downto 8) & enable_array_rs485_in(3)(7 downto 0)
+                             & enable_array_rs485_in(2)(15 downto 8) & enable_array_rs485_in(2)(7 downto 0)
+                             & enable_array_rs485_in(1)(15 downto 8) & enable_array_rs485_in(1)(7 downto 0)
+                             & enable_array_rs485_in(0)(15 downto 8) & enable_array_rs485_in(0)(7 downto 0) & "00000011"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= SET_ENABLE_WAIT_2;
           else
             new_enables <= '1';
@@ -319,8 +396,20 @@
           end if;
 
+        when SET_ENABLE_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= SET_ENABLE_TRANSMIT;
+          
         when SET_PRESCALING_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (prescaling_ready = '1') then
             new_prescaling <= '0';
-            FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" 
+                             & overflow_array_rs485_in & prescaling_rs485_in & "00000110"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= SET_PRESCALING_WAIT_2;
           else
             new_prescaling <= '1';
@@ -328,8 +417,26 @@
           end if;
 
+        when SET_PRESCALING_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT;
+          
         when READ_RATES_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (rates_ready = '1') then
             read_rates <= '0';
-            FTU_rs485_control_State <= READ_RATES_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & overflow_array_rs485_in
+                             & conv_std_logic_vector(rate_array_rs485(4),32)(31 downto 24) & conv_std_logic_vector(rate_array_rs485(4),32)(23 downto 16) 
+                             & conv_std_logic_vector(rate_array_rs485(4),32)(15 downto 8) & conv_std_logic_vector(rate_array_rs485(4),32)(7 downto 0)
+                             & conv_std_logic_vector(rate_array_rs485(3),32)(31 downto 24) & conv_std_logic_vector(rate_array_rs485(3),32)(23 downto 16) 
+                             & conv_std_logic_vector(rate_array_rs485(3),32)(15 downto 8) & conv_std_logic_vector(rate_array_rs485(3),32)(7 downto 0)
+                             & conv_std_logic_vector(rate_array_rs485(2),32)(31 downto 24) & conv_std_logic_vector(rate_array_rs485(2),32)(23 downto 16) 
+                             & conv_std_logic_vector(rate_array_rs485(2),32)(15 downto 8) & conv_std_logic_vector(rate_array_rs485(2),32)(7 downto 0)
+                             & conv_std_logic_vector(rate_array_rs485(1),32)(31 downto 24) & conv_std_logic_vector(rate_array_rs485(1),32)(23 downto 16) 
+                             & conv_std_logic_vector(rate_array_rs485(1),32)(15 downto 8) & conv_std_logic_vector(rate_array_rs485(1),32)(7 downto 0)
+                             & conv_std_logic_vector(rate_array_rs485(0),32)(31 downto 24) & conv_std_logic_vector(rate_array_rs485(0),32)(23 downto 16) 
+                             & conv_std_logic_vector(rate_array_rs485(0),32)(15 downto 8) & conv_std_logic_vector(rate_array_rs485(0),32)(7 downto 0) & "00000010"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= READ_RATES_WAIT_2;
           else
             read_rates <= '1';
@@ -337,8 +444,23 @@
           end if;
 
+        when READ_RATES_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= READ_RATES_TRANSMIT;
+          
         when READ_DAC_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (DACs_ready = '1') then
             read_DACs <= '0';
-            FTU_rs485_control_State <= READ_DAC_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000"
+                             & conv_std_logic_vector(dac_array_rs485_in(7),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(7),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(3),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(3),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(2),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(2),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(1),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(1),16)(7 downto 0)
+                             & conv_std_logic_vector(dac_array_rs485_in(0),16)(15 downto 8) & conv_std_logic_vector(dac_array_rs485_in(0),16)(7 downto 0) & "00000001"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= READ_DAC_WAIT_2;
           else
             read_DACs <= '1';
@@ -346,8 +468,22 @@
           end if;
 
+        when READ_DAC_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= READ_DAC_TRANSMIT;
+          
         when READ_ENABLE_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (enables_ready = '1') then
             read_enables <= '0';
-            FTU_rs485_control_State <= READ_ENABLE_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" 
+                             & enable_array_rs485_in(3)(15 downto 8) & enable_array_rs485_in(3)(7 downto 0)
+                             & enable_array_rs485_in(2)(15 downto 8) & enable_array_rs485_in(2)(7 downto 0)
+                             & enable_array_rs485_in(1)(15 downto 8) & enable_array_rs485_in(1)(7 downto 0)
+                             & enable_array_rs485_in(0)(15 downto 8) & enable_array_rs485_in(0)(7 downto 0) & "00000100"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= READ_ENABLE_WAIT_2;
           else
             read_enables <= '1';
@@ -355,8 +491,20 @@
           end if;
 
+        when READ_ENABLE_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= READ_ENABLE_TRANSMIT;
+          
         when READ_PRESCALING_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (prescaling_ready = '1') then
             read_prescaling <= '0';
-            FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" 
+                             & overflow_array_rs485_in & prescaling_rs485_in & "00000111"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= READ_PRESCALING_WAIT_2;
           else
             read_prescaling <= '1';
@@ -364,12 +512,27 @@
           end if;
 
+        when READ_PRESCALING_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT;
+          
         when PING_PONG_WAIT =>  -- wait until FTU control says "done" and then answer to FTM
           if (ping_pong_ready = '1') then
             ping_pong <= '0';
-            FTU_rs485_control_State <= PING_PONG_TRANSMIT;
+            crc_enable_sig <= '1';
+            crc_input_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8)
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" & "00000000" & "00000000"
+                             & "00000000" & "00000000" & "00000000" 
+                             & dna(63 downto 0) & "00000101"
+                             & FIRMWARE_ID & "00" & brd_add & FTM_ADDRESS & RS485_START_DELIM;
+            FTU_rs485_control_State <= PING_PONG_WAIT_2;
           else
             ping_pong <= '1';
             FTU_rs485_control_State <= PING_PONG_WAIT;
           end if;
+
+        when PING_PONG_WAIT_2 =>
+          crc_enable_sig <= '0';
+          FTU_rs485_control_State <= PING_PONG_TRANSMIT;
           
         when SET_DAC_TRANSMIT =>
@@ -457,14 +620,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
-              tx_start_sig <= '1';
-              FTU_rs485_control_State <= READ_RATES_TRANSMIT;
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
+              tx_start_sig <= '1';
+              FTU_rs485_control_State <= SET_DAC_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= SET_DAC_TRANSMIT;              
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;
@@ -548,14 +712,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= SET_ENABLE_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= SET_ENABLE_TRANSMIT;        
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;
@@ -604,14 +769,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT;
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if; 
@@ -755,14 +921,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_RATES_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_RATES_TRANSMIT;
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;  
@@ -856,14 +1023,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_DAC_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_DAC_TRANSMIT;              
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;  
@@ -947,14 +1115,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_ENABLE_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_ENABLE_TRANSMIT;    
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;  
@@ -1008,14 +1177,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT;
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;  
@@ -1026,4 +1196,5 @@
 
         when PING_PONG_TRANSMIT =>
+          crc_enable_sig <= '0';
           if tx_busy_sig = '0' then
             if txcnt = 0 then           -- start delimiter
@@ -1099,14 +1270,15 @@
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then        -- CRC error counter
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= conv_std_logic_vector(crc_error_cnt_sig, 8);
               tx_start_sig <= '1';
               FTU_rs485_control_State <= PING_PONG_TRANSMIT;
             elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 1) then        -- check sum
               txcnt <= txcnt + 1;
-              tx_data_sig <= "00000000";  -- NOT YET IMPLEMENTED!!!
+              tx_data_sig <= crc_sig;
               tx_start_sig <= '1';
               FTU_rs485_control_State <= PING_PONG_TRANSMIT;
             else                        -- transmission finished
               txcnt <= 0;
+              reset_crc_sig <= '1';
               FTU_rs485_control_State <= RECEIVE;
             end if;  
Index: firmware/FTU/rs485/FTU_rs485_interpreter.vhd
===================================================================
--- firmware/FTU/rs485/FTU_rs485_interpreter.vhd	(revision 10047)
+++ firmware/FTU/rs485/FTU_rs485_interpreter.vhd	(revision 10050)
@@ -39,4 +39,5 @@
     block_valid            : IN  std_logic;
     brd_add                : IN  std_logic_vector(5 downto 0);
+    crc_error_cnt          : OUT integer range 0 to 255 := 0;
     int_new_DACs           : OUT std_logic := '0';
     int_new_enables        : OUT std_logic := '0';
@@ -56,4 +57,9 @@
 
   signal block_valid_sr : std_logic_vector(3 downto 0) := (others => '0');
+  signal reset_crc_sig  : std_logic := '0';
+  signal crc_enable_sig : std_logic := '0';
+  signal crc_match_sig  : std_logic := '0';
+  signal data_block_sig : std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0) := (others => '0');
+  signal crc_error_cntr : integer range 0 to 255 := 0;
 
   signal dac_array_rs485_out_sig    : dac_array_type    := DEFAULT_DAC;
@@ -61,15 +67,52 @@
   signal prescaling_rs485_out_sig   : STD_LOGIC_VECTOR(7 downto 0) := conv_std_logic_vector(DEFAULT_PRESCALING,8);
   
-  type FTU_rs485_interpreter_StateType is (WAIT_FOR_DATA, CHECK_HEADER, DECODE);
+  type FTU_rs485_interpreter_StateType is (INIT, WAIT_FOR_DATA, WAIT_CRC, CHECK_CRC, CHECK_HEADER, DECODE);
   signal FTU_rs485_interpreter_State : FTU_rs485_interpreter_StateType;
+
+  component ucrc_par
+    generic(
+      POLYNOMIAL : std_logic_vector;
+      INIT_VALUE : std_logic_vector;
+      DATA_WIDTH : integer range 2 to 256;
+      SYNC_RESET : integer range 0 to 1
+    );
+    port(
+      clk_i   : in  std_logic;
+      rst_i   : in  std_logic;
+      clken_i : in  std_logic;
+      data_i  : in  std_logic_vector(DATA_WIDTH - 1 downto 0);
+      match_o : out std_logic;
+      crc_o   : out std_logic_vector(POLYNOMIAL'length - 1 downto 0)
+    );
+  end component;
   
 begin
 
+  Inst_ucrc_par : ucrc_par
+    generic map(
+      POLYNOMIAL => CRC_POLYNOMIAL,
+      INIT_VALUE => CRC_INIT_VALUE,
+      DATA_WIDTH => 224,
+      SYNC_RESET => 1
+    )
+    port map(
+      clk_i   => clk,
+      rst_i   => reset_crc_sig,
+      clken_i => crc_enable_sig,
+      data_i  => data_block_sig,
+      match_o => crc_match_sig,
+      crc_o   => open
+    );
+  
   FTU_rs485_interpreter_FSM: process (clk)
   begin
     if Rising_edge(clk) then
       case FTU_rs485_interpreter_State is
+
+        when INIT =>
+          reset_crc_sig <= '1';
+          FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
         
-        when WAIT_FOR_DATA => -- default state, waiting for valid 16-byte block 
+        when WAIT_FOR_DATA => -- default state, waiting for valid 28-byte block 
           block_valid_sr <= block_valid_sr(2 downto 0) & block_valid;
           int_new_DACs        <= '0';
@@ -82,9 +125,30 @@
           int_ping_pong       <= '0';
           if (block_valid_sr(3 downto 2) = "01") then  -- rising edge of valid signal
+            crc_enable_sig <= '1';
+            data_block_sig <= data_block;
+            FTU_rs485_interpreter_State <= WAIT_CRC;
+          else
+            crc_enable_sig <= '0';
+            FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
+          end if;
+          reset_crc_sig <= '0';
+
+        when WAIT_CRC =>
+          crc_enable_sig <= '0';
+          FTU_rs485_interpreter_State <= CHECK_CRC;
+          
+        when CHECK_CRC =>
+          reset_crc_sig  <= '1';
+          if (crc_match_sig = '1') then
             FTU_rs485_interpreter_State <= CHECK_HEADER;
+            crc_error_cnt <= crc_error_cntr;
+            crc_error_cntr <= 0;
           else
-            FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
-          end if;
-
+            if crc_error_cntr < 255 then
+              crc_error_cntr <= crc_error_cntr + 1;
+            end if;
+            FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
+          end if;
+          
         when CHECK_HEADER => -- check start delimiter and addresses
           int_new_DACs        <= '0';
@@ -103,5 +167,6 @@
             FTU_rs485_interpreter_State <= WAIT_FOR_DATA;
           end if;
-
+          reset_crc_sig <= '0';
+          
         when DECODE => -- decode instruction
           if(data_block(39 downto 32) = "00000000") then -- set DACs
Index: firmware/FTU/rs485/ucrc_par.vhd
===================================================================
--- firmware/FTU/rs485/ucrc_par.vhd	(revision 10050)
+++ firmware/FTU/rs485/ucrc_par.vhd	(revision 10050)
@@ -0,0 +1,176 @@
+----------------------------------------------------------------------
+----                                                              ----
+---- Ultimate CRC.                                                ----
+----                                                              ----
+---- This file is part of the ultimate CRC projectt               ----
+---- http://www.opencores.org/cores/ultimate_crc/                 ----
+----                                                              ----
+---- Description                                                  ----
+---- CRC generator/checker, parallel implementation.              ----
+----                                                              ----
+----                                                              ----
+---- To Do:                                                       ----
+---- -                                                            ----
+----                                                              ----
+---- Author(s):                                                   ----
+---- - Geir Drange, gedra@opencores.org                           ----
+----                                                              ----
+----------------------------------------------------------------------
+----                                                              ----
+---- Copyright (C) 2005 Authors and OPENCORES.ORG                 ----
+----                                                              ----
+---- This source file may be used and distributed without         ----
+---- restriction provided that this copyright statement is not    ----
+---- removed from the file and that any derivative work contains  ----
+---- the original copyright notice and the associated disclaimer. ----
+----                                                              ----
+---- This source file is free software; you can redistribute it   ----
+---- and/or modify it under the terms of the GNU General          ----
+---- Public License as published by the Free Software Foundation; ----
+---- either version 2.0 of the License, or (at your option) any   ----
+---- later version.                                               ----
+----                                                              ----
+---- This source is distributed in the hope that it will be       ----
+---- useful, but WITHOUT ANY WARRANTY; without even the implied   ----
+---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ----
+---- PURPOSE. See the GNU General Public License for more details.----
+----                                                              ----
+---- You should have received a copy of the GNU General           ----
+---- Public License along with this source; if not, download it   ----
+---- from http://www.gnu.org/licenses/gpl.txt                     ----
+----                                                              ----
+----------------------------------------------------------------------
+--
+-- CVS Revision History
+--
+-- $Log: not supported by cvs2svn $
+-- Revision 1.1  2005/05/09 15:58:38  gedra
+-- Parallel implementation
+--
+--
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity ucrc_par is
+   generic (
+      POLYNOMIAL : std_logic_vector;
+      INIT_VALUE : std_logic_vector;
+      DATA_WIDTH : integer range 2 to 256;
+      SYNC_RESET : integer range 0 to 1);  -- use sync./async reset
+   port (
+      clk_i   : in  std_logic;          -- clock
+      rst_i   : in  std_logic;          -- init CRC
+      clken_i : in  std_logic;          -- clock enable
+      data_i  : in  std_logic_vector(DATA_WIDTH - 1 downto 0);  -- data input
+      match_o : out std_logic;          -- CRC match flag
+      crc_o   : out std_logic_vector(POLYNOMIAL'length - 1 downto 0));  -- CRC output
+end ucrc_par;
+
+architecture rtl of ucrc_par is
+
+   constant msb      : integer                        := POLYNOMIAL'length - 1;
+   constant init_msb : integer                        := INIT_VALUE'length - 1;
+   constant p        : std_logic_vector(msb downto 0) := POLYNOMIAL;
+   constant dw       : integer                        := DATA_WIDTH;
+   constant pw       : integer                        := POLYNOMIAL'length;
+   type fb_array is array (dw downto 1) of std_logic_vector(msb downto 0);
+   type dmsb_array is array (dw downto 1) of std_logic_vector(msb downto 1);
+   signal crca       : fb_array;
+   signal da, ma     : dmsb_array;
+   signal crc, zero  : std_logic_vector(msb downto 0);
+   signal arst, srst : std_logic;
+   
+begin
+
+-- Parameter checking: Invalid generics will abort simulation/synthesis
+   PCHK1 : if msb /= init_msb generate
+      process
+      begin
+         report "POLYNOMIAL and INIT_VALUE vectors must be equal length!"
+            severity failure;
+         wait;
+      end process;
+   end generate PCHK1;
+
+   PCHK2 : if (msb < 3) or (msb > 31) generate
+      process
+      begin
+         report "POLYNOMIAL must be of order 4 to 32!"
+            severity failure;
+         wait;
+      end process;
+   end generate PCHK2;
+
+   PCHK3 : if p(0) /= '1' generate      -- LSB must be 1
+      process
+      begin
+         report "POLYNOMIAL must have lsb set to 1!"
+            severity failure;
+         wait;
+      end process;
+   end generate PCHK3;
+
+-- Generate vector of each data bit
+   CA : for i in 1 to dw generate       -- data bits
+      DAT : for j in 1 to msb generate
+         da(i)(j) <= data_i(i - 1);
+      end generate DAT;
+   end generate CA;
+
+-- Generate vector of each CRC MSB
+   MS0 : for i in 1 to msb generate
+      ma(1)(i) <= crc(msb);
+   end generate MS0;
+   MSP : for i in 2 to dw generate
+      MSU : for j in 1 to msb generate
+         ma(i)(j) <= crca(i - 1)(msb);
+      end generate MSU;
+   end generate MSP;
+
+-- Generate feedback matrix
+   crca(1)(0)            <= da(1)(1) xor crc(msb);
+   crca(1)(msb downto 1) <= crc(msb - 1 downto 0) xor ((da(1) xor ma(1)) and p(msb downto 1));
+   FB : for i in 2 to dw generate
+      crca(i)(0)            <= da(i)(1) xor crca(i - 1)(msb);
+      crca(i)(msb downto 1) <= crca(i - 1)(msb - 1 downto 0) xor
+                               ((da(i) xor ma(i)) and p(msb downto 1));
+   end generate FB;
+
+-- Reset signal
+   SR : if SYNC_RESET = 1 generate
+      srst <= rst_i;
+      arst <= '0';
+   end generate SR;
+   AR : if SYNC_RESET = 0 generate
+      srst <= '0';
+      arst <= rst_i;
+   end generate AR;
+
+-- CRC process
+   crc_o <= crc;
+   zero  <= (others => '0');
+
+   CRCP : process (clk_i, arst)
+   begin
+      if arst = '1' then                -- async. reset
+         crc     <= INIT_VALUE;
+         match_o <= '0';
+      elsif rising_edge(clk_i) then
+         if srst = '1' then             -- sync. reset
+            crc     <= INIT_VALUE;
+            match_o <= '0';
+         elsif clken_i = '1' then
+            crc <= crca(dw);
+            if crca(dw) = zero then
+               match_o <= '1';
+            else
+               match_o <= '0';
+            end if;
+         end if;
+      end if;
+   end process;
+   
+end rtl;
+
