Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBKeyboard.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #include "stdint.h" 00020 00021 #include "USBKeyboard.h" 00022 00023 #define REPORT_ID_KEYBOARD 1 00024 #define REPORT_ID_VOLUME 3 00025 00026 00027 typedef struct { 00028 unsigned char usage; 00029 unsigned char modifier; 00030 } KEYMAP; 00031 00032 #ifdef US_KEYBOARD 00033 /* US keyboard (as HID standard) */ 00034 #define KEYMAP_SIZE (148) 00035 const KEYMAP keymap[KEYMAP_SIZE] = { 00036 {0, 0}, /* NUL */ 00037 {0, 0}, /* SOH */ 00038 {0, 0}, /* STX */ 00039 {0, 0}, /* ETX */ 00040 {0, 0}, /* EOT */ 00041 {0, 0}, /* ENQ */ 00042 {0, 0}, /* ACK */ 00043 {0, 0}, /* BEL */ 00044 {0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */ 00045 {0x2b, 0}, /* TAB */ /* Keyboard Tab */ 00046 {0x28, 0}, /* LF */ /* Keyboard Return (Enter) */ 00047 {0, 0}, /* VT */ 00048 {0, 0}, /* FF */ 00049 {0, 0}, /* CR */ 00050 {0, 0}, /* SO */ 00051 {0, 0}, /* SI */ 00052 {0, 0}, /* DEL */ 00053 {0, 0}, /* DC1 */ 00054 {0, 0}, /* DC2 */ 00055 {0, 0}, /* DC3 */ 00056 {0, 0}, /* DC4 */ 00057 {0, 0}, /* NAK */ 00058 {0, 0}, /* SYN */ 00059 {0, 0}, /* ETB */ 00060 {0, 0}, /* CAN */ 00061 {0, 0}, /* EM */ 00062 {0, 0}, /* SUB */ 00063 {0, 0}, /* ESC */ 00064 {0, 0}, /* FS */ 00065 {0, 0}, /* GS */ 00066 {0, 0}, /* RS */ 00067 {0, 0}, /* US */ 00068 {0x2c, 0}, /* */ 00069 {0x1e, KEY_SHIFT}, /* ! */ 00070 {0x34, KEY_SHIFT}, /* " */ 00071 {0x20, KEY_SHIFT}, /* # */ 00072 {0x21, KEY_SHIFT}, /* $ */ 00073 {0x22, KEY_SHIFT}, /* % */ 00074 {0x24, KEY_SHIFT}, /* & */ 00075 {0x34, 0}, /* ' */ 00076 {0x26, KEY_SHIFT}, /* ( */ 00077 {0x27, KEY_SHIFT}, /* ) */ 00078 {0x25, KEY_SHIFT}, /* * */ 00079 {0x2e, KEY_SHIFT}, /* + */ 00080 {0x36, 0}, /* , */ 00081 {0x2d, 0}, /* - */ 00082 {0x37, 0}, /* . */ 00083 {0x38, 0}, /* / */ 00084 {0x27, 0}, /* 0 */ 00085 {0x1e, 0}, /* 1 */ 00086 {0x1f, 0}, /* 2 */ 00087 {0x20, 0}, /* 3 */ 00088 {0x21, 0}, /* 4 */ 00089 {0x22, 0}, /* 5 */ 00090 {0x23, 0}, /* 6 */ 00091 {0x24, 0}, /* 7 */ 00092 {0x25, 0}, /* 8 */ 00093 {0x26, 0}, /* 9 */ 00094 {0x33, KEY_SHIFT}, /* : */ 00095 {0x33, 0}, /* ; */ 00096 {0x36, KEY_SHIFT}, /* < */ 00097 {0x2e, 0}, /* = */ 00098 {0x37, KEY_SHIFT}, /* > */ 00099 {0x38, KEY_SHIFT}, /* ? */ 00100 {0x1f, KEY_SHIFT}, /* @ */ 00101 {0x04, KEY_SHIFT}, /* A */ 00102 {0x05, KEY_SHIFT}, /* B */ 00103 {0x06, KEY_SHIFT}, /* C */ 00104 {0x07, KEY_SHIFT}, /* D */ 00105 {0x08, KEY_SHIFT}, /* E */ 00106 {0x09, KEY_SHIFT}, /* F */ 00107 {0x0a, KEY_SHIFT}, /* G */ 00108 {0x0b, KEY_SHIFT}, /* H */ 00109 {0x0c, KEY_SHIFT}, /* I */ 00110 {0x0d, KEY_SHIFT}, /* J */ 00111 {0x0e, KEY_SHIFT}, /* K */ 00112 {0x0f, KEY_SHIFT}, /* L */ 00113 {0x10, KEY_SHIFT}, /* M */ 00114 {0x11, KEY_SHIFT}, /* N */ 00115 {0x12, KEY_SHIFT}, /* O */ 00116 {0x13, KEY_SHIFT}, /* P */ 00117 {0x14, KEY_SHIFT}, /* Q */ 00118 {0x15, KEY_SHIFT}, /* R */ 00119 {0x16, KEY_SHIFT}, /* S */ 00120 {0x17, KEY_SHIFT}, /* T */ 00121 {0x18, KEY_SHIFT}, /* U */ 00122 {0x19, KEY_SHIFT}, /* V */ 00123 {0x1a, KEY_SHIFT}, /* W */ 00124 {0x1b, KEY_SHIFT}, /* X */ 00125 {0x1c, KEY_SHIFT}, /* Y */ 00126 {0x1d, KEY_SHIFT}, /* Z */ 00127 {0x2f, 0}, /* [ */ 00128 {0x31, 0}, /* \ */ 00129 {0x30, 0}, /* ] */ 00130 {0x23, KEY_SHIFT}, /* ^ */ 00131 {0x2d, KEY_SHIFT}, /* _ */ 00132 {0x35, 0}, /* ` */ 00133 {0x04, 0}, /* a */ 00134 {0x05, 0}, /* b */ 00135 {0x06, 0}, /* c */ 00136 {0x07, 0}, /* d */ 00137 {0x08, 0}, /* e */ 00138 {0x09, 0}, /* f */ 00139 {0x0a, 0}, /* g */ 00140 {0x0b, 0}, /* h */ 00141 {0x0c, 0}, /* i */ 00142 {0x0d, 0}, /* j */ 00143 {0x0e, 0}, /* k */ 00144 {0x0f, 0}, /* l */ 00145 {0x10, 0}, /* m */ 00146 {0x11, 0}, /* n */ 00147 {0x12, 0}, /* o */ 00148 {0x13, 0}, /* p */ 00149 {0x14, 0}, /* q */ 00150 {0x15, 0}, /* r */ 00151 {0x16, 0}, /* s */ 00152 {0x17, 0}, /* t */ 00153 {0x18, 0}, /* u */ 00154 {0x19, 0}, /* v */ 00155 {0x1a, 0}, /* w */ 00156 {0x1b, 0}, /* x */ 00157 {0x1c, 0}, /* y */ 00158 {0x1d, 0}, /* z */ 00159 {0x2f, KEY_SHIFT}, /* { */ 00160 {0x31, KEY_SHIFT}, /* | */ 00161 {0x30, KEY_SHIFT}, /* } */ 00162 {0x35, KEY_SHIFT}, /* ~ */ 00163 {0,0}, /* DEL */ 00164 00165 {0x3a, 0}, /* F1 */ 00166 {0x3b, 0}, /* F2 */ 00167 {0x3c, 0}, /* F3 */ 00168 {0x3d, 0}, /* F4 */ 00169 {0x3e, 0}, /* F5 */ 00170 {0x3f, 0}, /* F6 */ 00171 {0x40, 0}, /* F7 */ 00172 {0x41, 0}, /* F8 */ 00173 {0x42, 0}, /* F9 */ 00174 {0x43, 0}, /* F10 */ 00175 {0x44, 0}, /* F11 */ 00176 {0x45, 0}, /* F12 */ 00177 00178 {0x46, 0}, /* PRINT_SCREEN */ 00179 {0x47, 0}, /* SCROLL_LOCK */ 00180 {0x39, 0}, /* CAPS_LOCK */ 00181 {0x53, 0}, /* NUM_LOCK */ 00182 {0x49, 0}, /* INSERT */ 00183 {0x4a, 0}, /* HOME */ 00184 {0x4b, 0}, /* PAGE_UP */ 00185 {0x4e, 0}, /* PAGE_DOWN */ 00186 }; 00187 00188 #else 00189 /* UK keyboard */ 00190 #define KEYMAP_SIZE (148) 00191 const KEYMAP keymap[KEYMAP_SIZE] = { 00192 {0, 0}, /* NUL */ 00193 {0, 0}, /* SOH */ 00194 {0, 0}, /* STX */ 00195 {0, 0}, /* ETX */ 00196 {0, 0}, /* EOT */ 00197 {0, 0}, /* ENQ */ 00198 {0, 0}, /* ACK */ 00199 {0, 0}, /* BEL */ 00200 {0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */ 00201 {0x2b, 0}, /* TAB */ /* Keyboard Tab */ 00202 {0x28, 0}, /* LF */ /* Keyboard Return (Enter) */ 00203 {0, 0}, /* VT */ 00204 {0, 0}, /* FF */ 00205 {0, 0}, /* CR */ 00206 {0, 0}, /* SO */ 00207 {0, 0}, /* SI */ 00208 {0, 0}, /* DEL */ 00209 {0, 0}, /* DC1 */ 00210 {0, 0}, /* DC2 */ 00211 {0, 0}, /* DC3 */ 00212 {0, 0}, /* DC4 */ 00213 {0, 0}, /* NAK */ 00214 {0, 0}, /* SYN */ 00215 {0, 0}, /* ETB */ 00216 {0, 0}, /* CAN */ 00217 {0, 0}, /* EM */ 00218 {0, 0}, /* SUB */ 00219 {0, 0}, /* ESC */ 00220 {0, 0}, /* FS */ 00221 {0, 0}, /* GS */ 00222 {0, 0}, /* RS */ 00223 {0, 0}, /* US */ 00224 {0x2c, 0}, /* */ 00225 {0x1e, KEY_SHIFT}, /* ! */ 00226 {0x1f, KEY_SHIFT}, /* " */ 00227 {0x32, 0}, /* # */ 00228 {0x21, KEY_SHIFT}, /* $ */ 00229 {0x22, KEY_SHIFT}, /* % */ 00230 {0x24, KEY_SHIFT}, /* & */ 00231 {0x34, 0}, /* ' */ 00232 {0x26, KEY_SHIFT}, /* ( */ 00233 {0x27, KEY_SHIFT}, /* ) */ 00234 {0x25, KEY_SHIFT}, /* * */ 00235 {0x2e, KEY_SHIFT}, /* + */ 00236 {0x36, 0}, /* , */ 00237 {0x2d, 0}, /* - */ 00238 {0x37, 0}, /* . */ 00239 {0x38, 0}, /* / */ 00240 {0x27, 0}, /* 0 */ 00241 {0x1e, 0}, /* 1 */ 00242 {0x1f, 0}, /* 2 */ 00243 {0x20, 0}, /* 3 */ 00244 {0x21, 0}, /* 4 */ 00245 {0x22, 0}, /* 5 */ 00246 {0x23, 0}, /* 6 */ 00247 {0x24, 0}, /* 7 */ 00248 {0x25, 0}, /* 8 */ 00249 {0x26, 0}, /* 9 */ 00250 {0x33, KEY_SHIFT}, /* : */ 00251 {0x33, 0}, /* ; */ 00252 {0x36, KEY_SHIFT}, /* < */ 00253 {0x2e, 0}, /* = */ 00254 {0x37, KEY_SHIFT}, /* > */ 00255 {0x38, KEY_SHIFT}, /* ? */ 00256 {0x34, KEY_SHIFT}, /* @ */ 00257 {0x04, KEY_SHIFT}, /* A */ 00258 {0x05, KEY_SHIFT}, /* B */ 00259 {0x06, KEY_SHIFT}, /* C */ 00260 {0x07, KEY_SHIFT}, /* D */ 00261 {0x08, KEY_SHIFT}, /* E */ 00262 {0x09, KEY_SHIFT}, /* F */ 00263 {0x0a, KEY_SHIFT}, /* G */ 00264 {0x0b, KEY_SHIFT}, /* H */ 00265 {0x0c, KEY_SHIFT}, /* I */ 00266 {0x0d, KEY_SHIFT}, /* J */ 00267 {0x0e, KEY_SHIFT}, /* K */ 00268 {0x0f, KEY_SHIFT}, /* L */ 00269 {0x10, KEY_SHIFT}, /* M */ 00270 {0x11, KEY_SHIFT}, /* N */ 00271 {0x12, KEY_SHIFT}, /* O */ 00272 {0x13, KEY_SHIFT}, /* P */ 00273 {0x14, KEY_SHIFT}, /* Q */ 00274 {0x15, KEY_SHIFT}, /* R */ 00275 {0x16, KEY_SHIFT}, /* S */ 00276 {0x17, KEY_SHIFT}, /* T */ 00277 {0x18, KEY_SHIFT}, /* U */ 00278 {0x19, KEY_SHIFT}, /* V */ 00279 {0x1a, KEY_SHIFT}, /* W */ 00280 {0x1b, KEY_SHIFT}, /* X */ 00281 {0x1c, KEY_SHIFT}, /* Y */ 00282 {0x1d, KEY_SHIFT}, /* Z */ 00283 {0x2f, 0}, /* [ */ 00284 {0x64, 0}, /* \ */ 00285 {0x30, 0}, /* ] */ 00286 {0x23, KEY_SHIFT}, /* ^ */ 00287 {0x2d, KEY_SHIFT}, /* _ */ 00288 {0x35, 0}, /* ` */ 00289 {0x04, 0}, /* a */ 00290 {0x05, 0}, /* b */ 00291 {0x06, 0}, /* c */ 00292 {0x07, 0}, /* d */ 00293 {0x08, 0}, /* e */ 00294 {0x09, 0}, /* f */ 00295 {0x0a, 0}, /* g */ 00296 {0x0b, 0}, /* h */ 00297 {0x0c, 0}, /* i */ 00298 {0x0d, 0}, /* j */ 00299 {0x0e, 0}, /* k */ 00300 {0x0f, 0}, /* l */ 00301 {0x10, 0}, /* m */ 00302 {0x11, 0}, /* n */ 00303 {0x12, 0}, /* o */ 00304 {0x13, 0}, /* p */ 00305 {0x14, 0}, /* q */ 00306 {0x15, 0}, /* r */ 00307 {0x16, 0}, /* s */ 00308 {0x17, 0}, /* t */ 00309 {0x18, 0}, /* u */ 00310 {0x19, 0}, /* v */ 00311 {0x1a, 0}, /* w */ 00312 {0x1b, 0}, /* x */ 00313 {0x1c, 0}, /* y */ 00314 {0x1d, 0}, /* z */ 00315 {0x2f, KEY_SHIFT}, /* { */ 00316 {0x64, KEY_SHIFT}, /* | */ 00317 {0x30, KEY_SHIFT}, /* } */ 00318 {0x32, KEY_SHIFT}, /* ~ */ 00319 {0,0}, /* DEL */ 00320 00321 {0x3a, 0}, /* F1 */ 00322 {0x3b, 0}, /* F2 */ 00323 {0x3c, 0}, /* F3 */ 00324 {0x3d, 0}, /* F4 */ 00325 {0x3e, 0}, /* F5 */ 00326 {0x3f, 0}, /* F6 */ 00327 {0x40, 0}, /* F7 */ 00328 {0x41, 0}, /* F8 */ 00329 {0x42, 0}, /* F9 */ 00330 {0x43, 0}, /* F10 */ 00331 {0x44, 0}, /* F11 */ 00332 {0x45, 0}, /* F12 */ 00333 00334 {0x46, 0}, /* PRINT_SCREEN */ 00335 {0x47, 0}, /* SCROLL_LOCK */ 00336 {0x39, 0}, /* CAPS_LOCK */ 00337 {0x53, 0}, /* NUM_LOCK */ 00338 {0x49, 0}, /* INSERT */ 00339 {0x4a, 0}, /* HOME */ 00340 {0x4b, 0}, /* PAGE_UP */ 00341 {0x4e, 0}, /* PAGE_DOWN */ 00342 }; 00343 #endif 00344 00345 uint8_t * USBKeyboard::reportDesc() { 00346 static uint8_t reportDescriptor[] = { 00347 USAGE_PAGE(1), 0x01, // Generic Desktop 00348 USAGE(1), 0x06, // Keyboard 00349 COLLECTION(1), 0x01, // Application 00350 REPORT_ID(1), REPORT_ID_KEYBOARD, 00351 00352 USAGE_PAGE(1), 0x07, // Key Codes 00353 USAGE_MINIMUM(1), 0xE0, 00354 USAGE_MAXIMUM(1), 0xE7, 00355 LOGICAL_MINIMUM(1), 0x00, 00356 LOGICAL_MAXIMUM(1), 0x01, 00357 REPORT_SIZE(1), 0x01, 00358 REPORT_COUNT(1), 0x08, 00359 INPUT(1), 0x02, // Data, Variable, Absolute 00360 REPORT_COUNT(1), 0x01, 00361 REPORT_SIZE(1), 0x08, 00362 INPUT(1), 0x01, // Constant 00363 00364 00365 REPORT_COUNT(1), 0x05, 00366 REPORT_SIZE(1), 0x01, 00367 USAGE_PAGE(1), 0x08, // LEDs 00368 USAGE_MINIMUM(1), 0x01, 00369 USAGE_MAXIMUM(1), 0x05, 00370 OUTPUT(1), 0x02, // Data, Variable, Absolute 00371 REPORT_COUNT(1), 0x01, 00372 REPORT_SIZE(1), 0x03, 00373 OUTPUT(1), 0x01, // Constant 00374 00375 00376 REPORT_COUNT(1), 0x06, 00377 REPORT_SIZE(1), 0x08, 00378 LOGICAL_MINIMUM(1), 0x00, 00379 LOGICAL_MAXIMUM(1), 0x65, 00380 USAGE_PAGE(1), 0x07, // Key Codes 00381 USAGE_MINIMUM(1), 0x00, 00382 USAGE_MAXIMUM(1), 0x65, 00383 INPUT(1), 0x00, // Data, Array 00384 END_COLLECTION(0), 00385 00386 // Media Control 00387 USAGE_PAGE(1), 0x0C, 00388 USAGE(1), 0x01, 00389 COLLECTION(1), 0x01, 00390 REPORT_ID(1), REPORT_ID_VOLUME, 00391 USAGE_PAGE(1), 0x0C, 00392 LOGICAL_MINIMUM(1), 0x00, 00393 LOGICAL_MAXIMUM(1), 0x01, 00394 REPORT_SIZE(1), 0x01, 00395 REPORT_COUNT(1), 0x07, 00396 USAGE(1), 0xB5, // Next Track 00397 USAGE(1), 0xB6, // Previous Track 00398 USAGE(1), 0xB7, // Stop 00399 USAGE(1), 0xCD, // Play / Pause 00400 USAGE(1), 0xE2, // Mute 00401 USAGE(1), 0xE9, // Volume Up 00402 USAGE(1), 0xEA, // Volume Down 00403 INPUT(1), 0x02, // Input (Data, Variable, Absolute) 00404 REPORT_COUNT(1), 0x01, 00405 INPUT(1), 0x01, 00406 END_COLLECTION(0), 00407 }; 00408 reportLength = sizeof(reportDescriptor); 00409 return reportDescriptor; 00410 } 00411 00412 00413 bool USBKeyboard::EP1_OUT_callback() { 00414 uint16_t bytesRead = 0; 00415 uint8_t led[65]; 00416 USBDevice::readEP(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE); 00417 00418 // we take led[1] because led[0] is the report ID 00419 lock_status = led[1] & 0x07; 00420 00421 // We activate the endpoint to be able to recceive data 00422 if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE)) 00423 return false; 00424 return true; 00425 } 00426 00427 uint8_t USBKeyboard::lockStatus() { 00428 return lock_status; 00429 } 00430 00431 int USBKeyboard::_putc(int c) { 00432 return keyCode(c, keymap[c].modifier); 00433 } 00434 00435 bool USBKeyboard::keyCode(uint8_t key, uint8_t modifier) { 00436 // Send a simulated keyboard keypress. Returns true if successful. 00437 HID_REPORT report; 00438 00439 report.data[0] = REPORT_ID_KEYBOARD; 00440 report.data[1] = modifier; 00441 report.data[2] = 0; 00442 report.data[3] = keymap[key].usage; 00443 report.data[4] = 0; 00444 report.data[5] = 0; 00445 report.data[6] = 0; 00446 report.data[7] = 0; 00447 report.data[8] = 0; 00448 00449 report.length = 9; 00450 00451 if (!send(&report)) { 00452 return false; 00453 } 00454 00455 report.data[1] = 0; 00456 report.data[3] = 0; 00457 00458 if (!send(&report)) { 00459 return false; 00460 } 00461 00462 return true; 00463 00464 } 00465 00466 00467 bool USBKeyboard::mediaControl(MEDIA_KEY key) { 00468 HID_REPORT report; 00469 00470 report.data[0] = REPORT_ID_VOLUME; 00471 report.data[1] = (1 << key) & 0x7f; 00472 00473 report.length = 2; 00474 00475 if (!send(&report)) { 00476 return false; 00477 } 00478 00479 report.data[0] = REPORT_ID_VOLUME; 00480 report.data[1] = 0; 00481 00482 report.length = 2; 00483 00484 return send(&report); 00485 }
Generated on Wed Jul 13 2022 10:21:29 by
1.7.2