]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blobdiff - hw/lxmaster_transmitter.vhd
RoCoN and TUMBL firmware for control of stepper motor with IRC sensor.
[fpga/lx-cpu1/lx-rocon.git] / hw / lxmaster_transmitter.vhd
index 02092407ba2de6aec3393ff56a1b23683b35e390..1c9153c310cdd74eebed0044408464c0cd7b644d 100644 (file)
@@ -7,6 +7,9 @@ use work.lx_rocon_pkg.all;
 
 -- LX Master (Transmitter)
 entity lxmaster_transmitter is
+       generic (
+               cycle_cnt_width_g : natural := 12
+       );
        port
        (
                clk_i             : in std_logic;
@@ -19,6 +22,10 @@ entity lxmaster_transmitter is
                register_i        : in std_logic;
                register_o        : out std_logic_vector(1 downto 0);
                register_we_i     : in std_logic;
+               -- Cycle period
+               cycle_reg_i       : in std_logic_vector(cycle_cnt_width_g-1 downto 0);
+               cycle_reg_o       : out std_logic_vector(cycle_cnt_width_g-1 downto 0);
+               cycle_reg_we_i    : in std_logic;
                -- Watchdog
                wdog_i            : in std_logic;
                wdog_we_i         : in std_logic;
@@ -64,7 +71,8 @@ architecture Behavioral of lxmaster_transmitter is
        signal lxmaster_sync_last_bit_r : std_logic;
        -- Counters
        signal lxmaster_wdog_counter_s  : natural range 0 to (wdog_length_c-1);
-       signal lxmaster_frame_counter_s : natural range 0 to (frame_length_c-1);
+       signal lxmaster_frame_counter_s : natural range 0 to (2**cycle_cnt_width_g - 1);
+       signal lxmaster_cycle_limit_r   : std_logic_vector(cycle_cnt_width_g-1 downto 0);
        signal lxmaster_msg_counter_s   : natural range 0 to (msg_max_count_c-1);
        signal lxmaster_msg_counter_r   : natural range 0 to (msg_max_count_c-1);
        -- CRC
@@ -80,22 +88,31 @@ architecture Behavioral of lxmaster_transmitter is
        -- Bit 1: Watchdog not kicked (O)
        signal lxmaster_register_in_s   : std_logic;
        signal lxmaster_register_out_s  : std_logic_vector(1 downto 0);
+       -- Output buffers
+       signal sync_s                   : std_logic;
+       signal sync_r                   : std_logic;
+       signal mosi_s                   : std_logic;
+       signal mosi_r                   : std_logic;
 
 begin
 
        -- Directly route out some signals
        clock_o              <= clk_i; -- Cannot mix with logic
-       sync_o               <= not lxmaster_sync_r; -- Active in log. 0
-       mosi_o               <= '1' when lxmaster_sync_r = '0' and lxmaster_sync_last_bit_r = '0'
+       sync_s               <= not lxmaster_sync_r; -- Active in log. 0
+       mosi_s               <= '1' when lxmaster_sync_r = '0' and lxmaster_sync_last_bit_r = '0'
                                 else lxmaster_crc_reg_r(0) when lxmaster_state_r = ST_CRC
                                 else lxmaster_loaded_data_r(0);
+       sync_o               <= sync_r;
+       mosi_o               <= mosi_r;
+
        -- CRC
        lxmaster_crc_reg_s   <= '0' & lxmaster_crc_reg_r(7 downto 1) when lxmaster_state_r = ST_CRC else lxmaster_crc_out_s;
        lxmaster_crc_data_s  <= '1' when lxmaster_state_r = ST_CRC else lxmaster_loaded_data_r(0);
        lxmaster_crc_reset_s <= '1' when lxmaster_state_r /= ST_XFER or reset_i = '1' else '0';
 
-       -- Register
+       -- Registers output
        register_o           <= lxmaster_register_out_s;
+       cycle_reg_o          <= lxmaster_cycle_limit_r;
 
 ram: xilinx_dualport_bram
        generic map
@@ -280,7 +297,7 @@ transmitter_update:
                                        end if;
 
                                when ST_END =>
-                                       if lxmaster_frame_counter_s = (frame_length_c - 1) then
+                                       if lxmaster_frame_counter_s < 2 then
                                                -- Initialize first step
                                                lxmaster_state_s           <= ST_INIT;
                                                ram_addr_s                 <= lxmaster_register_in_s & x"00";
@@ -318,11 +335,13 @@ state:
                -- Increment counter
                if reset_i = '1' then
 
-                       lxmaster_frame_counter_s     <= (frame_length_c - 1);
+                       lxmaster_frame_counter_s     <= 1;
                        lxmaster_wdog_counter_s      <= 0;
                        lxmaster_register_in_s       <= '0';
                        lxmaster_register_out_s      <= (others => '0');
                        lxmaster_last_word_r         <= '1';
+                       lxmaster_cycle_limit_r       <= std_logic_vector(to_unsigned(frame_length_c,
+                                                       lxmaster_cycle_limit_r'length));
 
                else
 
@@ -330,11 +349,11 @@ state:
                                lxmaster_register_in_s     <= register_i;
                        end if;
 
-                       if lxmaster_frame_counter_s = (frame_length_c - 1) then
+                       if lxmaster_frame_counter_s < 2 then
                                lxmaster_register_out_s(0) <= lxmaster_register_in_s;
-                               lxmaster_frame_counter_s   <= 0;
+                               lxmaster_frame_counter_s   <= to_integer(unsigned(lxmaster_cycle_limit_r));
                        else
-                               lxmaster_frame_counter_s   <= lxmaster_frame_counter_s + 1;
+                               lxmaster_frame_counter_s   <= lxmaster_frame_counter_s - 1;
                        end if;
 
                        if wdog_we_i = '1' and wdog_i = '1' then
@@ -347,6 +366,10 @@ state:
                                lxmaster_register_out_s(1)  <= '1';
                        end if;
 
+                       if cycle_reg_we_i = '1' then
+                               lxmaster_cycle_limit_r      <= cycle_reg_i;
+                       end if;
+
                end if;
 
                lxmaster_sync_r                 <= lxmaster_sync_s;
@@ -354,4 +377,13 @@ state:
 
        end process;
 
+update_outputs:
+       process
+       begin
+               wait until clk_i'event and clk_i = '0';
+
+               sync_r  <= sync_s;
+               mosi_r  <= mosi_s;
+       end process;
+
 end Behavioral;