| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 | 
							- //
 - // Created by robin on 1/8/16.
 - //
 - 
 - UsbKeyboardDevice UsbKeyboard = UsbKeyboardDevice("us");
 - 
 - 
 - /* We use a simplifed keyboard report descriptor which does not support the
 -  * boot protocol. We don't allow setting status LEDs and but we do allow
 -  * simultaneous key presses.
 -  * The report descriptor has been created with usb.org's "HID Descriptor Tool"
 -  * which can be downloaded from http://www.usb.org/developers/hidpage/.
 -  * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
 -  * for the second INPUT item.
 -  */
 - PROGMEM const char usbHidReportDescriptor[35] = { /* USB report descriptor */
 -         0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
 -         0x09, 0x06,                    // USAGE (Keyboard)
 -         0xa1, 0x01,                    // COLLECTION (Application)
 -         0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
 -         0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
 -         0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
 -         0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
 -         0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
 -         0x75, 0x01,                    //   REPORT_SIZE (1)
 -         0x95, 0x08,                    //   REPORT_COUNT (8)
 -         0x81, 0x02,                    //   INPUT (Data,Var,Abs)
 -         0x95, BUFFER_SIZE-1,           //   REPORT_COUNT (simultaneous keystrokes)
 -         0x75, 0x08,                    //   REPORT_SIZE (8)
 -         0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)
 -         0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))
 -         0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)
 -         0x81, 0x00,                    //   INPUT (Data,Ary,Abs)
 -         0xc0                           // END_COLLECTION
 - };
 - 
 - UsbKeyboardDevice::UsbKeyboardDevice(const char* layout)
 -     : _layout(0)
 - {
 -     PORTD = 0; // TODO: Only for USB pins?
 -     DDRD |= ~USBMASK;
 - 
 -     cli();
 -     usbDeviceDisconnect();
 -     usbDeviceConnect();
 - 
 - 
 -     usbInit();
 - 
 -     sei();
 - 
 -     // TODO: Remove the next two lines once we fix
 -     //       missing first keystroke bug properly.
 -     memset(reportBuffer, 0, sizeof(reportBuffer));
 -     usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
 -     setLayout(layout);
 - }
 - 
 - bool UsbKeyboardDevice::isUsbReady()
 - {
 -     UsbKeyboard.update();
 -     return usbInterruptIsReady();
 - }
 - 
 - void UsbKeyboardDevice::setLayout(const char* layout)
 - {
 -     delete _layout;
 -     _layout = new char[strlen(layout)];
 -     strcpy(_layout, layout);
 - }
 - 
 - int UsbKeyboardDevice::charModAltGr(char c, int* modifier)
 - {
 -     *modifier = MOD_ALT_RIGHT;
 -     return c;
 - }
 - 
 - int UsbKeyboardDevice::charModShift(char c, int* modifier)
 - {
 -     *modifier = MOD_SHIFT_LEFT;
 -     return c;
 - }
 - 
 - #ifdef ARD_USBKBD_AZERTY
 - int UsbKeyboardDevice::charToKeyAzerty(int c, int* modifier)
 - {
 -     *modifier = 0;
 - 
 -     if (c == '0')
 -         return charModShift(KEY_0, modifier);
 -     if (c >= '1' && c <= '9')
 -         return charModShift(KEY_1 + c - '1', modifier);
 - 
 -     if (c == '\n')
 -         return KEY_ENTER;
 -     if (c == ' ')
 -         return KEY_SPACE;
 - 
 - 
 -     if (c >= 'a' && c <= 'z')
 -     {
 -         if (c == 'a')
 -             c = 'q';
 -         else if (c == 'm')
 -             return KEY_SEMICOLON;
 -         else if (c == 'q')
 -             c = 'a';
 -         else if (c == 'w')
 -             c = 'z';
 -         else if (c == 'z')
 -             c = 'w';
 -         return KEY_A + c - 'a';
 -     }
 -     if (c >= 'A' && c <= 'Z')
 -     {
 -         if (c == 'A')
 -             c = 'Q';
 -         else if (c == 'M')
 -             return charModShift(KEY_SEMICOLON, modifier);
 -         else if (c == 'Q')
 -             c = 'A';
 -         else if (c == 'W')
 -             c = 'Z';
 -         else if (c == 'Z')
 -             c = 'W';
 -         return charModShift(KEY_A + c - 'A', modifier);
 -     }
 - 
 -     if (c == '~')
 -         return charModAltGr(KEY_2, modifier);
 -     if (c == '#')
 -         return charModAltGr(KEY_3, modifier);
 -     if (c == '{')
 -         return charModAltGr(KEY_4, modifier);
 -     if (c == '[')
 -         return charModAltGr(KEY_5, modifier);
 -     if (c == '|')
 -         return charModAltGr(KEY_6, modifier);
 -     if (c == '`')
 -         return charModAltGr(KEY_7, modifier);
 -     if (c == '\\')
 -         return charModAltGr(KEY_8, modifier);
 -     if (c == '^')
 -         return charModAltGr(KEY_9, modifier);
 -     if (c == '@')
 -         return charModAltGr(KEY_0, modifier);
 -     if (c == ']')
 -         return charModAltGr(KEY_HYPHEN, modifier);
 -     if (c == '}')
 -         return charModAltGr(KEY_EQUAL, modifier);
 -     if (c == -75)//µ
 -         return charModShift(KEY_BSLASH, modifier);
 -     if (c == '*')
 -         return KEY_BSLASH;
 - 
 -     if (c == '&')
 -         return KEY_1;
 -     if (c == -23)//é
 -         return KEY_2;
 -     if (c == '\"')
 -         return KEY_3;
 -     if (c == '\'')
 -         return KEY_4;
 -     if (c == '(')
 -         return KEY_5;
 -     if (c == '-')
 -         return KEY_6;
 -     if (c == -24)//è
 -         return KEY_7;
 -     if (c == '_')
 -         return KEY_8;
 -     if (c == -25)//ç
 -         return KEY_9;
 -     if (c == -32)//à
 -         return KEY_0;
 -     if (c == ')')
 -         return KEY_HYPHEN;
 -     if (c == '=')
 -         return KEY_EQUAL;
 -     if (c == '+')
 -         return charModShift(KEY_EQUAL, modifier);
 - 
 -     if (c == ',')
 -         return KEY_M;
 -     if (c == ';')
 -         return KEY_COMMA;
 -     if (c == ':')
 -         return KEY_DOT;
 -     if (c == '!')
 -         return KEY_SLASH;
 -     if (c == -7)//ù
 -         return KEY_QUOTE;
 -     if (c == '<')
 -         return KEYP_NUS_BSLASH;
 - 
 -     if (c == '?')
 -         return charModShift(KEY_M, modifier);
 -     if (c == '.')
 -         return charModShift(KEY_COMMA, modifier);
 -     if (c == '/')
 -         return charModShift(KEY_DOT, modifier);
 -     if (c == -89)//§
 -         return charModShift(KEY_SLASH, modifier);
 -     if (c == '%')
 -         return charModShift(KEY_QUOTE, modifier);
 -     if (c == '>')
 -         return charModShift(KEYP_NUS_BSLASH, modifier);
 - 
 -     return 0;
 - }
 - #endif
 - 
 - #ifdef ARD_USBKBD_QWERTY
 - int UsbKeyboardDevice::charToKeyQwerty(int c, int* modifier)
 - {
 -     *modifier = 0;
 -     if (c == '0')
 -         return KEY_0;
 -     if (c >= '1' && c <= '9')
 -         return KEY_1 + c - '1';
 -     if (c >= 'a' && c <= 'z')
 -         return KEY_A + c - 'a';
 -     if (c >= 'A' && c <= 'Z')
 -         return charModShift(KEY_A + c - 'A', modifier);
 - 
 -     if (c == '\n')
 -         return KEY_ENTER;
 -     if (c == ' ')
 -         return KEY_SPACE;
 - 
 - 
 -     if (c == '.')
 -         return KEY_DOT;
 -     if (c == ',')
 -         return KEY_COMMA;
 -     if (c == '/')
 -         return KEY_SLASH;
 -     if (c == ';')
 -         return KEY_SEMICOLON;
 -     if (c == '`')
 -         return KEY_TILDE;
 -     if (c == '-')
 -         return KEY_HYPHEN;
 -     if (c == '=')
 -         return KEY_EQUAL;
 -     if (c == '\'')
 -         return KEY_QUOTE;
 -     if (c == '~')
 -         return charModShift(KEY_TILDE, modifier);
 -     if (c == '<')
 -         return charModShift(KEY_COMMA, modifier);
 -     if (c == '>')
 -         return charModShift(KEY_DOT, modifier);
 -     if (c == '?')
 -         return charModShift(KEY_SLASH, modifier);
 -     if (c == ':')
 -         return charModShift(KEY_SEMICOLON, modifier);
 - 
 -     if (c == '!')
 -         return charModShift(KEY_1, modifier);
 -     if (c == '@')
 -         return charModShift(KEY_2, modifier);
 -     if (c == '#')
 -         return charModShift(KEY_3, modifier);
 -     if (c == '$')
 -         return charModShift(KEY_4, modifier);
 -     if (c == '%')
 -         return charModShift(KEY_5, modifier);
 -     if (c == '^')
 -         return charModShift(KEY_6, modifier);
 -     if (c == '&')
 -         return charModShift(KEY_7, modifier);
 -     if (c == '*')
 -         return charModShift(KEY_8, modifier);
 -     if (c == '(')
 -         return charModShift(KEY_9, modifier);
 -     if (c == ')')
 -         return charModShift(KEY_0, modifier);
 -     if (c == '_')
 -         return charModShift(KEY_HYPHEN, modifier);
 -     if (c == '+')
 -         return charModShift(KEY_EQUAL, modifier);
 -     if (c == '"')
 -         return charModShift(KEY_QUOTE, modifier);
 - 
 -     if (c == '{')
 -         return charModShift(KEY_LBRACKET, modifier);
 -     if (c == '}')
 -         return charModShift(KEY_RBRACKET, modifier);
 -     if (c == '|')
 -         return charModShift(KEY_BSLASH, modifier);
 - 
 -     if (c == '[')
 -         return KEY_LBRACKET;
 -     if (c == ']')
 -         return KEY_RBRACKET;
 -     if (c == '\\')
 -         return KEY_BSLASH;
 -     return 0;
 - }
 - #endif
 - 
 - void UsbKeyboardDevice::sendKeyStrokes(const char* str)
 - {
 -     int (*charToKey)(int,int*) = 0;
 - #ifdef ARD_USBKBD_AZERTY
 -     if (!strcmp(_layout, "fr"))
 -     {
 -         charToKey = charToKeyAzerty;
 -     }
 - #endif
 - #ifdef ARD_USBKBD_QWERTY
 -     if (!strcmp(_layout, "us"))
 -     {
 -         charToKey = charToKeyQwerty;
 -     }
 - #endif
 -     if (!charToKey)
 -     {
 -         return;
 -     }
 - 
 -     while (*str)
 -     {
 -         int modifier = 0;
 -         int k = charToKey(*str, &modifier);
 -         /*if (!k)
 -         {
 -           k = KEY_SPACE;
 -           char buf[12];
 -           itoa((unsigned)*str, buf, 10);
 -           sendKeyStrokes(buf);
 -         }*/
 -         if (k)
 -         {
 -             UsbKeyboard.sendKeyStroke(k, modifier);
 -         }
 -         ++str;
 -     }
 - }
 - 
 - void UsbKeyboardDevice::sendKeyStroke(byte keyStroke, byte modifiers)
 - {
 - 
 -     while (!usbInterruptIsReady()) {
 -         // Note: We wait until we can send keystroke
 -         //       so we know the previous keystroke was
 -         //       sent.
 -     }
 - 
 -     memset(reportBuffer, 0, sizeof(reportBuffer));
 - 
 -     reportBuffer[0] = modifiers;
 -     reportBuffer[1] = keyStroke;
 - 
 -     usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
 - 
 -     while (!usbInterruptIsReady()) {
 -         // Note: We wait until we can send keystroke
 -         //       so we know the previous keystroke was
 -         //       sent.
 -     }
 - 
 -     // This stops endlessly repeating keystrokes:
 -     memset(reportBuffer, 0, sizeof(reportBuffer));
 -     usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
 - 
 - }
 - 
 - 
 - uchar usbFunctionSetup(uchar data[8])
 - {
 -     usbRequest_t    *rq = (usbRequest_t *)((void *)data);
 - 
 -     usbMsgPtr = UsbKeyboard.reportBuffer; //
 -     if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){
 -         /* class request type */
 - 
 -         if(rq->bRequest == USBRQ_HID_GET_REPORT){
 -             /* wValue: ReportType (highbyte), ReportID (lowbyte) */
 - 
 -             /* we only have one report type, so don't look at wValue */
 -             // TODO: Ensure it's okay not to return anything here?
 -             return 0;
 - 
 -         }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
 -             //            usbMsgPtr = &idleRate;
 -             //            return 1;
 -             return 0;
 -         }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
 -             idleRate = rq->wValue.bytes[1];
 -         }
 -     }else{
 -         /* no vendor specific requests implemented */
 -     }
 -     return 0;
 - }
 
 
  |