felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.79k stars 779 forks source link

Mini Keyboard Wireless Touchpad: touchpad is not working. #499

Closed rtek1000 closed 4 years ago

rtek1000 commented 4 years ago

I would like to inform you that the touchpad is not working.

I tried:

(another wired mouse works)

USB_desc.ino output:

Start

01

Device descriptor: Descriptor Length: 12 Descriptor type: 01 USB version: 0110 Device class: 00 Device Subclass: 00 Device Protocol: 00 Max.packet size: 08 Vendor ID: 0513 Product ID: 0318 Revision ID: 0100 Mfg.string index: 00 Prod.string index: 00 Serial number index: 00 Number of conf.: 01

Configuration descriptor: Total length: 003B Num.intf: 02 Conf.value: 01 Conf.string: 00 Attr.: A0 Max.pwr: 32

Interface descriptor: Intf.number: 00 Alt.: 00 Endpoints: 01 Intf. Class: 03 Intf. Subclass: 01 Intf. Protocol: 01 Intf.string: 00 Unknown descriptor: Length: 09 Type: 21 Contents: 100100012240000705

Endpoint descriptor: Endpoint address: 81 Attr.: 03 Max.pkt size: 0008 Polling interval: 08

Interface descriptor: Intf.number: 01 Alt.: 00 Endpoints: 01 Intf. Class: 03 Intf. Subclass: 01 Intf. Protocol: 02 Intf.string: 00 Unknown descriptor: Length: 09 Type: 21 Contents: 100100012277000705

Endpoint descriptor: Endpoint address: 82 Attr.: 03 Max.pkt size: 0008 Polling interval: 08

Addr:1(0.0.1)

Mini Keyboard

xxxajk commented 4 years ago

might be proprietary, and not support HID BOOT?

rtek1000 commented 4 years ago

Well, how can it be proprietary if it works on Linux, Android, Windows without having to install anything additional? And on the MAX3421E works the keyboard part.

Is it possible to perform some verification through Linux/Windows?

rtek1000 commented 4 years ago

I found this:

Usbhid-dump is a USB HID dumping utility based on libusb 1.0. It dumps USB HID device report descriptors and reports themselves as they are being sent, for all or specific device interfaces.

Warning: please be careful running usbhid-dump as a superuser without limiting your device selection with options. Usbhid-dump will try to dump every device possible and If you're using a USB keyboard to control your terminal, it will be detached and you will be unable to terminate usbhid-dump and regain control.

https://github.com/DIGImend/usbhid-dump

xxxajk commented 4 years ago

Without additional hardware, it gets complicated, but can be done using Linux. You will have to track and trace USB URBs. http://www.linux-usb.org/USBMon/dissertation/USB-dissertation.htm Prepare to get neck deep in information.

rtek1000 commented 4 years ago

Nice!!!!!! Lib 3.0 works all functions!!!

https://github.com/felis/UHS30/tree/master/libraries/UHS_host/UHS_HID/examples/USB_HOST_SHIELD/UHS_HID_RAW

xxxajk commented 4 years ago

Not surprised. UHS3.0 enumerates in a way that isn't as hackish.

rtek1000 commented 4 years ago

It seems that they had not yet invented the ASCII standard before making the keyboard map in this strange sequential order:

(Keyboard)
Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01
Data: 00 00 00 00 00 00 00 00

0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "Key released"
0x00 0x00 0x04 0x00 0x00 0x00 0x00 0x00 A
0x00 0x00 0x05 0x00 0x00 0x00 0x00 0x00 B
0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 C
...       0x07                          D
...       0x1b                          X
0x00 0x00 0x1c 0x00 0x00 0x00 0x00 0x00 Y
0x00 0x00 0x1d 0x00 0x00 0x00 0x00 0x00 Z
0x00 0x00 0x1e 0x00 0x00 0x00 0x00 0x00 1
0x00 0x00 0x1f 0x00 0x00 0x00 0x00 0x00 2
...       0x20                          3
...       0x25                          8
0x00 0x00 0x26 0x00 0x00 0x00 0x00 0x00 9
0x00 0x00 0x27 0x00 0x00 0x00 0x00 0x00 0
0x00 0x00 0x28 0x00 0x00 0x00 0x00 0x00 Enter/OK
0x00 0x00 0x29 0x00 0x00 0x00 0x00 0x00 Esc "Escape"
0x00 0x00 0x2a 0x00 0x00 0x00 0x00 0x00 Back "Backspace"
0x00 0x00 0x2b 0x00 0x00 0x00 0x00 0x00 Tab "Horizontal Tab"
0x00 0x00 0x2d 0x00 0x00 0x00 0x00 0x00 - "Hyphen"
0x00 0x00 0x2e 0x00 0x00 0x00 0x00 0x00 = "Equals sign"
0x00 0x00 0x2f 0x00 0x00 0x00 0x00 0x00 ´ "Acute Accent"
0x00 0x00 0x30 0x00 0x00 0x00 0x00 0x00 [ "Square brackets"
0x00 0x00 0x31 0x00 0x00 0x00 0x00 0x00 ] "Square brackets"
0x00 0x00 0x33 0x00 0x00 0x00 0x00 0x00 Ç "Majuscle C-cedilla" (Layout PtBr ABNT2)
0x00 0x00 0x34 0x00 0x00 0x00 0x00 0x00 ~ "Tilde/Swung dash"
0x00 0x00 0x35 0x00 0x00 0x00 0x00 0x00 ' "Apostrophe"
0x00 0x00 0x36 0x00 0x00 0x00 0x00 0x00 , "Comma"
0x00 0x00 0x37 0x00 0x00 0x00 0x00 0x00 . "Dot/Full stop"
0x00 0x00 0x38 0x00 0x00 0x00 0x00 0x00 ; "Semicolon"
0x00 0x00 0x39 0x00 0x00 0x00 0x00 0x00 Caps "Caps lock"
0x00 0x00 0x46 0x00 0x00 0x00 0x00 0x00 PrtSc "Print screen"
0x00 0x00 0x4a 0x00 0x00 0x00 0x00 0x00 Home
0x00 0x00 0x4b 0x00 0x00 0x00 0x00 0x00 PgUp "Page Up"
0x00 0x00 0x4c 0x00 0x00 0x00 0x00 0x00 Del "Delete"
0x00 0x00 0x4d 0x00 0x00 0x00 0x00 0x00 End
0x00 0x00 0x4e 0x00 0x00 0x00 0x00 0x00 PgDn "Page down"
0x00 0x00 0x4f 0x00 0x00 0x00 0x00 0x00 Arrow R
0x00 0x00 0x50 0x00 0x00 0x00 0x00 0x00 Arrow L
0x00 0x00 0x51 0x00 0x00 0x00 0x00 0x00 Arrow Up
0x00 0x00 0x52 0x00 0x00 0x00 0x00 0x00 Arrow Up

0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Ctrl
0x01 0x00 0x06 0x00 0x00 0x00 0x00 0x00 Ctrl+C "Copy"
0x01 0x00 0x19 0x00 0x00 0x00 0x00 0x00 Ctrl+V "Paste"
0x01 0x00 0x1b 0x00 0x00 0x00 0x00 0x00 Ctrl+X "Cut"
0x01 0x00 0x1c 0x00 0x00 0x00 0x00 0x00 Ctrl+Y "Redo"
0x01 0x00 0x1d 0x00 0x00 0x00 0x00 0x00 Ctrl+Z "Undo"

