Markus Pilz / Mbed 2 deprecated PS2toUSBHIDAdapter

Dependencies:   mbed

Revision:
5:61ad1a6be0fd
Parent:
3:a3ba8d3e3958
Child:
7:7ece3804edf5
--- a/main.cpp	Wed Oct 13 10:50:55 2010 +0000
+++ b/main.cpp	Sun Jun 07 14:36:40 2020 +0000
@@ -1,50 +1,130 @@
 /**
- * Test program.
+ *
  *
- * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
- * http://shinta.main.jp/
+ * PS/2 Code from : https://os.mbed.com/cookbook/PS2
+ * Conversion code from: https://gist.github.com/Slumber86/4439a6a5f2fcb5ece61a5c24b962535d
+ * https://github.com/keyboardio/KeyboardioHID/blob/master/src/BootKeyboard/BootKeyboard.cpp
+ * Explantion of PS/2 protocol: https://web.archive.org/web/20070321032851/https://www.beyondlogic.org/keyboard/keybrd.htm
+ * Source with LED command on arduino: https://playground.arduino.cc/PS2Keyboard/Cpp/
  */
 
 #include "mbed.h"
-#include "TextLCD.h"
-#include "PS2Mouse.h"
+#include "USBKeyboard.h"
 #include "PS2Keyboard.h"
-
-TextLCD lcd(p24, p26, p27, p28, p29, p30);
-PS2Keyboard ps2kb(p12, p11);
-PS2Mouse ps2ms(p23, p22);
+#include "Keymaps.h"
 
-int main() {
-    PS2Mouse::mouse_event_t evt_ms;
-    PS2Keyboard::keyboard_event_t evt_kb;
+DigitalOut myled2(LED2);
+DigitalOut myled4(LED4);
+PS2Keyboard ps2kb(p22, p23); //PS/2 keyboard (Clock, Data)
+USBKeyboard keyboard;
+LAYOUTS layo = LO_DE; //Layout of connected PS/2 keyboard, important only when additional keys are used
+bool ext, brk;
+int skip;
+uint8_t report[9]; //array with data for USB HID report
+Keymaps Kmap(layo, false); //keymap for normal keys
+Keymaps KmapE(layo, true); //keymap for keys with E0 prefix
+uint8_t leds;
+bool send_leds;
 
-    lcd.locate(0, 0);
-    lcd.printf("> Mouse        <");
-    lcd.locate(0, 1);
-    lcd.printf("> Keyboard     <");
+
+void report_add(uint8_t k); //add USB keycode to report array
+void report_remove(uint8_t k); //remove USB keycode from report array
 
-    int div = 0;
+int main()
+{
+    myled2=1;
+    PS2Keyboard::keyboard_event_t evt_kb;
+    while (!keyboard.configured()) {    // wait until keyboard is configured
+    }
+    wait(1.0);
+    myled2=0;
+    myled4=1;
     while (1) {
-        div++;
-        if (div % 2) {
-            if (ps2ms.processing(&evt_ms)) {
-                lcd.locate(0, 0);
-                lcd.printf("%c%c%c:%4d,%4d,%2d",
-                           evt_ms.left ? 'L' : '.',
-                           evt_ms.center ? 'C' : '.',
-                           evt_ms.right ? 'R' : '.',
-                           evt_ms.x, evt_ms.y, evt_ms.z);
-            }
-        } else {
-            if (ps2kb.processing(&evt_kb)) {
-                lcd.locate(0, 1);
-                for (int i = 0; i < evt_kb.length; i++) {
-                    lcd.printf("%02X", evt_kb.scancode[i]);
-                }
-                for (int i = 0; i < 16 - evt_kb.length * 2; i++) {
-                    lcd.printf("-");
+        if (ps2kb.processing(&evt_kb)) {
+            uint8_t k = evt_kb.scancode; //scancode of PS/2 keyboard
+            uint8_t k2 = 0; //translated keycode in USB format
+
+            if (k) {
+                if (skip) {
+                    --skip;
+                } else {
+                    if (k == 0xE0) { //special key, lookup in KE konversion table
+                        ext = true;
+                    } else if (k == 0xF0) { //breakcode, following scancode will be removed from report
+                        brk = true;
+                    } else if (k == 0xFA) { //acknowledgement from keyboard
+                        if (send_leds) {
+                            send_leds = false;
+                            //send_msg(leds); //send LED status to keyboard, not functional
+                        }
+                    } else {
+                        if (k == 0xE1) { //only one multibyte scancode uses this prefix
+                            k2 = 72;
+                            skip = 7; //following scancodes not nesessary for indentification, are skiped
+                            brk = true; //no longpress of this key possible
+                            report_add(k2);
+                            keyboard.scanCodeRep(report);
+                        } else {
+                            k2 = ext ? KmapE.K[k] : Kmap.K[k]; // konvesion from PS/2 to USB HID keycode
+                        }
+
+                        if (k2) {
+                            if (brk) {
+                                report_remove(k2);
+                                if (k2 == 83 || k2 == 71 || k2 == 57) { //keys relevant for keyboard LEDs
+                                    send_leds = true;
+                                    if (k2 == 83) {
+                                        leds ^= 2;
+                                    } else if (k2 == 71) {
+                                        leds ^= 1;
+                                    } else if (k2 == 57) {
+                                        leds ^= 4;
+                                    }
+                                    //send_msg(0xED); //send LED status to keyboard, not functional
+                                }
+                            } else {
+                                report_add(k2);
+                            }
+                            keyboard.scanCodeRep(report);
+                            brk = false;
+                            ext = false;
+                        }
+                    }
                 }
             }
         }
     }
 }
+
+
+void report_remove(uint8_t k)
+{
+    uint8_t i;
+    if (k >= 224) { //is modifier key
+        report[1] &= ~(1 << (k - 224));
+    } else {
+        for (i = 3; i < 9; ++i) { //loop only normal key places
+            if (report[i] == k) { //if key in report
+                report[i] = 0;
+                break;
+            }
+        }
+    }
+}
+
+void report_add(uint8_t k)
+{
+    uint8_t i;
+    if (k >= 224) { //is modifier key
+        report[1] |= 1 << (k - 224);
+    } else if (report[3] != k && report[4] != k &&
+               report[5] != k && report[6] != k &&
+               report[7] != k && report[8] != k) { //not already set in report
+        for (i = 3; i < 9; ++i) { //loop only normal key
+            if (report[i] == 0) { //first free place is set
+                report[i] = k;
+                break;
+            }
+        }
+    }
+}
\ No newline at end of file