⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mousectrl.vhd

📁 actel BASYs开发板自带的demo程序
💻 VHD
📖 第 1 页 / 共 3 页
字号:

   -- sets the value of x_pos from another module when setx is active
   -- else, computes the new x_pos from the old position when new x
   -- movement detected by adding the delta movement in x_inc, or by
   -- adding 256 or -256 when overflow occurs.
   set_x: process(clk)
   variable x_inter: std_logic_vector(10 downto 0);
   variable inc: std_logic_vector(10 downto 0);
   begin
      if(rising_edge(clk)) then
         -- if setx active, set new x_pos value
         if(setx = '1') then
            x_pos <= '0' & value;
         -- if delta movement received from mouse
         elsif(x_new = '1') then
            -- if negative movement on x axis
            if(x_sign = '1') then
               -- if overflow occurred
               if(x_overflow = '1') then
                  -- inc is -256
                  inc := "11100000000";
               else
                  -- inc is sign extended x_inc
                  inc := "111" & x_inc;
               end if;
               -- intermediary horizontal position
               x_inter := x_pos + inc;
               -- if first bit of x_inter is 1
               -- then negative overflow occurred and
               -- new x position is 0.
               -- Note: x_pos and x_inter have 11 bits,
               -- and because xpos has only 10, when
               -- first bit becomes 1, this is considered
               -- a negative number when moving left
               if(x_inter(10) = '1') then
                  x_pos <= (others => '0');
               else
                  x_pos <= x_inter;
               end if;
            -- if positive movement on x axis
            else
               -- if overflow occurred
               if(x_overflow = '1') then
                  -- inc is 256
                  inc := "00100000000";
               else
                  -- inc is sign extended x_inc
                  inc := "000" & x_inc;
               end if;
               -- intermediary horizontal position
               x_inter := x_pos + inc;
               -- if x_inter is greater than x_max
               -- then positive overflow occurred and
               -- new x position is x_max.
               if(x_inter > ('0' & x_max)) then
                  x_pos <= '0' & x_max;
               else
                  x_pos <= x_inter;
               end if;
            end if;
         end if;
      end if;
   end process set_x;

   -- sets the value of y_pos from another module when sety is active
   -- else, computes the new y_pos from the old position when new y
   -- movement detected by adding the delta movement in y_inc, or by
   -- adding 256 or -256 when overflow occurs.
   set_y: process(clk)
   variable y_inter: std_logic_vector(10 downto 0);
   variable inc: std_logic_vector(10 downto 0);
   begin
      if(rising_edge(clk)) then
         -- if sety active, set new y_pos value
         if(sety = '1') then
            y_pos <= '0' & value;
         -- if delta movement received from mouse
         elsif(y_new = '1') then
            -- if negative movement on y axis
            -- Note: axes origin is upper-left corner
            if(y_sign = '1') then
               -- if overflow occurred
               if(y_overflow = '1') then
                  -- inc is -256
                  inc := "11100000000";
               else
                  -- inc is sign extended y_inc
                  inc := "111" & y_inc;
               end if;
               -- intermediary vertical position
               y_inter := y_pos + inc;
               -- if first bit of y_inter is 1
               -- then negative overflow occurred and
               -- new y position is 0.
               -- Note: y_pos and y_inter have 11 bits,
               -- and because ypos has only 10, when
               -- first bit becomes 1, this is considered
               -- a negative number when moving upward
               if(y_inter(10) = '1') then
                  y_pos <= (others => '0');
               else
                  y_pos <= y_inter;
               end if;
            -- if positive movement on y axis
            else
               -- if overflow occurred
               if(y_overflow = '1') then
                  -- inc is 256
                  inc := "00100000000";
               else
                  -- inc is sign extended y_inc
                  inc := "000" & y_inc;
               end if;
               -- intermediary vertical position
               y_inter := y_pos + inc;
               -- if y_inter is greater than y_max
               -- then positive overflow occurred and
               -- new y position is y_max.
               if(y_inter > ('0' & y_max)) then
                  y_pos <= '0' & y_max;
               else
                  y_pos <= y_inter;
               end if;
            end if;
         end if;
      end if;
   end process set_y;

   -- sets the maximum value of the x movement register, stored in x_max
   -- when setmax_x is active, max value should be on value input pin
   set_max_x: process(clk,rst)
   begin
      if(rising_edge(clk)) then
         if(rst = '1') then
            x_max <= DEFAULT_MAX_X;
         elsif(setmax_x = '1') then
            x_max <= value;
         end if;
      end if;
   end process set_max_x;

   -- sets the maximum value of the y movement register, stored in y_max
   -- when setmax_y is active, max value should be on value input pin
   set_max_y: process(clk,rst)
   begin
      if(rising_edge(clk)) then
         if(rst = '1') then
            y_max <= DEFAULT_MAX_Y;
         elsif(setmax_y = '1') then
            y_max <= value;
         end if;
      end if;
   end process set_max_y;

   -- Synchronous one process fsm to handle the communication
   -- with the mouse.
   -- When reset and at start-up it enters reset state
   -- where it begins the procedure of initializing the mouse.
   -- After initialization is complete, it waits packets from
   -- the mouse.
   -- Read at Behavioral decription for details.
   manage_fsm: process(clk,rst)
   begin
      -- when reset occurs, give signals default values.
      if(rst = '1') then
         state <= reset;
         haswheel <= '0';
         x_overflow <= '0';
         y_overflow <= '0';
         x_sign <= '0';
         y_sign <= '0';
         x_inc <= (others => '0');
         y_inc <= (others => '0');
         x_new <= '0';
         y_new <= '0';
         new_event <= '0';
         left_down <= '0';
         middle_down <= '0';
         right_down <= '0';

      elsif(rising_edge(clk)) then

         -- at every rising edge of the clock, this signals
         -- are reset, thus assuring that they are active
         -- for one clock period only if a state sets then
         -- because the fsm will transition from the state
         -- that set them on the next rising edge of clock.
         write <= '0';
         x_new <= '0';
         y_new <= '0';
         
         case state is

            -- if just powered-up, reset occurred or some error in
            -- transmision encountered, then fsm will transition to
            -- this state. Here the RESET command (FF) is sent to the
            -- mouse, and various signals receive their default values
            -- From here the FSM transitions to a series of states that
            -- perform the mouse initialization procedure. All this
            -- state are prefixed by "reset_". After sending a byte
            -- to the mouse, it respondes by sending ack (FA). All
            -- states that wait ack from the mouse are postfixed by
            -- "_wait_ack".
            -- Read at Behavioral decription for details.
            when reset =>
               haswheel <= '0';
               x_overflow <= '0';
               y_overflow <= '0';
               x_sign <= '0';
               y_sign <= '0';
               x_inc <= (others => '0');
               y_inc <= (others => '0');
               x_new <= '0';
               y_new <= '0';
               left_down <= '0';
               middle_down <= '0';
               right_down <= '0';
               tx_data <= FF;
               write <= '1';
               state <= reset_wait_ack;

            -- wait ack for the reset command.
            -- when received transition to reset_wait_bat_completion.
            -- if error occurs go to reset state.
            when reset_wait_ack =>
               if(read = '1') then
                  -- if received ack
                  if(rx_data = FA) then
                     state <= reset_wait_bat_completion;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_wait_ack;
               end if;

            -- wait for bat completion test
            -- mouse should send AA if test is successful
            when reset_wait_bat_completion =>
               if(read = '1') then
                  if(rx_data = AA) then
                     state <= reset_wait_id;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_wait_bat_completion;
               end if;

            -- the mouse sends its id after performing bat test
            -- the mouse id should be 00
            when reset_wait_id =>
               if(read = '1') then
                  if(rx_data = OO) then
                     state <= reset_set_sample_rate_200;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_wait_id;
               end if;

            -- with this state begins the enable wheel mouse
            -- procedure. The procedure consists of setting
            -- the sample rate of the mouse first 200, then 100
            -- then 80. After this is done, the mouse id is
            -- requested and if the mouse id is 03, then
            -- mouse is in wheel mode and will send 4 byte packets
            -- when reporting is enabled.
            -- If the id is 00, the mouse does not have a wheel
            -- and will send 3 byte packets when reporting is enabled.
            -- This state issues the set_sample_rate command to the
            -- mouse.
            when reset_set_sample_rate_200 =>
               tx_data <= SET_SAMPLE_RATE;
               write <= '1';
               state <= reset_set_sample_rate_200_wait_ack;

            -- wait ack for set sample rate command
            when reset_set_sample_rate_200_wait_ack =>
               if(read = '1') then
                  if(rx_data = FA) then
                     state <= reset_send_sample_rate_200;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_set_sample_rate_200_wait_ack;
               end if;

            -- send the desired sample rate (200 = 0xC8)
            when reset_send_sample_rate_200 =>
               tx_data <= "11001000"; -- 0xC8
               write <= '1';
               state <= reset_send_sample_rate_200_wait_ack;

            -- wait ack for sending the sample rate
            when reset_send_sample_rate_200_wait_ack =>
               if(read = '1') then
                  if(rx_data = FA) then
                     state <= reset_set_sample_rate_100;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_send_sample_rate_200_wait_ack;
               end if;

            -- send the sample rate command
            when reset_set_sample_rate_100 =>
               tx_data <= SET_SAMPLE_RATE;
               write <= '1';
               state <= reset_set_sample_rate_100_wait_ack;

            -- wait ack for sending the sample rate command
            when reset_set_sample_rate_100_wait_ack =>
               if(read = '1') then
                  if(rx_data = FA) then
                     state <= reset_send_sample_rate_100;
                  else
                     state <= reset;
                  end if;
               elsif(err = '1') then
                  state <= reset;
               else
                  state <= reset_set_sample_rate_100_wait_ack;
               end if;

            -- send the desired sample rate (100 = 0x64)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -