Keyboard firmwares for Atmel AVR and Cortex-M
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

usb_keyboard.c 4.0KB

vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
vor 13 Jahren
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <avr/interrupt.h>
  2. #include <avr/pgmspace.h>
  3. #include "usb_keycodes.h"
  4. #include "usb_keyboard.h"
  5. #include "print.h"
  6. #include "debug.h"
  7. // keyboard report.
  8. static usb_keyboard_report_t _report0 = { {0,0,0,0,0,0}, 0 };
  9. static usb_keyboard_report_t _report1 = { {0,0,0,0,0,0}, 0 };
  10. usb_keyboard_report_t *usb_keyboard_report = &_report0;
  11. usb_keyboard_report_t *usb_keyboard_report_back = &_report1;
  12. // protocol setting from the host. We use exactly the same report
  13. // either way, so this variable only stores the setting since we
  14. // are required to be able to report which setting is in use.
  15. uint8_t usb_keyboard_protocol=1;
  16. // the idle configuration, how often we send the report to the
  17. // host (ms * 4) even when it hasn't changed
  18. uint8_t usb_keyboard_idle_config=125;
  19. // count until idle timeout
  20. uint8_t usb_keyboard_idle_count=0;
  21. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  22. volatile uint8_t usb_keyboard_leds=0;
  23. int8_t usb_keyboard_send(void)
  24. {
  25. return usb_keyboard_send_report(usb_keyboard_report);
  26. }
  27. int8_t usb_keyboard_send_report(usb_keyboard_report_t *report)
  28. {
  29. uint8_t i, intr_state, timeout;
  30. if (!usb_configured()) return -1;
  31. intr_state = SREG;
  32. cli();
  33. UENUM = KEYBOARD_ENDPOINT;
  34. timeout = UDFNUML + 50;
  35. while (1) {
  36. // are we ready to transmit?
  37. if (UEINTX & (1<<RWAL)) break;
  38. SREG = intr_state;
  39. // has the USB gone offline?
  40. if (!usb_configured()) return -1;
  41. // have we waited too long?
  42. if (UDFNUML == timeout) return -1;
  43. // get ready to try checking again
  44. intr_state = SREG;
  45. cli();
  46. UENUM = KEYBOARD_ENDPOINT;
  47. }
  48. UEDATX = report->mods;
  49. UEDATX = 0;
  50. for (i=0; i<6; i++) {
  51. UEDATX = report->keys[i];
  52. }
  53. UEINTX = 0x3A;
  54. usb_keyboard_idle_count = 0;
  55. SREG = intr_state;
  56. report->is_sent =true;
  57. usb_keyboard_print_report(report);
  58. return 0;
  59. }
  60. void usb_keyboard_swap_report(void) {
  61. usb_keyboard_report_t *tmp = usb_keyboard_report_back;
  62. usb_keyboard_report_back = usb_keyboard_report;
  63. usb_keyboard_report = tmp;
  64. }
  65. void usb_keyboard_clear_report(void) {
  66. usb_keyboard_clear_keys();
  67. usb_keyboard_clear_mods();
  68. usb_keyboard_report->is_sent = false;
  69. }
  70. void usb_keyboard_clear_keys(void) {
  71. for (int i = 0; i < 6; i++) usb_keyboard_report->keys[i] = 0;
  72. }
  73. void usb_keyboard_clear_mods(void)
  74. {
  75. usb_keyboard_report->mods = 0;
  76. }
  77. void usb_keyboard_add_code(uint8_t code)
  78. {
  79. if (IS_MOD(code)) {
  80. usb_keyboard_add_mod(code);
  81. } else {
  82. usb_keyboard_add_key(code);
  83. }
  84. }
  85. void usb_keyboard_add_key(uint8_t code)
  86. {
  87. for (int i = 0; i < 6; i++) {
  88. if (!usb_keyboard_report->keys[i]) {
  89. usb_keyboard_report->keys[i] = code;
  90. return;
  91. }
  92. }
  93. }
  94. void usb_keyboard_set_keys(uint8_t keys[6])
  95. {
  96. for (int i = 0; i < 6; i++)
  97. usb_keyboard_report->keys[i] = keys[i];
  98. }
  99. void usb_keyboard_set_mods(uint8_t mods)
  100. {
  101. usb_keyboard_report->mods = mods;
  102. }
  103. void usb_keyboard_add_mod(uint8_t code)
  104. {
  105. usb_keyboard_report->mods |= MOD_BIT(code);
  106. }
  107. void usb_keyboard_del_code(uint8_t code)
  108. {
  109. if (IS_MOD(code)) {
  110. usb_keyboard_del_mod(code);
  111. } else {
  112. usb_keyboard_del_key(code);
  113. }
  114. }
  115. void usb_keyboard_del_key(uint8_t code)
  116. {
  117. for (int i = 0; i < 6; i++) {
  118. if (usb_keyboard_report->keys[i] == code) {
  119. usb_keyboard_report->keys[i] = KB_NO;
  120. return;
  121. }
  122. }
  123. }
  124. void usb_keyboard_del_mod(uint8_t code)
  125. {
  126. usb_keyboard_report->mods &= ~MOD_BIT(code);
  127. }
  128. bool usb_keyboard_is_sent(void)
  129. {
  130. return usb_keyboard_report->is_sent;
  131. }
  132. bool usb_keyboard_has_key(void)
  133. {
  134. uint8_t keys = 0;
  135. for (int i = 0; i < 6; i++) keys |= usb_keyboard_report->keys[i];
  136. return keys ? true : false;
  137. }
  138. bool usb_keyboard_has_mod(void)
  139. {
  140. return usb_keyboard_report->mods ? true : false;
  141. }
  142. void usb_keyboard_print_report(usb_keyboard_report_t *report)
  143. {
  144. if (!debug_keyboard) return;
  145. print("keys: ");
  146. for (int i = 0; i < 6; i++) { phex(report->keys[i]); print(" "); }
  147. print(" mods: "); phex(report->mods); print("\n");
  148. }