0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Shift
0x02 0x00 0x1e 0x00 0x00 0x00 0x00 0x00 ! (Shift+1) "Exclamation mark"
0x02 0x00 0x1f 0x00 0x00 0x00 0x00 0x00 @ (Shift+2) "At sign"
0x02 0x00 0x20 0x00 0x00 0x00 0x00 0x00 # (Shift+3) "Number sign"
0x02 0x00 0x21 0x00 0x00 0x00 0x00 0x00 $ (Shift+4) "Dolar sign"
0x02 0x00 0x22 0x00 0x00 0x00 0x00 0x00 % (Shift+5) "Percent sign"
0x02 0x00 0x23 0x00 0x00 0x00 0x00 0x00 ¨ (Shift+6) "Diaeresis"
0x02 0x00 0x24 0x00 0x00 0x00 0x00 0x00 & (Shift+7) "Ampersand"
0x02 0x00 0x25 0x00 0x00 0x00 0x00 0x00 * (Shift+8) "Asterisk"
0x02 0x00 0x26 0x00 0x00 0x00 0x00 0x00 ( (Shift+9) "Round brackets"
0x02 0x00 0x27 0x00 0x00 0x00 0x00 0x00 ) (Shift+0) "Round brackets"
0x02 0x00 0x2d 0x00 0x00 0x00 0x00 0x00 _ (Shift+-) "Underscore/Understrike"
0x02 0x00 0x2e 0x00 0x00 0x00 0x00 0x00 + (Shift+=) "Plus sign"
0x02 0x00 0x2f 0x00 0x00 0x00 0x00 0x00 ` (Shift+´) "Grave accent"
0x02 0x00 0x30 0x00 0x00 0x00 0x00 0x00 { (Shift+[) "Curly brackets/Braces"
0x02 0x00 0x31 0x00 0x00 0x00 0x00 0x00 } (Shift+]) "Curly brackets/Braces"
0x02 0x00 0x34 0x00 0x00 0x00 0x00 0x00 ^ (Shift+~) "Circumflex accent/Carret"
0x02 0x00 0x35 0x00 0x00 0x00 0x00 0x00 " (Shift+') "Quotation mark"
0x02 0x00 0x36 0x00 0x00 0x00 0x00 0x00 < (Shift+,) "Less-than sign"
0x02 0x00 0x37 0x00 0x00 0x00 0x00 0x00 > (Shift+.) "Greater-than sign"
0x02 0x00 0x38 0x00 0x00 0x00 0x00 0x00 : (Shift+;) "Colon"

0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Alt

0x05 0x00 0x4c 0x00 0x00 0x00 0x00 0x00 Ctrl+Alt+Del

0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 AltGr
0x40 0x00 0x06 0x00 0x00 0x00 0x00 0x00 ₢ (AltGr+C) "(obsolete) symbol ₢ for the former Brazilian currency - ISO 4217 code BRB"
0x40 0x00 0x08 0x00 0x00 0x00 0x00 0x00 ° (AltGr+E) "Degree symbol"
0x40 0x00 0x14 0x00 0x00 0x00 0x00 0x00 / (AltGr+Q) "Slash"
0x40 0x00 0x1a 0x00 0x00 0x00 0x00 0x00 ? (AltGr+W) "Question mark"
0x40 0x00 0x1e 0x00 0x00 0x00 0x00 0x00 ¹ (AltGr+1) "Superscript one symbol"
0x40 0x00 0x1f 0x00 0x00 0x00 0x00 0x00 ² (AltGr+2) "Superscript two symbol"
0x40 0x00 0x20 0x00 0x00 0x00 0x00 0x00 ³ (AltGr+3) "Superscript three symbol"
0x40 0x00 0x21 0x00 0x00 0x00 0x00 0x00 £ (AltGr+4) "Pound sign symbol"
0x40 0x00 0x22 0x00 0x00 0x00 0x00 0x00 ¢ (AltGr+5) "Cent symbol"
0x40 0x00 0x23 0x00 0x00 0x00 0x00 0x00 ¬ (AltGr+6) "Logical negation symbol"
0x40 0x00 0x2e 0x00 0x00 0x00 0x00 0x00 § (AltGr+=) "Section sign symbol"
0x40 0x00 0x30 0x00 0x00 0x00 0x00 0x00 ª (AltGr+[) "Feminine ordinal indicator symbol"
0x40 0x00 0x31 0x00 0x00 0x00 0x00 0x00 º (AltGr+]) "Masculine ordinal indicator symbol"

0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00 Win (Start Menu)
0x80 0x00 0x08 0x00 0x00 0x00 0x00 0x00 Win+E (Explorer)
0x80 0x00 0x15 0x00 0x00 0x00 0x00 0x00 Win+R (Run)

(Multimedia keys)
Length 3 RAW input 3 bytes interface 1, Subclass 01, Protocol 02
Data: 00 00 00

0x00 0x00 0x00 "Key released"
0x02 0x21 0x02 Search
0x02 0x23 0x02 Home
0x02 0x96 0x01 "Launch Internet Browser"
0x02 0xb5 0x00 >>|
0x02 0xb6 0x00 |<<
0x02 0xcd 0x00 |>|| (Play/Pause)
0x02 0xe2 0x00 Mute
0x02 0xe9 0x00 V+
0x02 0xea 0x00 V-

0x02 0x83 0x01 "Launch Media Player"
0x02 0x8a 0x01 "Launch Email"

(Mouse)
Length 6 RAW input 6 bytes interface 1, Subclass 01, Protocol 02
Data: 01 00 00 00 00 00

0x01 0x00 0x00 0x00 0x00 0x00 "Button released"
0x01 0x01 0x00 0x00 0x00 0x00 "Button L" (One finger)
0x01 0x02 0x00 0x00 0x00 0x00 "Button R" (Three Fingers)
0x01 0x00 0x00 0x00 0x01 0x00 "Slide DnUp" (Two Fingers)
0x01 0x00 0x00 0x00 0xff 0x00 "Slide UpDn" (Two Fingers)
0x01 0x00 0xNN 0xMM 0x00 0x00 "Finger movement"
"Finger movement": 0x01 0x00 0xNN 0x00 0x00 0x00 "Move x" (From L to R: NN = 0x00 + speed); (From R to F: NN = 0xff - speed)
"Finger movement": 0x01 0x00 0x00 0xMM 0x00 0x00 "Move y" (From Up to Dn: MM = 0x00 + speed); (From Dn to Up: MM = 0xff - speed)

(Stand by; timeout = +/-60s; touchpad: off; wake up: key press)
Length 6 RAW input 6 bytes interface 1, Subclass 01, Protocol 02
Data: 01 00 00 00 00 00
Length 3 RAW input 3 bytes interface 1, Subclass 01, Protocol 02
Data: 02 00 00

Layout: mini_teclado

xxxajk commented 4 years ago

No, that's normal. Keyboards do not output ASCII, they output keyscan codes. http://www.philipstorr.id.au/pcbook/book3/scancode.htm

rtek1000 commented 4 years ago

What would be the best way to convert to ASCII?

I tested the code below, and it worked, but I think using a character array should be more compact.

//#define

// Load the USB Host System core
#define LOAD_USB_HOST_SYSTEM
// Load USB Host Shield
#define LOAD_USB_HOST_SHIELD
// Use USB hub, you might want this for multiple devices.
#define LOAD_UHS_HUB

// Patch printf so we can use it.
#define LOAD_UHS_PRINTF_HELPER
#define DEBUG_PRINTF_EXTRA_HUGE 0
#define DEBUG_PRINTF_EXTRA_HUGE_USB_HID 1

#define LOAD_UHS_HID

#include <Arduino.h>
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif

#include <UHS_host.h>

class myHID_processor : public UHS_HID_PROCESSOR {
  public:
    myHID_processor(void) {};

    bool caps_lock_buff = false;
    bool shift_accent_buff = false;
    int accent_buff = 0;

    bool haveAccent(uint8_t data) {
      if (accent_buff != 0) {
        return true;
      } else {
        return false;
      }
    }

    void printAccent(uint8_t data, bool shift) {
      if (shift) {
        switch (data) {
          case 0x23:
            printf_P(PSTR("¨")); //  ASCII 249  // ¨
            break;
          case 0x2f:
            printf_P(PSTR("`")); // char(data[2] + 49)); // ASCII 96  // `
            break;
          case 0x34:
            printf_P(PSTR("^")); // char(data[2] + 42)); // ASCII 94  // ^
            break;
          default:
            break;
        }
      } else {
        switch (data) {
          case 0x2f:
            printf_P(PSTR("´")); // char(data[2] + 192): ASCII 239 // ´
            break;
          case 0x34:
            printf_P(PSTR("~")); // char(data[2] + 74): ASCII 126 // ~
            break;
          default:
            break;
        }
      }
    }

    void accent(uint8_t data, bool data2) {
      if ((accent_buff == data) & (shift_accent_buff == data2)) {
        printAccent(accent_buff, shift_accent_buff);
        printAccent(accent_buff, shift_accent_buff);
        accent_buff = 0;
      } else if (accent_buff != 0) {
        printAccent(accent_buff, shift_accent_buff);
        printAccent(data, data2);
        accent_buff = 0;
        shift_accent_buff = false;
      } else {
        accent_buff = data;
        shift_accent_buff = data2;
      }
    }

    void letter(uint8_t let, bool capsLock) {
      if (capsLock) {
        if (haveAccent(let)) {
          switch (let + 61) {
            case 'A':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ä"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("À"));
                  } else {
                    printf_P(PSTR("Á"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Â"));
                  } else {
                    printf_P(PSTR("Ã"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'E':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ë"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("È"));
                  } else {
                    printf_P(PSTR("É"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ê"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'I':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ï"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ì"));
                  } else {
                    printf_P(PSTR("Í"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Î"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'O':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ö"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ò"));
                  } else {
                    printf_P(PSTR("Ó"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ô"));
                  } else {
                    printf_P(PSTR("Õ"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'U':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ü"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ù"));
                  } else {
                    printf_P(PSTR("Ú"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Û"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            default:
              printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
              break;
          }
          accent_buff = 0;
        } else {
          printf_P(PSTR("%c"), char(let + 61)); // A/a ~ Z/z
        }
      } else {
        if (haveAccent(let)) {
          switch (let + 61) {
            case 'A':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ä"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("à"));
                  } else {
                    printf_P(PSTR("á"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("â"));
                  } else {
                    printf_P(PSTR("ã"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'E':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ë"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("è"));
                  } else {
                    printf_P(PSTR("é"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ê"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'I':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ï"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ì"));
                  } else {
                    printf_P(PSTR("í"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("î"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'O':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ö"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ò"));
                  } else {
                    printf_P(PSTR("ó"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ô"));
                  } else {
                    printf_P(PSTR("Õ"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'U':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ü"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ù"));
                  } else {
                    printf_P(PSTR("ú"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("û"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            default:
              printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
              break;
          }
          accent_buff = 0;
        } else {
          printf_P(PSTR("%c"), char(let + 93)); // A/a ~ Z/z
        }
      }
    }

    void onRelease(UHS_HID_base *d) {
      printf_P(PSTR("HID driver type %d no longer available.\r\n"), d->driver);
    }
    void onStart(UHS_HID_base *d) {
      printf_P(PSTR("HID driver type %d started, Subclass %02x, Protocol %02x\r\n"), d->driver, d->parent->bSubClass, d->parent->bProtocol);
    }
    void onPoll(UHS_HID_base *d, uint8_t *data, uint16_t length) {
      switch (d->driver) {
        case UHS_HID_raw:
          //                    printf_P(PSTR("Length %d "), length);
          //                    printf_P(PSTR("RAW input %d bytes interface %d, Subclass %02x, Protocol %02x Data:"), length, d->parent->bIface, d->parent->bSubClass, d->parent->bProtocol);
          //                    for (int i = 0; i < length; i++) {
          //                      printf_P(PSTR(" %02x"), data[i]);
          //                    }
          //                    printf_P(PSTR("\r\n"));

          // A/a: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 04 00 00 00 00 00
          // Space: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 2c 00 00 00 00 00
          // release: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 00 00 00 00 00 00
          if ((length == 8) & (d->parent->bIface == 0) & (d->parent->bSubClass == 1) & (d->parent->bProtocol == 1)) {
            if ((data[0] == 0) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) {
              //printf_P(PSTR("< Pressed: %d >\r\n"), data[2]);
              if (data[2] == 0) {
                //printf_P(PSTR("< Release >\r\n"));
              } else if ((data[2] >= 0x04) & (data[2] <= 0x1d)) {
                letter(data[2], caps_lock_buff);
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 61)); // A/a ~ Z/z
              } else if (data[2] <= 0x26) {
                printf_P(PSTR("%c"), char(data[2] + 19)); // 1 ~ 9
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 19)); // 1 ~ 9
              } else if (data[2] == 0x27) {
                printf_P(PSTR("0"), char(data[2] + 9)); // 0
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 9)); // 0
              } else if (data[2] == 0x28) {
                printf_P(PSTR("\r\n")); // char(data[2] - 27): ASCII 13 // Enter <_|
                //printf_P(PSTR("< Pressed: Enter >\r\n")); // char(data[2] - 27): ASCII 13 // Enter <_|
              } else if (data[2] == 0x29) {
                printf_P(PSTR("<ESC>")); // char(data[2] - 14): ASCII 27 // Esc
                //printf_P(PSTR("< Pressed: Esc >\r\n")); // char(data[2] - 14): ASCII 27 // Esc
              } else if (data[2] == 0x2a) {
                printf_P(PSTR("<BACK>")); // char(data[2] - 34): ASCII 8 // Back <---
                //printf_P(PSTR("< Pressed: Back >\r\n")); // char(data[2] - 34): ASCII 8 // Back <---
              } else if (data[2] == 0x2b) {
                printf_P(PSTR("<TAB>")); // char(data[2] - 34): ASCII 9 // Tab
                //printf_P(PSTR("< Pressed: Tab >\r\n")); // char(data[2] - 34): ASCII 9 // Tab
              } else if (data[2] == 0x2d) {
                //printf_P(PSTR("%c"), char(keyMap[0][1])); // ASCII 45 // -
                printf_P(PSTR("-")); // char(data[2]): ASCII 45 // -
                //printf_P(PSTR("< Pressed: - >\r\n")); // char(data[2]): ASCII 45 // -
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("=")); // char(data[2] + 16): ASCII 61 // =
                //printf_P(PSTR("< Pressed: = >\r\n")); // char(data[2] + 16): ASCII 61 // =
              } else if (data[2] == 0x2f) {
                accent(data[2], false);
                //printf_P(PSTR("< Pressed: ´ >\r\n")); // char(data[2] + 192): ASCII 239 // ´
              } else if (data[2] == 0x30) {
                printf_P(PSTR("< Pressed: [ >\r\n")); // char(data[2] + 43): ASCII 91 // [
              } else if (data[2] == 0x31) {
                printf_P(PSTR("< Pressed: ] >\r\n")); // char(data[2] + 44): ASCII 93 // ]
              } else if (data[2] == 0x33) {
                if (caps_lock_buff) {
                  printf_P(PSTR("Ç"));
                } else {
                  printf_P(PSTR("ç"));
                }
                //printf_P(PSTR("< Pressed: Ç >\r\n")); // char(data[2] + 77): ASCII 128  // Ç
              } else if (data[2] == 0x34) {
                accent(data[2], false);
                //printf_P(PSTR("< Pressed: ~ >\r\n")); // char(data[2] + 74): ASCII 126 // ~
              } else if (data[2] == 0x35) {
                printf_P(PSTR("< Pressed: ' >\r\n")); // char(data[2] - 14): ASCII 39 // '
              } else if (data[2] == 0x36) {
                printf_P(PSTR("< Pressed: , >\r\n")); // char(data[2] - 10): ASCII 44 // ,
              } else if (data[2] == 0x37) {
                printf_P(PSTR("< Pressed: . >\r\n")); // char(data[2] - 9): ASCII 46 // .
              } else if (data[2] == 0x38) {
                printf_P(PSTR("< Pressed: ; >\r\n")); // char(data[2] + 3): ASCII 59 // ;
              } else if (data[2] == 0x39) {
                caps_lock_buff = !caps_lock_buff;
                //printf_P(PSTR("< Pressed: Caps >\r\n")); // ASCII None // Caps
              } else if ((data[2] >= 0x3a) & (data[2] <= 0x45)) {
                printf_P(PSTR("< Pressed: F%d >\r\n"), char(data[2] - 57));  // F1 ~ F12
              } else if (data[2] == 0x46) {
                printf_P(PSTR("< Pressed: PrtSc >\r\n")); // ASCII None // PrtSc
              } else if (data[2] == 0x4a) {
                printf_P(PSTR("< Pressed: Home >\r\n")); // ASCII None // Home
              } else if (data[2] == 0x4b) {
                printf_P(PSTR("< Pressed: PgUp >\r\n")); // ASCII None // PgUp
              } else if (data[2] == 0x4c) {
                printf_P(PSTR("< Pressed: Del >\r\n")); // char(data[2] + 51): ASCII 127  // Del
              } else if (data[2] == 0x4d) {
                printf_P(PSTR("< Pressed: End >\r\n")); // char(data[2] + 51): ASCII 127  // End
              } else if (data[2] == 0x4e) {
                printf_P(PSTR("< Pressed: PgDn >\r\n")); // ASCII None  // PgDn
              } else if (data[2] == 0x4f) {
                printf_P(PSTR("< Pressed: Arrow R >\r\n")); // ASCII None  // Arrow R
              } else if (data[2] == 0x50) {
                printf_P(PSTR("< Pressed: Arrow L >\r\n")); // ASCII None  // Arrow L
              } else if (data[2] == 0x51) {
                printf_P(PSTR("< Pressed: Arrow Dn >\r\n")); // ASCII None  // Arrow Dn
              } else if (data[2] == 0x52) {
                printf_P(PSTR("< Pressed: Arrow Up >\r\n")); // ASCII None  // Arrow Up
              }
            } else if ((data[0] == 2) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Shift
              if (data[2] == 0) {
                //printf_P(PSTR("< Release >\r\n"));
              } else if ((data[2] >= 0x04) & (data[2] <= 0x1d)) {
                letter(char(data[2]), true);
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 61)); // A/a ~ Z/z
              } else if (data[2] == 0x1e) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 3)); // ASCII 33  // !
              } else if (data[2] == 0x1f) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 33)); // ASCII 64  // @
              } else if (data[2] == 0x20) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 3)); // ASCII 35  // #
              } else if (data[2] == 0x21) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 3)); // ASCII 36  // $
              } else if (data[2] == 0x22) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 3)); // ASCII 37  // %
              } else if (data[2] == 0x23) {
                accent(data[2], true);  // ASCII 249  // ¨
                //printf_P(PSTR("< Pressed: ¨ >\r\n"), char(data[2] + 214)); // ASCII 249  // ¨
              } else if (data[2] == 0x24) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 2)); // ASCII 38  // &
              } else if (data[2] == 0x25) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 5)); // ASCII 42  // *
              } else if (data[2] == 0x26) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 2)); // ASCII 40  // (
              } else if (data[2] == 0x27) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 2)); // ASCII 41  // )
              } else if (data[2] == 0x2d) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 50)); // ASCII 95  // _
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] - 3)); // ASCII 43  // +
              } else if (data[2] == 0x2f) {
                accent(data[2], true);  // char(data[2] + 49)); // ASCII 96  // `
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 49)); // ASCII 96  // `
              } else if (data[2] == 0x30) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 75)); // ASCII 123  // {
              } else if (data[2] == 0x31) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 76)); // ASCII 125  // }
              } else if (data[2] == 0x33) {
                printf_P(PSTR("Ç"));
              } else if (data[2] == 0x34) {
                accent(data[2], true);  // char(data[2] + 42)); // ASCII 94  // ^
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 42)); // ASCII 94  // ^
              } else if (data[2] == 0x35) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] - 19)); // ASCII 34  // "
              } else if (data[2] == 0x36) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 6)); // ASCII 60  // <
              } else if (data[2] == 0x37) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 7)); // ASCII 62  // >
              } else if (data[2] == 0x38) {
                printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 2)); // ASCII 58  // :
              }
            } else if ((data[0] == 0x40) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // AltGR
              if (data[2] == 0x06) {
                printf_P(PSTR("₢")); // ISO 4217 // ₢ (AltGr + C) "(obsolete) symbol ₢ for the former Brazilian currency - ISO 4217 code BRB"
              } else if (data[2] == 0x08) {
                printf_P(PSTR("°")); // ASCII 248 // ° (AltGr + E) "Degree symbol"
              } else if (data[2] == 0x14) {
                printf_P(PSTR("/")); // ASCII 47 // / (AltGr + Q) "Slash"
              } else if (data[2] == 0x1a) {
                printf_P(PSTR("?")); // ASCII 63 // ? (AltGr + W) "Question mark"
              } else if (data[2] == 0x1e) {
                printf_P(PSTR("¹")); // ASCII 251 // ¹ (AltGr + 1) "Superscript one symbol"
              } else if (data[2] == 0x1f) {
                printf_P(PSTR("²")); // ASCII 253 // ² (AltGr + 2) "Superscript two symbol"
              } else if (data[2] == 0x20) {
                printf_P(PSTR("³")); // ASCII 252 // ³ (AltGr + 3) "Superscript three symbol"
              } else if (data[2] == 0x21) {
                printf_P(PSTR("£")); // ASCII 156 // £ (AltGr + 4) "Pound sign symbol"
              } else if (data[2] == 0x22) {
                printf_P(PSTR("¢")); // ASCII 189 // ¢ (AltGr + 5) "Cent symbol"
              } else if (data[2] == 0x23) {
                printf_P(PSTR("¬")); // ASCII 170 // ¬ (AltGr + 6) "Logical negation symbol"
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("§")); // ASCII 245 // § (AltGr + =) "Section sign symbol"
              } else if (data[2] == 0x30) {
                printf_P(PSTR("ª")); // ASCII 166 // ª (AltGr + =) "Feminine ordinal indicator symbol"
              } else if (data[2] == 0x31) {
                printf_P(PSTR("º")); // ASCII 167 // º (AltGr + =) "Masculine ordinal indicator symbol"
              }
            }
          }

          break;
        default:
          break;
      }
    }

    //const int keyMap[3][2] = {{0x2d, '-'}, {3, 4}, {5, 6}};
};

