Guest User

DigiKeyboard.h

a guest
Feb 9th, 2017
1,888
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.10 KB | None | 0 0
  1. /*
  2. * Based on Obdev's AVRUSB code and under the same license.
  3. *
  4. * TODO: Make a proper file header. :-)
  5. * Modified for Digispark by Digistump
  6. * Added full Keyboard usage values by Danjovic, February 2016
  7. * Report Buffer extended up to 6 keytrokes simultaneous by Danjovic, March 2016
  8. */
  9. #ifndef __DigiKeyboard_h__
  10. #define __DigiKeyboard_h__
  11.  
  12. #include <Arduino.h>
  13. #include <avr/pgmspace.h>
  14. #include <avr/interrupt.h>
  15. #include <avr/delay.h>
  16. #include <string.h>
  17.  
  18. #include "usbdrv.h"
  19. #include "scancode-ascii-table.h"
  20.  
  21. // TODO: Work around Arduino 12 issues better.
  22. //#include <WConstants.h>
  23. //#undef int()
  24.  
  25. typedef uint8_t byte;
  26.  
  27.  
  28. #define BUFFER_SIZE 2 // Minimum of 2: 1 for modifiers + 1 for keystroke
  29.  
  30.  
  31. static uchar idleRate; // in 4 ms units
  32.  
  33.  
  34. /* We use a simplifed keyboard report descriptor which does not support the
  35. * boot protocol. We don't allow setting status LEDs and but we do allow
  36. * simultaneous key presses.
  37. * The report descriptor has been created with usb.org's "HID Descriptor Tool"
  38. * which can be downloaded from http://www.usb.org/developers/hidpage/.
  39. * Redundant entries (such as LOGICAL_MINIMUM and USAGE_PAGE) have been omitted
  40. * for the second INPUT item.
  41. */
  42. const PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { /* USB report descriptor */
  43. 0x05, 0x01, // USAGE_PAGE (Generic Desktop)
  44. 0x09, 0x06, // USAGE (Keyboard)
  45. 0xa1, 0x01, // COLLECTION (Application)
  46. 0x05, 0x07, // USAGE_PAGE (Keyboard)
  47. 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
  48. 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
  49. 0x15, 0x00, // LOGICAL_MINIMUM (0)
  50. 0x25, 0x01, // LOGICAL_MAXIMUM (1)
  51. 0x75, 0x01, // REPORT_SIZE (1)
  52. 0x95, 0x08, // REPORT_COUNT (8)
  53. 0x81, 0x02, // INPUT (Data,Var,Abs)
  54. 0x95, 0x06, // REPORT_COUNT (6 simultaneous keystrokes)
  55. 0x75, 0x08, // REPORT_SIZE (8)
  56. 0x25, 0x65, // LOGICAL_MAXIMUM (101)
  57. 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
  58. 0x29, 0xE7, // USAGE_MAXIMUM (Right GUI)
  59. 0x81, 0x00, // INPUT (Data,Ary,Abs)
  60. 0xc0 // END_COLLECTION
  61. };
  62.  
  63.  
  64.  
  65. /* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
  66. * 10 Keyboard/Keypad Page for more codes.
  67. */
  68. #define MOD_CONTROL_LEFT (1<<0)
  69. #define MOD_SHIFT_LEFT (1<<1)
  70. #define MOD_ALT_LEFT (1<<2)
  71. #define MOD_GUI_LEFT (1<<3)
  72. #define MOD_CONTROL_RIGHT (1<<4)
  73. #define MOD_SHIFT_RIGHT (1<<5)
  74. #define MOD_ALT_RIGHT (1<<6)
  75. #define MOD_GUI_RIGHT (1<<7)
  76.  
  77. #define KEY_NOKEY 0x00 // Reserved (no event indicated)
  78. #define KEY_ERR_ROLLOVER 0x01 // Keyboard ErrorRollOver
  79. #define KEY_POSTFAIL 0x02 // Keyboard POSTFail
  80. #define KEY_ERR_UNDEFINED 0x03 // Keyboard ErrorUndefined
  81. #define KEY_A 0x04 // Keyboard a and A
  82. #define KEY_B 0x05 // Keyboard b and B
  83. #define KEY_C 0x06 // Keyboard c and C
  84. #define KEY_D 0x07 // Keyboard d and D
  85. #define KEY_E 0x08 // Keyboard e and E
  86. #define KEY_F 0x09 // Keyboard f and F
  87. #define KEY_G 0x0A // Keyboard g and G
  88. #define KEY_H 0x0B // Keyboard h and H
  89. #define KEY_I 0x0C // Keyboard i and I
  90. #define KEY_J 0x0D // Keyboard j and J
  91. #define KEY_K 0x0E // Keyboard k and K
  92. #define KEY_L 0x0F // Keyboard l and L
  93. #define KEY_M 0x10 // Keyboard m and M
  94. #define KEY_N 0x11 // Keyboard n and N
  95. #define KEY_O 0x12 // Keyboard o and O
  96. #define KEY_P 0x13 // Keyboard p and P
  97. #define KEY_Q 0x14 // Keyboard q and Q
  98. #define KEY_R 0x15 // Keyboard r and R
  99. #define KEY_S 0x16 // Keyboard s and S
  100. #define KEY_T 0x17 // Keyboard t and T
  101. #define KEY_U 0x18 // Keyboard u and U
  102. #define KEY_V 0x19 // Keyboard v and V
  103. #define KEY_W 0x1A // Keyboard w and W
  104. #define KEY_X 0x1B // Keyboard x and X
  105. #define KEY_Y 0x1C // Keyboard y and Y
  106. #define KEY_Z 0x1D // Keyboard z and Z
  107. #define KEY_1 0x1E // Keyboard 1 and !
  108. #define KEY_2 0x1F // Keyboard 2 and
  109. #define KEY_3 0x20 // Keyboard 3 and #
  110. #define KEY_4 0x21 // Keyboard 4 and $
  111. #define KEY_5 0x22 // Keyboard 5 and %
  112. #define KEY_6 0x23 // Keyboard 6 and ^
  113. #define KEY_7 0x24 // Keyboard 7 and &
  114. #define KEY_8 0x25 // Keyboard 8 and *
  115. #define KEY_9 0x26 // Keyboard 9 and (
  116. #define KEY_0 0x27 // Keyboard 0 and )
  117. #define KEY_ENTER 0x28 // Keyboard Return (ENTER)
  118. #define KEY_ESCAPE 0x29 // Keyboard ESCAPE
  119. #define KEY_DELETE 0x2A // Keyboard DELETE (Backspace)
  120. #define KEY_TAB 0x2B // Keyboard Tab
  121. #define KEY_SPACE 0x2C // Keyboard Spacebar
  122. #define KEY_MINUS 0x2D // Keyboard - and (underscore)
  123. #define KEY_EQUAL 0x2E // Keyboard = and +
  124. #define KEY_L_BRACKET 0x2F // Keyboard [ and {
  125. #define KEY_R_BRACKET 0x30 // Keyboard ] and }
  126. #define KEY_BACKSLASH 0x31 // Keyboard \ and |
  127. #define KEY_HASH 0x32 // Keyboard Non-US # and ~
  128. #define KEY_SEMICOLON 0x33 // Keyboard ; and :
  129. #define KEY_APOSTROPHE 0x34 // Keyboard ‘ and “
  130. #define KEY_GRAVE 0x35 // Keyboard Grave Accent and Tilde
  131. #define KEY_COMMA 0x36 // Keyboard , and <
  132. #define KEY_DOT 0x37 // Keyboard . and >
  133. #define KEY_SLASH 0x38 // Keyboard / and ?
  134. #define KEY_CAPS_LOCK 0x39 // Keyboard Caps Lock
  135. #define KEY_F1 0x3A // Keyboard F1
  136. #define KEY_F2 0x3B // Keyboard F2
  137. #define KEY_F3 0x3C // Keyboard F3
  138. #define KEY_F4 0x3D // Keyboard F4
  139. #define KEY_F5 0x3E // Keyboard F5
  140. #define KEY_F6 0x3F // Keyboard F6
  141. #define KEY_F7 0x40 // Keyboard F7
  142. #define KEY_F8 0x41 // Keyboard F8
  143. #define KEY_F9 0x42 // Keyboard F9
  144. #define KEY_F10 0x43 // Keyboard F10
  145. #define KEY_F11 0x44 // Keyboard F11
  146. #define KEY_F12 0x45 // Keyboard F12
  147. #define KEY_PRTSCN 0x46 // Keyboard PrintScreen
  148. #define KEY_SCR_LOCK 0x47 // Keyboard Scroll Lock
  149. #define KEY_PAUSE 0x48 // Keyboard Pause
  150. #define KEY_INSERT 0x49 // Keyboard Insert
  151. #define KEY_HOME 0x4A // Keyboard Home
  152. #define KEY_PAGE_UP 0x4B // Keyboard PageUp
  153. #define KEY_DELETE 0x4C // Keyboard Delete Forward
  154. #define KEY_END 0x4D // Keyboard End
  155. #define KEY_PAGE_DOWN 0x4E // Keyboard PageDown
  156. #define KEY_ARROW_RIGHT 0x4F // Keyboard RightArrow
  157. #define KEY_ARROW_LEFT 0x50 // Keyboard LeftArrow
  158. #define KEY_ARROW_DOWN 0x51 // Keyboard DownArrow
  159. #define KEY_ARROW_UP 0x52 // Keyboard UpArrow
  160.  
  161. #define KEY_RIGHT_ARROW 0x4F // Keyboard RightArrow -> Alternative arrow keys names
  162. #define KEY_LEFT_ARROW 0x50 // Keyboard LeftArrow
  163. #define KEY_DOWN_ARROW 0x51 // Keyboard DownArrow
  164. #define KEY_UP_ARROW 0x52 // Keyboard UpArrow
  165.  
  166. #define KEY_NUM_LOCK 0x53 // Keypad Num Lock and Clear
  167. #define KEY_KPAD_SLASH 0x54 // Keypad /
  168. #define KEY_KPAD_TIMES 0x55 // Keypad *
  169. #define KEY_KPAD_MINUS 0x56 // Keypad -
  170. #define KEY_KPAD_PLUS 0x57 // Keypad +
  171. #define KEY_KPAD_ENTER 0x58 // Keypad ENTER
  172. #define KEY_KPAD_1 0x59 // Keypad 1 and End
  173. #define KEY_KPAD_2 0x5A // Keypad 2 and Down Arrow
  174. #define KEY_KPAD_3 0x5B // Keypad 3 and PageDn
  175. #define KEY_KPAD_4 0x5C // Keypad 4 and Left Arrow
  176. #define KEY_KPAD_5 0x5D // Keypad 5
  177. #define KEY_KPAD_6 0x5E // Keypad 6 and Right Arrow
  178. #define KEY_KPAD_7 0x5F // Keypad 7 and Home
  179. #define KEY_KPAD_8 0x60 // Keypad 8 and Up Arrow
  180. #define KEY_KPAD_9 0x61 // Keypad 9 and PageUp
  181. #define KEY_KPAD_0 0x62 // Keypad 0 and Insert
  182. #define KEY_KPAD_DOT 0x63 // Keypad . and Delete
  183. #define KEY_INTL_BACKSLASH 0x64 // Keyboard Non-US \ and |
  184. #define KEY_APPLICATION 0x65 // Keyboard Application
  185. #define KEY_POWER 0x66 // Keyboard Power
  186. #define KEY_KPAD_EQUAL 0x67 // Keypad =
  187. #define KEY_F13 0x68 // Keyboard F13
  188. #define KEY_F14 0x69 // Keyboard F14
  189. #define KEY_F15 0x6A // Keyboard F15
  190. #define KEY_F16 0x6B // Keyboard F16
  191. #define KEY_F17 0x6C // Keyboard F17
  192. #define KEY_F18 0x6D // Keyboard F18
  193. #define KEY_F19 0x6E // Keyboard F19
  194. #define KEY_F20 0x6F // Keyboard F20
  195. #define KEY_F21 0x70 // Keyboard F21
  196. #define KEY_F22 0x71 // Keyboard F22
  197. #define KEY_F23 0x72 // Keyboard F23
  198. #define KEY_F24 0x73 // Keyboard F24
  199. #define KEY_EXECUTE 0x74 // Keyboard Execute
  200. #define KEY_HELP 0x75 // Keyboard Help
  201. #define KEY_MENU 0x76 // Keyboard Menu
  202. #define KEY_SELECT 0x77 // Keyboard Select
  203. #define KEY_STOP 0x78 // Keyboard Stop
  204. #define KEY_AGAIN 0x79 // Keyboard Again
  205. #define KEY_UNDO 0x7A // Keyboard Undo
  206. #define KEY_CUT 0x7B // Keyboard Cut
  207. #define KEY_COPY 0x7C // Keyboard Copy
  208. #define KEY_PASTE 0x7D // Keyboard Paste
  209. #define KEY_FIND 0x7E // Keyboard Find
  210. #define KEY_MUTE 0x7F // Keyboard Mute
  211. #define KEY_VOLUME_UP 0x80 // Keyboard Volume Up
  212. #define KEY_VOLUME_DOWN 0x81 // Keyboard Volume Down
  213. #define KEY_LOCK_CAPS_LOCK 0x82 // Keyboard Locking Caps Lock
  214. #define KEY_LOCK_NUM_LOCK 0x83 // Keyboard Locking Num Lock
  215. #define KEY_LOCK_SCR_LOCK 0x84 // Keyboard Locking Scroll Lock
  216. #define KEY_KPAD_COMMA 0x85 // Keypad Comma
  217. #define KEY_EQUAL_SIGN 0x86 // Keypad Equal Sign
  218. #define KEY_INTL1 0x87 // Keyboard International1
  219. #define KEY_INTL2 0x88 // Keyboard International2
  220. #define KEY_INTL3 0x89 // Keyboard International3
  221. #define KEY_INTL4 0x8A // Keyboard International4
  222. #define KEY_INTL5 0x8B // Keyboard International5
  223. #define KEY_INTL6 0x8C // Keyboard International6
  224. #define KEY_INTL7 0x8D // Keyboard International7
  225. #define KEY_INTL8 0x8E // Keyboard International8
  226. #define KEY_INTL9 0x8F // Keyboard International9
  227. #define KEY_LANG1 0x90 // Keyboard LANG1
  228. #define KEY_LANG2 0x91 // Keyboard LANG2
  229. #define KEY_LANG3 0x92 // Keyboard LANG3
  230. #define KEY_LANG4 0x93 // Keyboard LANG4
  231. #define KEY_LANG5 0x94 // Keyboard LANG5
  232. #define KEY_LANG6 0x95 // Keyboard LANG6
  233. #define KEY_LANG7 0x96 // Keyboard LANG7
  234. #define KEY_LANG8 0x97 // Keyboard LANG8
  235. #define KEY_LANG9 0x98 // Keyboard LANG9
  236. #define KEY_ALT_ERASE 0x99 // Keyboard Alternate Erase
  237. #define KEY_SYSREQ 0x9A // Keyboard SysReq/Attention
  238. #define KEY_CANCEL 0x9B // Keyboard Cancel
  239. #define KEY_CLEAR 0x9C // Keyboard Clear
  240. #define KEY_PRIOR 0x9D // Keyboard Prior
  241. #define KEY_RETURN 0x9E // Keyboard Return
  242. #define KEY_SEPARATOR 0x9F // Keyboard Separator
  243. #define KEY_OUT 0xA0 // Keyboard Out
  244. #define KEY_OPER 0xA1 // Keyboard Oper
  245. #define KEY_CLEAR 0xA2 // Keyboard Clear/Again
  246. #define KEY_CRSEL 0xA3 // Keyboard CrSel/Props
  247. #define KEY_EXSEL 0xA4 // Keyboard ExSel
  248. // Keys 0xA5 to 0xAF reserved
  249. #define KEY_KPAD_00 0xB0 // Keypad 00
  250. #define KEY_KPAD_000 0xB1 // Keypad 000
  251. #define KEY_THOUSANDS_SEP 0xB2 // Thousands Separator
  252. #define KEY_DECIMAL_SEP 0xB3 // Decimal Separator
  253. #define KEY_CURRENCY 0xB4 // Currency Unit
  254. #define KEY_SUB_CURRENCY 0xB5 // Currency Sub-unit
  255. #define KEY_KPAD_LEFT_PAREN 0xB6 // Keypad (
  256. #define KEY_KPAD_RIGHT_PAREN 0xB7 // Keypad )
  257. #define KEY_KPAD_LEFT_BRACE 0xB8 // Keypad {
  258. #define KEY_KPAD_RIGHT_BRACE 0xB9 // Keypad }
  259. #define KEY_KPAD_TAB 0xBA // Keypad Tab
  260. #define KEY_KPAD_BACKSPACE 0xBB // Keypad Backspace
  261. #define KEY_KPAD_A 0xBC // Keypad A
  262. #define KEY_KPAD_B 0xBD // Keypad B
  263. #define KEY_KPAD_C 0xBE // Keypad C
  264. #define KEY_KPAD_D 0xBF // Keypad D
  265. #define KEY_KPAD_E 0xC0 // Keypad E
  266. #define KEY_KPAD_F 0xC1 // Keypad F
  267. #define KEY_KPAD_XOR 0xC2 // Keypad XOR
  268. #define KEY_KPAD_CARET 0xC3 // Keypad ^
  269. #define KEY_KPAD_PERCENT 0xC4 // Keypad %
  270. #define KEY_KPAD_LESS_THAN 0xC5 // Keypad <
  271. #define KEY_KPAD_GREAT_THAN 0xC6 // Keypad >
  272. #define KEY_KPAD_AND 0xC7 // Keypad &
  273. #define KEY_KPAD_DBL_AND 0xC8 // Keypad &&
  274. #define KEY_KPAD_OR 0xC9 // Keypad |
  275. #define KEY_KPAD_DBL_OR 0xCA // Keypad ||
  276. #define KEY_KPAD_COLON 0xCB // Keypad :
  277. #define KEY_KPAD_HASH 0xCC // Keypad #
  278. #define KEY_KPAD_SPACE 0xCD // Keypad Space
  279. #define KEY_KPAD_AT 0xCE // Keypad @
  280. #define KEY_KPAD_EXCLAMATION 0xCF // Keypad !
  281. #define KEY_KPAD_MEM_STORE 0xD0 // Keypad Memory Store
  282. #define KEY_KPAD_MEM_RECALL 0xD1 // Keypad Memory Recall
  283. #define KEY_KPAD_MEM_CLEAR 0xD2 // Keypad Memory Clear
  284. #define KEY_KPAD_MEM_ADD 0xD3 // Keypad Memory Add
  285. #define KEY_KPAD_MEM_SUB 0xD4 // Keypad Memory Subtract
  286. #define KEY_KPAD_MEM_MULTIPLY 0xD5 // Keypad Memory Multiply
  287. #define KEY_KPAD_MEM_DIVIDE 0xD6 // Keypad Memory Divide
  288. #define KEY_PLUS_MINUS 0xD7 // Keypad +/-
  289. #define KEY_CLEAR 0xD8 // Keypad Clear
  290. #define KEY_CLEAR_ENTRY 0xD9 // Keypad Clear Entry
  291. #define KEY_BINARY 0xDA // Keypad Binary
  292. #define KEY_OCTAL 0xDB // Keypad Octal
  293. #define KEY_DECIMAL 0xDC // Keypad Decimal
  294. #define KEY_HEXADECIMAL 0xDD // Keypad Hexadecimal
  295. // Keys 0xDE to 0xDF reserved
  296. #define KEY_L_CONTROL 0xE0 // Keyboard LeftControl
  297. #define KEY_L_SHIFT 0xE1 // Keyboard LeftShift
  298. #define KEY_L_ALT 0xE2 // Keyboard LeftAlt
  299. #define KEY_L_GUI 0xE3 // Keyboard Left GUI
  300. #define KEY_R_CONTROL 0xE4 // Keyboard RightControl
  301. #define KEY_R_SHIFT 0xE5 // Keyboard RightShift
  302. #define KEY_R_ALT 0xE6 // Keyboard RightAlt
  303. #define KEY_R_GUI 0xE7 // Keyboard Right GUI
  304.  
  305.  
  306. class DigiKeyboardDevice : public Print {
  307. public:
  308. DigiKeyboardDevice () {
  309. cli();
  310. usbDeviceDisconnect();
  311. _delay_ms(250);
  312. usbDeviceConnect();
  313.  
  314.  
  315. usbInit();
  316.  
  317. sei();
  318.  
  319. // TODO: Remove the next two lines once we fix
  320. // missing first keystroke bug properly.
  321. memset(reportBuffer, 0, sizeof(reportBuffer));
  322. usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
  323. }
  324.  
  325. void update() {
  326. usbPoll();
  327. }
  328.  
  329. // delay while updating until we are finished delaying
  330. void delay(long milli) {
  331. unsigned long last = millis();
  332. while (milli > 0) {
  333. unsigned long now = millis();
  334. milli -= now - last;
  335. last = now;
  336. update();
  337. }
  338. }
  339.  
  340. void sendKeyStroke(byte keyStroke) {
  341. sendKeyStroke(keyStroke, 0);
  342. }
  343.  
  344. void sendKeyStroke(byte keyStroke, byte modifiers) {
  345. while (!usbInterruptIsReady()) {
  346. // Note: We wait until we can send keystroke
  347. // so we know the previous keystroke was
  348. // sent.
  349. usbPoll();
  350. _delay_ms(5);
  351. }
  352.  
  353. memset(reportBuffer, 0, sizeof(reportBuffer));
  354.  
  355. reportBuffer[0] = modifiers;
  356. reportBuffer[1] = keyStroke;
  357.  
  358. usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
  359.  
  360. while (!usbInterruptIsReady()) {
  361. // Note: We wait until we can send keystroke
  362. // so we know the previous keystroke was
  363. // sent.
  364. usbPoll();
  365. _delay_ms(5);
  366. }
  367.  
  368. // This stops endlessly repeating keystrokes:
  369. memset(reportBuffer, 0, sizeof(reportBuffer));
  370. usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
  371. }
  372.  
  373. size_t write(uint8_t chr) {
  374. uint8_t data = pgm_read_byte_near(ascii_to_scan_code_table + (chr - 8));
  375. sendKeyStroke(data & 0b01111111, data >> 7 ? MOD_SHIFT_RIGHT : 0);
  376. return 1;
  377. }
  378.  
  379. //private: TODO: Make friend?
  380. // maximum 6 keystrokes, defined in HID report
  381. uchar reportBuffer[7]; // buffer for HID reports [ 1 modifier byte + (len-1) key strokes]
  382. using Print::write;
  383. };
  384.  
  385. DigiKeyboardDevice DigiKeyboard = DigiKeyboardDevice();
  386.  
  387. #ifdef __cplusplus
  388. extern "C"{
  389. #endif
  390. // USB_PUBLIC uchar usbFunctionSetup
  391. uchar usbFunctionSetup(uchar data[8]) {
  392. usbRequest_t *rq = (usbRequest_t *)((void *)data);
  393.  
  394. usbMsgPtr = DigiKeyboard.reportBuffer; //
  395. if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
  396. /* class request type */
  397.  
  398. if (rq->bRequest == USBRQ_HID_GET_REPORT) {
  399. /* wValue: ReportType (highbyte), ReportID (lowbyte) */
  400.  
  401. /* we only have one report type, so don't look at wValue */
  402. // TODO: Ensure it's okay not to return anything here?
  403. return 0;
  404.  
  405. } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
  406. //usbMsgPtr = &idleRate;
  407. //return 1;
  408. return 0;
  409.  
  410. } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
  411. idleRate = rq->wValue.bytes[1];
  412.  
  413. }
  414. } else {
  415. /* no vendor specific requests implemented */
  416. }
  417.  
  418. return 0;
  419. }
  420. #ifdef __cplusplus
  421. } // extern "C"
  422. #endif
  423.  
  424.  
  425. #endif // __DigiKeyboard_h__
Advertisement
Add Comment
Please, Sign In to add comment