Teensy 4.1 core updated for C++20
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

676 Zeilen
18KB

  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include "usb_dev.h"
  31. #include "usb_keyboard.h"
  32. #include "core_pins.h" // for yield()
  33. #include "keylayouts.h"
  34. #include <string.h> // for memcpy()
  35. #include "avr/pgmspace.h" // for PROGMEM, DMAMEM, FASTRUN
  36. #include "debug/printf.h"
  37. #include "core_pins.h"
  38. #ifdef KEYBOARD_INTERFACE // defined by usb_dev.h -> usb_desc.h
  39. // which modifier keys are currently pressed
  40. // 1=left ctrl, 2=left shift, 4=left alt, 8=left gui
  41. // 16=right ctrl, 32=right shift, 64=right alt, 128=right gui
  42. uint8_t keyboard_modifier_keys=0;
  43. // which keys are currently pressed, up to 6 keys may be down at once
  44. uint8_t keyboard_keys[6]={0,0,0,0,0,0};
  45. #ifdef KEYMEDIA_INTERFACE
  46. uint16_t keymedia_consumer_keys[4];
  47. uint8_t keymedia_system_keys[3];
  48. #endif
  49. // protocol setting from the host. We use exactly the same report
  50. // either way, so this variable only stores the setting since we
  51. // are required to be able to report which setting is in use.
  52. uint8_t keyboard_protocol=1;
  53. // the idle configuration, how often we send the report to the
  54. // host (ms * 4) even when it hasn't changed
  55. uint8_t keyboard_idle_config=125;
  56. // count until idle timeout
  57. uint8_t keyboard_idle_count=0;
  58. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  59. volatile uint8_t keyboard_leds=0;
  60. static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint);
  61. static void write_key(KEYCODE_TYPE keycode);
  62. static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode);
  63. static uint8_t keycode_to_key(KEYCODE_TYPE keycode);
  64. static void usb_keyboard_press_key(uint8_t key, uint8_t modifier);
  65. static void usb_keyboard_release_key(uint8_t key, uint8_t modifier);
  66. #ifdef DEADKEYS_MASK
  67. static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode);
  68. #endif
  69. #ifdef KEYMEDIA_INTERFACE
  70. static void usb_keymedia_press_consumer_key(uint16_t key);
  71. static void usb_keymedia_release_consumer_key(uint16_t key);
  72. static void usb_keymedia_press_system_key(uint8_t key);
  73. static void usb_keymedia_release_system_key(uint8_t key);
  74. static int usb_keymedia_send(void);
  75. #endif
  76. #define TX_NUM 12
  77. #define TX_BUFSIZE 32
  78. static transfer_t tx_transfer[TX_NUM] __attribute__ ((used, aligned(32)));
  79. DMAMEM static uint8_t txbuffer[TX_NUM * TX_BUFSIZE] __attribute__ ((aligned(32)));
  80. static uint8_t tx_head=0;
  81. #if KEYBOARD_SIZE > TX_BUFSIZE
  82. #error "Internal error, transmit buffer size is too small for keyboard endpoint"
  83. #endif
  84. #if defined(KEYMEDIA_INTERFACE) && KEYMEDIA_SIZE > TX_BUFSIZE
  85. #error "Internal error, transmit buffer size is too small for media keys endpoint"
  86. #endif
  87. void usb_keyboard_configure(void)
  88. {
  89. memset(tx_transfer, 0, sizeof(tx_transfer));
  90. tx_head = 0;
  91. usb_config_tx(KEYBOARD_ENDPOINT, KEYBOARD_SIZE, 0, NULL); // normal keys use 8 byte packet
  92. #ifdef KEYMEDIA_INTERFACE
  93. usb_config_tx(KEYMEDIA_ENDPOINT, KEYMEDIA_SIZE, 0, NULL); // media keys use 8 byte packet
  94. #endif
  95. }
  96. // Step #1, decode UTF8 to Unicode code points
  97. //
  98. void usb_keyboard_write(uint8_t c)
  99. {
  100. static int utf8_state=0;
  101. static uint16_t unicode_wchar=0;
  102. if (c < 0x80) {
  103. // single byte encoded, 0x00 to 0x7F
  104. utf8_state = 0;
  105. usb_keyboard_write_unicode(c);
  106. } else if (c < 0xC0) {
  107. // 2nd, 3rd or 4th byte, 0x80 to 0xBF
  108. c &= 0x3F;
  109. if (utf8_state == 1) {
  110. utf8_state = 0;
  111. usb_keyboard_write_unicode(unicode_wchar | c);
  112. } else if (utf8_state == 2) {
  113. unicode_wchar |= ((uint16_t)c << 6);
  114. utf8_state = 1;
  115. }
  116. } else if (c < 0xE0) {
  117. // begin 2 byte sequence, 0xC2 to 0xDF
  118. // or illegal 2 byte sequence, 0xC0 to 0xC1
  119. unicode_wchar = (uint16_t)(c & 0x1F) << 6;
  120. utf8_state = 1;
  121. } else if (c < 0xF0) {
  122. // begin 3 byte sequence, 0xE0 to 0xEF
  123. unicode_wchar = (uint16_t)(c & 0x0F) << 12;
  124. utf8_state = 2;
  125. } else {
  126. // begin 4 byte sequence (not supported), 0xF0 to 0xF4
  127. // or illegal, 0xF5 to 0xFF
  128. utf8_state = 255;
  129. }
  130. }
  131. // Step #2: translate Unicode code point to keystroke sequence
  132. //
  133. static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint)
  134. {
  135. // Unicode code points beyond U+FFFF are not supported
  136. // technically this input should probably be called UCS-2
  137. if (cpoint < 32) {
  138. if (cpoint == 10) return KEY_ENTER & KEYCODE_MASK;
  139. if (cpoint == 11) return KEY_TAB & KEYCODE_MASK;
  140. return 0;
  141. }
  142. if (cpoint < 128) {
  143. return keycodes_ascii[cpoint - 0x20];
  144. }
  145. #ifdef ISO_8859_1_A0
  146. if (cpoint >= 0xA0 && cpoint < 0x100) {
  147. return keycodes_iso_8859_1[cpoint - 0xA0];
  148. }
  149. #endif
  150. //#ifdef UNICODE_20AC
  151. //if (cpoint == 0x20AC) return UNICODE_20AC & 0x3FFF;
  152. //#endif
  153. #ifdef KEYCODE_EXTRA00
  154. if (cpoint == UNICODE_EXTRA00) return (KEYCODE_EXTRA00) & 0x3FFF;
  155. #endif
  156. #ifdef KEYCODE_EXTRA01
  157. if (cpoint == UNICODE_EXTRA01) return (KEYCODE_EXTRA01) & 0x3FFF;
  158. #endif
  159. #ifdef KEYCODE_EXTRA02
  160. if (cpoint == UNICODE_EXTRA02) return (KEYCODE_EXTRA02) & 0x3FFF;
  161. #endif
  162. #ifdef KEYCODE_EXTRA03
  163. if (cpoint == UNICODE_EXTRA03) return (KEYCODE_EXTRA03) & 0x3FFF;
  164. #endif
  165. #ifdef KEYCODE_EXTRA04
  166. if (cpoint == UNICODE_EXTRA04) return (KEYCODE_EXTRA04) & 0x3FFF;
  167. #endif
  168. #ifdef KEYCODE_EXTRA05
  169. if (cpoint == UNICODE_EXTRA05) return (KEYCODE_EXTRA05) & 0x3FFF;
  170. #endif
  171. #ifdef KEYCODE_EXTRA06
  172. if (cpoint == UNICODE_EXTRA06) return (KEYCODE_EXTRA06) & 0x3FFF;
  173. #endif
  174. #ifdef KEYCODE_EXTRA07
  175. if (cpoint == UNICODE_EXTRA07) return (KEYCODE_EXTRA07) & 0x3FFF;
  176. #endif
  177. #ifdef KEYCODE_EXTRA08
  178. if (cpoint == UNICODE_EXTRA08) return (KEYCODE_EXTRA08) & 0x3FFF;
  179. #endif
  180. #ifdef KEYCODE_EXTRA09
  181. if (cpoint == UNICODE_EXTRA09) return (KEYCODE_EXTRA09) & 0x3FFF;
  182. #endif
  183. #ifdef KEYCODE_EXTRA0A
  184. if (cpoint == UNICODE_EXTRA0A) return (KEYCODE_EXTRA0A) & 0x3FFF;
  185. #endif
  186. return 0;
  187. }
  188. // Step #3: execute keystroke sequence
  189. //
  190. #ifdef DEADKEYS_MASK
  191. static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode)
  192. {
  193. keycode &= DEADKEYS_MASK;
  194. if (keycode == 0) return 0;
  195. #ifdef ACUTE_ACCENT_BITS
  196. if (keycode == ACUTE_ACCENT_BITS) return DEADKEY_ACUTE_ACCENT;
  197. #endif
  198. #ifdef CEDILLA_BITS
  199. if (keycode == CEDILLA_BITS) return DEADKEY_CEDILLA;
  200. #endif
  201. #ifdef CIRCUMFLEX_BITS
  202. if (keycode == CIRCUMFLEX_BITS) return DEADKEY_CIRCUMFLEX;
  203. #endif
  204. #ifdef DIAERESIS_BITS
  205. if (keycode == DIAERESIS_BITS) return DEADKEY_DIAERESIS;
  206. #endif
  207. #ifdef GRAVE_ACCENT_BITS
  208. if (keycode == GRAVE_ACCENT_BITS) return DEADKEY_GRAVE_ACCENT;
  209. #endif
  210. #ifdef TILDE_BITS
  211. if (keycode == TILDE_BITS) return DEADKEY_TILDE;
  212. #endif
  213. #ifdef RING_ABOVE_BITS
  214. if (keycode == RING_ABOVE_BITS) return DEADKEY_RING_ABOVE;
  215. #endif
  216. #ifdef DEGREE_SIGN_BITS
  217. if (keycode == DEGREE_SIGN_BITS) return DEADKEY_DEGREE_SIGN;
  218. #endif
  219. #ifdef CARON_BITS
  220. if (keycode == CARON_BITS) return DEADKEY_CARON;
  221. #endif
  222. #ifdef BREVE_BITS
  223. if (keycode == BREVE_BITS) return DEADKEY_BREVE;
  224. #endif
  225. #ifdef OGONEK_BITS
  226. if (keycode == OGONEK_BITS) return DEADKEY_OGONEK;
  227. #endif
  228. #ifdef DOT_ABOVE_BITS
  229. if (keycode == DOT_ABOVE_BITS) return DEADKEY_DOT_ABOVE;
  230. #endif
  231. #ifdef DOUBLE_ACUTE_BITS
  232. if (keycode == DOUBLE_ACUTE_BITS) return DEADKEY_DOUBLE_ACUTE;
  233. #endif
  234. return 0;
  235. }
  236. #endif
  237. void usb_keyboard_write_unicode(uint16_t cpoint)
  238. {
  239. KEYCODE_TYPE keycode;
  240. keycode = unicode_to_keycode(cpoint);
  241. if (keycode) {
  242. #ifdef DEADKEYS_MASK
  243. KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
  244. if (deadkeycode) write_key(deadkeycode);
  245. #endif
  246. write_key(keycode);
  247. }
  248. }
  249. // Step #4: do each keystroke
  250. //
  251. static void write_key(KEYCODE_TYPE keycode)
  252. {
  253. /*
  254. uint8_t key, modifier=0;
  255. #ifdef SHIFT_MASK
  256. if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT;
  257. #endif
  258. #ifdef ALTGR_MASK
  259. if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT;
  260. #endif
  261. #ifdef RCTRL_MASK
  262. if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
  263. #endif
  264. key = keycode & 0x3F;
  265. #ifdef KEY_NON_US_100
  266. if (key == KEY_NON_US_100) key = 100;
  267. #endif
  268. usb_keyboard_press(key, modifier);
  269. */
  270. usb_keyboard_press(keycode_to_key(keycode), keycode_to_modifier(keycode));
  271. }
  272. static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode)
  273. {
  274. uint8_t modifier=0;
  275. #ifdef SHIFT_MASK
  276. if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT;
  277. #endif
  278. #ifdef ALTGR_MASK
  279. if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT;
  280. #endif
  281. #ifdef RCTRL_MASK
  282. if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
  283. #endif
  284. return modifier;
  285. }
  286. static uint8_t keycode_to_key(KEYCODE_TYPE keycode)
  287. {
  288. uint8_t key = keycode & 0x3F;
  289. #ifdef KEY_NON_US_100
  290. if (key == KEY_NON_US_100) key = 100;
  291. #endif
  292. return key;
  293. }
  294. // Input can be:
  295. // 32 - 127 ASCII direct (U+0020 to U+007F) <-- uses layout
  296. // 128 - 0xC1FF Unicode direct (U+0080 to U+C1FF) <-- uses layout
  297. // 0xC200 - 0xDFFF Unicode UTF8 packed (U+0080 to U+07FF) <-- uses layout
  298. // 0xE000 - 0xE0FF Modifier key (bitmap, 8 keys, shift/ctrl/alt/gui)
  299. // 0xE200 - 0xE2FF System key (HID usage code, within usage page 1)
  300. // 0xE400 - 0xE7FF Media/Consumer key (HID usage code, within usage page 12)
  301. // 0xF000 - 0xFFFF Normal key (HID usage code, within usage page 7)
  302. void usb_keyboard_press_keycode(uint16_t n)
  303. {
  304. uint8_t key, mod, msb, modrestore=0;
  305. KEYCODE_TYPE keycode;
  306. #ifdef DEADKEYS_MASK
  307. KEYCODE_TYPE deadkeycode;
  308. #endif
  309. msb = n >> 8;
  310. if (msb >= 0xC2) {
  311. if (msb <= 0xDF) {
  312. n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
  313. } else if (msb == 0xF0) {
  314. usb_keyboard_press_key(n, 0);
  315. return;
  316. } else if (msb == 0xE0) {
  317. usb_keyboard_press_key(0, n);
  318. return;
  319. #ifdef KEYMEDIA_INTERFACE
  320. } else if (msb == 0xE2) {
  321. usb_keymedia_press_system_key(n);
  322. return;
  323. } else if (msb >= 0xE4 && msb <= 0xE7) {
  324. usb_keymedia_press_consumer_key(n & 0x3FF);
  325. return;
  326. #endif
  327. } else {
  328. return;
  329. }
  330. }
  331. keycode = unicode_to_keycode(n);
  332. if (!keycode) return;
  333. #ifdef DEADKEYS_MASK
  334. deadkeycode = deadkey_to_keycode(keycode);
  335. if (deadkeycode) {
  336. modrestore = keyboard_modifier_keys;
  337. if (modrestore) {
  338. keyboard_modifier_keys = 0;
  339. usb_keyboard_send();
  340. }
  341. // TODO: test if operating systems recognize
  342. // deadkey sequences when other keys are held
  343. mod = keycode_to_modifier(deadkeycode);
  344. key = keycode_to_key(deadkeycode);
  345. usb_keyboard_press_key(key, mod);
  346. usb_keyboard_release_key(key, mod);
  347. }
  348. #endif
  349. mod = keycode_to_modifier(keycode);
  350. key = keycode_to_key(keycode);
  351. usb_keyboard_press_key(key, mod | modrestore);
  352. }
  353. void usb_keyboard_release_keycode(uint16_t n)
  354. {
  355. uint8_t key, mod, msb;
  356. msb = n >> 8;
  357. if (msb >= 0xC2) {
  358. if (msb <= 0xDF) {
  359. n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
  360. } else if (msb == 0xF0) {
  361. usb_keyboard_release_key(n, 0);
  362. return;
  363. } else if (msb == 0xE0) {
  364. usb_keyboard_release_key(0, n);
  365. return;
  366. #ifdef KEYMEDIA_INTERFACE
  367. } else if (msb == 0xE2) {
  368. usb_keymedia_release_system_key(n);
  369. return;
  370. } else if (msb >= 0xE4 && msb <= 0xE7) {
  371. usb_keymedia_release_consumer_key(n & 0x3FF);
  372. return;
  373. #endif
  374. } else {
  375. return;
  376. }
  377. }
  378. KEYCODE_TYPE keycode = unicode_to_keycode(n);
  379. if (!keycode) return;
  380. mod = keycode_to_modifier(keycode);
  381. key = keycode_to_key(keycode);
  382. usb_keyboard_release_key(key, mod);
  383. }
  384. static void usb_keyboard_press_key(uint8_t key, uint8_t modifier)
  385. {
  386. int i, send_required = 0;
  387. if (modifier) {
  388. if ((keyboard_modifier_keys & modifier) != modifier) {
  389. keyboard_modifier_keys |= modifier;
  390. send_required = 1;
  391. }
  392. }
  393. if (key) {
  394. for (i=0; i < 6; i++) {
  395. if (keyboard_keys[i] == key) goto end;
  396. }
  397. for (i=0; i < 6; i++) {
  398. if (keyboard_keys[i] == 0) {
  399. keyboard_keys[i] = key;
  400. send_required = 1;
  401. goto end;
  402. }
  403. }
  404. }
  405. end:
  406. if (send_required) usb_keyboard_send();
  407. }
  408. static void usb_keyboard_release_key(uint8_t key, uint8_t modifier)
  409. {
  410. int i, send_required = 0;
  411. if (modifier) {
  412. if ((keyboard_modifier_keys & modifier) != 0) {
  413. keyboard_modifier_keys &= ~modifier;
  414. send_required = 1;
  415. }
  416. }
  417. if (key) {
  418. for (i=0; i < 6; i++) {
  419. if (keyboard_keys[i] == key) {
  420. keyboard_keys[i] = 0;
  421. send_required = 1;
  422. }
  423. }
  424. }
  425. if (send_required) usb_keyboard_send();
  426. }
  427. void usb_keyboard_release_all(void)
  428. {
  429. uint8_t i, anybits;
  430. anybits = keyboard_modifier_keys;
  431. keyboard_modifier_keys = 0;
  432. for (i=0; i < 6; i++) {
  433. anybits |= keyboard_keys[i];
  434. keyboard_keys[i] = 0;
  435. }
  436. if (anybits) usb_keyboard_send();
  437. #ifdef KEYMEDIA_INTERFACE
  438. anybits = 0;
  439. for (i=0; i < 4; i++) {
  440. if (keymedia_consumer_keys[i] != 0) anybits = 1;
  441. keymedia_consumer_keys[i] = 0;
  442. }
  443. for (i=0; i < 3; i++) {
  444. if (keymedia_system_keys[i] != 0) anybits = 1;
  445. keymedia_system_keys[i] = 0;
  446. }
  447. if (anybits) usb_keymedia_send();
  448. #endif
  449. }
  450. int usb_keyboard_press(uint8_t key, uint8_t modifier)
  451. {
  452. int r;
  453. keyboard_modifier_keys = modifier;
  454. keyboard_keys[0] = key;
  455. keyboard_keys[1] = 0;
  456. keyboard_keys[2] = 0;
  457. keyboard_keys[3] = 0;
  458. keyboard_keys[4] = 0;
  459. keyboard_keys[5] = 0;
  460. r = usb_keyboard_send();
  461. if (r) return r;
  462. keyboard_modifier_keys = 0;
  463. keyboard_keys[0] = 0;
  464. return usb_keyboard_send();
  465. }
  466. static uint8_t transmit_previous_timeout=0;
  467. // When the PC isn't listening, how long do we wait before discarding data?
  468. #define TX_TIMEOUT_MSEC 50
  469. static int usb_keyboard_transmit(int endpoint, const uint8_t *data, uint32_t len)
  470. {
  471. if (!usb_configuration) return -1;
  472. uint32_t head = tx_head;
  473. transfer_t *xfer = tx_transfer + head;
  474. uint32_t wait_begin_at = systick_millis_count;
  475. while (1) {
  476. uint32_t status = usb_transfer_status(xfer);
  477. if (!(status & 0x80)) {
  478. if (status & 0x68) {
  479. // TODO: what if status has errors???
  480. printf("ERROR status = %x, i=%d, ms=%u\n",
  481. status, tx_head, systick_millis_count);
  482. }
  483. transmit_previous_timeout = 0;
  484. break;
  485. }
  486. if (transmit_previous_timeout) return -1;
  487. if (systick_millis_count - wait_begin_at > TX_TIMEOUT_MSEC) {
  488. // waited too long, assume the USB host isn't listening
  489. transmit_previous_timeout = 1;
  490. return -1;
  491. }
  492. if (!usb_configuration) return -1;
  493. yield();
  494. }
  495. delayNanoseconds(30); // min req'd 11 ns, TODO: why is status ready too soon?
  496. uint8_t *buffer = txbuffer + head * TX_BUFSIZE;
  497. memcpy(buffer, data, len);
  498. usb_prepare_transfer(xfer, buffer, len, 0);
  499. arm_dcache_flush_delete(buffer, TX_BUFSIZE);
  500. usb_transmit(endpoint, xfer);
  501. if (++head >= TX_NUM) head = 0;
  502. tx_head = head;
  503. return 0;
  504. }
  505. // send the contents of keyboard_keys and keyboard_modifier_keys
  506. int usb_keyboard_send(void)
  507. {
  508. uint8_t buffer[KEYBOARD_SIZE];
  509. buffer[0] = keyboard_modifier_keys;
  510. buffer[1] = 0;
  511. buffer[2] = keyboard_keys[0];
  512. buffer[3] = keyboard_keys[1];
  513. buffer[4] = keyboard_keys[2];
  514. buffer[5] = keyboard_keys[3];
  515. buffer[6] = keyboard_keys[4];
  516. buffer[7] = keyboard_keys[5];
  517. return usb_keyboard_transmit(KEYBOARD_ENDPOINT, buffer, KEYBOARD_SIZE);
  518. }
  519. #ifdef KEYMEDIA_INTERFACE
  520. static void usb_keymedia_press_consumer_key(uint16_t key)
  521. {
  522. int i;
  523. if (key == 0) return;
  524. for (i=0; i < 4; i++) {
  525. if (keymedia_consumer_keys[i] == key) return;
  526. }
  527. for (i=0; i < 4; i++) {
  528. if (keymedia_consumer_keys[i] == 0) {
  529. keymedia_consumer_keys[i] = key;
  530. usb_keymedia_send();
  531. return;
  532. }
  533. }
  534. }
  535. static void usb_keymedia_release_consumer_key(uint16_t key)
  536. {
  537. int i;
  538. if (key == 0) return;
  539. for (i=0; i < 4; i++) {
  540. if (keymedia_consumer_keys[i] == key) {
  541. keymedia_consumer_keys[i] = 0;
  542. usb_keymedia_send();
  543. return;
  544. }
  545. }
  546. }
  547. static void usb_keymedia_press_system_key(uint8_t key)
  548. {
  549. int i;
  550. if (key == 0) return;
  551. for (i=0; i < 3; i++) {
  552. if (keymedia_system_keys[i] == key) return;
  553. }
  554. for (i=0; i < 3; i++) {
  555. if (keymedia_system_keys[i] == 0) {
  556. keymedia_system_keys[i] = key;
  557. usb_keymedia_send();
  558. return;
  559. }
  560. }
  561. }
  562. static void usb_keymedia_release_system_key(uint8_t key)
  563. {
  564. int i;
  565. if (key == 0) return;
  566. for (i=0; i < 3; i++) {
  567. if (keymedia_system_keys[i] == key) {
  568. keymedia_system_keys[i] = 0;
  569. usb_keymedia_send();
  570. return;
  571. }
  572. }
  573. }
  574. void usb_keymedia_release_all(void)
  575. {
  576. uint8_t i, anybits;
  577. anybits = 0;
  578. for (i=0; i < 4; i++) {
  579. if (keymedia_consumer_keys[i] != 0) anybits = 1;
  580. keymedia_consumer_keys[i] = 0;
  581. }
  582. for (i=0; i < 3; i++) {
  583. if (keymedia_system_keys[i] != 0) anybits = 1;
  584. keymedia_system_keys[i] = 0;
  585. }
  586. if (anybits) usb_keymedia_send();
  587. }
  588. // send the contents of keyboard_keys and keyboard_modifier_keys
  589. static int usb_keymedia_send(void)
  590. {
  591. uint8_t buffer[8];
  592. const uint16_t *consumer = keymedia_consumer_keys;
  593. // 44444444 44333333 33332222 22222211 11111111
  594. // 98765432 10987654 32109876 54321098 76543210
  595. buffer[0] = consumer[0];
  596. buffer[1] = (consumer[1] << 2) | ((consumer[0] >> 8) & 0x03);
  597. buffer[2] = (consumer[2] << 4) | ((consumer[1] >> 6) & 0x0F);
  598. buffer[3] = (consumer[3] << 6) | ((consumer[2] >> 4) & 0x3F);
  599. buffer[4] = consumer[3] >> 2;
  600. buffer[5] = keymedia_system_keys[0];
  601. buffer[6] = keymedia_system_keys[1];
  602. buffer[7] = keymedia_system_keys[2];
  603. return usb_keyboard_transmit(KEYMEDIA_ENDPOINT, buffer, KEYMEDIA_SIZE);
  604. }
  605. #endif // KEYMEDIA_INTERFACE
  606. #endif // KEYBOARD_INTERFACE