myHID_processor HID_processor1;
myHID_processor HID_processor2;
MAX3421E_HOST UHS_Usb;
UHS_USBHub hub_1(&UHS_Usb);
UHS_HID hid1(&UHS_Usb, &HID_processor1);
UHS_HID hid2(&UHS_Usb, &HID_processor2);

void setup() {
  USB_HOST_SERIAL.begin(115200);
  while (UHS_Usb.Init(1000) != 0);
  printf_P(PSTR("\r\nHID RAW demo Begin.\r\n"));
}

void loop() {
  delay(1);
}
rtek1000 commented 4 years ago

I tried using Arduino Nano / UNO / Pro Mini, but it didn't work, maybe for lack of memory. I could only use it with Mega2560, I couldn't make it work with STM32 either, the code has many adaptations made with #ifdef, without indentation, which confuses a lot, after indenting the code I could understand a little better, but still not enough (make it work with STM32). Maybe it's a good idea to use esp32 (520 KiB SRAM), but it didn't compile either.

The intention was to use Arduino Pro Mini (Atmega328) as a bridge between the MAX3421E and STM32 via serial port, but it didn't work out. It only worked with the Mega2560, but it's much more expensive and takes up a lot of physical space, even the Mega2560 PRO version. (I will try to switch the project from STM32 to Mega2560, but the ILI9341 display that is currently controlled by STM32 will be very slow)

