Teensy 4.1 core updated for C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. /* USB API for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/teensyduino.html
  3. * Copyright (c) 2008 PJRC.COM, LLC
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include <avr/io.h>
  24. #include <avr/pgmspace.h>
  25. #include <stdint.h>
  26. #include "usb_common.h"
  27. #include "usb_private.h"
  28. #include "usb_api.h"
  29. #include "wiring.h"
  30. // Step #1, decode UTF8 to Unicode code points
  31. //
  32. size_t usb_keyboard_class::write(uint8_t c)
  33. {
  34. if (c < 0x80) {
  35. // single byte encoded, 0x00 to 0x7F
  36. utf8_state = 0;
  37. write_unicode(c);
  38. } else if (c < 0xC0) {
  39. // 2nd, 3rd or 4th byte, 0x80 to 0xBF
  40. c &= 0x3F;
  41. if (utf8_state == 1) {
  42. utf8_state = 0;
  43. write_unicode(unicode_wchar | c);
  44. } else if (utf8_state == 2) {
  45. unicode_wchar |= ((uint16_t)c << 6);
  46. utf8_state = 1;
  47. }
  48. } else if (c < 0xE0) {
  49. // begin 2 byte sequence, 0xC2 to 0xDF
  50. // or illegal 2 byte sequence, 0xC0 to 0xC1
  51. unicode_wchar = (uint16_t)(c & 0x1F) << 6;
  52. utf8_state = 1;
  53. } else if (c < 0xF0) {
  54. // begin 3 byte sequence, 0xE0 to 0xEF
  55. unicode_wchar = (uint16_t)(c & 0x0F) << 12;
  56. utf8_state = 2;
  57. } else {
  58. // begin 4 byte sequence (not supported), 0xF0 to 0xF4
  59. // or illegal, 0xF5 to 0xFF
  60. utf8_state = 255;
  61. }
  62. return 1;
  63. }
  64. // Step #2: translate Unicode code point to keystroke sequence
  65. //
  66. KEYCODE_TYPE usb_keyboard_class::unicode_to_keycode(uint16_t cpoint)
  67. {
  68. // Unicode code points beyond U+FFFF are not supported
  69. // technically this input should probably be called UCS-2
  70. if (cpoint < 32) {
  71. if (cpoint == 10) return KEY_ENTER & KEYCODE_MASK;
  72. if (cpoint == 11) return KEY_TAB & KEYCODE_MASK;
  73. return 0;
  74. }
  75. if (cpoint < 128) {
  76. if (sizeof(KEYCODE_TYPE) == 1) {
  77. return pgm_read_byte(keycodes_ascii + (cpoint - 0x20));
  78. } else if (sizeof(KEYCODE_TYPE) == 2) {
  79. return pgm_read_word(keycodes_ascii + (cpoint - 0x20));
  80. }
  81. return 0;
  82. }
  83. #ifdef ISO_8859_1_A0
  84. if (cpoint <= 0xA0) return 0;
  85. if (cpoint < 0x100) {
  86. if (sizeof(KEYCODE_TYPE) == 1) {
  87. return pgm_read_byte(keycodes_iso_8859_1 + (cpoint - 0xA0));
  88. } else if (sizeof(KEYCODE_TYPE) == 2) {
  89. return pgm_read_word(keycodes_iso_8859_1 + (cpoint - 0xA0));
  90. }
  91. return 0;
  92. }
  93. #endif
  94. //#ifdef UNICODE_20AC
  95. //if (cpoint == 0x20AC) return UNICODE_20AC & 0x3FFF;
  96. //#endif
  97. #ifdef KEYCODE_EXTRA00
  98. if (cpoint == UNICODE_EXTRA00) return KEYCODE_EXTRA00 & 0x3FFF;
  99. #endif
  100. #ifdef KEYCODE_EXTRA01
  101. if (cpoint == UNICODE_EXTRA01) return KEYCODE_EXTRA01 & 0x3FFF;
  102. #endif
  103. #ifdef KEYCODE_EXTRA02
  104. if (cpoint == UNICODE_EXTRA02) return KEYCODE_EXTRA02 & 0x3FFF;
  105. #endif
  106. #ifdef KEYCODE_EXTRA03
  107. if (cpoint == UNICODE_EXTRA03) return KEYCODE_EXTRA03 & 0x3FFF;
  108. #endif
  109. #ifdef KEYCODE_EXTRA04
  110. if (cpoint == UNICODE_EXTRA04) return KEYCODE_EXTRA04 & 0x3FFF;
  111. #endif
  112. #ifdef KEYCODE_EXTRA05
  113. if (cpoint == UNICODE_EXTRA05) return KEYCODE_EXTRA05 & 0x3FFF;
  114. #endif
  115. #ifdef KEYCODE_EXTRA06
  116. if (cpoint == UNICODE_EXTRA06) return KEYCODE_EXTRA06 & 0x3FFF;
  117. #endif
  118. #ifdef KEYCODE_EXTRA07
  119. if (cpoint == UNICODE_EXTRA07) return KEYCODE_EXTRA07 & 0x3FFF;
  120. #endif
  121. #ifdef KEYCODE_EXTRA08
  122. if (cpoint == UNICODE_EXTRA08) return KEYCODE_EXTRA08 & 0x3FFF;
  123. #endif
  124. #ifdef KEYCODE_EXTRA09
  125. if (cpoint == UNICODE_EXTRA09) return KEYCODE_EXTRA09 & 0x3FFF;
  126. #endif
  127. return 0;
  128. }
  129. // Step #3: execute keystroke sequence
  130. //
  131. void usb_keyboard_class::write_keycode(KEYCODE_TYPE keycode)
  132. {
  133. if (!keycode) return;
  134. #ifdef DEADKEYS_MASK
  135. KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
  136. if (deadkeycode) write_key(deadkeycode);
  137. #endif
  138. write_key(keycode);
  139. }
  140. KEYCODE_TYPE usb_keyboard_class::deadkey_to_keycode(KEYCODE_TYPE keycode)
  141. {
  142. #ifdef DEADKEYS_MASK
  143. keycode &= DEADKEYS_MASK;
  144. if (keycode == 0) return 0;
  145. #ifdef ACUTE_ACCENT_BITS
  146. if (keycode == ACUTE_ACCENT_BITS) return DEADKEY_ACUTE_ACCENT;
  147. #endif
  148. #ifdef CEDILLA_BITS
  149. if (keycode == CEDILLA_BITS) return DEADKEY_CEDILLA;
  150. #endif
  151. #ifdef CIRCUMFLEX_BITS
  152. if (keycode == CIRCUMFLEX_BITS) return DEADKEY_CIRCUMFLEX;
  153. #endif
  154. #ifdef DIAERESIS_BITS
  155. if (keycode == DIAERESIS_BITS) return DEADKEY_DIAERESIS;
  156. #endif
  157. #ifdef GRAVE_ACCENT_BITS
  158. if (keycode == GRAVE_ACCENT_BITS) return DEADKEY_GRAVE_ACCENT;
  159. #endif
  160. #ifdef TILDE_BITS
  161. if (keycode == TILDE_BITS) return DEADKEY_TILDE;
  162. #endif
  163. #ifdef RING_ABOVE_BITS
  164. if (keycode == RING_ABOVE_BITS) return DEADKEY_RING_ABOVE;
  165. #endif
  166. #endif // DEADKEYS_MASK
  167. return 0;
  168. }
  169. // Step #4: do each keystroke
  170. //
  171. void usb_keyboard_class::write_key(KEYCODE_TYPE keycode)
  172. {
  173. keyboard_report_data[0] = keycode_to_modifier(keycode);
  174. keyboard_report_data[1] = 0;
  175. keyboard_report_data[2] = keycode_to_key(keycode);
  176. keyboard_report_data[3] = 0;
  177. keyboard_report_data[4] = 0;
  178. keyboard_report_data[5] = 0;
  179. keyboard_report_data[6] = 0;
  180. keyboard_report_data[7] = 0;
  181. send_now();
  182. keyboard_report_data[0] = 0;
  183. keyboard_report_data[2] = 0;
  184. send_now();
  185. }
  186. uint8_t usb_keyboard_class::keycode_to_modifier(KEYCODE_TYPE keycode)
  187. {
  188. uint8_t modifier=0;
  189. #ifdef SHIFT_MASK
  190. if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT;
  191. #endif
  192. #ifdef ALTGR_MASK
  193. if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT;
  194. #endif
  195. #ifdef RCTRL_MASK
  196. if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL;
  197. #endif
  198. return modifier;
  199. }
  200. uint8_t usb_keyboard_class::keycode_to_key(KEYCODE_TYPE keycode)
  201. {
  202. uint8_t key = keycode & 0x3F;
  203. #ifdef KEY_NON_US_100
  204. if (key == KEY_NON_US_100) key = 100;
  205. #endif
  206. return key;
  207. }
  208. void usb_keyboard_class::set_modifier(uint16_t c)
  209. {
  210. keyboard_report_data[0] = (uint8_t)c;
  211. }
  212. void usb_keyboard_class::set_key1(uint8_t c)
  213. {
  214. keyboard_report_data[2] = c;
  215. }
  216. void usb_keyboard_class::set_key2(uint8_t c)
  217. {
  218. keyboard_report_data[3] = c;
  219. }
  220. void usb_keyboard_class::set_key3(uint8_t c)
  221. {
  222. keyboard_report_data[4] = c;
  223. }
  224. void usb_keyboard_class::set_key4(uint8_t c)
  225. {
  226. keyboard_report_data[5] = c;
  227. }
  228. void usb_keyboard_class::set_key5(uint8_t c)
  229. {
  230. keyboard_report_data[6] = c;
  231. }
  232. void usb_keyboard_class::set_key6(uint8_t c)
  233. {
  234. keyboard_report_data[7] = c;
  235. }
  236. void usb_keyboard_class::send_now(void)
  237. {
  238. uint8_t intr_state, timeout;
  239. if (!usb_configuration) return;
  240. intr_state = SREG;
  241. cli();
  242. UENUM = KEYBOARD_ENDPOINT;
  243. timeout = UDFNUML + 50;
  244. while (1) {
  245. // are we ready to transmit?
  246. if (UEINTX & (1<<RWAL)) break;
  247. SREG = intr_state;
  248. // has the USB gone offline?
  249. if (!usb_configuration) return;
  250. // have we waited too long?
  251. if (UDFNUML == timeout) return;
  252. // get ready to try checking again
  253. intr_state = SREG;
  254. cli();
  255. UENUM = KEYBOARD_ENDPOINT;
  256. }
  257. UEDATX = keyboard_report_data[0];
  258. UEDATX = keyboard_report_data[1];
  259. UEDATX = keyboard_report_data[2];
  260. UEDATX = keyboard_report_data[3];
  261. UEDATX = keyboard_report_data[4];
  262. UEDATX = keyboard_report_data[5];
  263. UEDATX = keyboard_report_data[6];
  264. UEDATX = keyboard_report_data[7];
  265. UEINTX = 0x3A;
  266. keyboard_idle_count = 0;
  267. SREG = intr_state;
  268. }
  269. void usb_keyboard_class::press(uint16_t n)
  270. {
  271. uint8_t key, mod, msb, modrestore=0;
  272. msb = n >> 8;
  273. if (msb >= 0xC2) {
  274. if (msb <= 0xDF) {
  275. n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
  276. } else if (msb == 0xF0) {
  277. presskey(n, 0);
  278. return;
  279. } else if (msb == 0xE0) {
  280. presskey(0, n);
  281. return;
  282. } else if (msb == 0xE2) {
  283. press_system_key(n);
  284. return;
  285. } else if (msb >= 0xE4 && msb <= 0xE7) {
  286. press_consumer_key(n & 0x3FF);
  287. return;
  288. } else {
  289. return;
  290. }
  291. }
  292. KEYCODE_TYPE keycode = unicode_to_keycode(n);
  293. if (!keycode) return;
  294. #ifdef DEADKEYS_MASK
  295. KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode);
  296. if (deadkeycode) {
  297. modrestore = keyboard_report_data[0];
  298. if (modrestore) {
  299. keyboard_report_data[0] = 0;
  300. send_now();
  301. }
  302. // TODO: test if operating systems recognize
  303. // deadkey sequences when other keys are held
  304. mod = keycode_to_modifier(deadkeycode);
  305. key = keycode_to_key(deadkeycode);
  306. presskey(key, mod);
  307. releasekey(key, mod);
  308. }
  309. #endif
  310. mod = keycode_to_modifier(keycode);
  311. key = keycode_to_key(keycode);
  312. presskey(key, mod | modrestore);
  313. }
  314. void usb_keyboard_class::release(uint16_t n)
  315. {
  316. uint8_t key, mod, msb;
  317. msb = n >> 8;
  318. if (msb >= 0xC2) {
  319. if (msb <= 0xDF) {
  320. n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6);
  321. } else if (msb == 0xF0) {
  322. releasekey(n, 0);
  323. return;
  324. } else if (msb == 0xE0) {
  325. releasekey(0, n);
  326. return;
  327. } else if (msb == 0xE2) {
  328. release_system_key(n);
  329. return;
  330. } else if (msb >= 0xE4 && msb <= 0xE7) {
  331. release_consumer_key(n & 0x3FF);
  332. return;
  333. } else {
  334. return;
  335. }
  336. }
  337. KEYCODE_TYPE keycode = unicode_to_keycode(n);
  338. if (!keycode) return;
  339. mod = keycode_to_modifier(keycode);
  340. key = keycode_to_key(keycode);
  341. releasekey(key, mod);
  342. }
  343. void usb_keyboard_class::presskey(uint8_t key, uint8_t modifier)
  344. {
  345. bool send_required = false;
  346. uint8_t i;
  347. if (modifier) {
  348. if ((keyboard_report_data[0] & modifier) != modifier) {
  349. keyboard_report_data[0] |= modifier;
  350. send_required = true;
  351. }
  352. }
  353. if (key) {
  354. for (i=2; i < 8; i++) {
  355. if (keyboard_report_data[i] == key) goto end;
  356. }
  357. for (i=2; i < 8; i++) {
  358. if (keyboard_report_data[i] == 0) {
  359. keyboard_report_data[i] = key;
  360. send_required = true;
  361. goto end;
  362. }
  363. }
  364. }
  365. end:
  366. if (send_required) send_now();
  367. }
  368. void usb_keyboard_class::releasekey(uint8_t key, uint8_t modifier)
  369. {
  370. bool send_required = false;
  371. uint8_t i;
  372. if (modifier) {
  373. if ((keyboard_report_data[0] & modifier) != 0) {
  374. keyboard_report_data[0] &= ~modifier;
  375. send_required = true;
  376. }
  377. }
  378. if (key) {
  379. for (i=2; i < 8; i++) {
  380. if (keyboard_report_data[i] == key) {
  381. keyboard_report_data[i] = 0;
  382. send_required = true;
  383. }
  384. }
  385. }
  386. if (send_required) send_now();
  387. }
  388. void usb_keyboard_class::releaseAll(void)
  389. {
  390. uint8_t i, anybits;
  391. anybits = keyboard_report_data[0];
  392. for (i=2; i < 8; i++) {
  393. anybits |= keyboard_report_data[i];
  394. keyboard_report_data[i] = 0;
  395. }
  396. if (!anybits) return;
  397. keyboard_report_data[0] = 0;
  398. send_now();
  399. }
  400. void usb_keyboard_class::press_consumer_key(uint16_t key)
  401. {
  402. if (key == 0) return;
  403. for (uint8_t i=0; i < 4; i++) {
  404. if (keymedia_consumer_keys[i] == key) return;
  405. }
  406. for (uint8_t i=0; i < 4; i++) {
  407. if (keymedia_consumer_keys[i] == 0) {
  408. keymedia_consumer_keys[i] = key;
  409. keymedia_send();
  410. return;
  411. }
  412. }
  413. }
  414. void usb_keyboard_class::release_consumer_key(uint16_t key)
  415. {
  416. if (key == 0) return;
  417. for (uint8_t i=0; i < 4; i++) {
  418. if (keymedia_consumer_keys[i] == key) {
  419. keymedia_consumer_keys[i] = 0;
  420. keymedia_send();
  421. return;
  422. }
  423. }
  424. }
  425. void usb_keyboard_class::press_system_key(uint8_t key)
  426. {
  427. if (key == 0) return;
  428. for (uint8_t i=0; i < 3; i++) {
  429. if (keymedia_system_keys[i] == key) return;
  430. }
  431. for (uint8_t i=0; i < 3; i++) {
  432. if (keymedia_system_keys[i] == 0) {
  433. keymedia_system_keys[i] = key;
  434. keymedia_send();
  435. return;
  436. }
  437. }
  438. }
  439. void usb_keyboard_class::release_system_key(uint8_t key)
  440. {
  441. if (key == 0) return;
  442. for (uint8_t i=0; i < 3; i++) {
  443. if (keymedia_system_keys[i] == key) {
  444. keymedia_system_keys[i] = 0;
  445. keymedia_send();
  446. return;
  447. }
  448. }
  449. }
  450. void usb_keyboard_class::keymedia_release_all(void)
  451. {
  452. uint8_t anybits = 0;
  453. for (uint8_t i=0; i < 4; i++) {
  454. if (keymedia_consumer_keys[i] != 0) anybits = 1;
  455. keymedia_consumer_keys[i] = 0;
  456. }
  457. for (uint8_t i=0; i < 3; i++) {
  458. if (keymedia_system_keys[i] != 0) anybits = 1;
  459. keymedia_system_keys[i] = 0;
  460. }
  461. if (anybits) keymedia_send();
  462. }
  463. // send the contents of keyboard_keys and keyboard_modifier_keys
  464. void usb_keyboard_class::keymedia_send(void)
  465. {
  466. uint8_t intr_state, timeout;
  467. if (!usb_configuration) return;
  468. intr_state = SREG;
  469. cli();
  470. UENUM = KEYMEDIA_ENDPOINT;
  471. timeout = UDFNUML + 50;
  472. while (1) {
  473. // are we ready to transmit?
  474. if (UEINTX & (1<<RWAL)) break;
  475. SREG = intr_state;
  476. // has the USB gone offline?
  477. if (!usb_configuration) return;
  478. // have we waited too long?
  479. if (UDFNUML == timeout) return;
  480. // get ready to try checking again
  481. intr_state = SREG;
  482. cli();
  483. UENUM = KEYMEDIA_ENDPOINT;
  484. }
  485. // 44444444 44333333 33332222 22222211 11111111
  486. // 98765432 10987654 32109876 54321098 76543210
  487. UEDATX = keymedia_consumer_keys[0];
  488. UEDATX = (keymedia_consumer_keys[1] << 2) | ((keymedia_consumer_keys[0] >> 8) & 0x03);
  489. UEDATX = (keymedia_consumer_keys[2] << 4) | ((keymedia_consumer_keys[1] >> 6) & 0x0F);
  490. UEDATX = (keymedia_consumer_keys[3] << 6) | ((keymedia_consumer_keys[2] >> 4) & 0x3F);
  491. UEDATX = keymedia_consumer_keys[3] >> 2;
  492. UEDATX = keymedia_system_keys[0];
  493. UEDATX = keymedia_system_keys[1];
  494. UEDATX = keymedia_system_keys[2];
  495. UEINTX = 0x3A;
  496. SREG = intr_state;
  497. }
  498. void usb_mouse_class::move(int8_t x, int8_t y, int8_t wheel, int8_t horiz)
  499. {
  500. uint8_t intr_state, timeout;
  501. if (!usb_configuration) return;
  502. if (x == -128) x = -127;
  503. if (y == -128) y = -127;
  504. if (wheel == -128) wheel = -127;
  505. if (horiz == -128) horiz = -127;
  506. intr_state = SREG;
  507. cli();
  508. UENUM = MOUSE_ENDPOINT;
  509. timeout = UDFNUML + 50;
  510. while (1) {
  511. // are we ready to transmit?
  512. if (UEINTX & (1<<RWAL)) break;
  513. SREG = intr_state;
  514. // has the USB gone offline?
  515. if (!usb_configuration) return;
  516. // have we waited too long?
  517. if (UDFNUML == timeout) return;
  518. // get ready to try checking again
  519. intr_state = SREG;
  520. cli();
  521. UENUM = MOUSE_ENDPOINT;
  522. }
  523. UEDATX = mouse_buttons;
  524. UEDATX = x;
  525. UEDATX = y;
  526. UEDATX = wheel;
  527. UEDATX = horiz;
  528. UEINTX = 0x3A;
  529. SREG = intr_state;
  530. }
  531. void usb_mouse_class::click(uint8_t b)
  532. {
  533. mouse_buttons = b;
  534. move(0, 0);
  535. mouse_buttons = 0;
  536. move(0, 0);
  537. }
  538. void usb_mouse_class::scroll(int8_t wheel, int8_t horiz)
  539. {
  540. move(0, 0, wheel, horiz);
  541. }
  542. void usb_mouse_class::set_buttons(uint8_t left, uint8_t middle, uint8_t right, uint8_t back, uint8_t forward)
  543. {
  544. uint8_t mask=0;
  545. if (left) mask |= 1;
  546. if (middle) mask |= 4;
  547. if (right) mask |= 2;
  548. if (back) mask |= 8;
  549. if (forward) mask |= 16;
  550. mouse_buttons = mask;
  551. move(0, 0);
  552. }
  553. void usb_mouse_class::press(uint8_t b)
  554. {
  555. uint8_t prev = mouse_buttons;
  556. mouse_buttons |= (b & 7);
  557. if (mouse_buttons != prev) move(0, 0);
  558. }
  559. void usb_mouse_class::release(uint8_t b)
  560. {
  561. uint8_t prev = mouse_buttons;
  562. mouse_buttons &= ~(b & 7);
  563. if (mouse_buttons != prev) move(0, 0);
  564. }
  565. bool usb_mouse_class::isPressed(uint8_t b)
  566. {
  567. return ((mouse_buttons & (b & 7)) != 0);
  568. }
  569. void usb_joystick_class::send_now(void)
  570. {
  571. uint8_t intr_state, timeout;
  572. if (!usb_configuration) return;
  573. intr_state = SREG;
  574. cli();
  575. UENUM = JOYSTICK_ENDPOINT;
  576. timeout = UDFNUML + 50;
  577. while (1) {
  578. // are we ready to transmit?
  579. if (UEINTX & (1<<RWAL)) break;
  580. SREG = intr_state;
  581. // has the USB gone offline?
  582. if (!usb_configuration) return;
  583. // have we waited too long?
  584. if (UDFNUML == timeout) return;
  585. // get ready to try checking again
  586. intr_state = SREG;
  587. cli();
  588. UENUM = JOYSTICK_ENDPOINT;
  589. }
  590. UEDATX = joystick_report_data[0];
  591. UEDATX = joystick_report_data[1];
  592. UEDATX = joystick_report_data[2];
  593. UEDATX = joystick_report_data[3];
  594. UEDATX = joystick_report_data[4];
  595. UEDATX = joystick_report_data[5];
  596. UEDATX = joystick_report_data[6];
  597. UEDATX = joystick_report_data[7];
  598. UEDATX = joystick_report_data[8];
  599. UEDATX = joystick_report_data[9];
  600. UEDATX = joystick_report_data[10];
  601. UEDATX = joystick_report_data[11];
  602. UEINTX = 0x3A;
  603. SREG = intr_state;
  604. }
  605. static volatile uint8_t prev_byte=0;
  606. void usb_serial_class::begin(long speed)
  607. {
  608. // make sure USB is initialized
  609. usb_init();
  610. uint16_t begin_wait = (uint16_t)millis();
  611. while (1) {
  612. if (usb_configuration) {
  613. delay(200); // a little time for host to load a driver
  614. return;
  615. }
  616. if (usb_suspended) {
  617. uint16_t begin_suspend = (uint16_t)millis();
  618. while (usb_suspended) {
  619. // must remain suspended for a while, because
  620. // normal USB enumeration causes brief suspend
  621. // states, typically under 0.1 second
  622. if ((uint16_t)millis() - begin_suspend > 250) {
  623. return;
  624. }
  625. }
  626. }
  627. // ... or a timout (powered by a USB power adaptor that
  628. // wiggles the data lines to keep a USB device charging)
  629. if ((uint16_t)millis() - begin_wait > 2500) return;
  630. }
  631. prev_byte = 0;
  632. }
  633. void usb_serial_class::end()
  634. {
  635. usb_shutdown();
  636. delay(25);
  637. }
  638. // number of bytes available in the receive buffer
  639. int usb_serial_class::available()
  640. {
  641. uint8_t c;
  642. c = prev_byte; // assume 1 byte static volatile access is atomic
  643. if (c) return 1;
  644. c = readnext();
  645. if (c) {
  646. prev_byte = c;
  647. return 1;
  648. }
  649. return 0;
  650. }
  651. // get the next character, or -1 if nothing received
  652. int usb_serial_class::read()
  653. {
  654. uint8_t c;
  655. c = prev_byte;
  656. if (c) {
  657. prev_byte = 0;
  658. return c;
  659. }
  660. c = readnext();
  661. if (c) return c;
  662. return -1;
  663. }
  664. int usb_serial_class::peek()
  665. {
  666. uint8_t c;
  667. c = prev_byte;
  668. if (c) return c;
  669. c = readnext();
  670. if (c) {
  671. prev_byte = c;
  672. return c;
  673. }
  674. return -1;
  675. }
  676. // get the next character, or 0 if nothing
  677. uint8_t usb_serial_class::readnext(void)
  678. {
  679. uint8_t c, intr_state;
  680. // interrupts are disabled so these functions can be
  681. // used from the main program or interrupt context,
  682. // even both in the same program!
  683. intr_state = SREG;
  684. cli();
  685. if (!usb_configuration) {
  686. SREG = intr_state;
  687. return 0;
  688. }
  689. UENUM = DEBUG_RX_ENDPOINT;
  690. try_again:
  691. if (!(UEINTX & (1<<RWAL))) {
  692. // no packet in buffer
  693. SREG = intr_state;
  694. return 0;
  695. }
  696. // take one byte out of the buffer
  697. c = UEDATX;
  698. if (c == 0) {
  699. // if we see a zero, discard it and
  700. // discard the rest of this packet
  701. UEINTX = 0x6B;
  702. goto try_again;
  703. }
  704. // if this drained the buffer, release it
  705. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
  706. SREG = intr_state;
  707. return c;
  708. }
  709. // discard any buffered input
  710. void usb_serial_class::flush()
  711. {
  712. uint8_t intr_state;
  713. if (usb_configuration) {
  714. intr_state = SREG;
  715. cli();
  716. UENUM = DEBUG_RX_ENDPOINT;
  717. while ((UEINTX & (1<<RWAL))) {
  718. UEINTX = 0x6B;
  719. }
  720. SREG = intr_state;
  721. }
  722. prev_byte = 0;
  723. }
  724. // transmit a character.
  725. size_t usb_serial_class::write(uint8_t c)
  726. {
  727. //static uint8_t previous_timeout=0;
  728. uint8_t timeout, intr_state;
  729. // if we're not online (enumerated and configured), error
  730. if (!usb_configuration) goto error;
  731. // interrupts are disabled so these functions can be
  732. // used from the main program or interrupt context,
  733. // even both in the same program!
  734. intr_state = SREG;
  735. cli();
  736. UENUM = DEBUG_TX_ENDPOINT;
  737. // if we gave up due to timeout before, don't wait again
  738. #if 0
  739. // this seems to be causig a lockup... why????
  740. if (previous_timeout) {
  741. if (!(UEINTX & (1<<RWAL))) {
  742. SREG = intr_state;
  743. return;
  744. }
  745. previous_timeout = 0;
  746. }
  747. #endif
  748. // wait for the FIFO to be ready to accept data
  749. timeout = UDFNUML + TRANSMIT_TIMEOUT;
  750. while (1) {
  751. // are we ready to transmit?
  752. if (UEINTX & (1<<RWAL)) break;
  753. SREG = intr_state;
  754. // have we waited too long? This happens if the user
  755. // is not running an application that is listening
  756. if (UDFNUML == timeout) {
  757. //previous_timeout = 1;
  758. goto error;
  759. }
  760. // has the USB gone offline?
  761. if (!usb_configuration) goto error;
  762. // get ready to try checking again
  763. intr_state = SREG;
  764. cli();
  765. UENUM = DEBUG_TX_ENDPOINT;
  766. }
  767. // actually write the byte into the FIFO
  768. UEDATX = c;
  769. // if this completed a packet, transmit it now!
  770. if (!(UEINTX & (1<<RWAL))) {
  771. UEINTX = 0x3A;
  772. debug_flush_timer = 0;
  773. } else {
  774. debug_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  775. }
  776. SREG = intr_state;
  777. return 1;
  778. error:
  779. setWriteError();
  780. return 0;
  781. }
  782. // These are Teensy-specific extensions to the Serial object
  783. // immediately transmit any buffered output.
  784. // This doesn't actually transmit the data - that is impossible!
  785. // USB devices only transmit when the host allows, so the best
  786. // we can do is release the FIFO buffer for when the host wants it
  787. void usb_serial_class::send_now(void)
  788. {
  789. uint8_t intr_state;
  790. intr_state = SREG;
  791. cli();
  792. if (debug_flush_timer) {
  793. UENUM = DEBUG_TX_ENDPOINT;
  794. while ((UEINTX & (1<<RWAL))) {
  795. UEDATX = 0;
  796. }
  797. UEINTX = 0x3A;
  798. debug_flush_timer = 0;
  799. }
  800. SREG = intr_state;
  801. }
  802. uint32_t usb_serial_class::baud(void)
  803. {
  804. return ((uint32_t)DEBUG_TX_SIZE * 10000 / DEBUG_TX_INTERVAL);
  805. }
  806. uint8_t usb_serial_class::stopbits(void)
  807. {
  808. return 1;
  809. }
  810. uint8_t usb_serial_class::paritytype(void)
  811. {
  812. return 0;
  813. }
  814. uint8_t usb_serial_class::numbits(void)
  815. {
  816. return 8;
  817. }
  818. uint8_t usb_serial_class::dtr(void)
  819. {
  820. return 1;
  821. }
  822. uint8_t usb_serial_class::rts(void)
  823. {
  824. return 1;
  825. }
  826. usb_serial_class::operator bool()
  827. {
  828. if (usb_configuration) return true;
  829. return false;
  830. }
  831. // Preinstantiate Objects //////////////////////////////////////////////////////
  832. usb_serial_class Serial = usb_serial_class();
  833. usb_keyboard_class Keyboard = usb_keyboard_class();
  834. usb_mouse_class Mouse = usb_mouse_class();
  835. usb_joystick_class Joystick = usb_joystick_class();