PS/2 keyboard driver IP core
for Xilinx EDK
Martin Tùma, FEL ÈVUT
Features
- Provides high-level interface for communication with a PS/2 device
- Full bidirectional PS/2 protocol support
- Provides polling mode and interrupt mode interface to the device
- Usable on all boards with PS/2 connector supported by Xilinx EDK
Introduction
This application note describes a PS/2 keyboard driver EDK IP core which
handles the physical and electrical part of the PS/2 protocol and provides
a command based, high-level interface for communication with a PS/2 keyboard.
Description
Synopsis
#include <ps2_kbd_driver.h>
void ps2_kbd_init(PS2KbdInst *instance,
Xuint32 baseaddr, PS2KbdMode opmode)
void ps2_kbd_set_irq_handler(PS2KbdInst *instance,
ps2_kbd_irq_handler hndlr)
Xuint8 ps2_kbd_get_code(PS2KbdInst *instance)
void ps2_kbd_set_code(PS2KbdInst *instance, Xuint8 code)
void ps2_kbd_irq_handler(void *instance)
XStatus ps2_kbd_selftest(PS2KbdInst *instance)
Description
The ps2_kbd_init() function initializes an instance of the driver for
the device given by it's base address. It also sets the operation mode of the
device which can by either PS2_KBD_POLLING_MODE or
PS2_KBD_IRQ_MODE.
If interrupt mode set, the function ps2_kbd_set_irq_handler sets the
user interrupt handler for the device. Received data is automaticaly stored in
drivers FIFO. If you want to handle the received scancode in the interrupt
handler self, you can call ps2_kbd_get_code() in the handler.
The ps2_kbd_get_code() function returns the last scancode/response
command sent by the keyboard if a new scancode/command has arrived since the
last function call, zero otherwise. When the received scan code is not valid
(parity error), the function initializes sending a repeat command (0xFE) to the
device and returns 0. If in interrupt mode, data is read from the internal
FIFO.
The ps2_kbd_set_code() function sends a command with the value
code to the keyboard. This function always succeeds as the host is the
bus master in the PS/2 protocol. If another one send operation is still in
progress while the function is called, the function waits until the previous
transmission is finished.
If the device is in interrupt mode, ps2_kbd_irq_handler() has to be
registred as the interrupt handler for the device in Xilkernel or on the IRQ
controller on standalone systems.
Design Files
The accompanying ZIP file (ps2_kbd_driver.zip) contains the following
files:
Structure
- drivers
- ps2_kbd_driver_v1_00_a
- data
- ps2_kbd_driver_v2_1_0.mdd
- ps2_kbd_driver_v2_1_0.tcl
- src
- Makefile
- ps2_kbd_driver.c
- ps2_kbd_driver.h
- ps2_kbd_driver_l.h
- ps2_kbd_driver_selftest.c
- pcores
- ps2_kbd_driver_v1_00_a
- data
- ps2_kbd_driver_v2_1_0.mpd
- ps2_kbd_driver_v2_1_0.pao
- hdl
- vhdl
- ps2_clk_mod.vhd
- ps2_drv.vhd
- ps2_kbd_driver.vhd
- ps2_mainfsm_mod.vhd
- ps2_rcv_mod.vhd
- ps2_send_mod.vhd
- user_logic.vhd
Description
- ps2_kbd_driver_v2_1_0.mpd
- Microprocessor Peripheral Definition file (MPD). Describes bus and
external port connections of the peripheral device.
- ps2_kbd_driver_v2_1_0.pao
- Peripheral Analyse Order file (PAO). Dictates the correct order of
synthesis for the VHDL source files.
- ps2_kbd_driver.vhd
- Peripheral top level design. Instantiates the IPIF and user
logic.
- user_logic.vhd
- Connects the PS2 driver main module to the OPB throught the IPIF.
- ps2_drv.vhd
- PS2 driver main module.
- ps2_mainfsm_mod.vhd
- PS2 driver main FSM - switches between the transmit and the recieve
module.
- ps2_clk_mod.vhd
- PS2 driver clock module. Filters PS2 clock and detects
falling/rising edge on it.
- ps2_rcv_mod.vhd
- PS2 driver receive module. Handles incoming PS2 communication.
- ps2_send_mod.vhd
- PS2 driver transmit module. Handles outgoing PS2 communication.
- ps2_kbd_driver_v2_1_0.mdd
- Microprocessor Driver Definition file (MDD). Lists the peripherals
that are able to use the software driver.
- ps2_kbd_driver_v2_1_0.tcl
- TCL script used by EDK for
#define statements
generation (e.g. baseaddress) in the xparameters.h header
file.
- Makefile
- Makefile used for building the SW driver.
- ps2_kbd_driver.c
- Software driver source file.
- ps2_kbd_driver.h
- Software driver header file.
- ps2_kbd_driver_l.h
- Software driver low-level macros & definitions.
- ps2_kbd_driver_selftest.c
- Peripheral self-test. Contains code to test the correct operation
of the peripheral.
Design Implementation
This section describes how to create a simple EDK project to see a working
demo of the peripheral driver.
- Start EDK and create a new project with the Base System Builder (BSB).
You can find detailed instructions how to do this in the EDK tutorial
[1].
In the peripheral selection part of the wizard leave all devices exept RS232
(will be used as STDIN and STDOUT) unchecked. Also disable the creation of
all sample applications (Memory test, Peripheral SelfTest).
- Copy both top directories (pcores, drivers) of the accompanying archive
to the root directory of your new EDK project.
- In the main EDK menu select: "Project"->"Rescan User Repositories".
- In the "Project Information Area" select "IP Catalog". Under "Project
Local pcores" you should see "PS2_KBD_DRIVER". Double click on it to add the
IP to the design. A ps2_kbd_driver_0 item should now appear in the
System Assembly View window.
- Connect the IP to the OPB bus by selecting mp_opb as the bus
connection for the SOPB connector of ps2_kbd_driver_0 in the
System Assembly View window.
- Switch the "Filters" radio button to "Ports" and connect the IP ports.
Set ps2_kbd_driver_0_PS2_clk net for PS2_clk and
ps2_kbd_driver_0_PS2_data for PS2_data. If you intend to use
the device in interrupt mode, also connect the interrupt port to the
interrupt port of the processor (or the interrupt controller when used).
- Switch the "Filters" radio button to "Addresses" and click on the
"Generate Addresses" button.
- If other Processor-Bus clock frequency then 50 MHz is used, a matching
C_OPB_Clk_FREQ_HZ generic value must be chosen in the IP core
configuration ("System Assembly View
window"->"ps2_kbd_driver_0"->"Configure IP").
- Edit the UCF file. You can open it from the "Project Information Area"
window under the "Project" bookmark. Add constraints for the PS2 clock and
PS2 data pins. Name the pins PS2_clk and PS2_data. The
constraints are board-specific and you can find them in the documentation
for your board. For example for the Spartan-3E Starter board you need to add
the following to the UCF file:
NET PS2_clk LOC = G14 | IOSTANDARD = LVCMOS33;
NET PS2_data LOC = G13 | IOSTANDARD = LVCMOS33;
- Edit the MHS file. Add the following two lines at the end of the file:
PORT PS2_clk = ps2_kbd_driver_0_PS2_clk, DIR=IO
PORT PS2_data = ps2_kbd_driver_0_PS2_data, DIR=IO
- In the main menu click on "Hardware"->"Generate Bitstream". The HW
part of the project should now successfully synthetize.
- In the "Project Information Area" select "Applications" and click on
"Add Software Application Project" to create a new SW project.
- Add a new source to the created SW project with the following content:
#include "xparameters.h"
#include "ps2_kbd_driver.h"
void main() {
PS2KbdInst kbd;
ps2_kbd_init (
&kbd,
XPAR_PS2_KBD_DRIVER_0_BASEADDR,
PS2_KBD_POLLING_MODE
);
ps2_kbd_selftest(&kbd);
}
- Select the SW project to initialize the BRAM in the "Project Information
Area". Disable any other application (microblaze_0_bootloop,
microblaze_0_xmdstub) to initialize the BRAM.
- In the EDK main menu select "Software"->"Build All User Applications".
The SW project should successfully compile.
- Select "Device Configuration"->"Download Bitstream" to program the
device.
A keyboard connected to the FPGA board should blink with its leds like start
lights as soon as the FPGA finishes its configuration. Informations about the
process of the selftest are also writen to STDOUT (RS232).
Implementation notes
Although the IP core/driver was primary designed for a ps2 keyboard, it can
be used (except the self-test function of course) for any PS2 device, for
example a mouse, since it only handles byte transfers from/to device which are
independent on the upper layer protocol.
References
[1]
http://www.xilinx.com/support/techsup/tutorials/edk_tutorials.htm
Atachments
1. ps2_kbd_driver.zip
- A ZIP archive containing the sources