If anyone wants to try this keyboard with Mega2560, follows the code, need to use the UHS30 library:

#if defined(STM32F1xx)
#define SERIAL_PORT_MONITOR Serial
#else
#define SERIAL_PORT_MONITOR Serial
#endif

// Load the USB Host System core
#define LOAD_USB_HOST_SYSTEM
// Load USB Host Shield
#define LOAD_USB_HOST_SHIELD
// Use USB hub, you might want this for multiple devices.
#define LOAD_UHS_HUB

// Patch printf so we can use it.
#define LOAD_UHS_PRINTF_HELPER
#define DEBUG_PRINTF_EXTRA_HUGE 0
#define DEBUG_PRINTF_EXTRA_HUGE_USB_HID 1

#define LOAD_UHS_HID

#include <Arduino.h>
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif

#if defined(STM32F1xx)
// https://os.mbed.com/users/mega64/code/mbed-STM32F103C8/annotate/414e9c822e99/targets/cmsis/TARGET_Atmel/TARGET_SAM_CortexM4/utils/cmsis/TARGET_SAMG55/include/samg55n19.h/#95
#define SPI0_IRQn 8 // STM32F103C8
#define PERIPH_COUNT_IRQn 49 // STM32F103C8
#define STDIO_IS_OK_TO_USE_AS_IS 1 // STM32F103C8
#define SWI_IRQ_NUM SPI0_IRQn // STM32F103C8
#define UHS_SS PA15 // STM32F103C8
#define UHS_INT PA8 // STM32F103C8
#define UHS_MAX3421E_SPD 1000000 // STM32F103C8
#endif

