diff --git a/README.adoc b/README.adoc index 816b2ee..a6317c3 100644 --- a/README.adoc +++ b/README.adoc @@ -5,6 +5,16 @@ This library allows an Arduino board with USB capabilities to act as a Keyboard. For more information about this library please visit us at https://www.arduino.cc/reference/en/language/functions/usb/keyboard/ += Contributors = + +Original code (pre-library): Peter Barrett + +Contributor: MRNIU + += Usage = + +See examples/Serial/Serial.ino + == License == Copyright (c) Arduino LLC. All right reserved. diff --git a/src/Keyboard.cpp b/src/Keyboard.cpp index 4a948f6..fbc895e 100644 --- a/src/Keyboard.cpp +++ b/src/Keyboard.cpp @@ -35,32 +35,32 @@ static const uint8_t _hidReportDescriptor[] PROGMEM = { 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x02, // REPORT_ID (2) 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, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) - + 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x73, // LOGICAL_MAXIMUM (115) 0x05, 0x07, // USAGE_PAGE (Keyboard) - + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x73, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION }; -Keyboard_::Keyboard_(void) +Keyboard_::Keyboard_(void) { static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); HID().AppendDescriptor(&node); @@ -91,16 +91,16 @@ const uint8_t _asciimap[128] = 0x00, // ETX 0x00, // EOT 0x00, // ENQ - 0x00, // ACK + 0x00, // ACK 0x00, // BEL 0x2a, // BS Backspace 0x2b, // TAB Tab 0x28, // LF Enter - 0x00, // VT - 0x00, // FF - 0x00, // CR - 0x00, // SO - 0x00, // SI + 0x00, // VT + 0x00, // FF + 0x00, // CR + 0x00, // SO + 0x00, // SI 0x00, // DEL 0x00, // DC1 0x00, // DC2 @@ -110,13 +110,13 @@ const uint8_t _asciimap[128] = 0x00, // SYN 0x00, // ETB 0x00, // CAN - 0x00, // EM + 0x00, // EM 0x00, // SUB 0x00, // ESC - 0x00, // FS - 0x00, // GS - 0x00, // RS - 0x00, // US + 0x00, // FS + 0x00, // GS + 0x00, // RS + 0x00, // US 0x2c, // ' ' 0x1e|SHIFT, // ! @@ -219,93 +219,90 @@ const uint8_t _asciimap[128] = uint8_t USBPutChar(uint8_t c); -// press() adds the specified key (printing, non-printing, or modifier) -// to the persistent key report and sends the report. Because of the way -// USB HID works, the host acts like the key remains pressed until we -// call release(), releaseAll(), or otherwise clear the report and resend. -size_t Keyboard_::press(uint8_t k) +size_t Keyboard_::set(uint8_t k, bool s) { uint8_t i; if (k >= 136) { // it's a non-printing key (not a modifier) k = k - 136; } else if (k >= 128) { // it's a modifier key - _keyReport.modifiers |= (1<<(k-128)); + if(s) _keyReport.modifiers |= (1<<(k-128)); + else _keyReport.modifiers |= (1<<(k-128)); k = 0; } else { // it's a printing key k = pgm_read_byte(_asciimap + k); + // 转换成 hex 格式 if (!k) { - setWriteError(); + if(s) setWriteError(); return 0; } if (k & 0x80) { // it's a capital letter or other character reached with shift - _keyReport.modifiers |= 0x02; // the left shift modifier + if(s) _keyReport.modifiers |= 0x02; // the left shift modifier + else _keyReport.modifiers &= ~(0x02); k &= 0x7F; } } - - // Add k to the key report only if it's not already present - // and if there is an empty slot. - if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && - _keyReport.keys[2] != k && _keyReport.keys[3] != k && - _keyReport.keys[4] != k && _keyReport.keys[5] != k) { - + + if(s){ + if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && + _keyReport.keys[2] != k && _keyReport.keys[3] != k && + _keyReport.keys[4] != k && _keyReport.keys[5] != k) { + + for (i=0; i<6; i++) { + if (_keyReport.keys[i] == 0x00) { + _keyReport.keys[i] = k; + break; + } + } + if (i == 6) { + setWriteError(); + return 0; + } + } + } + else { for (i=0; i<6; i++) { - if (_keyReport.keys[i] == 0x00) { - _keyReport.keys[i] = k; - break; + if (0 != k && _keyReport.keys[i] == k) { + _keyReport.keys[i] = 0x00; } } - if (i == 6) { - setWriteError(); - return 0; - } + + } + return 1; +} + +// press() adds the specified key (printing, non-printing, or modifier) +// to the persistent key report and sends the report. Because of the way +// USB HID works, the host acts like the key remains pressed until we +// call release(), releaseAll(), or otherwise clear the report and resend. +size_t Keyboard_::press(uint8_t k) +{ + auto ret = set(k, true); + if(ret) { + sendReport(&_keyReport); } - sendReport(&_keyReport); return 1; } // release() takes the specified key out of the persistent key report and // sends the report. This tells the OS the key is no longer pressed and that // it shouldn't be repeated any more. -size_t Keyboard_::release(uint8_t k) +size_t Keyboard_::release(uint8_t k) { - uint8_t i; - if (k >= 136) { // it's a non-printing key (not a modifier) - k = k - 136; - } else if (k >= 128) { // it's a modifier key - _keyReport.modifiers &= ~(1<<(k-128)); - k = 0; - } else { // it's a printing key - k = pgm_read_byte(_asciimap + k); - if (!k) { - return 0; - } - if (k & 0x80) { // it's a capital letter or other character reached with shift - _keyReport.modifiers &= ~(0x02); // the left shift modifier - k &= 0x7F; - } + auto ret = set(k, false); + if(ret) { + sendReport(&_keyReport); } - - // Test the key report to see if k is present. Clear it if it exists. - // Check all positions in case the key is present more than once (which it shouldn't be) - for (i=0; i<6; i++) { - if (0 != k && _keyReport.keys[i] == k) { - _keyReport.keys[i] = 0x00; - } - } - - sendReport(&_keyReport); return 1; } void Keyboard_::releaseAll(void) { _keyReport.keys[0] = 0; - _keyReport.keys[1] = 0; + _keyReport.keys[1] = 0; _keyReport.keys[2] = 0; - _keyReport.keys[3] = 0; + _keyReport.keys[3] = 0; _keyReport.keys[4] = 0; - _keyReport.keys[5] = 0; + _keyReport.keys[5] = 0; _keyReport.modifiers = 0; sendReport(&_keyReport); } @@ -335,4 +332,3 @@ size_t Keyboard_::write(const uint8_t *buffer, size_t size) { Keyboard_ Keyboard; #endif - diff --git a/src/Keyboard.h b/src/Keyboard.h index 96882d8..a6a4028 100644 --- a/src/Keyboard.h +++ b/src/Keyboard.h @@ -96,6 +96,7 @@ class Keyboard_ : public Print { private: KeyReport _keyReport; + size_t set(uint8_t k, bool s); void sendReport(KeyReport* keys); public: Keyboard_(void); @@ -111,4 +112,3 @@ extern Keyboard_ Keyboard; #endif #endif -