Difference between revisions of "Unit PL050"
(Created page with "Return to Unit Reference === Description === ---- ''To be documented'' === Constants === ---- ''To be documented'' === Type definitions === ---- ''To...") |
|||
(8 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
---- | ---- | ||
− | '' | + | '''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 === | === Constants === | ||
---- | ---- | ||
− | '' | + | |
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''PL050 specific constants''' <code> PL050_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>PL050_KEYBOARD_DESCRIPTION = 'ARM PrimeCell PL050 PS2 Keyboard';</code> | ||
+ | | Description of PL050 Keyboard device | ||
+ | |- | ||
+ | | <code>PL050_MOUSE_DESCRIPTION = 'ARM PrimeCell PL050 PS2 Mouse';</code> | ||
+ | | Description of PL050 Mouse device | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>PL050_KEYBOARD_SCANCODE_COUNT = 256;</code> | ||
+ | | Number of keyboard scancode buffers for receive | ||
+ | |- | ||
+ | | <code>PL050_MOUSE_PACKET_COUNT = 256;</code> | ||
+ | | Number of mouse packet buffers for receive | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>PL050_KEYBOARD_CLOCK_RATE = 8000000;</code> | ||
+ | | Default clock rate | ||
+ | |- | ||
+ | | <code>PL050_MOUSE_CLOCK_RATE = 8000000;</code> | ||
+ | | Default clock rate | ||
+ | |- | ||
+ | |colspan="2"| | ||
+ | |- | ||
+ | | <code>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;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''PL050 control register''' <code> PL050_CR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>PL050_CR_TYPE = (1 shl 5);</code> | ||
+ | | 0 = PS2/AT mode / 1 = No line control bit mode | ||
+ | |- | ||
+ | | <code>PL050_CR_RXINTREN = (1 shl 4);</code> | ||
+ | | Enable receiver interrupt. This bit field is used to enable the PrimeCell KMI receiver interrupt (If KMIRXINTREn = 1, the receiver interrupt is enabled) | ||
+ | |- | ||
+ | | <code>PL050_CR_TXINTREN = (1 shl 3);</code> | ||
+ | | Enable transmitter interrupt. This bit field is used to enable the PrimeCell KMI transmitter interrupt (If KMITXINTREn = 1, the transfer interrupt is enabled) | ||
+ | |- | ||
+ | | <code>PL050_CR_EN = (1 shl 2);</code> | ||
+ | | The enable PrimeCell KMI bit field is used to enable the KMI (If KmiEn = 1, the KMI is enabled) | ||
+ | |- | ||
+ | | <code>PL050_CR_FDL = (1 shl 1);</code> | ||
+ | | 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) | ||
+ | |- | ||
+ | | <code>PL050_CR_FCL = (1 shl 0);</code> | ||
+ | | 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) | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''PL050 status register''' <code> PL050_STAT_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>PL050_STAT_TXEMPTY = (1 shl 6);</code> | ||
+ | | 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) | ||
+ | |- | ||
+ | | <code>PL050_STAT_TXBUSY = (1 shl 5);</code> | ||
+ | | This bit indicates that the PrimeCell KMI is currently sending data (0 = Idle / 1 = Currently sending data) | ||
+ | |- | ||
+ | | <code>PL050_STAT_RXFULL = (1 shl 4);</code> | ||
+ | | 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) | ||
+ | |- | ||
+ | | <code>PL050_STAT_RXBUSY = (1 shl 3);</code> | ||
+ | | This bit indicates that the PrimeCell KMI is currently receiving data (0 = Idle / 1 = Currently receiving data) | ||
+ | |- | ||
+ | | <code>PL050_STAT_RXPARITY = (1 shl 2);</code> | ||
+ | | This bit reflects the parity bit for the last received data byte (odd parity) | ||
+ | |- | ||
+ | | <code>PL050_STAT_IC = (1 shl 1);</code> | ||
+ | | This bit reflects the status of the KMICLKIN line after synchronizing and sampling | ||
+ | |- | ||
+ | | <code>PL050_STAT_ID = (1 shl 0);</code> | ||
+ | | This bit reflects the status of the KMIDATAIN line after synchronizing | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;"> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''PL050 interrupt register''' <code> PL050_IIR_* </code></div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>PL050_IIR_TXINTR = (1 shl 1);</code> | ||
+ | | This bit is set to 1 if the KMITXINTR transmit interrupt is asserted | ||
+ | |- | ||
+ | | <code>PL050_IIR_RXINTR = (1 shl 0);</code> | ||
+ | | This bit is set to 1 if the KMIRXINTR receive interrupt is asserted | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Type definitions === | === Type definitions === | ||
---- | ---- | ||
− | '' | + | |
+ | '''PL050 KMI registers''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PPL050KMIRegisters = ^TPL050KMIRegisters;</code> | ||
+ | |||
+ | <code>TPL050KMIRegisters = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|Note: Layout of the PL050 registers (See: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0143c/i1005653.html) | ||
+ | |- | ||
+ | | <code>CR:LongWord;</code> | ||
+ | | Control register | ||
+ | |- | ||
+ | | <code>STAT:LongWord;</code> | ||
+ | | Status register | ||
+ | |- | ||
+ | | <code>DATA:LongWord;</code> | ||
+ | | Received data (read)/Data to be transmitted (write) | ||
+ | |- | ||
+ | | <code>CLKDIV:LongWord;</code> | ||
+ | | Clock divisor register | ||
+ | |- | ||
+ | | <code>IIR:LongWord;</code> | ||
+ | | Interrupt status register | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''PL050 keyboard scancode''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PPL050KeyboardScancode = ^TPL050KeyboardScancode;</code> | ||
+ | |||
+ | <code>TPL050KeyboardScancode = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>Keyboard:PPL050Keyboard;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>Count:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Index:LongInt;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Scancode:TPS2KeyboardScancode;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''PL050 keyboard''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PPL050Keyboard = ^TPL050Keyboard;</code> | ||
+ | |||
+ | <code>TPL050Keyboard = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''Keyboard Properties'' | ||
+ | |- | ||
+ | | <code>Keyboard:TKeyboardDevice;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"|''PL050 Properties'' | ||
+ | |- | ||
+ | | <code>IRQ:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Registers:PPL050KMIRegisters;</code> | ||
+ | | Device registers | ||
+ | |- | ||
+ | | <code>ScancodeSet:Byte;</code> | ||
+ | | The currently selected scancode set | ||
+ | |- | ||
+ | | <code>ScancodeData:array[0..(PL050_KEYBOARD_SCANCODE_COUNT - 1)] of TPL050KeyboardScancode;</code> | ||
+ | | Buffers for scancode receiving | ||
+ | |- | ||
+ | | <code>ScancodeStart:LongWord;</code> | ||
+ | | The scancode buffer to use for the next receive | ||
+ | |- | ||
+ | | <code>ScancodeCount:LongWord;</code> | ||
+ | | The number of scancode buffers that are in use | ||
+ | |- | ||
+ | | <code>LastCode:Word;</code> | ||
+ | | The scan code of the last key pressed | ||
+ | |- | ||
+ | | <code>ShiftState:LongWord;</code> | ||
+ | | The modifier flags of the current shift state | ||
+ | |- | ||
+ | |colspan="2"|''Statistics Properties'' | ||
+ | |- | ||
+ | | <code>DiscardCount:LongWord;</code> | ||
+ | | Number of received bytes discarded (due to no buffer or other reasons) | ||
+ | |- | ||
+ | | <code>InterruptCount:LongWord;</code> | ||
+ | | Number of interrupt requests received by the device | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''PL050 mouse packet''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PPL050MousePacket = ^TPL050MousePacket;</code> | ||
+ | |||
+ | <code>TPL050MousePacket = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | | <code>Mouse:PPL050Mouse;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | | <code>Count:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Packet:TPS2MousePacket;</code> | ||
+ | | | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | |||
+ | '''PL050 mouse''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;"> | ||
+ | <code>PPL050Mouse = ^TPL050Mouse;</code> | ||
+ | |||
+ | <code>TPL050Mouse = record</code> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | |colspan="2"|''Mouse Properties'' | ||
+ | |- | ||
+ | | <code>Mouse:TMouseDevice;</code> | ||
+ | | style="width: 50%;"| | ||
+ | |- | ||
+ | |colspan="2"|''PL050 Properties'' | ||
+ | |- | ||
+ | | <code>IRQ:LongWord;</code> | ||
+ | | | ||
+ | |- | ||
+ | | <code>Registers:PPL050KMIRegisters;</code> | ||
+ | | Device registers | ||
+ | |- | ||
+ | | <code>PacketData:array[0..(PL050_MOUSE_PACKET_COUNT - 1)] of TPL050MousePacket;</code> | ||
+ | | Buffers for mouse packet receiving | ||
+ | |- | ||
+ | | <code>PacketStart:LongWord;</code> | ||
+ | | The mouse packet buffer to use for the next receive | ||
+ | |- | ||
+ | | <code>PacketCount:LongWord;</code> | ||
+ | | The number of mouse packet buffers that are in use | ||
+ | |- | ||
+ | |colspan="2"|''Statistics Properties'' | ||
+ | |- | ||
+ | | <code>DiscardCount:LongWord;</code> | ||
+ | | Number of received bytes discarded (due to no buffer or other reasons) | ||
+ | |- | ||
+ | | <code>InterruptCount:LongWord;</code> | ||
+ | | Number of interrupt requests received by the device | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
=== Public variables === | === Public variables === | ||
---- | ---- | ||
− | None defined'' | + | ''None defined'' |
=== Function declarations === | === Function declarations === | ||
---- | ---- | ||
− | |||
+ | '''PL050 functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KeyboardCreate(Address:PtrUInt; const Name:String; IRQ,ClockRate:LongWord):PKeyboardDevice;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Create, register and attach a new PL050 Keyboard device which can be accessed using the keyboard API</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KeyboardDestroy(Keyboard:PKeyboardDevice):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Detach, deregister and destroy a PL050 Keyboard device created by this driver</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The Keyboard device to destroy | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050MouseCreate(Address:PtrUInt; const Name:String; IRQ,ClockRate:LongWord):PMouseDevice;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Create, register and attach a new PL050 Mouse device which can be accessed using the mouse API</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050MouseDestroy(Mouse:PMouseDevice):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Detach, deregister and destroy a PL050 Mouse device created by this driver</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Mouse | ||
+ | | The Mouse device to destroy | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''PL050 keyboard functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KeyboardControl(Keyboard:PKeyboardDevice; Request:Integer Argument1:PtrUInt; var Argument2:PtrUInt):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of KeyboardDeviceControl API for PL050 Keyboard</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use KeyboardDeviceControl instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure PL050KeyboardInterruptHandler(Keyboard:PKeyboardDevice);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Interrupt handler for the PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure PL050KeyboardWorker(Scancode:PPL050KeyboardScancode);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Worker function for the PL050 keyboard device, called on a worker thread when a recognized scancode is received by the interrupt handler</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''PL050 mouse functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050MouseControl(Mouse:PMouseDevice; Request:Integer; Argument1:PtrUInt; var Argument2:PtrUInt):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Implementation of MouseDeviceControl API for PL050 Mouse</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications, use MouseDeviceControl instead. | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure PL050MouseInterruptHandler(Mouse:PMouseDevice);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Interrupt handler for the PL050 mouse device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">procedure PL050MouseWorker(Packet:PPL050MousePacket);</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Worker function for the PL050 mouse device, called on a worker thread when a new mouse packet is received by the interrupt handler</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Note | ||
+ | | Not intended to be called directly by applications | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | |||
+ | '''PL050 helper functions''' | ||
+ | |||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIClear(Registers:PPL050KMIRegisters):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Clear the read buffer on a PL050 KMI device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Registers | ||
+ | | Pointer to the PL050 KMI registers for the device | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIRead(Registers:PPL050KMIRegisters; var Value:Byte):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Read one byte of data from a PL050 KMI device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIWrite(Registers:PPL050KMIRegisters; Value:Byte):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Write one byte of data to a PL050 KMI device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMICommand(Registers:PPL050KMIRegisters; Command:Byte; Data:PByte; DataSize:LongWord; Response:PByte; ResponseSize:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Send a PS/2 command and data to a PL050 KMI device and wait for the required response</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardReset(Keyboard:PPL050Keyboard):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Reset a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The keyboard device to reset | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardEnable(Keyboard:PPL050Keyboard):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Enable a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The keyboard device to enable | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardDisable(Keyboard:PPL050Keyboard):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Disable a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The keyboard device to disable | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardSetLEDs(Keyboard:PPL050Keyboard; LEDs:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set the keyboard LEDs for a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardSetTypematic(Keyboard:PPL050Keyboard; Rate,Delay:LongWord):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set the typematic rate and delay for a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardGetScancodeSet(Keyboard:PPL050Keyboard; var ScancodeSet:Byte):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the current scancode set from a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardSetScancodeSet(Keyboard:PPL050Keyboard; ScancodeSet:Byte):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set the scancode set for a PL050 keyboard device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardCheckPressed(Keyboard:PPL050Keyboard; ScanCode:Word):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Check if the passed scan code has been pressed (True if not previously pressed)</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The keyboard device to check for | ||
+ | |- | ||
+ | ! ScanCode | ||
+ | | The keyboard scan code to check | ||
+ | |- | ||
+ | ! Note | ||
+ | | Caller must hold the keyboard lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIKeyboardCheckRepeated(Keyboard:PPL050Keyboard; ScanCode:Word):Boolean;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Check if the passed scan code was the last key pressed and if the repeat delay has expired</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Keyboard | ||
+ | | The keyboard device to check for | ||
+ | |- | ||
+ | ! ScanCode | ||
+ | | The keyboard scan code to check | ||
+ | |- | ||
+ | ! Note | ||
+ | | Caller must hold the keyboard lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIMouseReset(Mouse:PPL050Mouse):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Reset a PL050 mouse device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Mouse | ||
+ | | The mouse device to reset | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! Note | ||
+ | | Caller must hold the mouse lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIMouseEnable(Mouse:PPL050Mouse):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Enable a PL050 mouse device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Mouse | ||
+ | | The mouse device to enable | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! Note | ||
+ | | Caller must hold the mouse lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIMouseDisable(Mouse:PPL050Mouse):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Disable a PL050 mouse device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! Mouse | ||
+ | | The mouse device to disable | ||
+ | |- | ||
+ | ! Return | ||
+ | | ERROR_SUCCESS if completed or another error code on failure | ||
+ | |- | ||
+ | ! Note | ||
+ | | Caller must hold the mouse lock | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
+ | <div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;"> | ||
+ | <pre style="border: 0; padding-bottom:0px;">function PL050KMIMouseSetSampleRate(Mouse:PPL050Mouse; Rate:Byte):LongWord;</pre> | ||
+ | <div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set the sample rate on a PL050 mouse device</div> | ||
+ | <div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;"> | ||
+ | {| class="wikitable" style="font-size: 14px; background: white;" | ||
+ | |- | ||
+ | ! 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 | ||
+ | |- | ||
+ | |} | ||
+ | </div></div> | ||
+ | <br /> | ||
Return to [[Unit_Reference|Unit Reference]] | Return to [[Unit_Reference|Unit Reference]] |
Latest revision as of 03:18, 17 November 2022
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