#include <UHS_host.h>

class myHID_processor : public UHS_HID_PROCESSOR {
  public:
    myHID_processor(void) {};

    bool caps_lock_buff = false;
    bool shift_accent_buff = false;
    int accent_buff = 0;

    bool haveAccent(uint8_t data) {
      if (accent_buff != 0) {
        return true;
      } else {
        return false;
      }
    }

    void printAccent(uint8_t data, bool shift) {
      if (shift) {
        if (data == 0x23) {
          printf_P(PSTR("¨")); // char(data[2] + 192): ASCII 239 // ´
        } else if (data == 0x2f) {
          printf_P(PSTR("`")); // char(data[2] + 74): ASCII 126 // ~
        } else if (data == 0x34) {
          printf_P(PSTR("^")); // char(data[2] + 74): ASCII 126 // ~
        }
      } else {
        if (data == 0x2f) {
          printf_P(PSTR("´")); // char(data[2] + 192): ASCII 239 // ´
        } else if (data == 0x34) {
          printf_P(PSTR("~")); // char(data[2] + 74): ASCII 126 // ~
        }
      }
    }

    void accent(uint8_t data, bool data2) {
      if ((accent_buff == data) & (shift_accent_buff == data2)) {
        printAccent(accent_buff, shift_accent_buff);
        printAccent(accent_buff, shift_accent_buff);
        printf_P(PSTR("\r\n")); //
        accent_buff = 0;
      } else if (accent_buff != 0) {
        printAccent(accent_buff, shift_accent_buff);
        printAccent(data, data2);
        printf_P(PSTR("\r\n")); //
        accent_buff = 0;
        shift_accent_buff = false;
      } else {
        accent_buff = data;
        shift_accent_buff = data2;
      }
    }

