PS/2 Mouse Controller Just like the PS/2 Keyboard, the communication between the mouse and the controller uses two signals, MouseClock and MouseData. These are the same two signals used in the keyboard. The interfacing to the mouse is more difficult than interfacing to the keyboard because the controller needs to send an initialization command to the mouse before the mouse will start sending data to the controller. At power-up, the mouse runs a self-test and sends out the codes AA and 00. The default power-up mode is streaming mode disabled, so the controller needs to send a command to the mouse to enable streaming mode. The controller sends the initialization command, F4, (Enable Streaming Mode Command) to the mouse. After receiving the initialization command, the mouse acknowledges the message by sending code FA (Mouse Acknowledge Command) back to the controller. The two lines, MouseClock and MouseData, are tri-state bi-directional, since at times they are driven by the mouse and at other times by the controller. The mouse always drives the clock signal for any serial data exchanges. The controller can inhibit mouse transmissions by pulling the clock line low at any time. The controller drives the data line when sending commands to the mouse. The mouse drives the data line when sending data to the controller. Mouse Initialization Steps: 1. To send the initialization command, the MouseClock line is driven low by the controller for at least 60us to inhibit any data transmissions from the mouse. This is the only case when the controller should ever drive the clock line. 2. The data line is then driven low by the controller to signal that it has a command to send to the mouse. This handshake signal of the data line starting out low takes the place of the start bit when sending commands to the mouse. 3. The clock line is driven high for some short time (see official doc for precise timing) and then tri-stated. 4. The mouse seeing data low and clock high, starts clocking in the 8-bit serial data from the controller. The 8-bit data is followed by an odd parity bit and a high stop bit. 5. After receiving the command, the mouse then responds to this message by sending an acknowledge command code, FA, back to the controller. This includes a low start bit, eight data bits, an odd parity bit, and a high stop bit. The mouse, as always, drives the clock line for the serial data transmission. The mouse is now initialized. 3 MouseClock start 4 d0 d1 d2 d3 d4 d5 d6 d7 parity stop 0 0 1 0 1 1 1 1 0 1 1 MouseData 2 0 Figure 1. Transmission of the initialization command. Altera I/O commands: IOWR_ALTERA_AVALON_PIO_DATA(base_address, data); // write data to PIO port data = IORD_ALTERA_AVALON_PIO_DATA(base_address); // read data from PIO port IOWR_ALTERA_AVALON_PIO_DIRECTION(base_address, direction); // change direction of port direction = 0 direction = 1 // mouse control of line // controller control of line Mouse Data Packet Processing Steps: 1. As long as the controller is not sending any signals (i.e. tri-stated) on both the clock and data lines, the mouse will send data packets to the controller. 2. Each mouse data packet consists of 3 bytes, and each byte is wrapped in an 11-bit packet with the start bit, odd parity bit and stop bit. So each data packet will have 33 bits. The 3-byte mouse data packet is shown in Figure 2. Bit 7 6 5 4 3 2 1 0 Byte 1 OverflowY OverflowX SignY SignX 1 MiddleB RightB LeftB Byte 2 X7 X6 X5 X4 X3 X2 X1 X0 Byte 3 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 OverflowY = Y data overflow bit (1 = overflow) OverflowX = X data overflow bit (1 = overflow) SignY = Y data sign bit (1 = negative) SignX = X data sign bit (1 = negative) MiddleB = middle mouse button status bit (1 = pressed; 0 = released) RightB = right mouse button status bit (1 = pressed; 0 = released) LeftB = left mouse button status bit (1 = pressed; 0 = released) X7 to X0 = moving distance of X in two’s complement (moving left = negative; moving right = position) Y7 to Y0 = moving distance of Y in two’s complement (moving down = negative; moving up = position) Figure 2. The 3-byte mouse data packet. First Nios2 System Here's an example for reading the PS2 clock line #include #include #include #include <stdio.h> "alt_types.h" "altera_avalon_pio_regs.h" "system.h" int main(){ printf("Hello from Nios II!\n"); int i; i = IORD_ALTERA_AVALON_PIO_DATA(PS2_CLK_BASE); while(i){ i = IORD_ALTERA_AVALON_PIO_DATA(PS2_CLK_BASE); } printf("%i\n",i); while(!i){ i = IORD_ALTERA_AVALON_PIO_DATA(PS2_CLK_BASE); } printf("%i\n",i); while(i){ i = IORD_ALTERA_AVALON_PIO_DATA(PS2_CLK_BASE); } printf("%i\n",i); while(!i){ i = IORD_ALTERA_AVALON_PIO_DATA(PS2_CLK_BASE); } printf("%i\n",i); return 0; } Here's the output after pressing a key on the keyboard Hello from Nios II! 0 1 0 1