---------------------------------------------------------------------------------- -- Company: ETH Zurich, Institute for Particle Physics -- Engineer: Q. Weitzel, P. Vogler -- -- Create Date: 09/13/2010 -- Design Name: -- Module Name: FTU_rs485_control - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: top level entity of FTU RS485 module -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library ftu_definitions; USE ftu_definitions.ftu_array_types.all; USE ftu_definitions.ftu_constants.all; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity FTU_rs485_control is port( main_clk : IN std_logic; brd_add : IN std_logic_vector(5 downto 0); rx_d : IN std_logic; rates_ready : IN std_logic; -- rate_array_rs485 has now valid rates for sending DACs_ready : IN std_logic; -- dac_array_rs485_in is ok for sending enables_ready : IN std_logic; -- enable_array_rs485_in is ok for sending prescaling_ready : IN std_logic; -- prescaling byte is ok for sending ping_pong_ready : IN std_logic; -- ping pong successful rate_array_rs485 : IN rate_array_type; overflow_array_rs485_in : IN STD_LOGIC_VECTOR(7 downto 0); dac_array_rs485_in : IN dac_array_type; enable_array_rs485_in : IN enable_array_type; prescaling_rs485_in : IN STD_LOGIC_VECTOR(7 downto 0); dna : IN STD_LOGIC_VECTOR(63 downto 0); rx_en : OUT std_logic; tx_d : OUT std_logic; tx_en : OUT std_logic; new_DACs : OUT std_logic := '0'; -- new DACs arrived via RS485 new_enables : OUT std_logic := '0'; -- new enables arrived via RS485 new_prescaling : OUT std_logic := '0'; -- new prescaling arrived via RS485 read_rates : OUT std_logic := '0'; -- FTM wants to read rates read_DACs : OUT std_logic := '0'; -- FTM wants to read DACs read_enables : OUT std_logic := '0'; -- FTM wants to read enable pattern read_prescaling : OUT std_logic := '0'; -- FTM wants to read prescaling value ping_pong : OUT std_logic := '0'; -- ping pong command from FTM dac_array_rs485_out : OUT dac_array_type; enable_array_rs485_out : OUT enable_array_type; prescaling_rs485_out : OUT STD_LOGIC_VECTOR(7 downto 0) ); end FTU_rs485_control; architecture Behavioral of FTU_rs485_control is signal tx_start_sig : std_logic := '0'; signal tx_data_sig : std_logic_vector (7 DOWNTO 0) := (others => '0'); signal tx_busy_sig : std_logic; -- initialized in FTU_rs485_interface signal rx_valid_sig : std_logic; -- initialized in FTU_rs485_interface signal rx_data_sig : std_logic_vector (7 DOWNTO 0); -- initialized in FTU_rs485_interface signal rx_busy_sig : std_logic; -- initialized in FTU_rs485_interface signal block_valid_sig : std_logic; -- initialized in FTU_rs485_receiver signal start_interpreter_sig : std_logic := '0'; signal data_block_sig : std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0); -- initialized in FTU_rs485_receiver signal int_new_DACs_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_new_enables_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_new_prescaling_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_read_rates_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_read_DACs_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_read_enables_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_read_prescaling_sig : std_logic; -- initialized in FTU_rs485_interpreter signal int_ping_pong_sig : std_logic; -- initialized in FTU_rs485_interpreter 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 port( rec_clk : in std_logic; -- rx_busy : in std_logic; rec_din : in std_logic_vector(7 downto 0); rec_den : in std_logic; rec_dout : out std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0); rec_valid : out std_logic ); end component; component FTU_rs485_interpreter port( clk : IN std_logic; data_block : IN std_logic_vector(RS485_BLOCK_WIDTH - 1 downto 0); 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; int_new_prescaling : OUT std_logic; int_read_rates : OUT std_logic; int_read_DACs : OUT std_logic; int_read_enables : OUT std_logic; int_read_prescaling : OUT std_logic; int_ping_pong : OUT std_logic; dac_array_rs485_out : OUT dac_array_type; enable_array_rs485_out : OUT enable_array_type; prescaling_rs485_out : OUT STD_LOGIC_VECTOR(7 downto 0) ); end component; component FTU_rs485_interface port( clk : IN std_logic; -- RS485 rx_d : IN std_logic; rx_en : OUT std_logic; tx_d : OUT std_logic; tx_en : OUT std_logic; -- FPGA rx_data : OUT std_logic_vector (7 DOWNTO 0); rx_busy : OUT std_logic := '0'; rx_valid : OUT std_logic := '0'; tx_data : IN std_logic_vector (7 DOWNTO 0); tx_busy : OUT std_logic := '0'; tx_start : IN std_logic ); end component; type FTU_rs485_control_StateType is (INIT, RECEIVE, READ_RATES_WAIT, READ_DAC_WAIT, READ_ENABLE_WAIT, READ_PRESCALING_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); signal FTU_rs485_control_State : FTU_rs485_control_StateType; 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); start_interpreter_sig <= block_valid_sig and (not rx_busy_sig); -- avoid answering to early to FTM 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 port map( rec_clk => main_clk, -- rx_busy => rx_busy_sig, rec_din => rx_data_sig, rec_den => rx_valid_sig, rec_dout => data_block_sig, rec_valid => block_valid_sig ); Inst_FTU_rs485_interpreter : FTU_rs485_interpreter port map( clk => main_clk, data_block => data_block_sig, block_valid => start_interpreter_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, int_new_prescaling => int_new_prescaling_sig, int_read_rates => int_read_rates_sig, int_read_DACs => int_read_DACs_sig, int_read_enables => int_read_enables_sig, int_read_prescaling => int_read_prescaling_sig, int_ping_pong => int_ping_pong_sig, dac_array_rs485_out => dac_array_rs485_out, enable_array_rs485_out => enable_array_rs485_out, prescaling_rs485_out => prescaling_rs485_out ); Inst_FTU_rs485_interface : FTU_rs485_interface port map( clk => main_clk, -- RS485 rx_d => rx_d, rx_en => rx_en, tx_d => tx_d, tx_en => tx_en, -- FPGA rx_data => rx_data_sig, rx_busy => rx_busy_sig, rx_valid => rx_valid_sig, tx_data => tx_data_sig, tx_busy => tx_busy_sig, tx_start => tx_start_sig ); --FTU RS485 control finite state machine FTU_rs485_control_FSM: process (main_clk) begin if Rising_edge(main_clk) then case FTU_rs485_control_State is when INIT => -- reset CRC register reset_crc_sig <= '1'; FTU_rs485_control_State <= RECEIVE; 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 new_DACs <= '1'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= SET_DAC_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '1') then new_DACs <= '0'; new_enables <= '1'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= SET_ENABLE_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '1'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= SET_PRESCALING_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '0' and int_read_rates_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '1'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= READ_RATES_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '0' and int_read_rates_sig = '0' and int_read_DACs_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '1'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= READ_DAC_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '0' and int_read_rates_sig = '0' and int_read_DACs_sig = '0' and int_read_enables_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '1'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= READ_ENABLE_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '0' and int_read_rates_sig = '0' and int_read_DACs_sig = '0' and int_read_enables_sig = '0' and int_read_prescaling_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '1'; ping_pong <= '0'; FTU_rs485_control_State <= READ_PRESCALING_WAIT; elsif (int_new_DACs_sig = '0' and int_new_enables_sig = '0' and int_new_prescaling_sig = '0' and int_read_rates_sig = '0' and int_read_DACs_sig = '0' and int_read_enables_sig = '0' and int_read_prescaling_sig = '0' and int_ping_pong_sig = '1') then new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '1'; FTU_rs485_control_State <= PING_PONG_WAIT; else new_DACs <= '0'; new_enables <= '0'; new_prescaling <= '0'; read_rates <= '0'; read_DACs <= '0'; read_enables <= '0'; read_prescaling <= '0'; ping_pong <= '0'; FTU_rs485_control_State <= RECEIVE; end if; when SET_DAC_WAIT=> -- wait until FTU control says "done" and then answer to FTM if (DACs_ready = '1') then new_DACs <= '0'; 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'; FTU_rs485_control_State <= SET_DAC_WAIT; end if; when SET_DAC_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= SET_ENABLE_WAIT; end if; when SET_ENABLE_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= SET_PRESCALING_WAIT; end if; when SET_PRESCALING_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= READ_RATES_WAIT; end if; when READ_RATES_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= READ_DAC_WAIT; end if; when READ_DAC_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= READ_ENABLE_WAIT; end if; when READ_ENABLE_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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'; FTU_rs485_control_State <= READ_PRESCALING_WAIT; end if; when READ_PRESCALING_WAIT_2 => -- wait one cycle for CRC calculation 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'; 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 => -- wait one cycle for CRC calculation crc_enable_sig <= '0'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; when SET_DAC_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 5 then -- data: DAC A low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(0),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 6 then -- data: DAC A high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(0),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 7 then -- data: DAC B low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(1),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 8 then -- data: DAC B high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(1),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 9 then -- data: DAC C low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(2),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 10 then -- data: DAC C high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(2),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 11 then -- data: DAC D low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(3),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 12 then -- data: DAC D high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(3),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 13 then -- data: DAC E low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(7),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = 14 then -- data: DAC E high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(7),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= SET_DAC_TRANSMIT; end if; when SET_ENABLE_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000011"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 5 then -- data: enable pattern A7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(0)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 6 then -- data: enable pattern A8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(0)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 7 then -- data: enable pattern B7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(1)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 8 then -- data: enable pattern B8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(1)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 9 then -- data: enable pattern C7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(2)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 10 then -- data: enable pattern C8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(2)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 11 then -- data: enable pattern D7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(3)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = 12 then -- data: enable pattern D8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(3)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= SET_ENABLE_TRANSMIT; end if; when SET_PRESCALING_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000110"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = 5 then -- data: prescaling txcnt <= txcnt + 1; tx_data_sig <= prescaling_rs485_in; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= SET_PRESCALING_TRANSMIT; end if; when READ_RATES_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000010"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 5 then -- data: counter A 7...0 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(0),32)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 6 then -- data: counter A 15...8 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(0),32)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 7 then -- data: counter A 23...16 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(0),32)(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 8 then -- data: counter A 31...24 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(0),32)(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 9 then -- data: counter B 7...0 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(1),32)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 10 then -- data: counter B 15...8 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(1),32)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 11 then -- data: counter B 23...16 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(1),32)(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 12 then -- data: counter B 31...24 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(1),32)(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 13 then -- data: counter C 7...0 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(2),32)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 14 then -- data: counter C 15...8 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(2),32)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 15 then -- data: counter C 23...16 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(2),32)(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 16 then -- data: counter C 31...24 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(2),32)(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 17 then -- data: counter D 7...0 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(3),32)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 18 then -- data: counter D 15...8 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(3),32)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 19 then -- data: counter D 23...16 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(3),32)(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 20 then -- data: counter D 31...24 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(3),32)(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 21 then -- data: trigger counter 7...0 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(4),32)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 22 then -- data: trigger counter 15...8 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(4),32)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 23 then -- data: trigger counter 23...16 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(4),32)(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 24 then -- data: trigger counter 31...24 txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(rate_array_rs485(4),32)(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = 25 then -- data: overflow register txcnt <= txcnt + 1; tx_data_sig <= overflow_array_rs485_in; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= READ_RATES_TRANSMIT; end if; when READ_DAC_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000001"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 5 then -- data: DAC A low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(0),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 6 then -- data: DAC A high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(0),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 7 then -- data: DAC B low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(1),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 8 then -- data: DAC B high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(1),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 9 then -- data: DAC C low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(2),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 10 then -- data: DAC C high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(2),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 11 then -- data: DAC D low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(3),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 12 then -- data: DAC D high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(3),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 13 then -- data: DAC E low txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(7),16)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = 14 then -- data: DAC E high txcnt <= txcnt + 1; tx_data_sig <= conv_std_logic_vector(dac_array_rs485_in(7),16)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= READ_DAC_TRANSMIT; end if; when READ_ENABLE_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000100"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 5 then -- data: enable pattern A7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(0)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 6 then -- data: enable pattern A8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(0)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 7 then -- data: enable pattern B7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(1)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 8 then -- data: enable pattern B8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(1)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 9 then -- data: enable pattern C7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(2)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 10 then -- data: enable pattern C8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(2)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 11 then -- data: enable pattern D7-0 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(3)(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = 12 then -- data: enable pattern D8 txcnt <= txcnt + 1; tx_data_sig <= enable_array_rs485_in(3)(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= READ_ENABLE_TRANSMIT; end if; when READ_PRESCALING_TRANSMIT => if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000111"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 5 then -- data: prescaling txcnt <= txcnt + 1; tx_data_sig <= prescaling_rs485_in; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = 6 then -- data: overflow register txcnt <= txcnt + 1; tx_data_sig <= overflow_array_rs485_in; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= READ_PRESCALING_TRANSMIT; end if; when PING_PONG_TRANSMIT => crc_enable_sig <= '0'; if tx_busy_sig = '0' then if txcnt = 0 then -- start delimiter txcnt <= txcnt + 1; tx_data_sig <= RS485_START_DELIM; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 1 then -- FTM address txcnt <= txcnt + 1; tx_data_sig <= FTM_ADDRESS; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 2 then -- board address txcnt <= txcnt + 1; tx_data_sig <= "00" & brd_add; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 3 then -- firmware ID txcnt <= txcnt + 1; tx_data_sig <= FIRMWARE_ID; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 4 then -- mirrored command txcnt <= txcnt + 1; tx_data_sig <= "00000101"; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 5 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(7 downto 0); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 6 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(15 downto 8); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 7 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(23 downto 16); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 8 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(31 downto 24); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 9 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(39 downto 32); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 10 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(47 downto 40); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 11 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(55 downto 48); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = 12 then -- data: device DNA txcnt <= txcnt + 1; tx_data_sig <= dna(63 downto 56); tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt < ((RS485_BLOCK_WIDTH / 8) - 2) then -- data: not used txcnt <= txcnt + 1; tx_data_sig <= "00000000"; tx_start_sig <= '1'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; elsif txcnt = ((RS485_BLOCK_WIDTH / 8) - 2) then -- CRC error counter txcnt <= txcnt + 1; 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 <= 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; else tx_start_sig <= '0'; FTU_rs485_control_State <= PING_PONG_TRANSMIT; end if; end case; end if; end process FTU_rs485_control_FSM; end Behavioral;