|
- /*
- PS2Keyboard.cpp - PS2Keyboard library
- Copyright (c) 2007 Free Software Foundation. All right reserved.
- Written by Christian Weichel <info@32leaves.net>
-
- ** Mostly rewritten Paul Stoffregen <paul@pjrc.com> 2010, 2011
- ** Modified for use beginning with Arduino 13 by L. Abraham Smith, <n3bah@microcompdesign.com> *
- ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan <cuninganreset@gmail.com> **
-
- for more information you can read the original wiki in arduino.cc
- at http://www.arduino.cc/playground/Main/PS2Keyboard
- or http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
-
- Version 2.4 (March 2013)
- - Support Teensy 3.0, Arduino Due, Arduino Leonardo & other boards
- - French keyboard layout, David Chochoi, tchoyyfr at yahoo dot fr
-
- Version 2.3 (October 2011)
- - Minor bugs fixed
-
- Version 2.2 (August 2011)
- - Support non-US keyboards - thanks to Rainer Bruch for a German keyboard :)
-
- Version 2.1 (May 2011)
- - timeout to recover from misaligned input
- - compatibility with Arduino "new-extension" branch
- - TODO: send function, proposed by Scott Penrose, scooterda at me dot com
-
- Version 2.0 (June 2010)
- - Buffering added, many scan codes can be captured without data loss
- if your sketch is busy doing other work
- - Shift keys supported, completely rewritten scan code to ascii
- - Slow linear search replaced with fast indexed table lookups
- - Support for Teensy, Arduino Mega, and Sanguino added
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
- #include "PS2Keyboard.h"
-
- #define BUFFER_SIZE 45
- static volatile uint8_t buffer[BUFFER_SIZE];
- static volatile uint8_t head, tail;
- static uint8_t DataPin;
- static uint8_t CharBuffer=0;
- static uint8_t UTF8next=0;
- static const PS2Keymap_t *keymap=NULL;
-
- // The ISR for the external interrupt
- void ps2interrupt(void)
- {
- static uint8_t bitcount=0;
- static uint8_t incoming=0;
- static uint32_t prev_ms=0;
- uint32_t now_ms;
- uint8_t n, val;
-
- val = digitalRead(DataPin);
- now_ms = millis();
- if (now_ms - prev_ms > 250) {
- bitcount = 0;
- incoming = 0;
- }
- prev_ms = now_ms;
- n = bitcount - 1;
- if (n <= 7) {
- incoming |= (val << n);
- }
- bitcount++;
- if (bitcount == 11) {
- uint8_t i = head + 1;
- if (i >= BUFFER_SIZE) i = 0;
- if (i != tail) {
- buffer[i] = incoming;
- head = i;
- }
- bitcount = 0;
- incoming = 0;
- }
- }
-
- static inline uint8_t get_scan_code(void)
- {
- uint8_t c, i;
-
- i = tail;
- if (i == head) return 0;
- i++;
- if (i >= BUFFER_SIZE) i = 0;
- c = buffer[i];
- tail = i;
- return c;
- }
-
- // http://www.quadibloc.com/comp/scan.htm
- // http://www.computer-engineering.org/ps2keyboard/scancodes2.html
-
- // These arrays provide a simple key map, to turn scan codes into ISO8859
- // output. If a non-US keyboard is used, these may need to be modified
- // for the desired output.
- //
-
- const PROGMEM PS2Keymap_t PS2Keymap_US = {
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '`', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
- 0, 0, 'z', 's', 'a', 'w', '2', 0,
- 0, 'c', 'x', 'd', 'e', '4', '3', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'y', '6', 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '/', 'l', ';', 'p', '-', 0,
- 0, 0, '\'', 0, '[', '=', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, ']', 0, '\\', 0, 0,
- 0, 0, 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '~', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
- 0, 0, 'Z', 'S', 'A', 'W', '@', 0,
- 0, 'C', 'X', 'D', 'E', '$', '#', 0,
- 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
- 0, 'N', 'B', 'H', 'G', 'Y', '^', 0,
- 0, 0, 'M', 'J', 'U', '&', '*', 0,
- 0, '<', 'K', 'I', 'O', ')', '(', 0,
- 0, '>', '?', 'L', ':', 'P', '_', 0,
- 0, 0, '"', 0, '{', '+', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '}', 0, '|', 0, 0,
- 0, 0, 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 0
- };
-
-
- const PROGMEM PS2Keymap_t PS2Keymap_German = {
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '^', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
- 0, 0, 'y', 's', 'a', 'w', '2', 0,
- 0, 'c', 'x', 'd', 'e', '4', '3', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'z', '6', 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '-', 'l', PS2_o_DIAERESIS, 'p', PS2_SHARP_S, 0,
- 0, 0, PS2_a_DIAERESIS, 0, PS2_u_DIAERESIS, '\'', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '+', 0, '#', 0, 0,
- 0, '<', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_DEGREE_SIGN, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
- 0, 0, 'Y', 'S', 'A', 'W', '"', 0,
- 0, 'C', 'X', 'D', 'E', '$', PS2_SECTION_SIGN, 0,
- 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
- 0, 'N', 'B', 'H', 'G', 'Z', '&', 0,
- 0, 0, 'M', 'J', 'U', '/', '(', 0,
- 0, ';', 'K', 'I', 'O', '=', ')', 0,
- 0, ':', '_', 'L', PS2_O_DIAERESIS, 'P', '?', 0,
- 0, 0, PS2_A_DIAERESIS, 0, PS2_U_DIAERESIS, '`', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '*', 0, '\'', 0, 0,
- 0, '>', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 1,
- // with altgr
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, 0, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, '@', 0, 0,
- 0, 0, 0, 0, 0, 0, PS2_SUPERSCRIPT_TWO, 0,
- 0, 0, 0, 0, PS2_CURRENCY_SIGN, 0, PS2_SUPERSCRIPT_THREE, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, PS2_MICRO_SIGN, 0, 0, '{', '[', 0,
- 0, 0, 0, 0, 0, '}', ']', 0,
- 0, 0, 0, 0, 0, 0, '\\', 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '~', 0, '#', 0, 0,
- 0, '|', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 }
- };
-
-
- const PROGMEM PS2Keymap_t PS2Keymap_French = {
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_SUPERSCRIPT_TWO, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'a', '&', 0,
- 0, 0, 'w', 's', 'q', 'z', PS2_e_ACUTE, 0,
- 0, 'c', 'x', 'd', 'e', '\'', '"', 0,
- 0, ' ', 'v', 'f', 't', 'r', '(', 0,
- 0, 'n', 'b', 'h', 'g', 'y', '-', 0,
- 0, 0, ',', 'j', 'u', PS2_e_GRAVE, '_', 0,
- 0, ';', 'k', 'i', 'o', PS2_a_GRAVE, PS2_c_CEDILLA, 0,
- 0, ':', '!', 'l', 'm', 'p', ')', 0,
- 0, 0, PS2_u_GRAVE, 0, '^', '=', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '$', 0, '*', 0, 0,
- 0, '<', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, 0, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'A', '1', 0,
- 0, 0, 'W', 'S', 'Q', 'Z', '2', 0,
- 0, 'C', 'X', 'D', 'E', '4', '3', 0,
- 0, ' ', 'V', 'F', 'T', 'R', '5', 0,
- 0, 'N', 'B', 'H', 'G', 'Y', '6', 0,
- 0, 0, '?', 'J', 'U', '7', '8', 0,
- 0, '.', 'K', 'I', 'O', '0', '9', 0,
- 0, '/', PS2_SECTION_SIGN, 'L', 'M', 'P', PS2_DEGREE_SIGN, 0,
- 0, 0, '%', 0, PS2_DIAERESIS, '+', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, PS2_POUND_SIGN, 0, PS2_MICRO_SIGN, 0, 0,
- 0, '>', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 1,
- // with altgr
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, 0, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, '@', 0, 0,
- 0, 0, 0, 0, 0, 0, '~', 0,
- 0, 0, 0, 0, 0 /*PS2_EURO_SIGN*/, '{', '#', 0,
- 0, 0, 0, 0, 0, 0, '[', 0,
- 0, 0, 0, 0, 0, 0, '|', 0,
- 0, 0, 0, 0, 0, '`', '\\', 0,
- 0, 0, 0, 0, 0, '@', '^', 0,
- 0, 0, 0, 0, 0, 0, ']', 0,
- 0, 0, 0, 0, 0, 0, '}', 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, PS2_CURRENCY_SIGN, 0, '#', 0, 0,
- 0, '|', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 }
- };
-
- const PROGMEM PS2Keymap_t PS2Keymap_Spanish = {
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_MASCULINE_ORDINAL, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
- 0, 0, 'z', 's', 'a', 'w', '2', 0,
- 0, 'c', 'x', 'd', 'e', '4', '3', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'y', '6', 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '-', 'l', 'n', 'p', '\'', 0,
- 0, 0, PS2_ACUTE_ACCENT, 0, '`', PS2_INVERTED_EXCLAMATION, 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '+', 0, PS2_c_CEDILLA, 0, 0,
- 0, '<', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_FEMININE_ORDINAL, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
- 0, 0, 'Z', 'S', 'A', 'W', '\"', 0,
- 0, 'C', 'X', 'D', 'E', '$', PS2_MIDDLE_DOT, 0,
- 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
- 0, 'N', 'B', 'H', 'G', 'Y', '&', 0,
- 0, 0, 'M', 'J', 'U', '/', '(', 0,
- 0, ';', 'K', 'I', 'O', '=', ')', 0,
- 0, ':', '_', 'L', 'N', 'P', '?', 0,
- 0, 0, PS2_DIAERESIS, 0, '^', PS2_INVERTED_QUESTION_MARK, 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '*', 0, PS2_C_CEDILLA, 0, 0,
- 0, '>', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 1,
- // with altgr
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '\\', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '|', 0,
- 0, 0, 'z', 's', 'a', 'w', '@', 0,
- 0, 'c', 'x', 'd', PS2_EURO_SIGN, '~', '#', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'y', PS2_NOT_SIGN, 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '-', 'l', 'n', 'p', '\'', 0,
- 0, 0, '{', 0, '[', PS2_INVERTED_EXCLAMATION, 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, ']', 0, '}', 0, 0,
- 0, '|', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 }
- };
-
- const PROGMEM PS2Keymap_t PS2Keymap_Italian = {
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '\\', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
- 0, 0, 'z', 's', 'a', 'w', '2', 0,
- 0, 'c', 'x', 'd', 'e', '4', '3', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'y', '6', 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '-', 'l', PS2_o_GRAVE, 'p', '\'', 0,
- 0, 0, PS2_a_GRAVE, 0, PS2_e_GRAVE, PS2_i_GRAVE, 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '+', 0, PS2_u_GRAVE, 0, 0,
- 0, '<', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '|', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
- 0, 0, 'Z', 'S', 'A', 'W', '\"', 0,
- 0, 'C', 'X', 'D', 'E', '$', PS2_POUND_SIGN, 0,
- 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
- 0, 'N', 'B', 'H', 'G', 'Y', '&', 0,
- 0, 0, 'M', 'J', 'U', '/', '(', 0,
- 0, ';', 'K', 'I', 'O', '=', ')', 0,
- 0, ':', '_', 'L', PS2_c_CEDILLA, 0, '?', 0,
- 0, 0, PS2_DEGREE_SIGN, 0, PS2_e_ACUTE, '^', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '*', 0, PS2_SECTION_SIGN, 0, 0,
- 0, '>', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 1,
- // with altgr
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, PS2_NOT_SIGN, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', PS2_SUPERSCRIPT_ONE, 0,
- 0, 0, 'z', 's', 'a', 'w', PS2_SUPERSCRIPT_TWO, 0,
- 0, 'c', 'x', 'd', PS2_EURO_SIGN, PS2_FRACTION_ONE_QUARTER, PS2_SUPERSCRIPT_THREE, 0,
- 0, ' ', 'v', 'f', 't', 'r', PS2_FRACTION_ONE_HALF, 0,
- 0, 'n', 'b', 'h', 'g', 'y', PS2_NOT_SIGN, 0,
- 0, 0, 'm', 'j', 'u', '{', '[', 0,
- 0, ',', 'k', 'i', 'o', '}', ']', 0,
- 0, '.', '-', 'l', '@', 'p', '\'', 0,
- 0, 0, '#', 0, '[', '~', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, ']', 0, 0, 0, 0,
- 0, PS2_LEFT_DOUBLE_ANGLE_QUOTE, 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 }
- };
-
- const PROGMEM PS2Keymap_t PS2Keymap_UK = {
- // https://github.com/PaulStoffregen/PS2Keyboard/issues/15
- // without shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, '`', 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'q', '1', 0,
- 0, 0, 'z', 's', 'a', 'w', '2', 0,
- 0, 'c', 'x', 'd', 'e', '4', '3', 0,
- 0, ' ', 'v', 'f', 't', 'r', '5', 0,
- 0, 'n', 'b', 'h', 'g', 'y', '6', 0,
- 0, 0, 'm', 'j', 'u', '7', '8', 0,
- 0, ',', 'k', 'i', 'o', '0', '9', 0,
- 0, '.', '/', 'l', ';', 'p', '-', 0,
- 0, 0, '\'', 0, '[', '=', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, ']', 0, '#', 0, 0,
- 0, '\\', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- // with shift
- {0, PS2_F9, 0, PS2_F5, PS2_F3, PS2_F1, PS2_F2, PS2_F12,
- 0, PS2_F10, PS2_F8, PS2_F6, PS2_F4, PS2_TAB, 172 /* ¬ */, 0,
- 0, 0 /*Lalt*/, 0 /*Lshift*/, 0, 0 /*Lctrl*/, 'Q', '!', 0,
- 0, 0, 'Z', 'S', 'A', 'W', '"', 0,
- 0, 'C', 'X', 'D', 'E', '$', 163 /* £ */, 0,
- 0, ' ', 'V', 'F', 'T', 'R', '%', 0,
- 0, 'N', 'B', 'H', 'G', 'Y', '^', 0,
- 0, 0, 'M', 'J', 'U', '&', '*', 0,
- 0, '<', 'K', 'I', 'O', ')', '(', 0,
- 0, '>', '?', 'L', ':', 'P', '_', 0,
- 0, 0, '@', 0, '{', '+', 0, 0,
- 0 /*CapsLock*/, 0 /*Rshift*/, PS2_ENTER /*Enter*/, '}', 0, '~', 0, 0,
- 0, '|', 0, 0, 0, 0, PS2_BACKSPACE, 0,
- 0, '1', 0, '4', '7', 0, 0, 0,
- '0', '.', '2', '5', '6', '8', PS2_ESC, 0 /*NumLock*/,
- PS2_F11, '+', '3', '-', '*', '9', PS2_SCROLL, 0,
- 0, 0, 0, PS2_F7 },
- 0
- };
-
- #define BREAK 0x01
- #define MODIFIER 0x02
- #define SHIFT_L 0x04
- #define SHIFT_R 0x08
- #define ALTGR 0x10
-
- static char get_iso8859_code(void)
- {
- static uint8_t state=0;
- uint8_t s;
- char c;
-
- while (1) {
- s = get_scan_code();
- if (!s) return 0;
- if (s == 0xF0) {
- state |= BREAK;
- } else if (s == 0xE0) {
- state |= MODIFIER;
- } else {
- if (state & BREAK) {
- if (s == 0x12) {
- state &= ~SHIFT_L;
- } else if (s == 0x59) {
- state &= ~SHIFT_R;
- } else if (s == 0x11 && (state & MODIFIER)) {
- state &= ~ALTGR;
- }
- // CTRL, ALT & WIN keys could be added
- // but is that really worth the overhead?
- state &= ~(BREAK | MODIFIER);
- continue;
- }
- if (s == 0x12) {
- state |= SHIFT_L;
- continue;
- } else if (s == 0x59) {
- state |= SHIFT_R;
- continue;
- } else if (s == 0x11 && (state & MODIFIER)) {
- state |= ALTGR;
- }
- c = 0;
- if (state & MODIFIER) {
- switch (s) {
- case 0x70: c = PS2_INSERT; break;
- case 0x6C: c = PS2_HOME; break;
- case 0x7D: c = PS2_PAGEUP; break;
- case 0x71: c = PS2_DELETE; break;
- case 0x69: c = PS2_END; break;
- case 0x7A: c = PS2_PAGEDOWN; break;
- case 0x75: c = PS2_UPARROW; break;
- case 0x6B: c = PS2_LEFTARROW; break;
- case 0x72: c = PS2_DOWNARROW; break;
- case 0x74: c = PS2_RIGHTARROW; break;
- case 0x4A: c = '/'; break;
- case 0x5A: c = PS2_ENTER; break;
- default: break;
- }
- } else if ((state & ALTGR) && keymap->uses_altgr) {
- if (s < PS2_KEYMAP_SIZE)
- c = pgm_read_byte(keymap->altgr + s);
- } else if (state & (SHIFT_L | SHIFT_R)) {
- if (s < PS2_KEYMAP_SIZE)
- c = pgm_read_byte(keymap->shift + s);
- } else {
- if (s < PS2_KEYMAP_SIZE)
- c = pgm_read_byte(keymap->noshift + s);
- }
- state &= ~(BREAK | MODIFIER);
- if (c) return c;
- }
- }
- }
-
- bool PS2Keyboard::available() {
- if (CharBuffer || UTF8next) return true;
- CharBuffer = get_iso8859_code();
- if (CharBuffer) return true;
- return false;
- }
-
- void PS2Keyboard::clear() {
- CharBuffer = 0;
- UTF8next = 0;
- }
-
- uint8_t PS2Keyboard::readScanCode(void)
- {
- return get_scan_code();
- }
-
- int PS2Keyboard::read() {
- uint8_t result;
-
- result = UTF8next;
- if (result) {
- UTF8next = 0;
- } else {
- result = CharBuffer;
- if (result) {
- CharBuffer = 0;
- } else {
- result = get_iso8859_code();
- }
- if (result >= 128) {
- UTF8next = (result & 0x3F) | 0x80;
- result = ((result >> 6) & 0x1F) | 0xC0;
- }
- }
- if (!result) return -1;
- return result;
- }
-
- int PS2Keyboard::readUnicode() {
- int result;
-
- result = CharBuffer;
- if (!result) result = get_iso8859_code();
- if (!result) return -1;
- UTF8next = 0;
- CharBuffer = 0;
- return result;
- }
-
- PS2Keyboard::PS2Keyboard() {
- // nothing to do here, begin() does it all
- }
-
- void PS2Keyboard::begin(uint8_t data_pin, uint8_t irq_pin, const PS2Keymap_t &map) {
- uint8_t irq_num=255;
-
- DataPin = data_pin;
- keymap = ↦
-
- // initialize the pins
- #ifdef INPUT_PULLUP
- pinMode(irq_pin, INPUT_PULLUP);
- pinMode(data_pin, INPUT_PULLUP);
- #else
- pinMode(irq_pin, INPUT);
- digitalWrite(irq_pin, HIGH);
- pinMode(data_pin, INPUT);
- digitalWrite(data_pin, HIGH);
- #endif
-
- #ifdef CORE_INT_EVERY_PIN
- irq_num = irq_pin;
-
- #else
- switch(irq_pin) {
- #ifdef CORE_INT0_PIN
- case CORE_INT0_PIN:
- irq_num = 0;
- break;
- #endif
- #ifdef CORE_INT1_PIN
- case CORE_INT1_PIN:
- irq_num = 1;
- break;
- #endif
- #ifdef CORE_INT2_PIN
- case CORE_INT2_PIN:
- irq_num = 2;
- break;
- #endif
- #ifdef CORE_INT3_PIN
- case CORE_INT3_PIN:
- irq_num = 3;
- break;
- #endif
- #ifdef CORE_INT4_PIN
- case CORE_INT4_PIN:
- irq_num = 4;
- break;
- #endif
- #ifdef CORE_INT5_PIN
- case CORE_INT5_PIN:
- irq_num = 5;
- break;
- #endif
- #ifdef CORE_INT6_PIN
- case CORE_INT6_PIN:
- irq_num = 6;
- break;
- #endif
- #ifdef CORE_INT7_PIN
- case CORE_INT7_PIN:
- irq_num = 7;
- break;
- #endif
- #ifdef CORE_INT8_PIN
- case CORE_INT8_PIN:
- irq_num = 8;
- break;
- #endif
- #ifdef CORE_INT9_PIN
- case CORE_INT9_PIN:
- irq_num = 9;
- break;
- #endif
- #ifdef CORE_INT10_PIN
- case CORE_INT10_PIN:
- irq_num = 10;
- break;
- #endif
- #ifdef CORE_INT11_PIN
- case CORE_INT11_PIN:
- irq_num = 11;
- break;
- #endif
- #ifdef CORE_INT12_PIN
- case CORE_INT12_PIN:
- irq_num = 12;
- break;
- #endif
- #ifdef CORE_INT13_PIN
- case CORE_INT13_PIN:
- irq_num = 13;
- break;
- #endif
- #ifdef CORE_INT14_PIN
- case CORE_INT14_PIN:
- irq_num = 14;
- break;
- #endif
- #ifdef CORE_INT15_PIN
- case CORE_INT15_PIN:
- irq_num = 15;
- break;
- #endif
- #ifdef CORE_INT16_PIN
- case CORE_INT16_PIN:
- irq_num = 16;
- break;
- #endif
- #ifdef CORE_INT17_PIN
- case CORE_INT17_PIN:
- irq_num = 17;
- break;
- #endif
- #ifdef CORE_INT18_PIN
- case CORE_INT18_PIN:
- irq_num = 18;
- break;
- #endif
- #ifdef CORE_INT19_PIN
- case CORE_INT19_PIN:
- irq_num = 19;
- break;
- #endif
- #ifdef CORE_INT20_PIN
- case CORE_INT20_PIN:
- irq_num = 20;
- break;
- #endif
- #ifdef CORE_INT21_PIN
- case CORE_INT21_PIN:
- irq_num = 21;
- break;
- #endif
- #ifdef CORE_INT22_PIN
- case CORE_INT22_PIN:
- irq_num = 22;
- break;
- #endif
- #ifdef CORE_INT23_PIN
- case CORE_INT23_PIN:
- irq_num = 23;
- break;
- #endif
- }
- #endif
-
- head = 0;
- tail = 0;
- if (irq_num < 255) {
- attachInterrupt(irq_num, ps2interrupt, FALLING);
- }
- }
-
|