From e35a4b7ed3f96fecbea4b232ca30367c9c9e4ca1 Mon Sep 17 00:00:00 2001 From: lahiru Date: Mon, 28 Oct 2024 16:03:34 +0530 Subject: [PATCH 01/12] clear some headder file imports --- PS2Keyboard.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/PS2Keyboard.h b/PS2Keyboard.h index 4931e37..1ea44cc 100644 --- a/PS2Keyboard.h +++ b/PS2Keyboard.h @@ -25,12 +25,9 @@ #ifndef PS2Keyboard_h #define PS2Keyboard_h + +#include // for attachInterrupt, FALLING -#if defined(ARDUINO) && ARDUINO >= 100 -#include "Arduino.h" // for attachInterrupt, FALLING -#else -#include "WProgram.h" -#endif #include "utility/int_pins.h" From 42002ce527f22fca75e98ba3f9eb3d830fdf4fa4 Mon Sep 17 00:00:00 2001 From: lahiru Date: Mon, 28 Oct 2024 16:04:55 +0530 Subject: [PATCH 02/12] Correct interup remove unwanted keymaps --- PS2Keyboard.cpp | 414 +----------------------------------------------- 1 file changed, 6 insertions(+), 408 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index 53bfa1a..bc1de14 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -59,7 +59,7 @@ static uint8_t UTF8next=0; static const PS2Keymap_t *keymap=NULL; // The ISR for the external interrupt -void ps2interrupt(void) +void IRAM_ATTR ps2interrupt(void) { static uint8_t bitcount=0; static uint8_t incoming=0; @@ -152,280 +152,7 @@ const PROGMEM PS2Keymap_t PS2Keymap_US = { 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 -}; + // no hate but I have remove this #define BREAK 0x01 #define MODIFIER 0x02 @@ -556,9 +283,8 @@ 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; - +void PS2Keyboard::begin(uint8_t data_pin, uint8_t irq_pin, const PS2Keymap_t &map) { + uint8_t irq_num = irq_pin; DataPin = data_pin; keymap = ↦ @@ -571,138 +297,10 @@ void PS2Keyboard::begin(uint8_t data_pin, uint8_t irq_pin, const PS2Keymap_t &ma 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 - +#endif head = 0; tail = 0; + irq_num = digitalPinToInterrupt(irq_pin); if (irq_num < 255) { attachInterrupt(irq_num, ps2interrupt, FALLING); } From 25847cc883ba69e493edd0bb546ce8b7633a827b Mon Sep 17 00:00:00 2001 From: lahiru Date: Sat, 2 Nov 2024 09:04:57 +0530 Subject: [PATCH 03/12] implemented caps lock funtion and shift keys to override --- PS2Keyboard.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index bc1de14..75c64ca 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -54,9 +54,14 @@ static volatile uint8_t buffer[BUFFER_SIZE]; static volatile uint8_t head, tail; static uint8_t DataPin; +static uint8_t IRQPin; static uint8_t CharBuffer=0; static uint8_t UTF8next=0; static const PS2Keymap_t *keymap=NULL; +static bool capsLockOn = false; +static bool numLockOn = false; +static bool scrollLockOn = false; +static byte ledState = 0; // The ISR for the external interrupt void IRAM_ATTR ps2interrupt(void) @@ -160,6 +165,14 @@ const PROGMEM PS2Keymap_t PS2Keymap_US = { #define SHIFT_R 0x08 #define ALTGR 0x10 +#define SCROLL_LOCK 0x01 +#define NUM_LOCK 0x02 +#define CAPS_LOCK 0x04 + +#define LED_CONTROL 0xED + + + static char get_iso8859_code(void) { static uint8_t state=0; @@ -195,8 +208,29 @@ static char get_iso8859_code(void) continue; } else if (s == 0x11 && (state & MODIFIER)) { state |= ALTGR; - } - c = 0; + } else if (s == 0x58) { + capsLockOn = !capsLockOn; + if (capsLockOn) { + ledState |= CAPS_LOCK; + } else { + ledState &= ~CAPS_LOCK; + } + } else if (s == 0x77) { + numLockOn = !numLockOn; + if (numLockOn) { + ledState |= NUM_LOCK; + } else { + ledState &= ~NUM_LOCK; + } + } else if (s == 0x7E) { + scrollLockOn = !scrollLockOn; + if (scrollLockOn) { + ledState |= SCROLL_LOCK; + } else { + ledState &= ~SCROLL_LOCK; + } + } + c = 0; if (state & MODIFIER) { switch (s) { case 0x70: c = PS2_INSERT; break; @@ -216,12 +250,22 @@ static char get_iso8859_code(void) } else if ((state & ALTGR) && pgm_read_byte(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); + } else if(capsLockOn){ + if (state & (SHIFT_L | SHIFT_R)) { + if (s < PS2_KEYMAP_SIZE) + c = pgm_read_byte(keymap->noshift + s); + } else { + if (s < PS2_KEYMAP_SIZE) + c = pgm_read_byte(keymap->shift + 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; @@ -229,6 +273,8 @@ static char get_iso8859_code(void) } } + + bool PS2Keyboard::available() { if (CharBuffer || UTF8next) return true; CharBuffer = get_iso8859_code(); @@ -285,6 +331,7 @@ PS2Keyboard::PS2Keyboard() { void PS2Keyboard::begin(uint8_t data_pin, uint8_t irq_pin, const PS2Keymap_t &map) { uint8_t irq_num = irq_pin; + IRQPin= irq_pin; DataPin = data_pin; keymap = ↦ From c9febcbf4a75e035063a21564241ced3d0070809 Mon Sep 17 00:00:00 2001 From: lahiru Date: Sun, 3 Nov 2024 18:47:52 +0530 Subject: [PATCH 04/12] added some ardino support back --- PS2Keyboard.cpp | 360 +++++++++++++++++++++++++++++------------------- 1 file changed, 221 insertions(+), 139 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index 75c64ca..688eec4 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -53,7 +53,7 @@ #define BUFFER_SIZE 45 static volatile uint8_t buffer[BUFFER_SIZE]; static volatile uint8_t head, tail; -static uint8_t DataPin; +static uint8_t dataPin; static uint8_t IRQPin; static uint8_t CharBuffer=0; static uint8_t UTF8next=0; @@ -63,50 +63,121 @@ static bool numLockOn = false; static bool scrollLockOn = false; static byte ledState = 0; +#define LED_CONTROL 0xED + +#ifdef ESP32 +#define SUPPORT_IRAM_ATTR IRAM_ATTR +#else +#define SUPPORT_IRAM_ATTR // Empty definition for non-ESP32 boards +#endif + + +void sendPS2Command(byte command) { + pinMode(dataPin, OUTPUT); + pinMode(IRQPin, OUTPUT); + + unsigned long startMicros = micros(); + + digitalWrite(dataPin, LOW); + while (micros() - startMicros < 100); + startMicros = micros(); + + digitalWrite(IRQPin, LOW); + while (micros() - startMicros < 15); + startMicros = micros(); + + for (int i = 0; i < 8; i++) { + digitalWrite(IRQPin, HIGH); + while (micros() - startMicros < 15); + startMicros = micros(); + + digitalWrite(dataPin, (command >> i) & 1); + while (micros() - startMicros < 15); + startMicros = micros(); + + digitalWrite(IRQPin, LOW); + while (micros() - startMicros < 15); + startMicros = micros(); + } + + // Send Parity bit + digitalWrite(IRQPin, HIGH); + digitalWrite(dataPin, HIGH); + while (micros() - startMicros < 15); + startMicros = micros(); + + digitalWrite(IRQPin, LOW); + while (micros() - startMicros < 15); + startMicros = micros(); + + // Send Stop bit + digitalWrite(IRQPin, HIGH); + digitalWrite(dataPin, HIGH); + while (micros() - startMicros < 100); + + // Set pins back to input mode +#ifdef INPUT_PULLUP + pinMode(IRQPin, INPUT_PULLUP); + pinMode(dataPin, INPUT_PULLUP); +#else + pinMode(IRQPin, INPUT); + digitalWrite(IRQPin, HIGH); + pinMode(DataPin, INPUT); + digitalWrite(DataPin, HIGH); +#endif +} + +static void updateLEDs(byte command){ + + //Serial.print(LED_CONTROL); + sendPS2Command(LED_CONTROL); + // Serial.print(command); + sendPS2Command(command); + // Could not get this working +} + // The ISR for the external interrupt -void IRAM_ATTR 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; - } +void SUPPORT_IRAM_ATTR ps2interrupt(void) { + static uint8_t bitCount = 0; + static uint8_t incoming = 0; + static uint32_t prevMillis = 0; + uint32_t nowMillis; + uint8_t bitPos, val; + + val = digitalRead(dataPin); + nowMillis = millis(); + if (nowMillis - prevMillis > 250) { + bitCount = 0; + incoming = 0; + } + prevMillis = nowMillis; + bitPos = bitCount - 1; + if (bitPos <= 7) { + incoming |= (val << bitPos); + } + 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; +static inline uint8_t getScanCode(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 @@ -173,108 +244,119 @@ const PROGMEM PS2Keymap_t PS2Keymap_US = { -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; - } else if (s == 0x58) { - capsLockOn = !capsLockOn; - if (capsLockOn) { - ledState |= CAPS_LOCK; - } else { - ledState &= ~CAPS_LOCK; +static char get_iso8859_code(void) { + static uint8_t state = 0; + uint8_t scanCode; + char character; + + while (1) { + // Retrieve the scan code + scanCode = getScanCode(); + if (!scanCode) return 0; // No scan code available + + // Handle special cases for scan codes + if (scanCode == 0xF0) { + state |= BREAK; // Set BREAK state + } else if (scanCode == 0xE0) { + state |= MODIFIER; // Set MODIFIER state for extended keys + } else { + // Handle key release (BREAK state) + if (state & BREAK) { + if (scanCode == 0x12) { + state &= ~SHIFT_L; // Release Left Shift + } else if (scanCode == 0x59) { + state &= ~SHIFT_R; // Release Right Shift + } else if (scanCode == 0x11 && (state & MODIFIER)) { + state &= ~ALTGR; // Release AltGr } - } else if (s == 0x77) { - numLockOn = !numLockOn; - if (numLockOn) { - ledState |= NUM_LOCK; - } else { - ledState &= ~NUM_LOCK; + // Reset states and continue to next scan code + state &= ~(BREAK | MODIFIER); + continue; + } + + // Handle key press events for modifiers and locks + if (scanCode == 0x12) { + state |= SHIFT_L; // Left Shift pressed + continue; + } else if (scanCode == 0x59) { + state |= SHIFT_R; // Right Shift pressed + continue; + } else if (scanCode == 0x11 && (state & MODIFIER)) { + state |= ALTGR; // AltGr pressed + } else if (scanCode == 0x58) { + capsLockOn = !capsLockOn; // Toggle Caps Lock + ledState = capsLockOn ? (ledState | CAPS_LOCK) : (ledState & ~CAPS_LOCK); + updateLEDs(ledState); + } else if (scanCode == 0x77) { + numLockOn = !numLockOn; // Toggle Num Lock + ledState = numLockOn ? (ledState | NUM_LOCK) : (ledState & ~NUM_LOCK); + updateLEDs(ledState); + } else if (scanCode == 0x7E) { + scrollLockOn = !scrollLockOn; // Toggle Scroll Lock + ledState = scrollLockOn ? (ledState | SCROLL_LOCK) : (ledState & ~SCROLL_LOCK); + updateLEDs(ledState); + } + + // Process scan codes based on the current state + character = 0; + if (state & MODIFIER) { + // Handle special keys with modifier (like arrow keys) + switch (scanCode) { + case 0x70: character = PS2_INSERT; break; + case 0x6C: character = PS2_HOME; break; + case 0x7D: character = PS2_PAGEUP; break; + case 0x71: character = PS2_DELETE; break; + case 0x69: character = PS2_END; break; + case 0x7A: character = PS2_PAGEDOWN; break; + case 0x75: character = PS2_UPARROW; break; + case 0x6B: character = PS2_LEFTARROW; break; + case 0x72: character = PS2_DOWNARROW; break; + case 0x74: character = PS2_RIGHTARROW; break; + case 0x4A: character = '/'; break; + case 0x5A: character = PS2_ENTER; break; + default: break; } - } else if (s == 0x7E) { - scrollLockOn = !scrollLockOn; - if (scrollLockOn) { - ledState |= SCROLL_LOCK; - } else { - ledState &= ~SCROLL_LOCK; + } else if ((state & ALTGR) && pgm_read_byte(keymap->uses_altgr)) { + // Handle AltGr key combinations + if (scanCode < PS2_KEYMAP_SIZE) { + character = pgm_read_byte(keymap->altgr + scanCode); } - } - 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) && pgm_read_byte(keymap->uses_altgr)) { - if (s < PS2_KEYMAP_SIZE) - c = pgm_read_byte(keymap->altgr + s); - } else if(capsLockOn){ - if (state & (SHIFT_L | SHIFT_R)) { - if (s < PS2_KEYMAP_SIZE) - c = pgm_read_byte(keymap->noshift + s); - } else { - if (s < PS2_KEYMAP_SIZE) - c = pgm_read_byte(keymap->shift + 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; - } - } + } else if (capsLockOn) { + // Handle Caps Lock with or without Shift keys + if (state & (SHIFT_L | SHIFT_R)) { + if (scanCode < PS2_KEYMAP_SIZE) { + character = pgm_read_byte(keymap->noshift + scanCode); + } + } else { + if (scanCode < PS2_KEYMAP_SIZE) { + character = pgm_read_byte(keymap->shift + scanCode); + } + } + } else { + // Handle regular Shift and non-Shift key states + if (state & (SHIFT_L | SHIFT_R)) { + if (scanCode < PS2_KEYMAP_SIZE) { + character = pgm_read_byte(keymap->shift + scanCode); + } + } else { + if (scanCode < PS2_KEYMAP_SIZE) { + character = pgm_read_byte(keymap->noshift + scanCode); + } + } + } + + // Reset the states for the next scan code processing + state &= ~(BREAK | MODIFIER); + + // Return the character if one was generated + if (character) return character; + } + } } + bool PS2Keyboard::available() { if (CharBuffer || UTF8next) return true; CharBuffer = get_iso8859_code(); @@ -289,7 +371,7 @@ void PS2Keyboard::clear() { uint8_t PS2Keyboard::readScanCode(void) { - return get_scan_code(); + return getScanCode(); } int PS2Keyboard::read() { @@ -332,7 +414,7 @@ PS2Keyboard::PS2Keyboard() { void PS2Keyboard::begin(uint8_t data_pin, uint8_t irq_pin, const PS2Keymap_t &map) { uint8_t irq_num = irq_pin; IRQPin= irq_pin; - DataPin = data_pin; + dataPin = data_pin; keymap = ↦ // initialize the pins From 9df6c946ed02a537d30d97dc8e6a9de0b08bf046 Mon Sep 17 00:00:00 2001 From: lahiru Date: Sun, 3 Nov 2024 18:56:08 +0530 Subject: [PATCH 05/12] add static for avoid warning --- PS2Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index 688eec4..d9d0f97 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -72,7 +72,7 @@ static byte ledState = 0; #endif -void sendPS2Command(byte command) { +static void sendPS2Command(byte command) { pinMode(dataPin, OUTPUT); pinMode(IRQPin, OUTPUT); From 52b38b4c8a2841191b2c44581a826c91b946141e Mon Sep 17 00:00:00 2001 From: lahiru Date: Sun, 3 Nov 2024 18:57:11 +0530 Subject: [PATCH 06/12] change variable name --- PS2Keyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index d9d0f97..221fdc0 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -122,8 +122,8 @@ static void sendPS2Command(byte command) { #else pinMode(IRQPin, INPUT); digitalWrite(IRQPin, HIGH); - pinMode(DataPin, INPUT); - digitalWrite(DataPin, HIGH); + pinMode(dataPin, INPUT); + digitalWrite(dataPin, HIGH); #endif } From 765e7ce847d495d3afa6a95b892b7f61c1ab3f61 Mon Sep 17 00:00:00 2001 From: lahiru Date: Sun, 3 Nov 2024 22:48:19 +0530 Subject: [PATCH 07/12] Caps Lock Num lock and Scroll lock implimented --- PS2Keyboard.cpp | 82 ++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 31 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index 221fdc0..b9aaea8 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -71,51 +71,71 @@ static byte ledState = 0; #define SUPPORT_IRAM_ATTR // Empty definition for non-ESP32 boards #endif +// Parity check +// Return true for odd parity. +static bool parityCheck(uint16_t data) +{ + uint8_t count = 0; + for (int i = 0; i < 10; i++) { + count += (data >> i) & 1; + } + return count % 2 != 0; +} +/* +code taken from https://karooza.net/how-to-interface-a-ps2-keyboard +parity was needed and the writing should have done on rising edeg not in falling +*/ +static void sendPS2Command(uint8_t cmdCode) { + uint16_t cmd = cmdCode; // Cast to 16-bit to add parity and stop bits -static void sendPS2Command(byte command) { - pinMode(dataPin, OUTPUT); - pinMode(IRQPin, OUTPUT); + // Add parity bit if not already set + if (!parityCheck(cmd)) { + cmd |= 0x0100; + } - unsigned long startMicros = micros(); + // Add stop bit + cmd |= 0x0200; - digitalWrite(dataPin, LOW); - while (micros() - startMicros < 100); - startMicros = micros(); + // Set clock and data pins to output mode + pinMode(IRQPin, OUTPUT); + pinMode(dataPin, OUTPUT); + // Start Request to Send by pulling clock low for 100us digitalWrite(IRQPin, LOW); - while (micros() - startMicros < 15); + unsigned long startMicros = micros(); + while (micros() - startMicros < 100); // Wait for 100us + + // Pull data low to send the start bit + digitalWrite(dataPin, LOW); startMicros = micros(); + while (micros() - startMicros < 20); // Wait for 20us + + // Release clock line, allowing it to go high + pinMode(IRQPin, INPUT_PULLUP); - for (int i = 0; i < 8; i++) { - digitalWrite(IRQPin, HIGH); - while (micros() - startMicros < 15); - startMicros = micros(); + // Send 8 data bits, 1 parity bit, and 1 stop bit + for (int i = 0; i < 10; i++) { + // Wait for keyboard to take clock low (start of bit transmission) + while (digitalRead(IRQPin) > 0); - digitalWrite(dataPin, (command >> i) & 1); - while (micros() - startMicros < 15); - startMicros = micros(); + // Write the current bit to the data line + digitalWrite(dataPin, cmd & 0x0001); + cmd >>= 1; // Shift to the next bit - digitalWrite(IRQPin, LOW); - while (micros() - startMicros < 15); - startMicros = micros(); + // Wait for the keyboard to take clock high, indicating bit has been sampled + while (digitalRead(IRQPin) < 1); } - // Send Parity bit - digitalWrite(IRQPin, HIGH); - digitalWrite(dataPin, HIGH); - while (micros() - startMicros < 15); - startMicros = micros(); + // Release data line (high) for the stop bit + pinMode(dataPin, INPUT_PULLUP); - digitalWrite(IRQPin, LOW); - while (micros() - startMicros < 15); - startMicros = micros(); + // Wait for keyboard to acknowledge by taking clock low + while (digitalRead(IRQPin) > 0); - // Send Stop bit - digitalWrite(IRQPin, HIGH); - digitalWrite(dataPin, HIGH); - while (micros() - startMicros < 100); + // Wait for keyboard ACK by checking data line goes low + while (digitalRead(dataPin) > 0); - // Set pins back to input mode + // Reset pins to input mode with pull-up resistors #ifdef INPUT_PULLUP pinMode(IRQPin, INPUT_PULLUP); pinMode(dataPin, INPUT_PULLUP); From 5c526a0086d2e15af25d484294665c4d2861d8f1 Mon Sep 17 00:00:00 2001 From: lahiru Date: Mon, 4 Nov 2024 13:40:36 +0530 Subject: [PATCH 08/12] update Readme.md --- README.md | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 931f685..99986f5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,117 @@ -#PS/2 Keyboard Library# +# PS/2 Keyboard Library with ESP32 Support -PS2Keyboard allows you to use a keyboard for user input. +This library provides support for using a PS/2 keyboard as an input device, with additional enhancements to support ESP32, making it compatible with LoRa-based chat applications and improved code structure. -http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html +## Original Project -![](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.jpg) +The original PS/2 Keyboard Library was created by PJRC and allows easy interfacing of a PS/2 keyboard with microcontrollers, such as the Teensy. This library makes it easy to use a keyboard for user input. More details on the original project can be found here: + +- [PS2Keyboard Library](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html) + +![Original Library](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.jpg) + +## New Additions and Enhancements + +This fork includes additional features and improvements: + +- **ESP32 Support**: Added support for the ESP32 platform, making it compatible with LoRa-based chat applications and other ESP32 projects. +- **Efficient Interrupts**: Simplified interrupt handling for easier and more efficient management. +- **Caps Lock with Status LED**: Added support for the Caps Lock key along with an LED status indicator. +- **Code Optimization**: Removed bulky code sections, refactored to a modern C++ style, and enhanced code readability. + +## Getting Started + +### Prerequisites + +- **Platform**: This library is compatible with both the ESP32 and Teensy platforms. +- **Dependencies**: Ensure you have the required PS/2 keyboard and the correct wiring setup for your microcontroller. + +### Installation + +1. Clone this repository or download the library as a ZIP file. +2. Include the library in your project: + - For Arduino IDE: Go to `Sketch` -> `Include Library` -> `Add .ZIP Library...` and select the downloaded file. + - For PlatformIO: Add this library to your project’s `lib` folder. + +The following library dependency is shared across both environments: + +```ini +[common] +lib_deps = + https://github.com/lahirunirmalx/PS2Keyboard#dev-master +``` + +### Environment Configuration + +#### ESP32 Development Board + +This environment is set up for the ESP32 board, utilizing the Arduino framework with a monitor speed of 115200 baud. + +```ini +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +monitor_speed = 115200 +lib_deps = ${common.lib_deps} +``` + +#### Arduino Uno Board + +This environment is configured for the Arduino Uno board, also using the Arduino framework and a monitor speed of 115200 baud. + +```ini +[env:uno] +platform = atmelavr +board = uno +framework = arduino +monitor_speed = 115200 +lib_deps = ${common.lib_deps} +``` + +### Usage + +After installing the library, initialize the PS/2 keyboard with the appropriate pins for data and clock: + +```cpp +#include + +const int DataPin = 13; +const int IRQPin = 12; +PS2Keyboard keyboard; + +void setup() { + Serial.begin(9600); + keyboard.begin(DataPin, IRQPin); + Serial.println("PS/2 Keyboard ready for input..."); +} + +void loop() { + if (keyboard.available()) { + char c = keyboard.read(); + Serial.print(c); + } +} +``` + +Refer to the library's examples for more detailed usage. + +## Contributing + +Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements, feel free to open an issue or submit a pull request. + +### Support the Original Developers + +This project is built upon the great work done by the original authors at PJRC. Please consider supporting their projects and acknowledging their contributions. + +## License + +This project is licensed under the [MIT License](LICENSE). + +--- + +### Acknowledgments + +Thanks to PJRC for the original PS/2 Keyboard Library and all contributors to the ESP32 and LoRa community who make embedded development more accessible. + +--- \ No newline at end of file From dce49b1031968a20e46c8b82c8eafa180d38d5e7 Mon Sep 17 00:00:00 2001 From: lahiru Date: Wed, 15 Jan 2025 18:58:45 +0530 Subject: [PATCH 09/12] add some document changes --- PS2Keyboard.cpp | 5 +++++ library.json | 10 +++++++--- library.properties | 6 +++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index b9aaea8..9356ace 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -6,11 +6,16 @@ ** Mostly rewritten Paul Stoffregen 2010, 2011 ** Modified for use beginning with Arduino 13 by L. Abraham Smith, * ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan ** + ** Modified for ESP32 support ** 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.5 (January 2025) + - Better Inturpts + - Support for ESP32 + 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 diff --git a/library.json b/library.json index 77cc9c1..b6d8d99 100644 --- a/library.json +++ b/library.json @@ -21,15 +21,19 @@ { "name": "Cuningan", "email": "cuninganreset@gmail.com" + }, + { + "name": "Lahiru", + "email": "lahirunirmalx@gmail.com" } ], "repository": { "type": "git", - "url": "https://github.com/PaulStoffregen/PS2Keyboard.git" + "url": "https://github.com/lahirunirmalx/PS2Keyboard.git" }, - "version": "2.4", - "homepage": "http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html", + "version": "2.5", + "homepage": "", "frameworks": "arduino", "platforms": [ diff --git a/library.properties b/library.properties index 340d0ba..fd51f9b 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=PS2Keyboard -version=2.4 -author=Christian Weichel, Paul Stoffregen, L. Abraham Smith, Cuningan +version=2.5 +author=Christian Weichel, Paul Stoffregen, L. Abraham Smith, Cuningan , lahirunirmalx maintainer=Paul Stoffregen sentence=Use a PS/2 Keyboard for input paragraph= category=Signal Input/Output -url=https://github.com/PaulStoffregen/PS2Keyboard +url=https://github.com/lahirunirmalx/PS2Keyboard architectures=* From f667d7b46ffa8f34c1cfbdefe57e31b82532c16b Mon Sep 17 00:00:00 2001 From: lahiru Date: Sun, 3 Nov 2024 22:48:19 +0530 Subject: [PATCH 10/12] Caps Lock Num lock and Scroll lock implimented --- PS2Keyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index 9356ace..f84e135 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -5,8 +5,8 @@ ** Mostly rewritten Paul Stoffregen 2010, 2011 ** Modified for use beginning with Arduino 13 by L. Abraham Smith, * - ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan ** - ** Modified for ESP32 support ** + ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan * + ** Modified for ESP32 support * for more information you can read the original wiki in arduino.cc at http://www.arduino.cc/playground/Main/PS2Keyboard From 0b6b34db211a1a6d8380f45f1097c11b0edc2e72 Mon Sep 17 00:00:00 2001 From: lahiru Date: Tue, 20 Jan 2026 14:07:07 +0530 Subject: [PATCH 11/12] v3.0.0: ESP32/ESP8266 support, code cleanup, and release preparation - Added ESP32 and ESP8266 platform support with IRAM_ATTR interrupt handling - Caps Lock, Num Lock, Scroll Lock LED support - Removed duplicate defines and debug comments - Fixed typos and improved code documentation - Updated library.json with proper platforms and license - Updated library.properties with full description - Enhanced keywords.txt with all methods and constants - Rewrote README.md with comprehensive documentation - Removed International example (referenced non-existent keymaps) - Updated examples with cleaner headers --- PS2Keyboard.cpp | 53 +++--- PS2Keyboard.h | 13 +- README.md | 211 ++++++++++++++++------- examples/International/International.ino | 34 ---- examples/Simple_Test/Simple_Test.ino | 48 +++--- examples/TypeToDisplay/TypeToDisplay.ino | 46 ++--- keywords.txt | 44 ++++- library.json | 31 ++-- library.properties | 12 +- 9 files changed, 271 insertions(+), 221 deletions(-) delete mode 100644 examples/International/International.ino diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index f84e135..cfb79de 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -4,17 +4,19 @@ Written by Christian Weichel ** Mostly rewritten Paul Stoffregen 2010, 2011 - ** Modified for use beginning with Arduino 13 by L. Abraham Smith, * - ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan * - ** Modified for ESP32 support * + ** Modified for use beginning with Arduino 13 by L. Abraham Smith, + ** Modified for easy interrupt pin assignment on method begin(datapin,irq_pin). Cuningan + ** Modified for ESP32/ESP8266 support by Lahiru - 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 + For more information: + - https://github.com/lahirunirmalx/PS2Keyboard + - http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html - Version 2.5 (January 2025) - - Better Inturpts - - Support for ESP32 + Version 3.0 (January 2026) + - ESP32 and ESP8266 platform support + - Improved interrupt handling with IRAM_ATTR for ESP32 + - Caps Lock, Num Lock, Scroll Lock LED support + - Code cleanup and optimization Version 2.4 (March 2013) - Support Teensy 3.0, Arduino Due, Arduino Leonardo & other boards @@ -29,7 +31,6 @@ 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 @@ -68,12 +69,14 @@ static bool numLockOn = false; static bool scrollLockOn = false; static byte ledState = 0; +// LED control command for PS/2 keyboard #define LED_CONTROL 0xED -#ifdef ESP32 -#define SUPPORT_IRAM_ATTR IRAM_ATTR +// ESP32 requires IRAM_ATTR for interrupt handlers +#if defined(ESP32) + #define SUPPORT_IRAM_ATTR IRAM_ATTR #else -#define SUPPORT_IRAM_ATTR // Empty definition for non-ESP32 boards + #define SUPPORT_IRAM_ATTR #endif // Parity check @@ -152,13 +155,9 @@ static void sendPS2Command(uint8_t cmdCode) { #endif } -static void updateLEDs(byte command){ - - //Serial.print(LED_CONTROL); - sendPS2Command(LED_CONTROL); - // Serial.print(command); - sendPS2Command(command); - // Could not get this working +static void updateLEDs(byte command) { + sendPS2Command(LED_CONTROL); + sendPS2Command(command); } // The ISR for the external interrupt @@ -253,21 +252,17 @@ const PROGMEM PS2Keymap_t PS2Keymap_US = { 0 }; - // no hate but I have remove this - +// State machine flags for scan code processing #define BREAK 0x01 #define MODIFIER 0x02 #define SHIFT_L 0x04 #define SHIFT_R 0x08 #define ALTGR 0x10 -#define SCROLL_LOCK 0x01 -#define NUM_LOCK 0x02 -#define CAPS_LOCK 0x04 - -#define LED_CONTROL 0xED - - +// LED state bit flags +#define SCROLL_LOCK 0x01 +#define NUM_LOCK 0x02 +#define CAPS_LOCK 0x04 static char get_iso8859_code(void) { static uint8_t state = 0; diff --git a/PS2Keyboard.h b/PS2Keyboard.h index 1ea44cc..7f26fb3 100644 --- a/PS2Keyboard.h +++ b/PS2Keyboard.h @@ -4,8 +4,9 @@ Written by Christian Weichel ** Mostly rewritten Paul Stoffregen , June 2010 - ** Modified for use with Arduino 13 by L. Abraham Smith, * - ** Modified for easy interrup pin assignement on method begin(datapin,irq_pin). Cuningan ** + ** Modified for use with Arduino 13 by L. Abraham Smith, + ** Modified for easy interrupt pin assignment on method begin(datapin,irq_pin). Cuningan + ** Modified for ESP32/ESP8266 support by Lahiru This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -177,12 +178,8 @@ typedef struct { } PS2Keymap_t; +// US keyboard layout (default) extern const PROGMEM PS2Keymap_t PS2Keymap_US; -extern const PROGMEM PS2Keymap_t PS2Keymap_German; -extern const PROGMEM PS2Keymap_t PS2Keymap_French; -extern const PROGMEM PS2Keymap_t PS2Keymap_Spanish; -extern const PROGMEM PS2Keymap_t PS2Keymap_Italian; -extern const PROGMEM PS2Keymap_t PS2Keymap_UK; /** @@ -214,7 +211,7 @@ class PS2Keyboard { static void clear(); /** - * Retutns ps2 scan code. + * Returns the raw PS/2 scan code. */ static uint8_t readScanCode(void); diff --git a/README.md b/README.md index 99986f5..f1c7e90 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,133 @@ -# PS/2 Keyboard Library with ESP32 Support +# PS2Keyboard Library -This library provides support for using a PS/2 keyboard as an input device, with additional enhancements to support ESP32, making it compatible with LoRa-based chat applications and improved code structure. +[![License: LGPL v2.1](https://img.shields.io/badge/License-LGPL%20v2.1-blue.svg)](https://www.gnu.org/licenses/lgpl-2.1) +[![Version](https://img.shields.io/badge/version-3.0.0-green.svg)](https://github.com/lahirunirmalx/PS2Keyboard) -## Original Project +A PS/2 keyboard library for Arduino, Teensy, ESP32, and ESP8266 platforms. -The original PS/2 Keyboard Library was created by PJRC and allows easy interfacing of a PS/2 keyboard with microcontrollers, such as the Teensy. This library makes it easy to use a keyboard for user input. More details on the original project can be found here: +## Features -- [PS2Keyboard Library](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html) +- **Multi-platform support**: Arduino (Uno, Mega, Due, Leonardo), Teensy, ESP32, ESP8266 +- **Interrupt-driven**: Efficient interrupt-based input handling +- **Lock key support**: Caps Lock, Num Lock, and Scroll Lock with LED indicators +- **Easy to use**: Simple API with `begin()`, `available()`, and `read()` methods +- **US keyboard layout**: Standard US QWERTY layout included -![Original Library](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.jpg) +## Installation -## New Additions and Enhancements +### Arduino IDE -This fork includes additional features and improvements: +1. Download this repository as a ZIP file +2. In Arduino IDE: `Sketch` → `Include Library` → `Add .ZIP Library...` +3. Select the downloaded ZIP file -- **ESP32 Support**: Added support for the ESP32 platform, making it compatible with LoRa-based chat applications and other ESP32 projects. -- **Efficient Interrupts**: Simplified interrupt handling for easier and more efficient management. -- **Caps Lock with Status LED**: Added support for the Caps Lock key along with an LED status indicator. -- **Code Optimization**: Removed bulky code sections, refactored to a modern C++ style, and enhanced code readability. +### PlatformIO -## Getting Started +Add the following to your `platformio.ini`: -### Prerequisites +```ini +lib_deps = + https://github.com/lahirunirmalx/PS2Keyboard +``` -- **Platform**: This library is compatible with both the ESP32 and Teensy platforms. -- **Dependencies**: Ensure you have the required PS/2 keyboard and the correct wiring setup for your microcontroller. +## Wiring -### Installation +Connect your PS/2 keyboard to your microcontroller: -1. Clone this repository or download the library as a ZIP file. -2. Include the library in your project: - - For Arduino IDE: Go to `Sketch` -> `Include Library` -> `Add .ZIP Library...` and select the downloaded file. - - For PlatformIO: Add this library to your project’s `lib` folder. +| PS/2 Pin | Signal | Connect To | +|----------|--------|------------| +| 1 | Data | Data Pin (configurable) | +| 3 | GND | GND | +| 4 | VCC | 5V | +| 5 | Clock | IRQ Pin (configurable) | -The following library dependency is shared across both environments: +> **Note**: PS/2 keyboards require 5V power. Some boards may need level shifters for the data lines. -```ini -[common] -lib_deps = - https://github.com/lahirunirmalx/PS2Keyboard#dev-master +## Quick Start + +```cpp +#include + +const int DataPin = 8; +const int IRQpin = 5; + +PS2Keyboard keyboard; + +void setup() { + Serial.begin(115200); + keyboard.begin(DataPin, IRQpin); + Serial.println("PS/2 Keyboard Ready"); +} + +void loop() { + if (keyboard.available()) { + char c = keyboard.read(); + + if (c == PS2_ENTER) { + Serial.println(); + } else if (c == PS2_TAB) { + Serial.print("[Tab]"); + } else if (c == PS2_ESC) { + Serial.print("[ESC]"); + } else if (c == PS2_BACKSPACE) { + Serial.print("[Backspace]"); + } else { + Serial.print(c); + } + } +} ``` -### Environment Configuration +## Valid IRQ Pins + +| Board | Valid IRQ Pins | +|-------|----------------| +| Arduino Uno | 2, 3 | +| Arduino Mega | 2, 3, 18, 19, 20, 21 | +| Arduino Due | All pins (except 13) | +| Arduino Leonardo | 0, 1, 2, 3 | +| Teensy 3.x/4.x | All digital pins | +| Teensy 2.0 | 5, 6, 7, 8 | +| ESP32 | All GPIO pins | +| ESP8266 | All GPIO pins | + +## API Reference + +### Methods + +| Method | Description | +|--------|-------------| +| `begin(dataPin, irqPin)` | Initialize the keyboard with data and clock pins | +| `begin(dataPin, irqPin, keymap)` | Initialize with a custom keymap | +| `available()` | Returns `true` if a key is available to read | +| `read()` | Returns the next character (UTF-8 encoded) | +| `readUnicode()` | Returns the next character as Unicode | +| `readScanCode()` | Returns the raw PS/2 scan code | +| `clear()` | Clears the keyboard buffer | -#### ESP32 Development Board +### Special Key Constants -This environment is set up for the ESP32 board, utilizing the Arduino framework with a monitor speed of 115200 baud. +```cpp +PS2_ENTER // Enter key +PS2_TAB // Tab key +PS2_ESC // Escape key +PS2_BACKSPACE // Backspace key +PS2_DELETE // Delete key +PS2_INSERT // Insert key +PS2_HOME // Home key +PS2_END // End key +PS2_PAGEUP // Page Up key +PS2_PAGEDOWN // Page Down key +PS2_UPARROW // Up arrow +PS2_DOWNARROW // Down arrow +PS2_LEFTARROW // Left arrow +PS2_RIGHTARROW // Right arrow +PS2_F1 - PS2_F12 // Function keys +``` + +## Platform-Specific Configuration + +### ESP32 ```ini [env:esp32dev] @@ -53,65 +135,60 @@ platform = espressif32 board = esp32dev framework = arduino monitor_speed = 115200 -lib_deps = ${common.lib_deps} +lib_deps = + https://github.com/lahirunirmalx/PS2Keyboard ``` -#### Arduino Uno Board - -This environment is configured for the Arduino Uno board, also using the Arduino framework and a monitor speed of 115200 baud. +### Arduino Uno ```ini [env:uno] platform = atmelavr board = uno -framework = arduino +framework = arduino monitor_speed = 115200 -lib_deps = ${common.lib_deps} +lib_deps = + https://github.com/lahirunirmalx/PS2Keyboard ``` -### Usage - -After installing the library, initialize the PS/2 keyboard with the appropriate pins for data and clock: - -```cpp -#include - -const int DataPin = 13; -const int IRQPin = 12; -PS2Keyboard keyboard; +## Examples -void setup() { - Serial.begin(9600); - keyboard.begin(DataPin, IRQPin); - Serial.println("PS/2 Keyboard ready for input..."); -} +- **Simple_Test**: Basic keyboard input example +- **TypeToDisplay**: Display keyboard input on an LCD -void loop() { - if (keyboard.available()) { - char c = keyboard.read(); - Serial.print(c); - } -} -``` +## Version History -Refer to the library's examples for more detailed usage. +- **v3.0.0** (January 2026) + - ESP32 and ESP8266 platform support + - Improved interrupt handling + - Caps Lock, Num Lock, Scroll Lock LED support + - Code cleanup and optimization -## Contributing +- **v2.4** (March 2013) + - Teensy 3.0, Arduino Due, Leonardo support -Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements, feel free to open an issue or submit a pull request. +- **v2.0** (June 2010) + - Buffering, shift key support, indexed lookups -### Support the Original Developers +## Credits -This project is built upon the great work done by the original authors at PJRC. Please consider supporting their projects and acknowledging their contributions. +- Original library by [PJRC](http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html) +- Christian Weichel - Original author +- Paul Stoffregen - Major rewrite +- L. Abraham Smith - Arduino 13 modifications +- Cuningan - Flexible pin assignment +- Lahiru - ESP32/ESP8266 support and maintenance ## License -This project is licensed under the [MIT License](LICENSE). +This library is licensed under the [GNU Lesser General Public License v2.1](https://www.gnu.org/licenses/lgpl-2.1.html). ---- +## Contributing -### Acknowledgments +Contributions are welcome! Please open an issue or submit a pull request. -Thanks to PJRC for the original PS/2 Keyboard Library and all contributors to the ESP32 and LoRa community who make embedded development more accessible. +## Support ---- \ No newline at end of file +- [GitHub Issues](https://github.com/lahirunirmalx/PS2Keyboard/issues) +- [Arduino Forum](https://forum.arduino.cc) +- [ESP32 Forum](https://www.esp32.com) diff --git a/examples/International/International.ino b/examples/International/International.ino deleted file mode 100644 index 48fba5f..0000000 --- a/examples/International/International.ino +++ /dev/null @@ -1,34 +0,0 @@ -/* PS2Keyboard library, International Keyboard Layout Example - http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html - - keyboard.begin() accepts an optional 3rd parameter to - configure the PS2 keyboard layout. Uncomment the line for - your keyboard. If it doesn't exist, you can create it in - PS2Keyboard.cpp and email paul@pjrc.com to have it included - in future versions of this library. -*/ - -#include - -const int DataPin = 8; -const int IRQpin = 5; - -PS2Keyboard keyboard; - -void setup() { - //keyboard.begin(DataPin, IRQpin, PS2Keymap_US); - keyboard.begin(DataPin, IRQpin, PS2Keymap_German); - //keyboard.begin(DataPin, IRQpin, PS2Keymap_French); - //keyboard.begin(DataPin, IRQpin, PS2Keymap_Spanish); - //keyboard.begin(DataPin, IRQpin, PS2Keymap_Italian); - //keyboard.begin(DataPin, IRQpin, PS2Keymap_UK); - Serial.begin(9600); - Serial.println("International Keyboard Test:"); -} - -void loop() { - if (keyboard.available()) { - char c = keyboard.read(); - Serial.print(c); - } -} diff --git a/examples/Simple_Test/Simple_Test.ino b/examples/Simple_Test/Simple_Test.ino index bd28b4b..2d8db4f 100644 --- a/examples/Simple_Test/Simple_Test.ino +++ b/examples/Simple_Test/Simple_Test.ino @@ -1,42 +1,38 @@ -/* PS2Keyboard library example +/* + PS2Keyboard Library - Simple Test Example - PS2Keyboard now requries both pins specified for begin() - - keyboard.begin(data_pin, irq_pin); - - Valid irq pins: - Arduino Uno: 2, 3 - Arduino Due: All pins, except 13 (LED) - Arduino Mega: 2, 3, 18, 19, 20, 21 - Teensy 3.0: All pins, except 13 (LED) - Teensy 2.0: 5, 6, 7, 8 - Teensy 1.0: 0, 1, 2, 3, 4, 6, 7, 16 - Teensy++ 2.0: 0, 1, 2, 3, 18, 19, 36, 37 - Teensy++ 1.0: 0, 1, 2, 3, 18, 19, 36, 37 - Sanguino: 2, 10, 11 - - 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 + This example demonstrates basic PS/2 keyboard input. - Like the Original library and example this is under LGPL license. + Wiring: + PS/2 Data -> DataPin + PS/2 Clock -> IRQpin + PS/2 VCC -> 5V + PS/2 GND -> GND + + Valid IRQ pins by board: + Arduino Uno: 2, 3 + Arduino Mega: 2, 3, 18, 19, 20, 21 + Arduino Due: All pins (except 13) + Teensy 3.x/4.x: All digital pins + ESP32/ESP8266: All GPIO pins + + More info: https://github.com/lahirunirmalx/PS2Keyboard - Modified by Cuninganreset@gmail.com on 2010-03-22 - Modified by Paul Stoffregen June 2010 + License: LGPL v2.1 */ - + #include const int DataPin = 8; -const int IRQpin = 5; +const int IRQpin = 5; PS2Keyboard keyboard; void setup() { delay(1000); keyboard.begin(DataPin, IRQpin); - Serial.begin(9600); - Serial.println("Keyboard Test:"); + Serial.begin(115200); + Serial.println("PS/2 Keyboard Test - Type to begin:"); } void loop() { diff --git a/examples/TypeToDisplay/TypeToDisplay.ino b/examples/TypeToDisplay/TypeToDisplay.ino index 2b28f15..3dceb10 100644 --- a/examples/TypeToDisplay/TypeToDisplay.ino +++ b/examples/TypeToDisplay/TypeToDisplay.ino @@ -1,33 +1,23 @@ -/* TypeToDisplay - PS2Keyboard keystrokes show on a standard LCD Display - - Lcd support added 18/2/2018 D.R.Patterson - lcd character set: +/* + PS2Keyboard Library - Type To Display Example + + Display PS/2 keyboard keystrokes on a standard LCD display. + Tested on Arduino Mega with a Keypad Shield. + + LCD character set reference: http://forum.arduino.cc/index.php?topic=19002.0 - Tested on a mega with a Keypad Shield for Arduino - - PS2Keyboard now requries both pins specified for begin() - keyboard.begin(data_pin, irq_pin); - - Valid irq pins: - Arduino Uno: 2, 3 - Arduino Due: All pins, except 13 (LED) - Arduino Mega: 2, 3, 18, 19, 20, 21 - Teensy 2.0: All pins, except 13 (LED) - Teensy 2.0: 5, 6, 7, 8 - Teensy 1.0: 0, 1, 2, 3, 4, 6, 7, 16 - Teensy++ 2.0: 0, 1, 2, 3, 18, 19, 36, 37 - Teensy++ 1.0: 0, 1, 2, 3, 18, 19, 36, 37 - Sanguino: 2, 10, 11 - - 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 - - Like the Original library and example this is under LGPL license. - - Modified by Cuninganreset@gmail.com on 2010-03-22 - Modified by Paul Stoffregen June 2010 + Wiring: + PS/2 Data -> DataPin (19) + PS/2 Clock -> IRQpin (18) + PS/2 VCC -> 5V + PS/2 GND -> GND + + More info: https://github.com/lahirunirmalx/PS2Keyboard + + License: LGPL v2.1 + + Original LCD support by D.R.Patterson (2018) */ #include diff --git a/keywords.txt b/keywords.txt index bd2c18a..b374c6e 100644 --- a/keywords.txt +++ b/keywords.txt @@ -7,20 +7,48 @@ ####################################### PS2Keyboard KEYWORD1 +PS2Keymap_t KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### +begin KEYWORD2 +available KEYWORD2 +read KEYWORD2 +readUnicode KEYWORD2 +readScanCode KEYWORD2 +clear KEYWORD2 + ####################################### # Constants (LITERAL1) ####################################### -PS2_KC_BREAK LITERAL1 -PS2_KC_ENTER LITERAL1 -PS2_KC_ESC LITERAL1 -PS2_KC_KPLUS LITERAL1 -PS2_KC_KMINUS LITERAL1 -PS2_KC_KMULTI LITERAL1 -PS2_KC_NUM LITERAL1 -PS2_KC_BKSP LITERAL1 +PS2Keymap_US LITERAL1 +PS2_TAB LITERAL1 +PS2_ENTER LITERAL1 +PS2_BACKSPACE LITERAL1 +PS2_ESC LITERAL1 +PS2_INSERT LITERAL1 +PS2_DELETE LITERAL1 +PS2_HOME LITERAL1 +PS2_END LITERAL1 +PS2_PAGEUP LITERAL1 +PS2_PAGEDOWN LITERAL1 +PS2_UPARROW LITERAL1 +PS2_LEFTARROW LITERAL1 +PS2_DOWNARROW LITERAL1 +PS2_RIGHTARROW LITERAL1 +PS2_F1 LITERAL1 +PS2_F2 LITERAL1 +PS2_F3 LITERAL1 +PS2_F4 LITERAL1 +PS2_F5 LITERAL1 +PS2_F6 LITERAL1 +PS2_F7 LITERAL1 +PS2_F8 LITERAL1 +PS2_F9 LITERAL1 +PS2_F10 LITERAL1 +PS2_F11 LITERAL1 +PS2_F12 LITERAL1 +PS2_SCROLL LITERAL1 diff --git a/library.json b/library.json index b6d8d99..09604e5 100644 --- a/library.json +++ b/library.json @@ -1,14 +1,12 @@ { "name": "PS2Keyboard", - "keywords": "keyboard, emulation", - "description": "PS2Keyboard (PS/2) allows you to use a keyboard for user input", - "authors": - [ + "keywords": "keyboard, ps2, input, esp32, esp8266", + "description": "PS2Keyboard library allows you to use a PS/2 keyboard for user input. Supports Arduino, Teensy, ESP32, and ESP8266.", + "authors": [ { "name": "Paul Stoffregen", "email": "paul@pjrc.com", - "url": "http://www.pjrc.com", - "maintainer": true + "url": "http://www.pjrc.com" }, { "name": "Christian Weichel", @@ -24,23 +22,26 @@ }, { "name": "Lahiru", - "email": "lahirunirmalx@gmail.com" + "email": "lahirunirmalx@gmail.com", + "maintainer": true } ], - "repository": - { + "repository": { "type": "git", "url": "https://github.com/lahirunirmalx/PS2Keyboard.git" }, - "version": "2.5", - "homepage": "", + "version": "3.0.0", + "license": "LGPL-2.1", + "homepage": "https://github.com/lahirunirmalx/PS2Keyboard", "frameworks": "arduino", - "platforms": - [ + "platforms": [ "atmelavr", - "teensy" + "atmelsam", + "teensy", + "espressif32", + "espressif8266" ], "examples": [ - "examples/*/*.pde" + "examples/*/*.ino" ] } diff --git a/library.properties b/library.properties index fd51f9b..9ea5063 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=PS2Keyboard -version=2.5 -author=Christian Weichel, Paul Stoffregen, L. Abraham Smith, Cuningan , lahirunirmalx -maintainer=Paul Stoffregen -sentence=Use a PS/2 Keyboard for input -paragraph= +version=3.0.0 +author=Christian Weichel, Paul Stoffregen, L. Abraham Smith, Cuningan, Lahiru +maintainer=Lahiru +sentence=Use a PS/2 keyboard for user input. +paragraph=Supports Arduino, Teensy, ESP32, ESP8266 and other boards. Features include Caps Lock, Num Lock, and Scroll Lock LED support. category=Signal Input/Output url=https://github.com/lahirunirmalx/PS2Keyboard architectures=* - +includes=PS2Keyboard.h From 56c3d487a1792c6717280c701e11c2f80f96e4cf Mon Sep 17 00:00:00 2001 From: lahiru Date: Tue, 5 May 2026 18:07:03 +0530 Subject: [PATCH 12/12] fix caps lock behavior issue --- PS2Keyboard.cpp | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/PS2Keyboard.cpp b/PS2Keyboard.cpp index cfb79de..e236eea 100644 --- a/PS2Keyboard.cpp +++ b/PS2Keyboard.cpp @@ -341,28 +341,18 @@ static char get_iso8859_code(void) { if (scanCode < PS2_KEYMAP_SIZE) { character = pgm_read_byte(keymap->altgr + scanCode); } - } else if (capsLockOn) { - // Handle Caps Lock with or without Shift keys - if (state & (SHIFT_L | SHIFT_R)) { - if (scanCode < PS2_KEYMAP_SIZE) { - character = pgm_read_byte(keymap->noshift + scanCode); - } - } else { - if (scanCode < PS2_KEYMAP_SIZE) { - character = pgm_read_byte(keymap->shift + scanCode); - } - } - } else { - // Handle regular Shift and non-Shift key states - if (state & (SHIFT_L | SHIFT_R)) { - if (scanCode < PS2_KEYMAP_SIZE) { - character = pgm_read_byte(keymap->shift + scanCode); - } - } else { - if (scanCode < PS2_KEYMAP_SIZE) { - character = pgm_read_byte(keymap->noshift + scanCode); - } - } + } else if (scanCode < PS2_KEYMAP_SIZE) { + // Caps Lock affects only alphabetic keys (a-z). For digits, + // punctuation and function keys, Shift is the sole modifier. + // Detect "letter" by inspecting the unshifted entry rather + // than carrying a parallel flag table. + bool shift_active = (state & (SHIFT_L | SHIFT_R)) != 0; + uint8_t ns = pgm_read_byte(keymap->noshift + scanCode); + bool is_alpha = (ns >= 'a' && ns <= 'z'); + bool effective_shift = shift_active ^ (is_alpha && capsLockOn); + character = effective_shift + ? pgm_read_byte(keymap->shift + scanCode) + : ns; } // Reset the states for the next scan code processing