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.

пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
пре 13 година
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #include "util.h"
  8. #include "host.h"
  9. // protocol setting from the host. We use exactly the same report
  10. // either way, so this variable only stores the setting since we
  11. // are required to be able to report which setting is in use.
  12. uint8_t usb_keyboard_protocol=1;
  13. // the idle configuration, how often we send the report to the
  14. // host (ms * 4) even when it hasn't changed
  15. // Windows and Linux set 0 while OS X sets 6(24ms) by SET_IDLE request.
  16. uint8_t usb_keyboard_idle_config=125;
  17. // count until idle timeout
  18. uint8_t usb_keyboard_idle_count=0;
  19. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  20. volatile uint8_t usb_keyboard_leds=0;
  21. static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end);
  22. int8_t usb_keyboard_send_report(report_keyboard_t *report)
  23. {
  24. int8_t result = 0;
  25. #ifdef USB_NKRO_ENABLE
  26. if (keyboard_nkro)
  27. result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
  28. else
  29. #endif
  30. {
  31. if (usb_keyboard_protocol)
  32. result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
  33. else
  34. result = send_report(report, KBD_ENDPOINT, 0, 6);
  35. }
  36. if (result) return result;
  37. usb_keyboard_idle_count = 0;
  38. usb_keyboard_print_report(report);
  39. return 0;
  40. }
  41. void usb_keyboard_print_report(report_keyboard_t *report)
  42. {
  43. if (!debug_keyboard) return;
  44. print("keys: ");
  45. for (int i = 0; i < REPORT_KEYS; i++) { phex(report->keys[i]); print(" "); }
  46. print(" mods: "); phex(report->mods); print("\n");
  47. }
  48. static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end)
  49. {
  50. uint8_t intr_state, timeout;
  51. if (!usb_configured()) return -1;
  52. intr_state = SREG;
  53. cli();
  54. UENUM = endpoint;
  55. timeout = UDFNUML + 50;
  56. while (1) {
  57. // are we ready to transmit?
  58. if (UEINTX & (1<<RWAL)) break;
  59. SREG = intr_state;
  60. // has the USB gone offline?
  61. if (!usb_configured()) return -1;
  62. // have we waited too long?
  63. if (UDFNUML == timeout) return -1;
  64. // get ready to try checking again
  65. intr_state = SREG;
  66. cli();
  67. UENUM = endpoint;
  68. }
  69. UEDATX = report->mods;
  70. #ifdef USB_NKRO_ENABLE
  71. if (!keyboard_nkro)
  72. UEDATX = 0;
  73. #else
  74. UEDATX = 0;
  75. #endif
  76. for (uint8_t i = keys_start; i < keys_end; i++) {
  77. UEDATX = report->keys[i];
  78. }
  79. UEINTX = 0x3A;
  80. SREG = intr_state;
  81. return 0;
  82. }