an adapter from any connected PS/2 keyboard to USB HID output

Dependencies:   mbed

Translates PS/2 scancodes from keyboard to USB HID output. Keyboard LEDs not working for now, but key are handled.

main.cpp

Committer:
pilzm
Date:
2020-06-07
Revision:
7:7ece3804edf5
Parent:
5:61ad1a6be0fd

File content as of revision 7:7ece3804edf5:

/**
 *
 *
 * 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
 * Explanation of keycodes of different layouts: http://www.quadibloc.com/comp/scan.htm
 * Source with LED command on arduino: https://playground.arduino.cc/PS2Keyboard/Cpp/
 */

#include "mbed.h"
#include "USBKeyboard.h"
#include "PS2Keyboard.h"
#include "Keymaps.h"

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;


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 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) {
        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;
            }
        }
    }
}