Skip to content

Instantly share code, notes, and snippets.

@davidbkemp
Created January 11, 2015 07:59
Show Gist options
  • Save davidbkemp/1602e1efd2ab7a6188c7 to your computer and use it in GitHub Desktop.
Save davidbkemp/1602e1efd2ab7a6188c7 to your computer and use it in GitHub Desktop.

Revisions

  1. davidbkemp created this gist Jan 11, 2015.
    162 changes: 162 additions & 0 deletions gistfile1.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,162 @@
    // Modified from https://github.com/felis/USB_Host_Shield_2.0/blob/master/examples/HID/USBHIDBootKbd/USBHIDBootKbd.ino
    // Modified to print the ASCII hex codes of the keys pressed, and to handle some of the non-printable keys.

    #include <hidboot.h>
    #include <usbhub.h>
    // Satisfy IDE, which only needs to see the include statment in the ino.
    #ifdef dobogusinclude
    #include <spi4teensy3.h>
    #endif

    #define UHS_HID_BOOT_KEY_ESC 0x29
    #define UHS_HID_BOOT_KEY_DEL 0x4C
    #define UHS_HID_BOOT_KEY_BACKSPACE 0x2A
    #define UHS_HID_BOOT_KEY_HOME 0x4A
    #define UHS_HID_BOOT_KEY_PAGE_UP 0x4B
    #define UHS_HID_BOOT_KEY_END 0x4D
    #define UHS_HID_BOOT_KEY_PAGE_DN 0x4E
    #define UHS_HID_BOOT_KEY_TAB 0x2B
    #define UHS_HID_BOOT_KEY_CAPS 0x39


    class KbdRptParser : public KeyboardReportParser
    {
    void PrintKey(uint8_t mod, uint8_t key);
    uint8_t mapExtraAsciiKeys(uint8_t);

    protected:
    virtual void OnControlKeysChanged(uint8_t before, uint8_t after);

    virtual void OnKeyDown (uint8_t mod, uint8_t key);
    virtual void OnKeyUp (uint8_t mod, uint8_t key);
    virtual void OnKeyPressed(uint8_t key);
    };

    void KbdRptParser::PrintKey(uint8_t m, uint8_t key)
    {
    MODIFIERKEYS mod;
    *((uint8_t*)&mod) = m;
    Serial.print((mod.bmLeftCtrl == 1) ? "C" : " ");
    Serial.print((mod.bmLeftShift == 1) ? "S" : " ");
    Serial.print((mod.bmLeftAlt == 1) ? "A" : " ");
    Serial.print((mod.bmLeftGUI == 1) ? "G" : " ");

    Serial.print(" >");
    PrintHex<uint8_t>(key, 0x80);
    Serial.print("< ");

    Serial.print((mod.bmRightCtrl == 1) ? "C" : " ");
    Serial.print((mod.bmRightShift == 1) ? "S" : " ");
    Serial.print((mod.bmRightAlt == 1) ? "A" : " ");
    Serial.println((mod.bmRightGUI == 1) ? "G" : " ");
    };

    // Map some of the keys currently not handled by OemToAscii
    uint8_t KbdRptParser::mapExtraAsciiKeys(uint8_t key) {

    switch(key) {
    case UHS_HID_BOOT_KEY_SPACE: return ' ';
    case UHS_HID_BOOT_KEY_ZERO2: return '0';
    case UHS_HID_BOOT_KEY_PERIOD: return '.';
    case UHS_HID_BOOT_KEY_ESC: return 0x1B;
    case UHS_HID_BOOT_KEY_DEL: return 0x7F;
    case UHS_HID_BOOT_KEY_BACKSPACE: return 0x08;
    case UHS_HID_BOOT_KEY_TAB: return 0x09;
    }

    return ( 0);
    }


    void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key)
    {
    Serial.print("DN ");
    PrintKey(mod, key);
    uint8_t c = OemToAscii(mod, key);

    if (!c) {
    c = mapExtraAsciiKeys(key);
    }

    if (c) {
    OnKeyPressed(c);
    }

    }

    void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) {

    MODIFIERKEYS beforeMod;
    *((uint8_t*)&beforeMod) = before;

    MODIFIERKEYS afterMod;
    *((uint8_t*)&afterMod) = after;

    if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) {
    Serial.println("LeftCtrl changed");
    }
    if (beforeMod.bmLeftShift != afterMod.bmLeftShift) {
    Serial.println("LeftShift changed");
    }
    if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) {
    Serial.println("LeftAlt changed");
    }
    if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) {
    Serial.println("LeftGUI changed");
    }

    if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) {
    Serial.println("RightCtrl changed");
    }
    if (beforeMod.bmRightShift != afterMod.bmRightShift) {
    Serial.println("RightShift changed");
    }
    if (beforeMod.bmRightAlt != afterMod.bmRightAlt) {
    Serial.println("RightAlt changed");
    }
    if (beforeMod.bmRightGUI != afterMod.bmRightGUI) {
    Serial.println("RightGUI changed");
    }

    }

    void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)
    {
    Serial.print("UP ");
    PrintKey(mod, key);
    }

    void KbdRptParser::OnKeyPressed(uint8_t key)
    {
    Serial.print("ASCII: ");
    Serial.println(key, HEX);
    };

    USB Usb;
    //USBHub Hub(&Usb);
    HIDBoot<HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb);

    uint32_t next_time;

    KbdRptParser Prs;

    void setup()
    {
    Serial.begin( 115200 );
    while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
    Serial.println("Start");

    if (Usb.Init() == -1)
    Serial.println("OSC did not start.");

    delay( 200 );

    next_time = millis() + 5000;

    HidKeyboard.SetReportParser(0, (HIDReportParser*)&Prs);
    }

    void loop()
    {
    Usb.Task();
    }