Markus Pilz / Mbed 2 deprecated PS2toUSBHIDAdapter

Dependencies:   mbed

Committer:
pilzm
Date:
Sun Jun 07 14:36:40 2020 +0000
Revision:
5:61ad1a6be0fd
Parent:
3:a3ba8d3e3958
Child:
7:7ece3804edf5
An adapter from PS/2 keyboard without USB mode to USB HID keyboard output

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:aabf6427c82e 1 /**
pilzm 5:61ad1a6be0fd 2 *
shintamainjp 0:aabf6427c82e 3 *
pilzm 5:61ad1a6be0fd 4 * PS/2 Code from : https://os.mbed.com/cookbook/PS2
pilzm 5:61ad1a6be0fd 5 * Conversion code from: https://gist.github.com/Slumber86/4439a6a5f2fcb5ece61a5c24b962535d
pilzm 5:61ad1a6be0fd 6 * https://github.com/keyboardio/KeyboardioHID/blob/master/src/BootKeyboard/BootKeyboard.cpp
pilzm 5:61ad1a6be0fd 7 * Explantion of PS/2 protocol: https://web.archive.org/web/20070321032851/https://www.beyondlogic.org/keyboard/keybrd.htm
pilzm 5:61ad1a6be0fd 8 * Source with LED command on arduino: https://playground.arduino.cc/PS2Keyboard/Cpp/
shintamainjp 0:aabf6427c82e 9 */
shintamainjp 0:aabf6427c82e 10
shintamainjp 0:aabf6427c82e 11 #include "mbed.h"
pilzm 5:61ad1a6be0fd 12 #include "USBKeyboard.h"
shintamainjp 2:b06d5cea5b11 13 #include "PS2Keyboard.h"
pilzm 5:61ad1a6be0fd 14 #include "Keymaps.h"
shintamainjp 0:aabf6427c82e 15
pilzm 5:61ad1a6be0fd 16 DigitalOut myled2(LED2);
pilzm 5:61ad1a6be0fd 17 DigitalOut myled4(LED4);
pilzm 5:61ad1a6be0fd 18 PS2Keyboard ps2kb(p22, p23); //PS/2 keyboard (Clock, Data)
pilzm 5:61ad1a6be0fd 19 USBKeyboard keyboard;
pilzm 5:61ad1a6be0fd 20 LAYOUTS layo = LO_DE; //Layout of connected PS/2 keyboard, important only when additional keys are used
pilzm 5:61ad1a6be0fd 21 bool ext, brk;
pilzm 5:61ad1a6be0fd 22 int skip;
pilzm 5:61ad1a6be0fd 23 uint8_t report[9]; //array with data for USB HID report
pilzm 5:61ad1a6be0fd 24 Keymaps Kmap(layo, false); //keymap for normal keys
pilzm 5:61ad1a6be0fd 25 Keymaps KmapE(layo, true); //keymap for keys with E0 prefix
pilzm 5:61ad1a6be0fd 26 uint8_t leds;
pilzm 5:61ad1a6be0fd 27 bool send_leds;
shintamainjp 3:a3ba8d3e3958 28
pilzm 5:61ad1a6be0fd 29
pilzm 5:61ad1a6be0fd 30 void report_add(uint8_t k); //add USB keycode to report array
pilzm 5:61ad1a6be0fd 31 void report_remove(uint8_t k); //remove USB keycode from report array
shintamainjp 1:e5eac8a97060 32
pilzm 5:61ad1a6be0fd 33 int main()
pilzm 5:61ad1a6be0fd 34 {
pilzm 5:61ad1a6be0fd 35 myled2=1;
pilzm 5:61ad1a6be0fd 36 PS2Keyboard::keyboard_event_t evt_kb;
pilzm 5:61ad1a6be0fd 37 while (!keyboard.configured()) { // wait until keyboard is configured
pilzm 5:61ad1a6be0fd 38 }
pilzm 5:61ad1a6be0fd 39 wait(1.0);
pilzm 5:61ad1a6be0fd 40 myled2=0;
pilzm 5:61ad1a6be0fd 41 myled4=1;
shintamainjp 0:aabf6427c82e 42 while (1) {
pilzm 5:61ad1a6be0fd 43 if (ps2kb.processing(&evt_kb)) {
pilzm 5:61ad1a6be0fd 44 uint8_t k = evt_kb.scancode; //scancode of PS/2 keyboard
pilzm 5:61ad1a6be0fd 45 uint8_t k2 = 0; //translated keycode in USB format
pilzm 5:61ad1a6be0fd 46
pilzm 5:61ad1a6be0fd 47 if (k) {
pilzm 5:61ad1a6be0fd 48 if (skip) {
pilzm 5:61ad1a6be0fd 49 --skip;
pilzm 5:61ad1a6be0fd 50 } else {
pilzm 5:61ad1a6be0fd 51 if (k == 0xE0) { //special key, lookup in KE konversion table
pilzm 5:61ad1a6be0fd 52 ext = true;
pilzm 5:61ad1a6be0fd 53 } else if (k == 0xF0) { //breakcode, following scancode will be removed from report
pilzm 5:61ad1a6be0fd 54 brk = true;
pilzm 5:61ad1a6be0fd 55 } else if (k == 0xFA) { //acknowledgement from keyboard
pilzm 5:61ad1a6be0fd 56 if (send_leds) {
pilzm 5:61ad1a6be0fd 57 send_leds = false;
pilzm 5:61ad1a6be0fd 58 //send_msg(leds); //send LED status to keyboard, not functional
pilzm 5:61ad1a6be0fd 59 }
pilzm 5:61ad1a6be0fd 60 } else {
pilzm 5:61ad1a6be0fd 61 if (k == 0xE1) { //only one multibyte scancode uses this prefix
pilzm 5:61ad1a6be0fd 62 k2 = 72;
pilzm 5:61ad1a6be0fd 63 skip = 7; //following scancodes not nesessary for indentification, are skiped
pilzm 5:61ad1a6be0fd 64 brk = true; //no longpress of this key possible
pilzm 5:61ad1a6be0fd 65 report_add(k2);
pilzm 5:61ad1a6be0fd 66 keyboard.scanCodeRep(report);
pilzm 5:61ad1a6be0fd 67 } else {
pilzm 5:61ad1a6be0fd 68 k2 = ext ? KmapE.K[k] : Kmap.K[k]; // konvesion from PS/2 to USB HID keycode
pilzm 5:61ad1a6be0fd 69 }
pilzm 5:61ad1a6be0fd 70
pilzm 5:61ad1a6be0fd 71 if (k2) {
pilzm 5:61ad1a6be0fd 72 if (brk) {
pilzm 5:61ad1a6be0fd 73 report_remove(k2);
pilzm 5:61ad1a6be0fd 74 if (k2 == 83 || k2 == 71 || k2 == 57) { //keys relevant for keyboard LEDs
pilzm 5:61ad1a6be0fd 75 send_leds = true;
pilzm 5:61ad1a6be0fd 76 if (k2 == 83) {
pilzm 5:61ad1a6be0fd 77 leds ^= 2;
pilzm 5:61ad1a6be0fd 78 } else if (k2 == 71) {
pilzm 5:61ad1a6be0fd 79 leds ^= 1;
pilzm 5:61ad1a6be0fd 80 } else if (k2 == 57) {
pilzm 5:61ad1a6be0fd 81 leds ^= 4;
pilzm 5:61ad1a6be0fd 82 }
pilzm 5:61ad1a6be0fd 83 //send_msg(0xED); //send LED status to keyboard, not functional
pilzm 5:61ad1a6be0fd 84 }
pilzm 5:61ad1a6be0fd 85 } else {
pilzm 5:61ad1a6be0fd 86 report_add(k2);
pilzm 5:61ad1a6be0fd 87 }
pilzm 5:61ad1a6be0fd 88 keyboard.scanCodeRep(report);
pilzm 5:61ad1a6be0fd 89 brk = false;
pilzm 5:61ad1a6be0fd 90 ext = false;
pilzm 5:61ad1a6be0fd 91 }
pilzm 5:61ad1a6be0fd 92 }
shintamainjp 3:a3ba8d3e3958 93 }
shintamainjp 2:b06d5cea5b11 94 }
shintamainjp 1:e5eac8a97060 95 }
shintamainjp 0:aabf6427c82e 96 }
shintamainjp 0:aabf6427c82e 97 }
pilzm 5:61ad1a6be0fd 98
pilzm 5:61ad1a6be0fd 99
pilzm 5:61ad1a6be0fd 100 void report_remove(uint8_t k)
pilzm 5:61ad1a6be0fd 101 {
pilzm 5:61ad1a6be0fd 102 uint8_t i;
pilzm 5:61ad1a6be0fd 103 if (k >= 224) { //is modifier key
pilzm 5:61ad1a6be0fd 104 report[1] &= ~(1 << (k - 224));
pilzm 5:61ad1a6be0fd 105 } else {
pilzm 5:61ad1a6be0fd 106 for (i = 3; i < 9; ++i) { //loop only normal key places
pilzm 5:61ad1a6be0fd 107 if (report[i] == k) { //if key in report
pilzm 5:61ad1a6be0fd 108 report[i] = 0;
pilzm 5:61ad1a6be0fd 109 break;
pilzm 5:61ad1a6be0fd 110 }
pilzm 5:61ad1a6be0fd 111 }
pilzm 5:61ad1a6be0fd 112 }
pilzm 5:61ad1a6be0fd 113 }
pilzm 5:61ad1a6be0fd 114
pilzm 5:61ad1a6be0fd 115 void report_add(uint8_t k)
pilzm 5:61ad1a6be0fd 116 {
pilzm 5:61ad1a6be0fd 117 uint8_t i;
pilzm 5:61ad1a6be0fd 118 if (k >= 224) { //is modifier key
pilzm 5:61ad1a6be0fd 119 report[1] |= 1 << (k - 224);
pilzm 5:61ad1a6be0fd 120 } else if (report[3] != k && report[4] != k &&
pilzm 5:61ad1a6be0fd 121 report[5] != k && report[6] != k &&
pilzm 5:61ad1a6be0fd 122 report[7] != k && report[8] != k) { //not already set in report
pilzm 5:61ad1a6be0fd 123 for (i = 3; i < 9; ++i) { //loop only normal key
pilzm 5:61ad1a6be0fd 124 if (report[i] == 0) { //first free place is set
pilzm 5:61ad1a6be0fd 125 report[i] = k;
pilzm 5:61ad1a6be0fd 126 break;
pilzm 5:61ad1a6be0fd 127 }
pilzm 5:61ad1a6be0fd 128 }
pilzm 5:61ad1a6be0fd 129 }
pilzm 5:61ad1a6be0fd 130 }