The PS/2 Controller is a peripheral that allows for communication between the DE1-SoC Board and a PS/2 Device (Mouse or keyboard).
Device | PS/2 Controller | |||||||||
Configuration | 2 32-bit mapped registers | |||||||||
Input/Output | Either | |||||||||
Address Base | Controller 1: 0xFF200100. Controller 2: 0xFF200108 | |||||||||
Address Map |
| |||||||||
Initialization | None, but mouse or keyboard may require initialization (see references) | |||||||||
Interrupts |
| |||||||||
Hardware Setup | Plug a PS/2 Device into the PS/2 port on the DE1-SoC Board. | |||||||||
Reference | Full Documentation of controller from Altera
PS/2 Mouse Protocol PS/2 Keyboard Protocol PS/2 Non-device-specific Documentation (hardware) |
Use bit 15 (data valid) to determine if a read is valid. The "Number of bytes available" field (Data[31:16]) is unreliable when used for polling, as it returns the state of the queue one cycle earlier than when the bytes are actually available. For example, reading the data register in the same cycle as a byte is received will result in "1 byte available", but the byte will not be valid, and no bytes will be dequeued from the FIFO.
The PS/2 Controller only provides a method for communication of bytes between the board and the device. The style of communication that will take place (protocol) depends on the device in question.
For specific information on interacting with a PS/2 Mouse or Keyboard, see the references for details.
# Sends the command stored in r2, then waits for the response values stored in r3 and/or r4 (if there are any values greater than 0xff in those registers mean to not expect a response.) EXECUTE_COMMAND: movia r7, 0xFF200100 stwio r2, 0(r7) # Send command in r2 movui r5, 0xff bgt r3, r5, return_from_execute # If r3 is > 0xff, finished Exec_Loop_1: ldwio r6, 0(r7) # Since r3 < 0xff, wait for the response andi r6, r6, 0xff bne r3, r6, Exec_Loop_1 bgt r4, r5, return_from_execute # If r4 is > 0xff, finished Exec_Loop_2: ldwio r6, 0(r7) # Since r4 < 0xff, wait for the response andi r6, r6, 0xff bne r4, r6, Exec_Loop_2 return_from_execute: ret
#define RLEDs ((volatile long *) 0xFF200000) int main() { unsigned char byte1 = 0; unsigned char byte2 = 0; unsigned char byte3 = 0; volatile int * PS2_ptr = (int *) 0xFF200100; // PS/2 port address int PS2_data, RVALID; while (1) { PS2_data = *(PS2_ptr); // read the Data register in the PS/2 port RVALID = (PS2_data & 0x8000); // extract the RVALID field if (RVALID != 0) { /* always save the last three bytes received */ byte1 = byte2; byte2 = byte3; byte3 = PS2_data & 0xFF; } if ( (byte2 == 0xAA) && (byte3 == 0x00) ) { // mouse inserted; initialize sending of data *(PS2_ptr) = 0xF4; } // Display last byte on Red LEDs *RLEDs = byte3; } }