Revision: 272 Author: nieklinnenbank Date: Sun Aug 2 04:56:56 2009 Log: Implemented a PS2 keyboard driver using the new Device class. It is usable via /dev/keyboard0 and implements the interrupt() function to update it's state when a key status has changed. http://code.google.com/p/freenos/source/detail?r=272 Added: /trunk/srv/input /trunk/srv/input/SConscript /trunk/srv/input/keyboard /trunk/srv/input/keyboard/Keyboard.cpp /trunk/srv/input/keyboard/Keyboard.h /trunk/srv/input/keyboard/Main.cpp /trunk/srv/input/keyboard/SConscript ======================================= --- /dev/null +++ /trunk/srv/input/SConscript Sun Aug 2 04:56:56 2009 @@ -0,0 +1,18 @@ +# +# Copyright (C) 2009 Niek Linnenbank +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +SConscript(dirs = [ 'keyboard' ]) ======================================= --- /dev/null +++ /trunk/srv/input/keyboard/Keyboard.cpp Sun Aug 2 04:56:56 2009 @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <API/ProcessCtl.h> +#include <Macros.h> +#include <Error.h> +#include <Config.h> +#include "Keyboard.h" + +/** + * Temporary hardcoded keyboard map, from kb.c in SkelixOS. + * @see http://www.skelix.org + */ +const char Keyboard::keymap[0x3a][2] = +{ + /*00*/{0x0, 0x0}, {0x0, 0x0}, {'1', '!'}, {'2', '@'}, + /*04*/{'3', '#'}, {'4', '$'}, {'5', '%'}, {'6', '^'}, + /*08*/{'7', '&'}, {'8', '*'}, {'9', '('}, {'0', ')'}, + /*0c*/{'-', '_'}, {'=', '+'}, {'\b','\b'},{'\t','\t'}, + /*10*/{'q', 'Q'}, {'w', 'W'}, {'e', 'E'}, {'r', 'R'}, + /*14*/{'t', 'T'}, {'y', 'Y'}, {'u', 'U'}, {'i', 'I'}, + /*18*/{'o', 'O'}, {'p', 'P'}, {'[', '{'}, {']', '}'}, + /*1c*/{'\n','\n'},{0x0, 0x0}, {'a', 'A'}, {'s', 'S'}, + /*20*/{'d', 'D'}, {'f', 'F'}, {'g', 'G'}, {'h', 'H'}, + /*24*/{'j', 'J'}, {'k', 'K'}, {'l', 'L'}, {';', ':'}, + /*28*/{'\'','\"'},{'`', '~'}, {0x0, 0x0}, {'\\','|'}, + /*2c*/{'z', 'Z'}, {'x', 'X'}, {'c', 'C'}, {'v', 'V'}, + /*30*/{'b', 'B'}, {'n', 'N'}, {'m', 'M'}, {',', '<'}, + /*34*/{'.', '>'}, {'/', '?'}, {0x0, 0x0}, {'*', '*'}, + /*38*/{0x0, 0x0}, {' ', ' '} +}; + +Keyboard::Keyboard() : shiftState(ZERO) +{ +} + +Error Keyboard::initialize() +{ + return ProcessCtl(SELF, AllowIO, PS2_PORT); +} + +Error Keyboard::interrupt(Size vector) +{ + pending = true; + return ESUCCESS; +} + +Error Keyboard::read(s8 *buffer, Size size, Size offset) +{ + /* Do we have any new key events? */ + if (pending) + { + pending = false; + + /* + * Read byte from the keyboard. + */ + u8 keycode = inb(PS2_PORT); + + /* Update shift state. */ + if (keycode == 0x2a || keycode == 0xaa) + { + shiftState ^= 1; + } + /* Don't do anything on release. */ + else if (!(keycode & PS2_RELEASE) && + (keymap[keycode & 0x7f][shiftState])) + { + /* Write to buffer. */ + buffer[0] = keymap[keycode & 0x7f][shiftState]; + return 1; + } + } + return EAGAIN; +} ======================================= --- /dev/null +++ /trunk/srv/input/keyboard/Keyboard.h Sun Aug 2 04:56:56 2009 @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __INPUT_KEYBOARD_H +#define __INPUT_KEYBOARD_H + +#include <Device.h> +#include <Macros.h> +#include <Types.h> +#include <Error.h> + +/** PS2 Keyboard input port. */ +#define PS2_PORT 0x60 + +/** Interrupt number of the i8042 controller. */ +#define PS2_IRQ 1 + +/** Bit is set in the scancode, if a key is released. */ +#define PS2_RELEASE 0x80 + +/** + * @brief PS2 Keyboard device driver. + */ +class Keyboard : public Device +{ + public: + + /** + * @brief Constructor function. + */ + Keyboard(); + + /** + * @brief Initialize the PS2 Keyboard driver. + * @return Error status code. + */ + Error initialize(); + + /** + * @brief Executed when a key state has changed. + * @param vector Interrupt vector. + * @return Error status code. + */ + Error interrupt(Size vector); + + /** + * @brief Read a character from the keyboard. + * + * @param buffer Output buffer. + * @param size Number of bytes to read. + * @param offset Unused. + * @return Number of bytes read or error code on failure. + */ + Error read(s8 *buffer, Size size, Size offset); + + private: + + /** + * @brief Keyboard map table. + */ + static const char keymap[0x3a][2]; + + /** + * @brief State of the shift key. + * + * Non-zero if pressed, and ZERO otherwise. + */ + u8 shiftState; + + /** Do we have a byte ready? */ + bool pending; +}; + +#endif /* __INPUT_KEYBOARD_H */ ======================================= --- /dev/null +++ /trunk/srv/input/keyboard/Main.cpp Sun Aug 2 04:56:56 2009 @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Niek Linnenbank + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <FileType.h> +#include <DeviceServer.h> +#include "Keyboard.h" +#include <stdlib.h> +#include <unistd.h> + +int main(int argc, char **argv) +{ + DeviceServer server("keyboard", CharacterDeviceFile); + + /* Create a new keyboard object. */ + Keyboard *kb = new Keyboard; + + /* Register it with the DeviceServer. */ + server.add(kb); + server.interrupt(kb, PS2_IRQ); + + /* + * Start processing requests. + */ + return server.run(); +} ======================================= --- /dev/null +++ /trunk/srv/input/keyboard/SConscript Sun Aug 2 04:56:56 2009 @@ -0,0 +1,24 @@ +# +# Copyright (C) 2009 Niek Linnenbank +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +from build import * ++env = Prepare(target, [ 'libcrt', 'liballoc', 'libposix', 'libexec', 'libc', 'libteken' ],
+ [ 'filesystem', 'process', 'memory' ]) + +env.Program('server', [ 'Keyboard.cpp', 'Main.cpp' ], + LIBS = env['LIBS'], LIBPATH = env['LIBPATH'])