Keyboard firmwares for Atmel AVR and Cortex-M
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
13 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. /* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board
  2. * http://www.pjrc.com/teensy/usb_keyboard.html
  3. * Copyright (c) 2009 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 <avr/interrupt.h>
  26. #include "usb.h"
  27. #include "usb_keyboard.h"
  28. #include "usb_mouse.h"
  29. #include "usb_debug.h"
  30. /**************************************************************************
  31. *
  32. * Configurable Options
  33. *
  34. **************************************************************************/
  35. // You can change these to give your code its own name.
  36. #define STR_MANUFACTURER L"t.m.k."
  37. #define STR_PRODUCT L"t.m.k. keyboard"
  38. // Mac OS-X and Linux automatically load the correct drivers. On
  39. // Windows, even though the driver is supplied by Microsoft, an
  40. // INF file is needed to load the driver. These numbers need to
  41. // match the INF file.
  42. #define VENDOR_ID 0xFEED
  43. #define PRODUCT_ID 0xBABE
  44. // USB devices are supposed to implment a halt feature, which is
  45. // rarely (if ever) used. If you comment this line out, the halt
  46. // code will be removed, saving 102 bytes of space (gcc 4.3.0).
  47. // This is not strictly USB compliant, but works with all major
  48. // operating systems.
  49. #define SUPPORT_ENDPOINT_HALT
  50. /**************************************************************************
  51. *
  52. * Endpoint Buffer Configuration
  53. *
  54. **************************************************************************/
  55. #define ENDPOINT0_SIZE 32
  56. // 0:control endpoint is enabled automatically by controller.
  57. static const uint8_t PROGMEM endpoint_config_table[] = {
  58. // enable, UECFG0X(type, direction), UECFG1X(size, bank, allocation)
  59. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, // 1
  60. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(MOUSE_SIZE) | MOUSE_BUFFER, // 2
  61. 1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER, // 3
  62. 0, // 4
  63. 0, // 5
  64. 0, // 6
  65. };
  66. /**************************************************************************
  67. *
  68. * Descriptor Data
  69. *
  70. **************************************************************************/
  71. // Descriptors are the data that your computer reads when it auto-detects
  72. // this USB device (called "enumeration" in USB lingo). The most commonly
  73. // changed items are editable at the top of this file. Changing things
  74. // in here should only be done by those who've read chapter 9 of the USB
  75. // spec and relevant portions of any USB class specifications!
  76. static uint8_t PROGMEM device_descriptor[] = {
  77. 18, // bLength
  78. 1, // bDescriptorType
  79. 0x00, 0x02, // bcdUSB
  80. 0, // bDeviceClass
  81. 0, // bDeviceSubClass
  82. 0, // bDeviceProtocol
  83. ENDPOINT0_SIZE, // bMaxPacketSize0
  84. LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
  85. LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
  86. 0x00, 0x01, // bcdDevice
  87. 1, // iManufacturer
  88. 2, // iProduct
  89. 0, // iSerialNumber
  90. 1 // bNumConfigurations
  91. };
  92. // Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
  93. static uint8_t PROGMEM keyboard_hid_report_desc[] = {
  94. 0x05, 0x01, // Usage Page (Generic Desktop),
  95. 0x09, 0x06, // Usage (Keyboard),
  96. 0xA1, 0x01, // Collection (Application),
  97. 0x75, 0x01, // Report Size (1),
  98. 0x95, 0x08, // Report Count (8),
  99. 0x05, 0x07, // Usage Page (Key Codes),
  100. 0x19, 0xE0, // Usage Minimum (224),
  101. 0x29, 0xE7, // Usage Maximum (231),
  102. 0x15, 0x00, // Logical Minimum (0),
  103. 0x25, 0x01, // Logical Maximum (1),
  104. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  105. 0x95, 0x01, // Report Count (1),
  106. 0x75, 0x08, // Report Size (8),
  107. 0x81, 0x03, // Input (Constant), ;Reserved byte
  108. 0x95, 0x05, // Report Count (5),
  109. 0x75, 0x01, // Report Size (1),
  110. 0x05, 0x08, // Usage Page (LEDs),
  111. 0x19, 0x01, // Usage Minimum (1),
  112. 0x29, 0x05, // Usage Maximum (5),
  113. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  114. 0x95, 0x01, // Report Count (1),
  115. 0x75, 0x03, // Report Size (3),
  116. 0x91, 0x03, // Output (Constant), ;LED report padding
  117. 0x95, 0x06, // Report Count (6),
  118. 0x75, 0x08, // Report Size (8),
  119. 0x15, 0x00, // Logical Minimum (0),
  120. 0x25, 0x68, // Logical Maximum(104),
  121. 0x05, 0x07, // Usage Page (Key Codes),
  122. 0x19, 0x00, // Usage Minimum (0),
  123. 0x29, 0x68, // Usage Maximum (104),
  124. 0x81, 0x00, // Input (Data, Array),
  125. 0xc0 // End Collection
  126. };
  127. // Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
  128. static uint8_t PROGMEM mouse_hid_report_desc[] = {
  129. 0x05, 0x01, // Usage Page (Generic Desktop)
  130. 0x09, 0x02, // Usage (Mouse)
  131. 0xA1, 0x01, // Collection (Application)
  132. 0x05, 0x09, // Usage Page (Button)
  133. 0x19, 0x01, // Usage Minimum (Button #1)
  134. 0x29, 0x03, // Usage Maximum (Button #3)
  135. 0x15, 0x00, // Logical Minimum (0)
  136. 0x25, 0x01, // Logical Maximum (1)
  137. 0x95, 0x03, // Report Count (3)
  138. 0x75, 0x01, // Report Size (1)
  139. 0x81, 0x02, // Input (Data, Variable, Absolute)
  140. 0x95, 0x01, // Report Count (1)
  141. 0x75, 0x05, // Report Size (5)
  142. 0x81, 0x03, // Input (Constant)
  143. 0x05, 0x01, // Usage Page (Generic Desktop)
  144. 0x09, 0x30, // Usage (X)
  145. 0x09, 0x31, // Usage (Y)
  146. 0x15, 0x81, // Logical Minimum (-127)
  147. 0x25, 0x7F, // Logical Maximum (127)
  148. 0x75, 0x08, // Report Size (8),
  149. 0x95, 0x02, // Report Count (2),
  150. 0x81, 0x06, // Input (Data, Variable, Relative)
  151. 0x09, 0x38, // Usage (Wheel)
  152. 0x95, 0x01, // Report Count (1),
  153. 0x81, 0x06, // Input (Data, Variable, Relative)
  154. 0xC0 // End Collection
  155. };
  156. static uint8_t PROGMEM debug_hid_report_desc[] = {
  157. 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined)
  158. 0x09, 0x74, // Usage 0x74
  159. 0xA1, 0x53, // Collection 0x53
  160. 0x75, 0x08, // report size = 8 bits
  161. 0x15, 0x00, // logical minimum = 0
  162. 0x26, 0xFF, 0x00, // logical maximum = 255
  163. 0x95, DEBUG_TX_SIZE, // report count
  164. 0x09, 0x75, // usage
  165. 0x81, 0x02, // Input (array)
  166. 0xC0 // end collection
  167. };
  168. #define CONFIG1_DESC_SIZE (9+(9+9+7)+(9+9+7)+(9+9+7))
  169. #define KEYBOARD_HID_DESC_OFFSET (9+9)
  170. #define MOUSE_HID_DESC_OFFSET (9+(9+9+7)+9)
  171. #define DEBUG_HID_DESC_OFFSET (9+(9+9+7)+(9+9+7)+9)
  172. static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
  173. // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
  174. 9, // bLength;
  175. 2, // bDescriptorType;
  176. LSB(CONFIG1_DESC_SIZE), // wTotalLength
  177. MSB(CONFIG1_DESC_SIZE),
  178. 3, // bNumInterfaces
  179. 1, // bConfigurationValue
  180. 0, // iConfiguration
  181. 0xC0, // bmAttributes
  182. 50, // bMaxPower
  183. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  184. 9, // bLength
  185. 4, // bDescriptorType
  186. KEYBOARD_INTERFACE, // bInterfaceNumber
  187. 0, // bAlternateSetting
  188. 1, // bNumEndpoints
  189. 0x03, // bInterfaceClass (0x03 = HID)
  190. 0x01, // bInterfaceSubClass (0x01 = Boot)
  191. 0x01, // bInterfaceProtocol (0x01 = Keyboard)
  192. 0, // iInterface
  193. // HID descriptor, HID 1.11 spec, section 6.2.1
  194. 9, // bLength
  195. 0x21, // bDescriptorType
  196. 0x11, 0x01, // bcdHID
  197. 0, // bCountryCode
  198. 1, // bNumDescriptors
  199. 0x22, // bDescriptorType
  200. sizeof(keyboard_hid_report_desc), // wDescriptorLength
  201. 0,
  202. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  203. 7, // bLength
  204. 5, // bDescriptorType
  205. KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
  206. 0x03, // bmAttributes (0x03=intr)
  207. KEYBOARD_SIZE, 0, // wMaxPacketSize
  208. 1, // bInterval
  209. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  210. 9, // bLength
  211. 4, // bDescriptorType
  212. MOUSE_INTERFACE, // bInterfaceNumber
  213. 0, // bAlternateSetting
  214. 1, // bNumEndpoints
  215. 0x03, // bInterfaceClass (0x03 = HID)
  216. 0x01, // bInterfaceSubClass (0x01 = Boot)
  217. 0x02, // bInterfaceProtocol (0x02 = Mouse)
  218. 0, // iInterface
  219. // HID descriptor, HID 1.11 spec, section 6.2.1
  220. 9, // bLength
  221. 0x21, // bDescriptorType
  222. 0x11, 0x01, // bcdHID
  223. 0, // bCountryCode
  224. 1, // bNumDescriptors
  225. 0x22, // bDescriptorType
  226. sizeof(mouse_hid_report_desc), // wDescriptorLength
  227. 0,
  228. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  229. 7, // bLength
  230. 5, // bDescriptorType
  231. MOUSE_ENDPOINT | 0x80, // bEndpointAddress
  232. 0x03, // bmAttributes (0x03=intr)
  233. 4, 0, // wMaxPacketSize
  234. 1, // bInterval
  235. // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
  236. 9, // bLength
  237. 4, // bDescriptorType
  238. DEBUG_INTERFACE, // bInterfaceNumber
  239. 0, // bAlternateSetting
  240. 1, // bNumEndpoints
  241. 0x03, // bInterfaceClass (0x03 = HID)
  242. 0x00, // bInterfaceSubClass
  243. 0x00, // bInterfaceProtocol
  244. 0, // iInterface
  245. // HID descriptor, HID 1.11 spec, section 6.2.1
  246. 9, // bLength
  247. 0x21, // bDescriptorType
  248. 0x11, 0x01, // bcdHID
  249. 0, // bCountryCode
  250. 1, // bNumDescriptors
  251. 0x22, // bDescriptorType
  252. sizeof(debug_hid_report_desc), // wDescriptorLength
  253. 0,
  254. // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
  255. 7, // bLength
  256. 5, // bDescriptorType
  257. DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress
  258. 0x03, // bmAttributes (0x03=intr)
  259. DEBUG_TX_SIZE, 0, // wMaxPacketSize
  260. 1 // bInterval
  261. };
  262. // If you're desperate for a little extra code memory, these strings
  263. // can be completely removed if iManufacturer, iProduct, iSerialNumber
  264. // in the device desciptor are changed to zeros.
  265. struct usb_string_descriptor_struct {
  266. uint8_t bLength;
  267. uint8_t bDescriptorType;
  268. int16_t wString[];
  269. };
  270. static struct usb_string_descriptor_struct PROGMEM string0 = {
  271. 4,
  272. 3,
  273. {0x0409}
  274. };
  275. static struct usb_string_descriptor_struct PROGMEM string1 = {
  276. sizeof(STR_MANUFACTURER),
  277. 3,
  278. STR_MANUFACTURER
  279. };
  280. static struct usb_string_descriptor_struct PROGMEM string2 = {
  281. sizeof(STR_PRODUCT),
  282. 3,
  283. STR_PRODUCT
  284. };
  285. // This table defines which descriptor data is sent for each specific
  286. // request from the host (in wValue and wIndex).
  287. static struct descriptor_list_struct {
  288. uint16_t wValue; // descriptor type
  289. uint16_t wIndex;
  290. const uint8_t *addr;
  291. uint8_t length;
  292. } PROGMEM descriptor_list[] = {
  293. // DEVICE descriptor
  294. {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
  295. // CONFIGURATION descriptor
  296. {0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
  297. // HID REPORT
  298. {0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
  299. {0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
  300. // HID REPORT
  301. {0x2200, MOUSE_INTERFACE, mouse_hid_report_desc, sizeof(mouse_hid_report_desc)},
  302. {0x2100, MOUSE_INTERFACE, config1_descriptor+MOUSE_HID_DESC_OFFSET, 9},
  303. // HID REPORT
  304. {0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
  305. {0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
  306. // STRING descriptor
  307. {0x0300, 0x0000, (const uint8_t *)&string0, 4},
  308. {0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)},
  309. {0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}
  310. };
  311. #define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct))
  312. /**************************************************************************
  313. *
  314. * Variables - these are the only non-stack RAM usage
  315. *
  316. **************************************************************************/
  317. // zero when we are not configured, non-zero when enumerated
  318. static volatile uint8_t usb_configuration=0;
  319. /**************************************************************************
  320. *
  321. * Public Functions - these are the API intended for the user
  322. *
  323. **************************************************************************/
  324. // initialize USB
  325. void usb_init(void)
  326. {
  327. HW_CONFIG();
  328. USB_FREEZE(); // enable USB
  329. PLL_CONFIG(); // config PLL
  330. while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock
  331. USB_CONFIG(); // start USB clock
  332. UDCON = 0; // enable attach resistor
  333. usb_configuration = 0;
  334. UDIEN = (1<<EORSTE)|(1<<SOFE);
  335. sei();
  336. }
  337. // return 0 if the USB is not configured, or the configuration
  338. // number selected by the HOST
  339. uint8_t usb_configured(void)
  340. {
  341. return usb_configuration;
  342. }
  343. /**************************************************************************
  344. *
  345. * Private Functions - not intended for general user consumption....
  346. *
  347. **************************************************************************/
  348. // USB Device Interrupt - handle all device-level events
  349. // the transmit buffer flushing is triggered by the start of frame
  350. //
  351. ISR(USB_GEN_vect)
  352. {
  353. uint8_t intbits, t, i;
  354. static uint8_t div4=0;
  355. intbits = UDINT;
  356. UDINT = 0;
  357. if (intbits & (1<<EORSTI)) {
  358. UENUM = 0;
  359. UECONX = 1;
  360. UECFG0X = EP_TYPE_CONTROL;
  361. UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER;
  362. UEIENX = (1<<RXSTPE);
  363. usb_configuration = 0;
  364. }
  365. if ((intbits & (1<<SOFI)) && usb_configuration) {
  366. t = debug_flush_timer;
  367. if (t) {
  368. debug_flush_timer = -- t;
  369. if (!t) {
  370. UENUM = DEBUG_TX_ENDPOINT;
  371. while ((UEINTX & (1<<RWAL))) {
  372. UEDATX = 0;
  373. }
  374. UEINTX = 0x3A;
  375. }
  376. }
  377. if (keyboard_idle_config && (++div4 & 3) == 0) {
  378. UENUM = KEYBOARD_ENDPOINT;
  379. if (UEINTX & (1<<RWAL)) {
  380. keyboard_idle_count++;
  381. if (keyboard_idle_count == keyboard_idle_config) {
  382. keyboard_idle_count = 0;
  383. UEDATX = keyboard_modifier_keys;
  384. UEDATX = 0;
  385. for (i=0; i<6; i++) {
  386. UEDATX = keyboard_keys[i];
  387. }
  388. UEINTX = 0x3A;
  389. }
  390. }
  391. }
  392. }
  393. }
  394. // Misc functions to wait for ready and send/receive packets
  395. static inline void usb_wait_in_ready(void)
  396. {
  397. while (!(UEINTX & (1<<TXINI))) ;
  398. }
  399. static inline void usb_send_in(void)
  400. {
  401. UEINTX = ~(1<<TXINI);
  402. }
  403. static inline void usb_wait_receive_out(void)
  404. {
  405. while (!(UEINTX & (1<<RXOUTI))) ;
  406. }
  407. static inline void usb_ack_out(void)
  408. {
  409. UEINTX = ~(1<<RXOUTI);
  410. }
  411. // USB Endpoint Interrupt - endpoint 0 is handled here. The
  412. // other endpoints are manipulated by the user-callable
  413. // functions, and the start-of-frame interrupt.
  414. //
  415. ISR(USB_COM_vect)
  416. {
  417. uint8_t intbits;
  418. const uint8_t *list;
  419. const uint8_t *cfg;
  420. uint8_t i, n, len, en;
  421. uint8_t bmRequestType;
  422. uint8_t bRequest;
  423. uint16_t wValue;
  424. uint16_t wIndex;
  425. uint16_t wLength;
  426. uint16_t desc_val;
  427. const uint8_t *desc_addr;
  428. uint8_t desc_length;
  429. UENUM = 0;
  430. intbits = UEINTX;
  431. if (intbits & (1<<RXSTPI)) {
  432. bmRequestType = UEDATX;
  433. bRequest = UEDATX;
  434. wValue = UEDATX;
  435. wValue |= (UEDATX << 8);
  436. wIndex = UEDATX;
  437. wIndex |= (UEDATX << 8);
  438. wLength = UEDATX;
  439. wLength |= (UEDATX << 8);
  440. UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI));
  441. if (bRequest == GET_DESCRIPTOR) {
  442. list = (const uint8_t *)descriptor_list;
  443. for (i=0; ; i++) {
  444. if (i >= NUM_DESC_LIST) {
  445. UECONX = (1<<STALLRQ)|(1<<EPEN); //stall
  446. return;
  447. }
  448. desc_val = pgm_read_word(list);
  449. if (desc_val != wValue) {
  450. list += sizeof(struct descriptor_list_struct);
  451. continue;
  452. }
  453. list += 2;
  454. desc_val = pgm_read_word(list);
  455. if (desc_val != wIndex) {
  456. list += sizeof(struct descriptor_list_struct)-2;
  457. continue;
  458. }
  459. list += 2;
  460. desc_addr = (const uint8_t *)pgm_read_word(list);
  461. list += 2;
  462. desc_length = pgm_read_byte(list);
  463. break;
  464. }
  465. len = (wLength < 256) ? wLength : 255;
  466. if (len > desc_length) len = desc_length;
  467. do {
  468. // wait for host ready for IN packet
  469. do {
  470. i = UEINTX;
  471. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  472. if (i & (1<<RXOUTI)) return; // abort
  473. // send IN packet
  474. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  475. for (i = n; i; i--) {
  476. UEDATX = pgm_read_byte(desc_addr++);
  477. }
  478. len -= n;
  479. usb_send_in();
  480. } while (len || n == ENDPOINT0_SIZE);
  481. return;
  482. }
  483. if (bRequest == SET_ADDRESS) {
  484. usb_send_in();
  485. usb_wait_in_ready();
  486. UDADDR = wValue | (1<<ADDEN);
  487. return;
  488. }
  489. if (bRequest == SET_CONFIGURATION && bmRequestType == 0) {
  490. usb_configuration = wValue;
  491. usb_send_in();
  492. cfg = endpoint_config_table;
  493. for (i=1; i<=6; i++) {
  494. UENUM = i;
  495. en = pgm_read_byte(cfg++);
  496. UECONX = en;
  497. if (en) {
  498. UECFG0X = pgm_read_byte(cfg++);
  499. UECFG1X = pgm_read_byte(cfg++);
  500. }
  501. }
  502. UERST = 0x7E;
  503. UERST = 0;
  504. return;
  505. }
  506. if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) {
  507. usb_wait_in_ready();
  508. UEDATX = usb_configuration;
  509. usb_send_in();
  510. return;
  511. }
  512. if (bRequest == GET_STATUS) {
  513. usb_wait_in_ready();
  514. i = 0;
  515. #ifdef SUPPORT_ENDPOINT_HALT
  516. if (bmRequestType == 0x82) {
  517. UENUM = wIndex;
  518. if (UECONX & (1<<STALLRQ)) i = 1;
  519. UENUM = 0;
  520. }
  521. #endif
  522. UEDATX = i;
  523. UEDATX = 0;
  524. usb_send_in();
  525. return;
  526. }
  527. #ifdef SUPPORT_ENDPOINT_HALT
  528. if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE)
  529. && bmRequestType == 0x02 && wValue == 0) {
  530. i = wIndex & 0x7F;
  531. if (i >= 1 && i <= MAX_ENDPOINT) {
  532. usb_send_in();
  533. UENUM = i;
  534. if (bRequest == SET_FEATURE) {
  535. UECONX = (1<<STALLRQ)|(1<<EPEN);
  536. } else {
  537. UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN);
  538. UERST = (1 << i);
  539. UERST = 0;
  540. }
  541. return;
  542. }
  543. }
  544. #endif
  545. if (wIndex == KEYBOARD_INTERFACE) {
  546. if (bmRequestType == 0xA1) {
  547. if (bRequest == HID_GET_REPORT) {
  548. usb_wait_in_ready();
  549. UEDATX = keyboard_modifier_keys;
  550. UEDATX = 0;
  551. for (i=0; i<6; i++) {
  552. UEDATX = keyboard_keys[i];
  553. }
  554. usb_send_in();
  555. return;
  556. }
  557. if (bRequest == HID_GET_IDLE) {
  558. usb_wait_in_ready();
  559. UEDATX = keyboard_idle_config;
  560. usb_send_in();
  561. return;
  562. }
  563. if (bRequest == HID_GET_PROTOCOL) {
  564. usb_wait_in_ready();
  565. UEDATX = keyboard_protocol;
  566. usb_send_in();
  567. return;
  568. }
  569. }
  570. if (bmRequestType == 0x21) {
  571. if (bRequest == HID_SET_REPORT) {
  572. usb_wait_receive_out();
  573. keyboard_leds = UEDATX;
  574. usb_ack_out();
  575. usb_send_in();
  576. return;
  577. }
  578. if (bRequest == HID_SET_IDLE) {
  579. keyboard_idle_config = (wValue >> 8);
  580. keyboard_idle_count = 0;
  581. //usb_wait_in_ready();
  582. usb_send_in();
  583. return;
  584. }
  585. if (bRequest == HID_SET_PROTOCOL) {
  586. keyboard_protocol = wValue;
  587. //usb_wait_in_ready();
  588. usb_send_in();
  589. return;
  590. }
  591. }
  592. }
  593. if (wIndex == MOUSE_INTERFACE) {
  594. if (bmRequestType == 0xA1) {
  595. if (bRequest == HID_GET_REPORT) {
  596. usb_wait_in_ready();
  597. UEDATX = mouse_buttons;
  598. UEDATX = 0;
  599. UEDATX = 0;
  600. UEDATX = 0;
  601. usb_send_in();
  602. return;
  603. }
  604. if (bRequest == HID_GET_PROTOCOL) {
  605. usb_wait_in_ready();
  606. UEDATX = mouse_protocol;
  607. usb_send_in();
  608. return;
  609. }
  610. }
  611. if (bmRequestType == 0x21) {
  612. if (bRequest == HID_SET_PROTOCOL) {
  613. mouse_protocol = wValue;
  614. usb_send_in();
  615. return;
  616. }
  617. }
  618. }
  619. if (wIndex == DEBUG_INTERFACE) {
  620. if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) {
  621. len = wLength;
  622. do {
  623. // wait for host ready for IN packet
  624. do {
  625. i = UEINTX;
  626. } while (!(i & ((1<<TXINI)|(1<<RXOUTI))));
  627. if (i & (1<<RXOUTI)) return; // abort
  628. // send IN packet
  629. n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE;
  630. for (i = n; i; i--) {
  631. UEDATX = 0;
  632. }
  633. len -= n;
  634. usb_send_in();
  635. } while (len || n == ENDPOINT0_SIZE);
  636. return;
  637. }
  638. }
  639. }
  640. UECONX = (1<<STALLRQ) | (1<<EPEN); // stall
  641. }