Kiibohd Controller
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
Este repositório está arquivado. Você pode visualizar os arquivos e realizar clone, mas não poderá realizar push nem abrir issues e pull requests.

usb_keyboard_serial.c 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. /* USB Keyboard and CDC Serial Device for Teensy USB Development Board
  2. * Copyright (c) 2009 PJRC.COM, LLC
  3. * Modifications by Jacob Alexander (2011-2014)
  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. // Local Includes
  24. #include "usb_keyboard_serial.h"
  25. #include <print.h>
  26. // ----- Variables -----
  27. // zero when we are not configured, non-zero when enumerated
  28. static volatile uint8_t usb_configuration = 0;
  29. // the time remaining before we transmit any partially full
  30. // packet, or send a zero length packet.
  31. static volatile uint8_t transmit_flush_timer = 0;
  32. static uint8_t transmit_previous_timeout = 0;
  33. // serial port settings (baud rate, control signals, etc) set
  34. // by the PC. These are ignored, but kept in RAM.
  35. static uint8_t cdc_line_coding[7] = {0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08};
  36. static uint8_t cdc_line_rtsdtr = 0;
  37. // ----- USB Keyboard Functions -----
  38. // Sends normal keyboard out to host
  39. // NOTE: Make sure to match the descriptor
  40. void usb_keyboard_toHost()
  41. {
  42. uint8_t i;
  43. // Modifiers
  44. UEDATX = USBKeys_Modifiers;
  45. // Reserved Byte
  46. UEDATX = 0x00;
  47. // Normal Keys, only supports 6 in Boot mode
  48. for ( i = 0; i < 6; i++)
  49. {
  50. UEDATX = USBKeys_Keys[i];
  51. }
  52. UEINTX = 0x00;
  53. }
  54. // send the contents of USBKeys_Keys and USBKeys_Modifiers
  55. inline void usb_keyboard_send()
  56. {
  57. uint8_t intr_state, timeout;
  58. intr_state = SREG;
  59. timeout = UDFNUML + 50;
  60. // Ready to transmit keypresses?
  61. do
  62. {
  63. SREG = intr_state;
  64. // has the USB gone offline? or exceeded timeout?
  65. if ( !usb_configuration || UDFNUML == timeout )
  66. {
  67. erro_print("USB Offline? Timeout?");
  68. return;
  69. }
  70. // get ready to try checking again
  71. intr_state = SREG;
  72. cli();
  73. // If not using Boot protocol, send NKRO
  74. UENUM = USBKeys_Protocol ? KEYBOARD_NKRO_ENDPOINT : KEYBOARD_ENDPOINT;
  75. } while ( !( UEINTX & (1 << RWAL) ) );
  76. switch ( USBKeys_Protocol )
  77. {
  78. // Send boot keyboard interrupt packet(s)
  79. case 0:
  80. usb_keyboard_toHost();
  81. break;
  82. // Send NKRO keyboard interrupts packet(s)
  83. case 1:
  84. // Check modifiers
  85. if ( USBKeys_Changed & USBKeyChangeState_Modifiers )
  86. {
  87. UEDATX = 0x01; // ID
  88. UEDATX = USBKeys_Modifiers;
  89. UEINTX = 0; // Finished with ID
  90. USBKeys_Changed &= ~USBKeyChangeState_Modifiers; // Mark sent
  91. }
  92. // Check main key section
  93. else if ( USBKeys_Changed & USBKeyChangeState_MainKeys )
  94. {
  95. UEDATX = 0x03; // ID
  96. // 4-164 (first 20 bytes)
  97. for ( uint8_t byte = 0; byte < 20; byte++ )
  98. UEDATX = USBKeys_Keys[ byte ];
  99. UEINTX = 0; // Finished with ID
  100. USBKeys_Changed &= ~USBKeyChangeState_MainKeys; // Mark sent
  101. }
  102. // Check secondary key section
  103. else if ( USBKeys_Changed & USBKeyChangeState_SecondaryKeys )
  104. {
  105. UEDATX = 0x04; // ID
  106. // 176-221 (last 6 bytes)
  107. for ( uint8_t byte = 20; byte < 26; byte++ )
  108. UEDATX = USBKeys_Keys[ byte ];
  109. UEINTX = 0; // Finished with ID
  110. USBKeys_Changed &= ~USBKeyChangeState_SecondaryKeys; // Mark sent
  111. }
  112. // Check system control keys
  113. else if ( USBKeys_Changed & USBKeyChangeState_System )
  114. {
  115. UEDATX = 0x05; // ID
  116. UEDATX = USBKeys_SysCtrl;
  117. UEINTX = 0; // Finished with ID
  118. USBKeys_Changed &= ~USBKeyChangeState_System; // Mark sent
  119. }
  120. // Check consumer control keys
  121. else if ( USBKeys_Changed & USBKeyChangeState_Consumer )
  122. {
  123. UEDATX = 0x06; // ID
  124. UEDATX = (uint8_t)(USBKeys_ConsCtrl & 0x00FF);
  125. UEDATX = (uint8_t)(USBKeys_ConsCtrl >> 8);
  126. UEINTX = 0; // Finished with ID
  127. USBKeys_Changed &= ~USBKeyChangeState_Consumer; // Mark sent
  128. }
  129. break;
  130. }
  131. USBKeys_Idle_Count = 0;
  132. SREG = intr_state;
  133. }
  134. // ----- USB Virtual Serial Port (CDC) Functions -----
  135. // get the next character, or -1 if nothing received
  136. int16_t usb_serial_getchar(void)
  137. {
  138. uint8_t c, intr_state;
  139. // interrupts are disabled so these functions can be
  140. // used from the main program or interrupt context,
  141. // even both in the same program!
  142. intr_state = SREG;
  143. cli();
  144. if (!usb_configuration) {
  145. SREG = intr_state;
  146. return -1;
  147. }
  148. UENUM = CDC_RX_ENDPOINT;
  149. retry:
  150. c = UEINTX;
  151. if (!(c & (1<<RWAL))) {
  152. // no data in buffer
  153. if (c & (1<<RXOUTI)) {
  154. UEINTX = 0x6B;
  155. goto retry;
  156. }
  157. SREG = intr_state;
  158. return -2;
  159. }
  160. // take one byte out of the buffer
  161. c = UEDATX;
  162. // if buffer completely used, release it
  163. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x6B;
  164. SREG = intr_state;
  165. return c;
  166. }
  167. // number of bytes available in the receive buffer
  168. uint8_t usb_serial_available(void)
  169. {
  170. uint8_t n=0, i, intr_state;
  171. intr_state = SREG;
  172. cli();
  173. if (usb_configuration) {
  174. UENUM = CDC_RX_ENDPOINT;
  175. n = UEBCLX;
  176. if (!n) {
  177. i = UEINTX;
  178. if (i & (1<<RXOUTI) && !(i & (1<<RWAL))) UEINTX = 0x6B;
  179. }
  180. }
  181. SREG = intr_state;
  182. return n;
  183. }
  184. // discard any buffered input
  185. void usb_serial_flush_input(void)
  186. {
  187. uint8_t intr_state;
  188. if (usb_configuration) {
  189. intr_state = SREG;
  190. cli();
  191. UENUM = CDC_RX_ENDPOINT;
  192. while ((UEINTX & (1<<RWAL))) {
  193. UEINTX = 0x6B;
  194. }
  195. SREG = intr_state;
  196. }
  197. }
  198. // transmit a character. 0 returned on success, -1 on error
  199. int8_t usb_serial_putchar(uint8_t c)
  200. {
  201. uint8_t timeout, intr_state;
  202. // if we're not online (enumerated and configured), error
  203. if (!usb_configuration) return -1;
  204. // interrupts are disabled so these functions can be
  205. // used from the main program or interrupt context,
  206. // even both in the same program!
  207. intr_state = SREG;
  208. cli();
  209. UENUM = CDC_TX_ENDPOINT;
  210. // if we gave up due to timeout before, don't wait again
  211. if (transmit_previous_timeout) {
  212. if (!(UEINTX & (1<<RWAL))) {
  213. SREG = intr_state;
  214. return -1;
  215. }
  216. transmit_previous_timeout = 0;
  217. }
  218. // wait for the FIFO to be ready to accept data
  219. timeout = UDFNUML + TRANSMIT_TIMEOUT;
  220. while (1) {
  221. // are we ready to transmit?
  222. if (UEINTX & (1<<RWAL)) break;
  223. SREG = intr_state;
  224. // have we waited too long? This happens if the user
  225. // is not running an application that is listening
  226. if (UDFNUML == timeout) {
  227. transmit_previous_timeout = 1;
  228. return -1;
  229. }
  230. // has the USB gone offline?
  231. if (!usb_configuration) return -1;
  232. // get ready to try checking again
  233. intr_state = SREG;
  234. cli();
  235. UENUM = CDC_TX_ENDPOINT;
  236. }
  237. // actually write the byte into the FIFO
  238. UEDATX = c;
  239. // if this completed a packet, transmit it now!
  240. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
  241. transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  242. SREG = intr_state;
  243. return 0;
  244. }
  245. // transmit a character, but do not wait if the buffer is full,
  246. // 0 returned on success, -1 on buffer full or error
  247. int8_t usb_serial_putchar_nowait(uint8_t c)
  248. {
  249. uint8_t intr_state;
  250. if (!usb_configuration) return -1;
  251. intr_state = SREG;
  252. cli();
  253. UENUM = CDC_TX_ENDPOINT;
  254. if (!(UEINTX & (1<<RWAL))) {
  255. // buffer is full
  256. SREG = intr_state;
  257. return -2;
  258. }
  259. // actually write the byte into the FIFO
  260. UEDATX = c;
  261. // if this completed a packet, transmit it now!
  262. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
  263. transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  264. SREG = intr_state;
  265. return 0;
  266. }
  267. // transmit a buffer.
  268. // 0 returned on success, -1 on error
  269. // This function is optimized for speed! Each call takes approx 6.1 us overhead
  270. // plus 0.25 us per byte. 12 Mbit/sec USB has 8.67 us per-packet overhead and
  271. // takes 0.67 us per byte. If called with 64 byte packet-size blocks, this function
  272. // can transmit at full USB speed using 43% CPU time. The maximum theoretical speed
  273. // is 19 packets per USB frame, or 1216 kbytes/sec. However, bulk endpoints have the
  274. // lowest priority, so any other USB devices will likely reduce the speed. Speed
  275. // can also be limited by how quickly the PC-based software reads data, as the host
  276. // controller in the PC will not allocate bandwitdh without a pending read request.
  277. // (thanks to Victor Suarez for testing and feedback and initial code)
  278. int8_t usb_serial_write(const char *buffer, uint16_t size)
  279. {
  280. uint8_t timeout, intr_state, write_size;
  281. // if we're not online (enumerated and configured), error
  282. if (!usb_configuration) return -1;
  283. // interrupts are disabled so these functions can be
  284. // used from the main program or interrupt context,
  285. // even both in the same program!
  286. intr_state = SREG;
  287. cli();
  288. UENUM = CDC_TX_ENDPOINT;
  289. // if we gave up due to timeout before, don't wait again
  290. /*
  291. if (transmit_previous_timeout) {
  292. if (!(UEINTX & (1<<RWAL))) {
  293. SREG = intr_state;
  294. return -2;
  295. }
  296. transmit_previous_timeout = 0;
  297. }
  298. */
  299. // each iteration of this loop transmits a packet
  300. while (size) {
  301. // wait for the FIFO to be ready to accept data
  302. timeout = UDFNUML + TRANSMIT_TIMEOUT;
  303. while (1) {
  304. // are we ready to transmit?
  305. if (UEINTX & (1<<RWAL)) break;
  306. SREG = intr_state;
  307. // have we waited too long? This happens if the user
  308. // is not running an application that is listening
  309. if (UDFNUML == timeout) {
  310. transmit_previous_timeout = 1;
  311. return -3;
  312. }
  313. // has the USB gone offline?
  314. if (!usb_configuration) return -4;
  315. // get ready to try checking again
  316. intr_state = SREG;
  317. cli();
  318. UENUM = CDC_TX_ENDPOINT;
  319. }
  320. // compute how many bytes will fit into the next packet
  321. write_size = CDC_TX_SIZE - UEBCLX;
  322. if (write_size > size) write_size = size;
  323. size -= write_size;
  324. // write the packet
  325. switch (write_size) {
  326. #if (CDC_TX_SIZE == 64)
  327. case 64: UEDATX = *buffer++;
  328. case 63: UEDATX = *buffer++;
  329. case 62: UEDATX = *buffer++;
  330. case 61: UEDATX = *buffer++;
  331. case 60: UEDATX = *buffer++;
  332. case 59: UEDATX = *buffer++;
  333. case 58: UEDATX = *buffer++;
  334. case 57: UEDATX = *buffer++;
  335. case 56: UEDATX = *buffer++;
  336. case 55: UEDATX = *buffer++;
  337. case 54: UEDATX = *buffer++;
  338. case 53: UEDATX = *buffer++;
  339. case 52: UEDATX = *buffer++;
  340. case 51: UEDATX = *buffer++;
  341. case 50: UEDATX = *buffer++;
  342. case 49: UEDATX = *buffer++;
  343. case 48: UEDATX = *buffer++;
  344. case 47: UEDATX = *buffer++;
  345. case 46: UEDATX = *buffer++;
  346. case 45: UEDATX = *buffer++;
  347. case 44: UEDATX = *buffer++;
  348. case 43: UEDATX = *buffer++;
  349. case 42: UEDATX = *buffer++;
  350. case 41: UEDATX = *buffer++;
  351. case 40: UEDATX = *buffer++;
  352. case 39: UEDATX = *buffer++;
  353. case 38: UEDATX = *buffer++;
  354. case 37: UEDATX = *buffer++;
  355. case 36: UEDATX = *buffer++;
  356. case 35: UEDATX = *buffer++;
  357. case 34: UEDATX = *buffer++;
  358. case 33: UEDATX = *buffer++;
  359. #endif
  360. #if (CDC_TX_SIZE >= 32)
  361. case 32: UEDATX = *buffer++;
  362. case 31: UEDATX = *buffer++;
  363. case 30: UEDATX = *buffer++;
  364. case 29: UEDATX = *buffer++;
  365. case 28: UEDATX = *buffer++;
  366. case 27: UEDATX = *buffer++;
  367. case 26: UEDATX = *buffer++;
  368. case 25: UEDATX = *buffer++;
  369. case 24: UEDATX = *buffer++;
  370. case 23: UEDATX = *buffer++;
  371. case 22: UEDATX = *buffer++;
  372. case 21: UEDATX = *buffer++;
  373. case 20: UEDATX = *buffer++;
  374. case 19: UEDATX = *buffer++;
  375. case 18: UEDATX = *buffer++;
  376. case 17: UEDATX = *buffer++;
  377. #endif
  378. #if (CDC_TX_SIZE >= 16)
  379. case 16: UEDATX = *buffer++;
  380. case 15: UEDATX = *buffer++;
  381. case 14: UEDATX = *buffer++;
  382. case 13: UEDATX = *buffer++;
  383. case 12: UEDATX = *buffer++;
  384. case 11: UEDATX = *buffer++;
  385. case 10: UEDATX = *buffer++;
  386. case 9: UEDATX = *buffer++;
  387. #endif
  388. case 8: UEDATX = *buffer++;
  389. case 7: UEDATX = *buffer++;
  390. case 6: UEDATX = *buffer++;
  391. case 5: UEDATX = *buffer++;
  392. case 4: UEDATX = *buffer++;
  393. case 3: UEDATX = *buffer++;
  394. case 2: UEDATX = *buffer++;
  395. default:
  396. case 1: UEDATX = *buffer++;
  397. case 0: break;
  398. }
  399. // if this completed a packet, transmit it now!
  400. if (!(UEINTX & (1<<RWAL))) UEINTX = 0x3A;
  401. transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT;
  402. SREG = intr_state;
  403. }
  404. return 0;
  405. }
  406. // immediately transmit any buffered output.
  407. // This doesn't actually transmit the data - that is impossible!
  408. // USB devices only transmit when the host allows, so the best
  409. // we can do is release the FIFO buffer for when the host wants it
  410. void usb_serial_flush_output(void)
  411. {
  412. uint8_t intr_state;
  413. intr_state = SREG;
  414. cli();
  415. if (transmit_flush_timer) {
  416. UENUM = CDC_TX_ENDPOINT;
  417. UEINTX = 0x3A;
  418. transmit_flush_timer = 0;
  419. }
  420. SREG = intr_state;
  421. }
  422. // functions to read the various async serial settings. These
  423. // aren't actually used by USB at all (communication is always
  424. // at full USB speed), but they are set by the host so we can
  425. // set them properly if we're converting the USB to a real serial
  426. // communication
  427. uint32_t usb_serial_get_baud(void)
  428. {
  429. uint32_t *baud = (uint32_t*)cdc_line_coding;
  430. return *baud;
  431. }
  432. uint8_t usb_serial_get_stopbits(void)
  433. {
  434. return cdc_line_coding[4];
  435. }
  436. uint8_t usb_serial_get_paritytype(void)
  437. {
  438. return cdc_line_coding[5];
  439. }
  440. uint8_t usb_serial_get_numbits(void)
  441. {
  442. return cdc_line_coding[6];
  443. }
  444. uint8_t usb_serial_get_control(void)
  445. {
  446. return cdc_line_rtsdtr;
  447. }
  448. // write the control signals, DCD, DSR, RI, etc
  449. // There is no CTS signal. If software on the host has transmitted
  450. // data to you but you haven't been calling the getchar function,
  451. // it remains buffered (either here or on the host) and can not be
  452. // lost because you weren't listening at the right time, like it
  453. // would in real serial communication.
  454. int8_t usb_serial_set_control(uint8_t signals)
  455. {
  456. uint8_t intr_state;
  457. intr_state = SREG;
  458. cli();
  459. if (!usb_configuration) {
  460. // we're not enumerated/configured
  461. SREG = intr_state;
  462. return -1;
  463. }
  464. UENUM = CDC_ACM_ENDPOINT;
  465. if (!(UEINTX & (1<<RWAL))) {
  466. // unable to write
  467. // TODO; should this try to abort the previously
  468. // buffered message??
  469. SREG = intr_state;
  470. return -1;
  471. }
  472. UEDATX = 0xA1;
  473. UEDATX = 0x20;
  474. UEDATX = 0;
  475. UEDATX = 0;
  476. UEDATX = 0; // 0 seems to work nicely. what if this is 1??
  477. UEDATX = 0;
  478. UEDATX = 1;
  479. UEDATX = 0;
  480. UEDATX = signals;
  481. UEINTX = 0x3A;
  482. SREG = intr_state;
  483. return 0;
  484. }
  485. // ----- General USB Functions -----
  486. // Set the avr into firmware reload mode
  487. void usb_device_reload()
  488. {
  489. cli();
  490. // Disable watchdog, if enabled
  491. // Disable all peripherals
  492. UDCON = 1;
  493. USBCON = (1 << FRZCLK); // Disable USB
  494. UCSR1B = 0;
  495. _delay_ms( 5 );
  496. #if defined(__AVR_AT90USB162__) // Teensy 1.0
  497. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
  498. TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
  499. DDRB = 0; DDRC = 0; DDRD = 0;
  500. PORTB = 0; PORTC = 0; PORTD = 0;
  501. asm volatile("jmp 0x3E00");
  502. #elif defined(__AVR_ATmega32U4__) // Teensy 2.0
  503. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  504. TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
  505. DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
  506. PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  507. asm volatile("jmp 0x7E00");
  508. #elif defined(__AVR_AT90USB646__) // Teensy++ 1.0
  509. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  510. TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
  511. DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
  512. PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  513. asm volatile("jmp 0xFC00");
  514. #elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0
  515. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  516. TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
  517. DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
  518. PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  519. asm volatile("jmp 0x1FC00");
  520. #endif
  521. }
  522. // WDT Setup for software reset the chip
  523. void wdt_init(void)
  524. {
  525. MCUSR = 0;
  526. wdt_disable();
  527. }
  528. // initialize USB
  529. void usb_init(void)
  530. {
  531. HW_CONFIG();
  532. USB_FREEZE(); // enable USB
  533. PLL_CONFIG(); // config PLL
  534. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  535. USB_CONFIG(); // start USB clock
  536. UDCON = 0; // enable attach resistor
  537. usb_configuration = 0;
  538. UDIEN = (1<<EORSTE) | (1<<SOFE);
  539. sei();
  540. // Disable watchdog timer after possible software reset
  541. //wdt_init(); // XXX Not working...seems to be ok without this, not sure though
  542. }
  543. // return 0 if the USB is not configured, or the configuration
  544. // number selected by the HOST
  545. uint8_t usb_configured()
  546. {
  547. return usb_configuration;
  548. }
  549. // USB Device Interrupt - handle all device-level events
  550. // the transmit buffer flushing is triggered by the start of frame
  551. //
  552. ISR( USB_GEN_vect )
  553. {
  554. uint8_t intbits, t_cdc;
  555. intbits = UDINT;
  556. UDINT = 0;
  557. if ( intbits & (1 << EORSTI) )
  558. {
  559. UENUM = 0;
  560. UECONX = 1;
  561. UECFG0X = EP_TYPE_CONTROL;
  562. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  563. UEIENX = (1 << RXSTPE);
  564. usb_configuration = 0;
  565. cdc_line_rtsdtr = 0;
  566. }
  567. if ( (intbits & (1 << SOFI)) && usb_configuration )
  568. {
  569. t_cdc = transmit_flush_timer;
  570. if ( t_cdc )
  571. {
  572. transmit_flush_timer = --t_cdc;
  573. if ( !t_cdc )
  574. {
  575. UENUM = CDC_TX_ENDPOINT;
  576. UEINTX = 0x3A;
  577. }
  578. }
  579. static uint8_t div4 = 0;
  580. if ( USBKeys_Idle_Config && (++div4 & 3) == 0 )
  581. {
  582. USBKeys_Idle_Count++;
  583. if ( USBKeys_Idle_Count == USBKeys_Idle_Config )
  584. {
  585. // XXX TODO Is this even used? If so, when? -Jacob
  586. // From hasu's code, this section looks like it could fix the Mac SET_IDLE problem
  587. // Send normal keyboard interrupt packet(s)
  588. switch ( USBKeys_Protocol )
  589. {
  590. // Send boot keyboard interrupt packet(s)
  591. case 0: usb_keyboard_toHost(); break;
  592. // Send NKRO keyboard interrupts packet(s)
  593. //case 1: usb_nkrokeyboard_toHost(); break; // XXX Not valid anymore
  594. }
  595. print("IDLE");
  596. }
  597. }
  598. }
  599. }
  600. // Misc functions to wait for ready and send/receive packets
  601. static inline void usb_wait_in_ready(void)
  602. {
  603. while (!(UEINTX & (1<<TXINI))) ;
  604. }
  605. static inline void usb_send_in(void)
  606. {
  607. UEINTX = ~(1<<TXINI);
  608. }
  609. static inline void usb_wait_receive_out(void)
  610. {
  611. while (!(UEINTX & (1<<RXOUTI))) ;
  612. }
  613. static inline void usb_ack_out(void)
  614. {
  615. UEINTX = ~(1<<RXOUTI);
  616. }
  617. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  618. // other endpoints are manipulated by the user-callable
  619. // functions, and the start-of-frame interrupt.
  620. //
  621. ISR(USB_COM_vect)
  622. {
  623. uint8_t intbits;
  624. const uint8_t *list;
  625. const uint8_t *cfg;
  626. uint8_t i, n, len, en;
  627. uint8_t *p;
  628. uint8_t bmRequestType;
  629. uint8_t bRequest;
  630. uint16_t wValue;
  631. uint16_t wIndex;
  632. uint16_t wLength;
  633. uint16_t desc_val;
  634. const uint8_t *desc_addr;
  635. uint8_t desc_length;
  636. UENUM = 0;
  637. intbits = UEINTX;
  638. if (intbits & (1<<RXSTPI))
  639. {
  640. bmRequestType = UEDATX;
  641. bRequest = UEDATX;
  642. wValue = UEDATX;
  643. wValue |= (UEDATX << 8);
  644. wIndex = UEDATX;
  645. wIndex |= (UEDATX << 8);
  646. wLength = UEDATX;
  647. wLength |= (UEDATX << 8);
  648. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  649. if ( bRequest == GET_DESCRIPTOR )
  650. {
  651. list = (const uint8_t *)descriptor_list;
  652. for ( i = 0; ; i++ )
  653. {
  654. if ( i >= NUM_DESC_LIST )
  655. {
  656. UECONX = (1 << STALLRQ) | (1 << EPEN); //stall
  657. return;
  658. }
  659. desc_val = pgm_read_word(list);
  660. if ( desc_val != wValue )
  661. {
  662. list += sizeof( struct descriptor_list_struct );
  663. continue;
  664. }
  665. list += 2;
  666. desc_val = pgm_read_word(list);
  667. if ( desc_val != wIndex )
  668. {
  669. list += sizeof(struct descriptor_list_struct) - 2;
  670. continue;
  671. }
  672. list += 2;
  673. desc_addr = (const uint8_t *)pgm_read_word(list);
  674. list += 2;
  675. desc_length = pgm_read_byte(list);
  676. break;
  677. }
  678. len = (wLength < 256) ? wLength : 255;
  679. if (len > desc_length) len = desc_length;
  680. do {
  681. // wait for host ready for IN packet
  682. do {
  683. i = UEINTX;
  684. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  685. if (i & (1<<RXOUTI)) return; // abort
  686. // send IN packet
  687. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  688. for (i = n; i; i--) {
  689. UEDATX = pgm_read_byte(desc_addr++);
  690. }
  691. len -= n;
  692. usb_send_in();
  693. } while (len || n == ENDPOINT0_SIZE);
  694. return;
  695. }
  696. if (bRequest == SET_ADDRESS) {
  697. usb_send_in();
  698. usb_wait_in_ready();
  699. UDADDR = wValue | (1<<ADDEN);
  700. return;
  701. }
  702. if ( bRequest == SET_CONFIGURATION && bmRequestType == 0 )
  703. {
  704. usb_configuration = wValue;
  705. cdc_line_rtsdtr = 0;
  706. transmit_flush_timer = 0;
  707. usb_send_in();
  708. cfg = endpoint_config_table;
  709. // Setup each of the 6 additional endpoints (0th already configured)
  710. for ( i = 1; i < 6; i++ )
  711. {
  712. UENUM = i;
  713. en = pgm_read_byte(cfg++);
  714. UECONX = en;
  715. if (en)
  716. {
  717. UECFG0X = pgm_read_byte(cfg++);
  718. UECFG1X = pgm_read_byte(cfg++);
  719. }
  720. }
  721. UERST = 0x7E;
  722. UERST = 0;
  723. return;
  724. }
  725. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  726. usb_wait_in_ready();
  727. UEDATX = usb_configuration;
  728. usb_send_in();
  729. return;
  730. }
  731. if ( ( wIndex == KEYBOARD_INTERFACE && USBKeys_Protocol == 0 )
  732. || ( wIndex == KEYBOARD_NKRO_INTERFACE && USBKeys_Protocol == 1 ) )
  733. {
  734. if ( bmRequestType == 0xA1)
  735. {
  736. if ( bRequest == HID_GET_REPORT )
  737. {
  738. usb_wait_in_ready();
  739. // Send normal keyboard interrupt packet(s)
  740. switch ( USBKeys_Protocol )
  741. {
  742. // Send boot keyboard interrupt packet(s)
  743. case 0: usb_keyboard_toHost(); break;
  744. // Send NKRO keyboard interrupts packet(s)
  745. //case 1: usb_nkrokeyboard_toHost(); break; // XXX Not valid anymore
  746. }
  747. usb_send_in();
  748. return;
  749. }
  750. if ( bRequest == HID_GET_IDLE )
  751. {
  752. usb_wait_in_ready();
  753. UEDATX = USBKeys_Idle_Config;
  754. usb_send_in();
  755. return;
  756. }
  757. if ( bRequest == HID_GET_PROTOCOL )
  758. {
  759. usb_wait_in_ready();
  760. UEDATX = USBKeys_Protocol;
  761. usb_send_in();
  762. return;
  763. }
  764. }
  765. if ( bmRequestType == 0x21 )
  766. {
  767. if ( bRequest == HID_SET_REPORT )
  768. {
  769. usb_wait_receive_out();
  770. USBKeys_LEDs = UEDATX;
  771. usb_ack_out();
  772. usb_send_in();
  773. return;
  774. }
  775. if ( bRequest == HID_SET_IDLE )
  776. {
  777. usb_wait_in_ready();
  778. USBKeys_Idle_Config = (wValue >> 8);
  779. USBKeys_Idle_Count = 0;
  780. usb_send_in();
  781. print("HID IDLE");
  782. return;
  783. }
  784. if ( bRequest == HID_SET_PROTOCOL )
  785. {
  786. usb_wait_in_ready();
  787. USBKeys_Protocol = wValue; // 0 - Boot Mode, 1 - NKRO Mode
  788. usb_send_in();
  789. print("HID SET");
  790. return;
  791. }
  792. }
  793. }
  794. if (bRequest == CDC_GET_LINE_CODING && bmRequestType == 0xA1) {
  795. usb_wait_in_ready();
  796. p = cdc_line_coding;
  797. for (i=0; i<7; i++) {
  798. UEDATX = *p++;
  799. }
  800. usb_send_in();
  801. return;
  802. }
  803. if (bRequest == CDC_SET_LINE_CODING && bmRequestType == 0x21) {
  804. usb_wait_receive_out();
  805. p = cdc_line_coding;
  806. for (i=0; i<7; i++) {
  807. *p++ = UEDATX;
  808. }
  809. usb_ack_out();
  810. usb_send_in();
  811. return;
  812. }
  813. if (bRequest == CDC_SET_CONTROL_LINE_STATE && bmRequestType == 0x21) {
  814. cdc_line_rtsdtr = wValue;
  815. usb_wait_in_ready();
  816. usb_send_in();
  817. return;
  818. }
  819. if (bRequest == GET_STATUS) {
  820. usb_wait_in_ready();
  821. i = 0;
  822. if (bmRequestType == 0x82) {
  823. UENUM = wIndex;
  824. if (UECONX & (1<<STALLRQ)) i = 1;
  825. UENUM = 0;
  826. }
  827. UEDATX = i;
  828. UEDATX = 0;
  829. usb_send_in();
  830. return;
  831. }
  832. if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
  833. && bmRequestType == 0x02 && wValue == 0) {
  834. i = wIndex & 0x7F;
  835. if (i >= 1 && i <= MAX_ENDPOINT) {
  836. usb_send_in();
  837. UENUM = i;
  838. if (bRequest == SET_FEATURE) {
  839. UECONX = (1<<STALLRQ)|(1<<EPEN);
  840. } else {
  841. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  842. UERST = (1 << i);
  843. UERST = 0;
  844. }
  845. return;
  846. }
  847. }
  848. }
  849. UECONX = (1 << STALLRQ) | (1 << EPEN); // stall
  850. }