Mouse ctrl and top added

This commit is contained in:
Florian Reitz 2019-06-17 12:52:56 +02:00
parent 3ba31c311f
commit d69f115303
2 changed files with 273 additions and 0 deletions

224
mouseCtrl.vhd Normal file
View File

@ -0,0 +1,224 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_unsigned.all;
entity mouseCtrl is
port(
clk7m : in STD_LOGIC;
clr : in STD_LOGIC;
sel : in STD_LOGIC;
PS2C : inout STD_LOGIC;
PS2D : inout STD_LOGIC;
byte3 : out STD_LOGIC_VECTOR(7 downto 0);
xData : out STD_LOGIC_VECTOR(8 downto 0);
yData : out STD_LOGIC_VECTOR(8 downto 0)
);
end mouseCtrl;
architecture mouseCtrl of mouseCtrl is
type STATE_T is (start, clklo, datlo, relclk, sndbyt, wtack,
wtclklo, wtcdrel, wtclklo1, wtclkhi1, getack, wtclklo2,
wtclkhi2, getmdata);
signal state: STATE_T;
signal PS2Cf, PS2Df, cen, den, sndflg, xs, ys: STD_LOGIC;
signal ps2cin, ps2din ps2cio, ps2dio: STD_LOGIC;
signal ps2c_filter, ps2d_filter: STD_LOGIC_VECTOR(7 downto 0);
signal xMouseV, yMouseV: STD_LOGIC_VECTOR(8 downto 0);
signal xMouseD, yMouseD: STD_LOGIC_VECTOR(8 downto 0);
signal shift1, shift2, shift3: STD_LOGIC_VECTOR(10 downto 0);
signal f4cmd: STD_LOGIC_VECTOR(9 downto 0);
signal bitCount, bitCount1: STD_LOGIC_VECTOR(3 downto 0);
signal bitCount3: STD_LOGIC_VECTOR(5 downto 0);
signal count: STD_LOGIC_VECTOR(11 downto 0);
constant COUNT_MAX : STD_LOGIC_VECTOR(11 downto 0) := X"2BC"; -- 700 100us
constant BIT_COUNT_MAX: STD_LOGIC_VECTOR(3 downto 0) := "1010"; -- 10
constant BIT_COUNT1_MAX: STD_LOGIC_VECTOR(3 downto 0) := "1100"; -- 12 ack
constant BIT_COUNT3_MAX: STD_LOGIC_VECTOR(5 downto 0) := "100001"; -- 33
begin
-- tri-state buffers
ps2cio <= ps2cin when cen = '1' else 'Z';
ps2dio <= ps2din when den = '1' else 'Z';
PS2C <= ps2cio;
PS2D <= ps2dio;
-- filter for PS2 clock
filter: process(clk7m, clr)
begin
if clr = '1' then
ps2c_filter <= (others => '0');
ps2d_filter <= (others => '0');
PS2Cf <= '1';
PS2Df <= '1';
elsif rising_edge(clk7m) then
ps2c_filter(7) <= ps2cio;
ps2c_filter(6 downto 0) <= ps2c_filter(7 downto 1);
ps2d_filter(7) <= ps2dio;
ps2d_filter(6 downto 0) <= ps2d_filter(7 downto 1);
if ps2c_filter = X"FF" then
PS2Cf <= '1';
elsif ps2c_filter = X"00" then
PS2Cf <= '0';
end if;
if ps2d_filter = X"FF" then
PS2Df <= '1';
elsif ps2d_filter = X"00" then
PS2Df <= '0';
end if;
end if;
end process filter;
-- state machine for reading mouse
smouse: process(clk7m, clr)
begin
if clr = '1' then
state <= start;
cen <= '0';
den <= '0';
ps2din <= '0';
count <= (others => '0');
bitCount1 <= (others => '0');
bitCount3 <= (others => '0');
shift1 <= (others => '0');
shift2 <= (others => '0');
shift3 <= (others => '0');
xMouseV <= (others => '0');
yMouseV <= (others => '0');
xMouseD <= (others => '0');
yMouseD <= (others => '0');
sndflg <= '0';
elsif falling_edge(clk7m) then
case state is
when start =>
cen <= '1'; -- enable clock output
ps2cin <= '0'; -- start bit
count <= (others => '0'); -- reset count
state <= clklo;
when clklo =>
if count < COUNT_MAX then
count <= count + 1;
state <= clklo;
else
state <= datlo;
den <= '1'; -- enable data output
end if;
when datlo =>
state <= relclk
cen <= '0'; -- release clock
when relclk =>
sndflg <= '1';
state <= sndbyt;
when sndbyt =>
if bitCount < BIT_COUNT_MAX then
state <= sndbyt;
else
state <= wtack;
sndflg <= '0';
den <= '0'; -- release data
end if;
when wtack => -- wait for data low
if PS2Df = '1' then
state <= wtack;
else
state <= wtclklo;
end if;
when wtclklo => -- wait for clock low
if PS2Cf = '1' then
state <= wtclklo;
else
state <= wtcdrel;
end if;
when wtcdrel => -- wait to release clock and data
if PS2Cf = '1' and PS2Df = '1' then
state <= wtclklo1;
bitCount1 <= (others => '0');
else
state <= wtcdrel;
end if;
when wtclklo1 => -- wait for clock low
if bitCount1 < BIT_COUNT1_MAX then
if PS2Cf = '1' then
state <= wtclklo1;
else
state wtclkhi1; -- get ack byte FA
shift1 <= PS2Df & shift1(10 downto 1);
end if;
else
state <= getack;
end if;
when wtclkhi1 => -- wait for clock high
if PS2Cf = '0' then
state <= wtclkhi1;
else
state <= wtclklo1;
bitCount1 <= bitCount1 + 1;
end if;
when getack => -- get ack FA
yMouseV <= shift1(9 downto 1);
xMouseV <= shift2(8 downto 0);
byte3 <= shift1(10 downto 5) & shift1(1 downto 0);
state <= wtclklo2;
bitCount3 <= (others => '0');
when wtclklo2 => -- wait for clock low
if bitCount3 < BIT_COUNT3_MAX then
if PS2Cf = '1' then
state <= wtclklo2;
else
state <= wtclkhi2;
shift1 <= PS2Df & shift1(10 downto 1);
shift2 <= shift1(0) & shift2(10 downto 1);
shift3 <= shift2(0) & shift3(10 downto 1);
end if;
else
xMouseV <= shift3(5) & shift2(8 downto 1); -- x velocity
yMouseV <= shift3(6) & shift1(8 downto 1); -- y velocity
byte3 <= shift3(8 downto 1);
state <= getmdata;
end if;
when wtclkhi2 => -- wait for clock high
if PS2Cf = '0' then
state <= wtclkhi2;
else
state <= wtclklo2;
bitCount3 <= bitCount3 + 1;
end if;
when getmdata => -- read mouse data and keep going
xMouseD <= xMouseD + xMouseV; -- x distance
yMouseD <= yMouseD + yMouseV; -- y distance
bitCount3 <= (others => '0');
state <= wtclklo2;
end case;
end if;
end process smouse;
-- send F4 command to mouse
sndf4: process(PS2Cf, clr, sndflg)
begin
if clr = '1' then
f4cmd <= "1011110100"; -- stop-parity-F4
ps2din <= '0';
bitCount <= (others => '0');
elsif falling_edge(PS2Cf) and sndflg = '1' then
ps2din <= f4cmd(0);
f4cmd(8 downto 0) <= f4cmd(9 downto 1);
f4cmd(9) <= '0';
bitCount <= bitCount + 1;
end if;
end process sndf4;
-- output select
outsel: process(xMouseV, yMouseV, xMouseD, yMouseD, sel)
begin
if sel = '0' then
xData <= xMouseV;
yData <= yMouseV;
else
xData <= xMouseD;
yData <= yMouseD;
end if;
end process outsel;
end architecture mouseCtrl;