    void letter(uint8_t let, bool capsLock) {
      if (capsLock) {
        if (haveAccent(let)) {
          switch (let + 61) {
            case 'A':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ä\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("À\r\n"));
                  } else {
                    printf_P(PSTR("Á\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Â\r\n"));
                  } else {
                    printf_P(PSTR("Ã\r\n"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'E':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ë\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("È\r\n"));
                  } else {
                    printf_P(PSTR("É\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ê\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'I':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ï\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ì\r\n"));
                  } else {
                    printf_P(PSTR("Í\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Î\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'O':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ö\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ò\r\n"));
                  } else {
                    printf_P(PSTR("Ó\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ô\r\n"));
                  } else {
                    printf_P(PSTR("Õ\r\n"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'U':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("Ü\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ù\r\n"));
                  } else {
                    printf_P(PSTR("Ú\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Û\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
                  break;
              }
              break;
            default:
              printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
              break;
          }
          accent_buff = 0;
        } else {
          printf_P(PSTR("%c\r\n"), char(let + 61)); // A/a ~ Z/z
        }
      } else {
        if (haveAccent(let)) {
          switch (let + 61) {
            case 'A':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ä\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("à\r\n"));
                  } else {
                    printf_P(PSTR("á\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("â\r\n"));
                  } else {
                    printf_P(PSTR("ã\r\n"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'E':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ë\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("è\r\n"));
                  } else {
                    printf_P(PSTR("é\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ê\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'I':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ï\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ì\r\n"));
                  } else {
                    printf_P(PSTR("í\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("î\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'O':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ö\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ò\r\n"));
                  } else {
                    printf_P(PSTR("ó\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("Ô\r\n"));
                  } else {
                    printf_P(PSTR("Õ\r\n"));
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            case 'U':
              switch (accent_buff) {
                case 0x23:
                  printf_P(PSTR("ü\r\n"));
                  break;
                case 0x2f:
                  if (shift_accent_buff) {
                    printf_P(PSTR("ù\r\n"));
                  } else {
                    printf_P(PSTR("ú\r\n"));
                  }
                  break;
                case 0x34:
                  if (shift_accent_buff) {
                    printf_P(PSTR("û\r\n"));
                  } else {
                    printAccent(accent_buff, shift_accent_buff);
                    printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  }
                  break;
                default:
                  printAccent(accent_buff, shift_accent_buff);
                  printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
                  break;
              }
              break;
            default:
              printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
              break;
          }
          accent_buff = 0;
        } else {
          printf_P(PSTR("%c\r\n"), char(let + 93)); // A/a ~ Z/z
        }
      }
    }

    void onRelease(UHS_HID_base *d) {
      //printf_P(PSTR("HID driver type %d no longer available.\r\n"), d->driver);
      printf_P(PSTR("DrvOff\r\n"), d->driver);
    }
    void onStart(UHS_HID_base *d) {
      //printf_P(PSTR("HID driver type %d started, Subclass %02x, Protocol %02x\r\n"), d->driver, d->parent->bSubClass, d->parent->bProtocol);
      printf_P(PSTR("DrvOn\r\n"), d->driver);
    }
    void onPoll(UHS_HID_base *d, uint8_t *data, uint16_t length) {
      switch (d->driver) {
        case UHS_HID_raw:
          //          printf_P(PSTR("Length %d "), length);
          //          printf_P(PSTR("RAW input %d bytes interface %d, Subclass %02x, Protocol %02x Data:"), length, d->parent->bIface, d->parent->bSubClass, d->parent->bProtocol);
          //          for (int i = 0; i < length; i++) {
          //            printf_P(PSTR(" %02x"), data[i]);
          //          }
          //          printf_P(PSTR("\r\n"));

          // A/a: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 04 00 00 00 00 00
          // Space: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 2c 00 00 00 00 00
          // release: Length 8 RAW input 8 bytes interface 0, Subclass 01, Protocol 01 Data: 00 00 00 00 00 00 00 00
          if ((length == 8) & (d->parent->bIface == 0) & (d->parent->bSubClass == 1) & (d->parent->bProtocol == 1)) {
            if ((data[0] == 0) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) {
              //printf_P(PSTR("< Pressed: %d >\r\n"), data[2]);
              if (data[2] == 0) {
                printf_P(PSTR("KeyRelease\r\n"));
              } else if ((data[2] >= 0x04) & (data[2] <= 0x1d)) {
                letter(data[2], caps_lock_buff);
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 61)); // A/a ~ Z/z
              } else if (data[2] <= 0x26) {
                printf_P(PSTR("%c\r\n"), char(data[2] + 19)); // 1 ~ 9
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 19)); // 1 ~ 9
              } else if (data[2] == 0x27) {
                printf_P(PSTR("0\r\n"), char(data[2] + 9)); // 0
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 9)); // 0
              } else if (data[2] == 0x28) {
                //printf_P(PSTR("%c\r\n"), char(13)); // char(data[2] - 27): ASCII 13 // Enter <_|
                printf_P(PSTR("Enter\r\n")); // char(data[2] - 27): ASCII 13 // Enter <_|
              } else if (data[2] == 0x29) {
                //printf_P(PSTR("%c\r\n"), char(27)); // char(data[2] - 14): ASCII 27 // Esc
                printf_P(PSTR("Esc\r\n")); // char(data[2] - 14): ASCII 27 // Esc
              } else if (data[2] == 0x2a) {
                //printf_P(PSTR("%c\r\n"), char(8)); // char(data[2] - 34): ASCII 8 // Back <---
                printf_P(PSTR("Back\r\n")); // char(data[2] - 34): ASCII 8 // Back <---
                //printf_P(PSTR("< Pressed: Back >\r\n")); // char(data[2] - 34): ASCII 8 // Back <---
              } else if (data[2] == 0x2b) {
                //printf_P(PSTR("%c\r\n"), char(9)); // char(data[2] - 34): ASCII 9 // Tab
                printf_P(PSTR("Tab\r\n")); // char(data[2] - 34): ASCII 9 // Tab
              } else if (data[2] == 0x2c) {
                printf_P(PSTR("Spc\r\n")); // ASCII None // Spacebar
              } else if (data[2] == 0x2d) {
                //printf_P(PSTR("%c"), char(keyMap[0][1])); // ASCII 45 // -
                printf_P(PSTR("-\r\n")); // char(data[2]): ASCII 45 // -
                //printf_P(PSTR("< Pressed: - >\r\n")); // char(data[2]): ASCII 45 // -
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("=\r\n")); // char(data[2] + 16): ASCII 61 // =
                //printf_P(PSTR("< Pressed: = >\r\n")); // char(data[2] + 16): ASCII 61 // =
              } else if (data[2] == 0x2f) {
                accent(data[2], false);
                //printf_P(PSTR("< Pressed: ´ >\r\n")); // char(data[2] + 192): ASCII 239 // ´
              } else if (data[2] == 0x30) {
                printf_P(PSTR("[\r\n")); // char(data[2] + 43): ASCII 91 // [
              } else if (data[2] == 0x31) {
                printf_P(PSTR("]\r\n")); // char(data[2] + 44): ASCII 93 // ]
              } else if (data[2] == 0x33) {
                if (caps_lock_buff) {
                  printf_P(PSTR("Ç\r\n"));
                } else {
                  printf_P(PSTR("ç\r\n"));
                }
                //printf_P(PSTR("< Pressed: Ç >\r\n")); // char(data[2] + 77): ASCII 128  // Ç
              } else if (data[2] == 0x34) {
                accent(data[2], false);
                //printf_P(PSTR("< Pressed: ~ >\r\n")); // char(data[2] + 74): ASCII 126 // ~
              } else if (data[2] == 0x35) {
                printf_P(PSTR("'\r\n")); // char(data[2] - 14): ASCII 39 // '
              } else if (data[2] == 0x36) {
                printf_P(PSTR(",\r\n")); // char(data[2] - 10): ASCII 44 // ,
              } else if (data[2] == 0x37) {
                printf_P(PSTR(".\r\n")); // char(data[2] - 9): ASCII 46 // .
              } else if (data[2] == 0x38) {
                printf_P(PSTR(";\r\n")); // char(data[2] + 3): ASCII 59 // ;
              } else if (data[2] == 0x39) {
                caps_lock_buff = !caps_lock_buff;
                printf_P(PSTR("Caps\r\n")); // ASCII None // Caps
              } else if ((data[2] >= 0x3a) & (data[2] <= 0x42)) {
                printf_P(PSTR("F%c\r\n"), char(data[2] - 9));  // F1 ~ F9: 112 ~ 123
              } else if ((data[2] >= 0x43) & (data[2] <= 0x45)) {
                printf_P(PSTR("F1%c\r\n"), char(data[2] - 19));  // F10 ~ F12: 112 ~ 123
              } else if (data[2] == 0x46) {
                printf_P(PSTR("PrtSc\r\n")); // ASCII None // PrtSc
              } else if (data[2] == 0x4a) {
                printf_P(PSTR("Home\r\n")); // ASCII None // Home
              } else if (data[2] == 0x4b) {
                printf_P(PSTR("PgUp\r\n")); // ASCII None // PgUp
              } else if (data[2] == 0x4c) {
                printf_P(PSTR("Del\r\n")); // char(data[2] + 51): ASCII 127  // Del
              } else if (data[2] == 0x4d) {
                printf_P(PSTR("End\r\n")); // char(data[2] + 51): ASCII 127  // End
              } else if (data[2] == 0x4e) {
                printf_P(PSTR("PgDn\r\n")); // ASCII None  // PgDn
              } else if (data[2] == 0x4f) {
                printf_P(PSTR("ArrR\r\n")); // ASCII None  // Arrow R
              } else if (data[2] == 0x50) {
                printf_P(PSTR("ArrL\r\n")); // ASCII None  // Arrow L
              } else if (data[2] == 0x51) {
                printf_P(PSTR("ArrD\r\n")); // ASCII None  // Arrow Dn
              } else if (data[2] == 0x52) {
                printf_P(PSTR("ArrU\r\n")); // ASCII None  // Arrow Up
              } else {
                printf_P(PSTR("KeyPress: %d\r\n"), data[2]); //
              }
            } else if ((data[0] == 1) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Ctrl
              if (data[2] == 0) {
                printf_P(PSTR("Ctrl\r\n")); //
              }
            } else if ((data[0] == 2) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Shift
              if (data[2] == 0) {
                printf_P(PSTR("Shift\r\n"));
                //printf_P(PSTR("%c"), char(16)); // Shift
              } else if ((data[2] >= 0x04) & (data[2] <= 0x1d)) {
                letter(char(data[2]), true);
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 61)); // A/a ~ Z/z
              } else if (data[2] == 0x1e) {
                printf_P(PSTR("!\r\n")); //, char(data[2] + 3)); // ASCII 33  // !
              } else if (data[2] == 0x1f) {
                printf_P(PSTR("@\r\n")); //, char(data[2] + 33)); // ASCII 64  // @
              } else if (data[2] == 0x20) {
                printf_P(PSTR("#\r\n")); //, char(data[2] + 3)); // ASCII 35  // #
              } else if (data[2] == 0x21) {
                printf_P(PSTR("$\r\n")); //, char(data[2] + 3)); // ASCII 36  // $
              } else if (data[2] == 0x22) {
                printf_P(PSTR("%\r\n")); //, char(data[2] + 3)); // ASCII 37  // %
              } else if (data[2] == 0x23) {
                accent(data[2], true);  // ASCII 249  // ¨
                //printf_P(PSTR("< Pressed: ¨ >\r\n"), char(data[2] + 214)); // ASCII 249  // ¨
              } else if (data[2] == 0x24) {
                printf_P(PSTR("&\r\n")); //, char(data[2] + 2)); // ASCII 38  // &
              } else if (data[2] == 0x25) {
                printf_P(PSTR("*\r\n")); //, char(data[2] + 5)); // ASCII 42  // *
              } else if (data[2] == 0x26) {
                printf_P(PSTR("(\r\n")); //, char(data[2] + 2)); // ASCII 40  // (
              } else if (data[2] == 0x27) {
                printf_P(PSTR(")\r\n")); //, char(data[2] + 2)); // ASCII 41  // )
              } else if (data[2] == 0x2d) {
                printf_P(PSTR("_\r\n")); //, char(data[2] + 50)); // ASCII 95  // _
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("+\r\n")); //, char(data[2] - 3)); // ASCII 43  // +
              } else if (data[2] == 0x2f) {
                accent(data[2], true);  // char(data[2] + 49)); // ASCII 96  // `
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 49)); // ASCII 96  // `
              } else if (data[2] == 0x30) {
                printf_P(PSTR("{\r\n")); //, char(data[2] + 75)); // ASCII 123  // {
              } else if (data[2] == 0x31) {
                printf_P(PSTR("}\r\n")); //, char(data[2] + 76)); // ASCII 125  // }
              } else if (data[2] == 0x33) {
                printf_P(PSTR("Ç\r\n"));
              } else if (data[2] == 0x34) {
                accent(data[2], true);  // char(data[2] + 42)); // ASCII 94  // ^
                //printf_P(PSTR("< Pressed: %c >\r\n"), char(data[2] + 42)); // ASCII 94  // ^
              } else if (data[2] == 0x35) {
                printf_P(PSTR("\"\r\n")); //, char(data[2] - 19)); // ASCII 34  // "
              } else if (data[2] == 0x36) {
                printf_P(PSTR("<\r\n")); //, char(data[2] + 6)); // ASCII 60  // <
              } else if (data[2] == 0x37) {
                printf_P(PSTR(">\r\n")); //, char(data[2] + 7)); // ASCII 62  // >
              } else if (data[2] == 0x38) {
                printf_P(PSTR(":\r\n")); //, char(data[2] + 2)); // ASCII 58  // :
              } else {
                printf_P(PSTR("KeyPress: %d\r\n"), data[2]); //
              }
            } else if ((data[0] == 3) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Shift+Ctrl
              if (data[2] == 0x00) {
                printf_P(PSTR("Shift+Ctrl\r\n")); //
              }
            } else if ((data[0] == 4) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Alt
              if (data[2] == 0x00) {
                printf_P(PSTR("Alt\r\n")); //
              }
            } else if ((data[0] == 5) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Ctrl+Alt
              if (data[2] == 0x00) {
                printf_P(PSTR("Ctrl+Alt\r\n")); //
              } else if (data[2] == 0x4c) {
                printf_P(PSTR("Ctrl+Alt+Del\r\n")); //
              }
            } else if ((data[0] == 6) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Shift+Alt
              if (data[2] == 0x00) {
                printf_P(PSTR("Shift+Alt\r\n")); //
              }
            } else if ((data[0] == 0x40) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // AltGR
              if (data[2] == 0x00) {
                printf_P(PSTR("AltGr\r\n")); //
              } else if (data[2] == 0x06) {
                printf_P(PSTR("₢\r\n")); // ISO 4217 // ₢ (AltGr + C) "(obsolete) symbol ₢ for the former Brazilian currency - ISO 4217 code BRB"
              } else if (data[2] == 0x08) {
                printf_P(PSTR("°\r\n")); // ASCII 248 // ° (AltGr + E) "Degree symbol"
              } else if (data[2] == 0x14) {
                printf_P(PSTR("/\r\n")); // ASCII 47 // / (AltGr + Q) "Slash"
              } else if (data[2] == 0x1a) {
                printf_P(PSTR("?\r\n")); // ASCII 63 // ? (AltGr + W) "Question mark"
              } else if (data[2] == 0x1e) {
                printf_P(PSTR("¹\r\n")); // ASCII 251 // ¹ (AltGr + 1) "Superscript one symbol"
              } else if (data[2] == 0x1f) {
                printf_P(PSTR("²\r\n")); // ASCII 253 // ² (AltGr + 2) "Superscript two symbol"
              } else if (data[2] == 0x20) {
                printf_P(PSTR("³\r\n")); // ASCII 252 // ³ (AltGr + 3) "Superscript three symbol"
              } else if (data[2] == 0x21) {
                printf_P(PSTR("£\r\n")); // ASCII 156 // £ (AltGr + 4) "Pound sign symbol"
              } else if (data[2] == 0x22) {
                printf_P(PSTR("¢\r\n")); // ASCII 189 // ¢ (AltGr + 5) "Cent symbol"
              } else if (data[2] == 0x23) {
                printf_P(PSTR("¬\r\n")); // ASCII 170 // ¬ (AltGr + 6) "Logical negation symbol"
              } else if (data[2] == 0x2e) {
                printf_P(PSTR("§\r\n")); // ASCII 245 // § (AltGr + =) "Section sign symbol"
              } else if (data[2] == 0x30) {
                printf_P(PSTR("ª\r\n")); // ASCII 166 // ª (AltGr + =) "Feminine ordinal indicator symbol"
              } else if (data[2] == 0x31) {
                printf_P(PSTR("º\r\n")); // ASCII 167 // º (AltGr + =) "Masculine ordinal indicator symbol"
              } else {
                printf_P(PSTR("KeyPress: %d\r\n"), data[2]); //
              }
            } else if ((data[0] == 0x80) & (data[1] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0) & (data[6] == 0) & (data[7] == 0)) { // Win
              if (data[2] == 0) {
                printf_P(PSTR("Win\r\n")); //
              } else {
                printf_P(PSTR("KeyPress: %d\r\n"), data[2]); //
              }
            }
          } else if ((length == 3) & (d->parent->bIface == 1) & (d->parent->bSubClass == 1) & (d->parent->bProtocol == 2)) {
            // Length 3 RAW input 3 bytes interface 1, Subclass 01, Protocol 02 Data: 02 00 00
            if ((data[0] == 0x02) & (data[2] == 0)) { // MultiMedia Left Round
              if (data[1] == 0) {
                printf_P(PSTR("MediaRelease\r\n")); //
              } else if (data[1] == 0xe9) {
                printf_P(PSTR("MediaV+\r\n")); //
              } else if (data[1] == 0xea) {
                printf_P(PSTR("MediaV-\r\n")); //
              } else if (data[1] == 0xb5) {
                printf_P(PSTR("MediaFF\r\n")); //
              } else if (data[1] == 0xb6) {
                printf_P(PSTR("MediaRew\r\n")); //
              } else if (data[1] == 0xcd) {
                printf_P(PSTR("MediaPlayPause\r\n")); //
              } else if (data[1] == 0xe2) {
                printf_P(PSTR("MediaMute\r\n")); //
              } else {
                printf_P(PSTR("MultiMedia KeyPress: %d\r\n"), data[1]); //
              }
            } else if ((data[0] == 0x02) & (data[2] == 1)) { // MultiMedia Btn column
              if (data[1] == 0x83) {
                printf_P(PSTR("MediaPlayer\r\n")); //
              } else if (data[1] == 0x8a) {
                printf_P(PSTR("MediaMail\r\n")); //
              } else if (data[1] == 0x96) {
                printf_P(PSTR("MediaBrowser\r\n")); //
              } else {
                printf_P(PSTR("MultiMedia KeyPress: %d\r\n"), data[1]); //
              }
            } else if ((data[0] == 0x02) & (data[2] == 2)) { // MultiMedia Btn column
              if (data[1] == 0x21) {
                printf_P(PSTR("MediaSearch\r\n")); //
              } else if (data[1] == 0x23) {
                printf_P(PSTR("MediaHomePage\r\n")); //
              } else {
                printf_P(PSTR("MultiMedia KeyPress: %d\r\n"), data[1]); //
              }
            }
            // Length 3 RAW input 3 bytes interface 1, Subclass 01, Protocol 02 Data: 02 b6 00

          } else if ((length == 6) & (d->parent->bIface == 1) & (d->parent->bSubClass == 1) & (d->parent->bProtocol == 2)) {
            // Length 6 RAW input 6 bytes interface 1, Subclass 01, Protocol 02 Data: 01 01 00 00 00 00
            if ((data[0] == 0x01) & (data[2] == 0) & (data[3] == 0) & (data[4] == 0) & (data[5] == 0)) { //
              if (data[1] == 0) {
                printf_P(PSTR("MouseRelease\r\n")); //
              } else if (data[1] == 0x01) {
                printf_P(PSTR("MouseBtnL\r\n")); //
              } else if (data[1] == 0x02) {
                printf_P(PSTR("MouseBtnR\r\n")); //
              } else {
                printf_P(PSTR("Mouse BtnPress: %d\r\n"), data[1]); //
              }
            } else if ((data[0] == 0x01) & (data[1] == 0) & (data[2] == 0) & (data[3] == 0) & (data[5] == 0)) { //
              if (data[4] == 0x01) {
                printf_P(PSTR("MouseScrlUp\r\n")); //
              } else if (data[4] == 0xff) {
                printf_P(PSTR("MouseScrlDn\r\n")); //
              } else {
                printf_P(PSTR("Mouse Function: %d\r\n"), data[1]); //
              }
            } else if ((data[0] == 0x01) & (data[1] == 0) & (data[4] == 0) & (data[5] == 0)) { //
              byte xSig, ySig, xVal, yVal;
              if (data[2] <= 0x80) {
                xSig = '+';
                xVal = data[2];
                // printf_P(PSTR("MouseX+%d\r\n"), data[2]); //
              } else if (data[2] > 0x80) {
                xSig = '-';
                xVal = 0xff - data[2];
                // printf_P(PSTR("MouseX-%d\r\n"), 0xff - data[2]); //
              }
              if (data[3] <= 0x80) {
                ySig = '-';
                yVal = data[3];
                // printf_P(PSTR("MouseY+%d\r\n"), data[3]); //
              } else if (data[3] > 0x80) {
                ySig = '+';
                yVal = 0xff - data[3];
                // printf_P(PSTR("MouseY-%d\r\n"), 0xff - data[3]); //
              }
              printf_P(PSTR("Mov X%c%d Y%c%d\r\n"), xSig, xVal, ySig, yVal); //
            }

          } else {
            printf_P(PSTR("Length %d "), length);
            printf_P(PSTR("RAW input %d bytes interface %d, Subclass %02x, Protocol %02x Data:"), length, d->parent->bIface, d->parent->bSubClass, d->parent->bProtocol);
            for (int i = 0; i < length; i++) {
              printf_P(PSTR(" %02x"), data[i]);
            }
            printf_P(PSTR("\r\n"));
          }

          break;
        default:
          break;
      }
    }
};

