0

I'm using Quartus II 13.0sp1, DE1 Board for testing, and Cyclone II FPGA EP2C20F484C7N. I need to write program in VHDL that sends command to device. I have already created entity and architecture which I successfully used to receive keys from keyboard. Now I need entity that send command to mouse, since mouse expects me to send it commands to start streaming mode.

My biggest problem is that I don't know how to DECLARE and USE ps2_clk and ps2_dat pins to send command to mouse and to receive data from mouse (using same pins to both-way communication). Just after I send 11 bits to mouse, I need to receive one bit using same pin (ps2_dat), and after that receiver ACK byte from mouse using that same pin. Also before I send command I need to pulldown clock line low, for period of 100 microseconds, and after that I need to release clock line so that mouse can generate clock.

I hava no idea how to implements this. Or maybe I misunderstood protocol?

user36382
  • 3
  • 2
  • If I may interject - I think what he's asking is how his FPGA data line can be receiving data and then switch to sending it, without any apparent direction pin. If you don't realise that PS/2 is open collector/drain it's a bit puzzling. – carveone Jan 30 '14 at 23:08

1 Answers1

2

The PS2 clock and Data lines are implemented as open-drain with pullup resistors. Thus you treat it in a similar way to i2c. So, in your entity, you could do:

Port (
   ....
   io_ps2_dat : inout std_logic;
   io_ps2_clk : inout std_logic;
   ....
);

Bear in mind that for open drain you must make the pin '0' or 'Z'. Not '1'! Never drive a '1' on an open drain bus as you may fry the mouse. If you put a 'Z' on, the pin will read one, pulled to high by the resistor.

io_ps2_dat <= '0';
....
io_ps2_dat <= 'Z';

Does this get you started?

Edit: I'll add a bit more about comms in host-to-device communications.

The PS/2 mouse always generates the clock signal. If the host wants to send, it must go to "Request-to-send" state:

  • Pulling Clock low for at least 100 microseconds (inhibit comms). You can do this by simply putting '0' on the io_ps2_clk line. Because it's open drain this is perfectly safe and the mouse will notice.
  • Enter Request-to-send mode by pulling Data low, then release Clock.

When the mouse detects this state, it will begin generating a clock signals and reads in 8 data bits and one stop bit when the clock is high. This you (the host) can change the Data line only when the Clock line is low.

After the stop bit is received, the mouse will acknowledge the received byte by bringing the Data line low and generating one last clock pulse. (ACK# - it's very I2Cish).

carveone
  • 2,568
  • 1
  • 15
  • 22
  • Thank you for this great answer. So just to make it clear - when ever I need to put '1' on data line, I put 'Z', because of open drain, and when I need to put '0', I just put '0'. So pulling down clock means putting '0' on clock line, and after 100 microseconds I should put 'Z'. Is that correct? – user36382 Jan 30 '14 at 17:28
  • Yes. That's exactly right. Put '0' on clock for 100us, then put '0' on data and "release" (ie: put 'Z') on the clock. Keep '0' on data and that's the start bit done. The mouse should then pull the clock low (after a period which I can't remember offhand - it's 10Khz isn't it?) which is your cue to put Bit#0 on the line...etc...etc. You should check the exact conversation as I'm not sure if there's a parity bit in there somewhere. – carveone Jan 30 '14 at 23:03
  • Yes, there is odd parity bit. Thank you very very much. – user36382 Jan 31 '14 at 12:03