49
mouseTop.vhd Normal file
View File

@ -0,0 +1,49 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use work.ps2_components.all;
entity mouseTop is
port(
mclk : in STD_LOGIC;
PS2C : inout STD_LOGIC;
PS2D : inout STD_LOGIC;
btn : in STD_LOGIC_VECTOR(3 downto 0);
ld : out STD_LOGIC_VECTOR(3 downto 0);
aToG : out STD_LOGIC_VECTOR(6 downto 0);
dp : out STD_LOGIC;
an : out STD_LOGIC_VECTOR(3 downto 0)
);
end mouseTop;
architecture mouseTop of mouseTop is
signal clk7m, clk190, clr: STD_LOGIC;
signal byte3: STD_LOGIC_VECTOR(7 downto 0);
signal xData, yData: STD_LOGIC_VECTOR(8 downto 0);
signal xMouse: STD_LOGIC_VECTOR(15 downto 0);
begin
clr <= btn(3);
dp <= '1'; -- decimal points off
xMouse <= xData(7 downto 0) & yData(7 downto 0);
ld(0) <= yData(8);
ld(1) <= xData(8);
ld(2) <= byte3(1); -- right button
ld(3) <= byte3(0); -- left button
U1 : clkdiv2
port map(mclk => mclk, clr => clr, clk7m => clk7m, clk190 => clk190);
U2 : mouseCtrl
port map(clk7m => clk7m, clr => clr, sel => btn(0),
PS2C => PS2C, PS2D => PS2D, byte3 => byte3,
xData => xData, yData => yData);
U3 : x7segb
port map(x => xMouse, cclk => clk190, clr => clr,
aToG => aToG, an => an);
end mouseTop;