Unit PL050
Return to Unit Reference
Description
ARM PrimeCell PL050 PS2 Keyboard/Mouse Interface Driver unit
The PL050 is an Advanced Microcontroller Bus Architecture (AMBA) compliant peripheral that implements a PS/2 compatible Keyboard and Mouse interface. This driver supports all of the standard functionality of the PL050 KMI controller including both Keyboard and Mouse devices as well as setting LEDs, repeat rate, repeat delay and sample rate values.
The driver uses interrupt transfers for receiving keyboard and mouse inputs but uses only polling mode for transmitting data to the keyboard or mouse device. This driver has only been tested with the QEMU Versatile PB emulation of the PL050 device and has not been confirmed to work with real hardware.
Notes:
- Currently QEMU only supports Scancode set 2 so scancode sets 1 and 3 are not implemented.
- On Windows, QEMU appears to send invalid scancodes for Print Screen and Pause/Break keys.
- On Windows, QEMU does not differentiate between the cursor keys (Up, Down, Left, Right, Home, End, PgUp, PgDown) and the numeric keypad keys so each of these will always return their numeric keypad equivalent. This means that to use the cursor keys you need to turn off Number Lock otherwise they are interpreted as number keys instead.
Constants
PL050_*
PL050_KEYBOARD_DESCRIPTION = 'ARM PrimeCell PL050 PS2 Keyboard';
|
Description of PL050 Keyboard device |
PL050_MOUSE_DESCRIPTION = 'ARM PrimeCell PL050 PS2 Mouse';
|
Description of PL050 Mouse device |
PL050_KEYBOARD_SCANCODE_COUNT = 256;
|
Number of keyboard scancode buffers for receive |
PL050_MOUSE_PACKET_COUNT = 256;
|
Number of mouse packet buffers for receive |
PL050_KEYBOARD_CLOCK_RATE = 8000000;
|
Default clock rate |
PL050_MOUSE_CLOCK_RATE = 8000000;
|
Default clock rate |
PL050_KEYBOARD_SHIFTSTATE_MASK = KEYBOARD_LEFT_CTRL or KEYBOARD_LEFT_SHIFT or KEYBOARD_LEFT_ALT or KEYBOARD_RIGHT_CTRL or KEYBOARD_RIGHT_SHIFT or KEYBOARD_RIGHT_ALT;
|
PL050_CR_*
PL050_CR_TYPE = (1 shl 5);
|
0 = PS2/AT mode / 1 = No line control bit mode |
PL050_CR_RXINTREN = (1 shl 4);
|
Enable receiver interrupt. This bit field is used to enable the PrimeCell KMI receiver interrupt (If KMIRXINTREn = 1, the receiver interrupt is enabled) |
PL050_CR_TXINTREN = (1 shl 3);
|
Enable transmitter interrupt. This bit field is used to enable the PrimeCell KMI transmitter interrupt (If KMITXINTREn = 1, the transfer interrupt is enabled) |
PL050_CR_EN = (1 shl 2);
|
The enable PrimeCell KMI bit field is used to enable the KMI (If KmiEn = 1, the KMI is enabled) |
PL050_CR_FDL = (1 shl 1);
|
The force KMI data LOW bit field is used to force the PrimeCell KMI data pad LOW regardless of the state of the KMI finite state machine (FSM) (If FKMID = 1, the PrimeCell KMI data pad is forced LOW) |
PL050_CR_FCL = (1 shl 0);
|
The force KMI clock LOW bit field is used to force the PrimeCell KMI clock pad LOW regardless of the state of the KMI FSM (If FKMIC = 1, the PrimeCell KMI clock pad is forced LOW) |
PL050_STAT_*
PL050_STAT_TXEMPTY = (1 shl 6);
|
This bit indicates that the transmit register is empty and ready to transmit (0 = Transmit register full / 1 = Transmit register empty, ready to be written) |
PL050_STAT_TXBUSY = (1 shl 5);
|
This bit indicates that the PrimeCell KMI is currently sending data (0 = Idle / 1 = Currently sending data) |
PL050_STAT_RXFULL = (1 shl 4);
|
This bit indicates that the receiver register is full and ready to be read (0 = Receive register empty / 1 = Receive register full, ready to be read) |
PL050_STAT_RXBUSY = (1 shl 3);
|
This bit indicates that the PrimeCell KMI is currently receiving data (0 = Idle / 1 = Currently receiving data) |
PL050_STAT_RXPARITY = (1 shl 2);
|
This bit reflects the parity bit for the last received data byte (odd parity) |
PL050_STAT_IC = (1 shl 1);
|
This bit reflects the status of the KMICLKIN line after synchronizing and sampling |
PL050_STAT_ID = (1 shl 0);
|
This bit reflects the status of the KMIDATAIN line after synchronizing |
PL050_IIR_*
PL050_IIR_TXINTR = (1 shl 1);
|
This bit is set to 1 if the KMITXINTR transmit interrupt is asserted |
PL050_IIR_RXINTR = (1 shl 0);
|
This bit is set to 1 if the KMIRXINTR receive interrupt is asserted |
Type definitions
PL050 KMI registers
PPL050KMIRegisters = ^TPL050KMIRegisters;
TPL050KMIRegisters = record
Note: Layout of the PL050 registers (See: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0143c/i1005653.html) | |
CR:LongWord;
|
Control register |
STAT:LongWord;
|
Status register |
DATA:LongWord;
|
Received data (read)/Data to be transmitted (write) |
CLKDIV:LongWord;
|
Clock divisor register |
IIR:LongWord;
|
Interrupt status register |
PL050 keyboard scancode
PPL050KeyboardScancode = ^TPL050KeyboardScancode;
TPL050KeyboardScancode = record
Keyboard:PPL050Keyboard;
|
|
Count:LongWord;
|
|
Index:LongInt;
|
|
Scancode:TPS2KeyboardScancode;
|
PL050 keyboard
PPL050Keyboard = ^TPL050Keyboard;
TPL050Keyboard = record
Keyboard Properties | |
Keyboard:TKeyboardDevice;
|
|
PL050 Properties | |
IRQ:LongWord;
|
|
Registers:PPL050KMIRegisters;
|
Device registers |
ScancodeSet:Byte;
|
The currently selected scancode set |
ScancodeData:array[0..(PL050_KEYBOARD_SCANCODE_COUNT - 1)] of TPL050KeyboardScancode;
|
Buffers for scancode receiving |
ScancodeStart:LongWord;
|
The scancode buffer to use for the next receive |
ScancodeCount:LongWord;
|
The number of scancode buffers that are in use |
LastCode:Word;
|
The scan code of the last key pressed |
ShiftState:LongWord;
|
The modifier flags of the current shift state |
Statistics Properties | |
DiscardCount:LongWord;
|
Number of received bytes discarded (due to no buffer or other reasons) |
InterruptCount:LongWord;
|
Number of interrupt requests received by the device |
PL050 mouse packet
PPL050MousePacket = ^TPL050MousePacket;
TPL050MousePacket = record
Mouse:PPL050Mouse;
|
|
Count:LongWord;
|
|
Packet:TPS2MousePacket;
|
PL050 mouse
PPL050Mouse = ^TPL050Mouse;
TPL050Mouse = record
Mouse Properties | |
Mouse:TMouseDevice;
|
|
PL050 Properties | |
IRQ:LongWord;
|
|
Registers:PPL050KMIRegisters;
|
Device registers |
PacketData:array[0..(PL050_MOUSE_PACKET_COUNT - 1)] of TPL050MousePacket;
|
Buffers for mouse packet receiving |
PacketStart:LongWord;
|
The mouse packet buffer to use for the next receive |
PacketCount:LongWord;
|
The number of mouse packet buffers that are in use |
Statistics Properties | |
DiscardCount:LongWord;
|
Number of received bytes discarded (due to no buffer or other reasons) |
InterruptCount:LongWord;
|
Number of interrupt requests received by the device |
Public variables
None defined
Function declarations
PL050 functions
function PL050KeyboardCreate(Address:PtrUInt; const Name:String; IRQ,ClockRate:LongWord):PKeyboardDevice;
Address | The address of the PL050 registers |
---|---|
Name | The text description of this device which will show in the device list (Optional) |
IRQ | The interrupt number for the PL050 |
ClockRate | The clock source frequency for the PL050 |
Return | Pointer to the new Keyboard device or nil if the Keyboard device could not be created |
function PL050KeyboardDestroy(Keyboard:PKeyboardDevice):LongWord;
Keyboard | The Keyboard device to destroy |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050MouseCreate(Address:PtrUInt; const Name:String; IRQ,ClockRate:LongWord):PMouseDevice;
Address | The address of the PL050 registers |
---|---|
Name | The text description of this device which will show in the device list (Optional) |
IRQ | The interrupt number for the PL050 |
ClockRate | The clock source frequency for the PL050 |
Return | Pointer to the new Mouse device or nil if the Mouse device could not be created |
function PL050MouseDestroy(Mouse:PMouseDevice):LongWord;
Mouse | The Mouse device to destroy |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
PL050 keyboard functions
function PL050KeyboardControl(Keyboard:PKeyboardDevice; Request:Integer Argument1:PtrUInt; var Argument2:PtrUInt):LongWord;
Note | Not intended to be called directly by applications, use KeyboardDeviceControl instead. |
---|
procedure PL050KeyboardInterruptHandler(Keyboard:PKeyboardDevice);
Note | Not intended to be called directly by applications |
---|
procedure PL050KeyboardWorker(Scancode:PPL050KeyboardScancode);
Note | Not intended to be called directly by applications |
---|
PL050 mouse functions
function PL050MouseControl(Mouse:PMouseDevice; Request:Integer; Argument1:PtrUInt; var Argument2:PtrUInt):LongWord;
Note | Not intended to be called directly by applications, use MouseDeviceControl instead. |
---|
procedure PL050MouseInterruptHandler(Mouse:PMouseDevice);
Note | Not intended to be called directly by applications |
---|
procedure PL050MouseWorker(Packet:PPL050MousePacket);
Note | Not intended to be called directly by applications |
---|
PL050 helper functions
function PL050KMIClear(Registers:PPL050KMIRegisters):LongWord;
Registers | Pointer to the PL050 KMI registers for the device |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIRead(Registers:PPL050KMIRegisters; var Value:Byte):LongWord;
Registers | Pointer to the PL050 KMI registers for the device |
---|---|
Value | The returned value read from the device |
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIWrite(Registers:PPL050KMIRegisters; Value:Byte):LongWord;
Registers | Pointer to the PL050 KMI registers for the device |
---|---|
Value | The data value to write to the device |
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMICommand(Registers:PPL050KMIRegisters; Command:Byte; Data:PByte; DataSize:LongWord; Response:PByte; ResponseSize:LongWord):LongWord;
Registers | Pointer to the PL050 KMI registers for the device |
---|---|
Command | The PS/2 command to send to the device |
Data | Pointer to the data to be sent with the command (Optional) |
DataSize | The size in bytes of the data to be sent |
Response | Pointer to a buffer to store the response from the device (Optional) |
ResponseSize | The size in bytes of the response to be received |
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIKeyboardReset(Keyboard:PPL050Keyboard):LongWord;
Keyboard | The keyboard device to reset |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIKeyboardEnable(Keyboard:PPL050Keyboard):LongWord;
Keyboard | The keyboard device to enable |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIKeyboardDisable(Keyboard:PPL050Keyboard):LongWord;
Keyboard | The keyboard device to disable |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
function PL050KMIKeyboardSetLEDs(Keyboard:PPL050Keyboard; LEDs:LongWord):LongWord;
Keyboard | The keyboard device to set the scancode set for |
---|---|
LEDs | Type keyboard LED values to set (eg KEYBOARD_LED_CAPSLOCK) |
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the keyboard lock |
function PL050KMIKeyboardSetTypematic(Keyboard:PPL050Keyboard; Rate,Delay:LongWord):LongWord;
Keyboard | The keyboard device to set the scancode set for |
---|---|
Rate | Type typematic repeat rate to set (Milliseconds) |
Delay | The typematic repeat delay to set (Repeat rate intervals before first repeat) |
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the keyboard lock |
function PL050KMIKeyboardGetScancodeSet(Keyboard:PPL050Keyboard; var ScancodeSet:Byte):LongWord;
Keyboard | The keyboard device to get the scancode set from |
---|---|
ScancodeSet | The returned scancode set value (eg PS2_KEYBOARD_SCANCODE_SET2) |
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the keyboard lock |
function PL050KMIKeyboardSetScancodeSet(Keyboard:PPL050Keyboard; ScancodeSet:Byte):LongWord;
Keyboard | The keyboard device to set the scancode set for |
---|---|
ScancodeSet | The scancode set to set (eg PS2_KEYBOARD_SCANCODE_SET2) |
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the keyboard lock |
function PL050KMIKeyboardCheckPressed(Keyboard:PPL050Keyboard; ScanCode:Word):Boolean;
Keyboard | The keyboard device to check for |
---|---|
ScanCode | The keyboard scan code to check |
Note | Caller must hold the keyboard lock |
function PL050KMIKeyboardCheckRepeated(Keyboard:PPL050Keyboard; ScanCode:Word):Boolean;
Keyboard | The keyboard device to check for |
---|---|
ScanCode | The keyboard scan code to check |
Note | Caller must hold the keyboard lock |
function PL050KMIMouseReset(Mouse:PPL050Mouse):LongWord;
Mouse | The mouse device to reset |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the mouse lock |
function PL050KMIMouseEnable(Mouse:PPL050Mouse):LongWord;
Mouse | The mouse device to enable |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the mouse lock |
function PL050KMIMouseDisable(Mouse:PPL050Mouse):LongWord;
Mouse | The mouse device to disable |
---|---|
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the mouse lock |
function PL050KMIMouseSetSampleRate(Mouse:PPL050Mouse; Rate:Byte):LongWord;
Mouse | The mouse device to set the rate for |
---|---|
Rate | The sample rate to set (samples per second) |
Return | ERROR_SUCCESS if completed or another error code on failure |
Note | Caller must hold the mouse lock |
Return to Unit Reference