Keyboard firmwares for Atmel AVR and Cortex-M
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.

keyboard_vusb.c 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include "usbdrv.h"
  2. #include "usb_keycodes.h"
  3. #include "keyboard.h"
  4. #include "print.h"
  5. static report_t report0;
  6. static report_t report1;
  7. static report_t *report = &report0;
  8. static report_t *report_prev = &report1;
  9. void report_send(void)
  10. {
  11. if (usbInterruptIsReady()){
  12. usbSetInterrupt((void *)report, sizeof(*report));
  13. }
  14. }
  15. report_t *report_get(void)
  16. {
  17. return report;
  18. }
  19. uint8_t report_mods(void)
  20. {
  21. return report->mods;
  22. }
  23. uint8_t *report_keys(void)
  24. {
  25. return report->keys;
  26. }
  27. bool report_has_key(void)
  28. {
  29. for (int i = 0; i < REPORT_KEYS; i++) {
  30. if (report->keys[i])
  31. return true;
  32. }
  33. return false;
  34. }
  35. void report_add_mod(uint8_t mod)
  36. {
  37. report->mods |= mod;
  38. }
  39. void report_add_key(uint8_t code)
  40. {
  41. int8_t i = 0;
  42. int8_t empty = -1;
  43. for (; i < REPORT_KEYS; i++) {
  44. if (report_prev->keys[i] == code) {
  45. report->keys[i] = code;
  46. break;
  47. }
  48. if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
  49. empty = i;
  50. }
  51. }
  52. if (i == REPORT_KEYS && empty != -1) {
  53. report->keys[empty] = code;
  54. }
  55. }
  56. void report_add_code(uint8_t code)
  57. {
  58. if (IS_MOD(code)) {
  59. report_add_mod(code);
  60. } else {
  61. report_add_key(code);
  62. }
  63. }
  64. void report_swap(void)
  65. {
  66. report_t *tmp = report_prev;
  67. report_prev = report;
  68. report = tmp;
  69. }
  70. void report_clear(void)
  71. {
  72. report->mods = 0;
  73. for (int8_t i = 0; i < REPORT_KEYS; i++) {
  74. report->keys[i] = 0;
  75. }
  76. }
  77. static uchar idleRate; /* repeat rate for keyboards, never used for mice */
  78. usbMsgLen_t usbFunctionSetup(uchar data[8])
  79. {
  80. usbRequest_t *rq = (void *)data;
  81. print("Setup: ");
  82. if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){ /* class request type */
  83. print("CLASS: ");
  84. phex(rq->bRequest);
  85. if(rq->bRequest == USBRQ_HID_GET_REPORT){
  86. print("GET_REPORT");
  87. /* we only have one report type, so don't look at wValue */
  88. usbMsgPtr = (void *)report;
  89. return sizeof(*report);
  90. }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
  91. print("GET_IDLE: ");
  92. phex(idleRate);
  93. usbMsgPtr = &idleRate;
  94. return 1;
  95. }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
  96. idleRate = rq->wValue.bytes[1];
  97. print("SET_IDLE: ");
  98. phex(idleRate);
  99. }
  100. print("\n");
  101. }else{
  102. print("VENDOR\n");
  103. /* no vendor specific requests implemented */
  104. }
  105. return 0; /* default for not implemented requests: return no data back to host */
  106. }
  107. PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
  108. 0x05, 0x01, // Usage Page (Generic Desktop),
  109. 0x09, 0x06, // Usage (Keyboard),
  110. 0xA1, 0x01, // Collection (Application),
  111. 0x75, 0x01, // Report Size (1),
  112. 0x95, 0x08, // Report Count (8),
  113. 0x05, 0x07, // Usage Page (Key Codes),
  114. 0x19, 0xE0, // Usage Minimum (224),
  115. 0x29, 0xE7, // Usage Maximum (231),
  116. 0x15, 0x00, // Logical Minimum (0),
  117. 0x25, 0x01, // Logical Maximum (1),
  118. 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
  119. 0x95, 0x01, // Report Count (1),
  120. 0x75, 0x08, // Report Size (8),
  121. 0x81, 0x03, // Input (Constant), ;Reserved byte
  122. 0x95, 0x05, // Report Count (5),
  123. 0x75, 0x01, // Report Size (1),
  124. 0x05, 0x08, // Usage Page (LEDs),
  125. 0x19, 0x01, // Usage Minimum (1),
  126. 0x29, 0x05, // Usage Maximum (5),
  127. 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
  128. 0x95, 0x01, // Report Count (1),
  129. 0x75, 0x03, // Report Size (3),
  130. 0x91, 0x03, // Output (Constant), ;LED report padding
  131. 0x95, 0x06, // Report Count (6),
  132. 0x75, 0x08, // Report Size (8),
  133. 0x15, 0x00, // Logical Minimum (0),
  134. 0x25, 0xFF, // Logical Maximum(255),
  135. 0x05, 0x07, // Usage Page (Key Codes),
  136. 0x19, 0x00, // Usage Minimum (0),
  137. 0x29, 0xFF, // Usage Maximum (255),
  138. 0x81, 0x00, // Input (Data, Array),
  139. 0xc0 // End Collection
  140. };