myHID_processor HID_processor1;
myHID_processor HID_processor2;
MAX3421E_HOST UHS_Usb;
UHS_USBHub hub_1(&UHS_Usb);
UHS_HID hid1(&UHS_Usb, &HID_processor1);
UHS_HID hid2(&UHS_Usb, &HID_processor2);

// For the Adafruit shield, these are the default.
//#define TFT_DC PB9
//#define TFT_CS PB8

void setup() {
  //  pinMode(TFT_DC, OUTPUT);
  //  pinMode(TFT_CS, OUTPUT);
  //  digitalWrite(TFT_DC, HIGH);
  //  digitalWrite(TFT_CS, HIGH);

  //  // put your setup code here, to run once:
  //#if defined(__STM32F1__)
  //  // Remap USART 1
  //  //  afio_remap(AFIO_REMAP_USART1);
  //
  //  // Remap SPI 1
  //  // Source: https://community.platformio.org/t/pio-arduino-stm32f103cbt6-remap/6786/5
  //  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY); // PB3 free
  //  afio_remap(AFIO_REMAP_SPI1);
  //
  //  gpio_set_mode (GPIOB, 3, GPIO_AF_OUTPUT_PP);
  //  gpio_set_mode (GPIOB, 4, GPIO_INPUT_FLOATING);
  //  gpio_set_mode (GPIOB, 5, GPIO_AF_OUTPUT_PP);
  //#endif
#if defined(STM32F1xx)
  SPI.setMOSI(PB5); // using pin number PYn
  SPI.setMISO(PB4); // using pin name PY_n
  SPI.setSCLK(PB3); // using pin number PYn
  SPI.setSSEL(PA15); // using pin number PYn
  //SPI.setClockDivider(32);

  pinMode(PB8, INPUT);

  //pinMode(PA15, OUTPUT);
  //digitalWrite(PA15, HIGH);
  //  SPI.begin(PA15);
  //

  pinMode(PC13, OUTPUT);
  digitalWrite(PC13, LOW);

#endif

  //Serial.begin(115200);
#if defined(__STM32F1__)
  // delay(5000);
#endif
  USB_HOST_SERIAL.begin(115200);

#if defined(STM32F1xx)
  digitalWrite(PC13, HIGH);
#endif
  printf_P(PSTR("\r\nStart.\r\n"));
#if defined(STM32F1xx)
  //delay(5000);
#endif
  while (UHS_Usb.Init(1000) != 0) {
    printf_P(PSTR("\r\nStarting USB HID.\r\n"));
#if defined(STM32F1xx)
    digitalWrite(PC13, !digitalRead(PC13));
#endif
    delay(500);
  }
  printf_P(PSTR("\r\nHID Begin.\r\n"));
  //Serial.print(F("\r\nHID RAW demo Begin.\r\n"));
}

void loop() {
  delay(1);
}
rtek1000 commented 4 years ago

It worked with arduino Pro Mini! (UHS_HID_RAW.ino from UHS30 lib) Some library file must be corrupted. I deleted them all and installed it again. Thanks.

rtek1000 commented 4 years ago

Note: Keyboard receiver (USB) worked with 3.3V

xxxajk commented 4 years ago

It has to do with the enumeration sequence. Your device is apparently sensitive to multiple probes.