Table of Contents

PIC18: Connecting to a PS/2 mouse

In a previous article we saw how to connect to a PS/2 keyboard. Here we are completing topic by describing how a PS/2 mouse can be interfaced to a PIC micro.

Connections remain the same; there are still four wires that carry +5V, ground, Data and Clock signals. Plus the same mini-DIN (male and female) connectors are used. Similar to the above article in the following articles clock line is blue and data line is yellow, but their position is inverted, so data traces are now on top.

Also the transmission protocol is the same, with clock pulses generated by the device (mouse in this case) and frames that consist of a start bit, 8 data bits, a parity bit and finally a stop bit. Data is still transmitted Least Significant Bit (LSB).

Physical connection to the PIC18

Instead of removing the male plug, as we did for the PS/2 keyboard, we are going to keep the mouse intact by means of a PS/2 female connector; with this approach the mouse could be easily swapped with another in case we would like to further experiment the protocol, for instance by studying Intellisense extensions (not discussed in this article).

Mouse data packets

The mouse keeps track of movement around the X-Y space and the state of its buttons by use of counters. The content of these counters are periodically sent to the host in the form a 3-byte movement data packet. The movement counters represent the mouse's offset relative to its position when the previous movement data packet was issued.

Movement data can be sent in Stream Mode, in which the mouse issues movement data packets when movement occurs or button state changes or in Remote Mode, where the host must poll the mouse to get movement data packets.

In this article we will use only Remote Mode; this operation mode is achieved by sending the command 0xEB (Read Data), which occurs everytime TMR0 overflows:

Here we can see an example trace where 0XEB command (Read Data) was issued by the PIC:

The mouse responds with an 'acknowledge' (0xFA) and then with the 3 bytes of the movement data packet, in this case 0x08, 0x6C and 0x4A:

The code

The most important routines are described here.

In Main, when TMR0 interrupt occurs ReadMouseValues routine is called, which, in turn calls the following subs:

PS2SendCommand is composed of the following steps:

Now the mouse should start generating clock pulses; the host then issues a Read Data command (0xEB). As stated before:

Data sent from the host to the device is read on the rising edge of the Clock

That means that Data signal has to be stable (0 or 1) before Clock signal rises and for the whole length of the up state of it:

The mouse expects to receive a parity bit:

And finally we're releasing Data and Clock lines:

Now that EB (Read Data) is sent read first mouse byte (ACK = FA); we are not interested in this byte, which should be 0xFA.

This is how PS2MouseReadByte routine works:

Now that's the part we are interested in, that is the mouse data byte; let's stress the following concept:

Data sent from the device to the host is read on the falling edge of the Clock

That means that Data signal is already stable (0 or 1) after Clock signal goes down:

PS2DataByteFA (acknowledge), PS2DataByte1 (flags and buttons), PS2DataByte2 (X movement) and PS2DataByte3 (Y movement) are being assigned the above values and then finally displayed onto LCD.

Also displayed are mouse buttons pressed and movement overflow status.

Reference

http://www.computer-engineering.org/ps2mouse/