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 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. uint8_t usb_keyboard_idle_config=125;
  16. // count until idle timeout
  17. uint8_t usb_keyboard_idle_count=0;
  18. // 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
  19. volatile uint8_t usb_keyboard_leds=0;
  20. static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end);
  21. int8_t usb_keyboard_send_report(report_keyboard_t *report)
  22. {
  23. int8_t result = 0;
  24. #ifdef USB_NKRO_ENABLE
  25. if (keyboard_nkro)
  26. result = send_report(report, KBD2_ENDPOINT, 0, KBD2_REPORT_KEYS);
  27. else
  28. #endif
  29. {
  30. if (usb_keyboard_protocol)
  31. result = send_report(report, KBD_ENDPOINT, 0, KBD_REPORT_KEYS);
  32. else
  33. result = send_report(report, KBD_ENDPOINT, 0, 6);
  34. }
  35. if (result) return result;
  36. usb_keyboard_idle_count = 0;
  37. usb_keyboard_print_report(report);
  38. return 0;
  39. }
  40. void usb_keyboard_print_report(report_keyboard_t *report)
  41. {
  42. if (!debug_keyboard) return;
  43. print("keys: ");
  44. for (int i = 0; i < REPORT_KEYS; i++) { phex(report->keys[i]); print(" "); }
  45. print(" mods: "); phex(report->mods); print("\n");
  46. }
  47. static inline int8_t send_report(report_keyboard_t *report, uint8_t endpoint, uint8_t keys_start, uint8_t keys_end)
  48. {
  49. uint8_t intr_state, timeout;
  50. if (!usb_configured()) return -1;
  51. intr_state = SREG;
  52. cli();
  53. UENUM = endpoint;
  54. timeout = UDFNUML + 50;
  55. while (1) {
  56. // are we ready to transmit?
  57. if (UEINTX & (1<<RWAL)) break;
  58. SREG = intr_state;
  59. // has the USB gone offline?
  60. if (!usb_configured()) return -1;
  61. // have we waited too long?
  62. if (UDFNUML == timeout) return -1;
  63. // get ready to try checking again
  64. intr_state = SREG;
  65. cli();
  66. UENUM = endpoint;
  67. }
  68. UEDATX = report->mods;
  69. #ifdef USB_NKRO_ENABLE
  70. if (!keyboard_nkro)
  71. UEDATX = 0;
  72. #else
  73. UEDATX = 0;
  74. #endif
  75. for (uint8_t i = keys_start; i < keys_end; i++) {
  76. UEDATX = report->keys[i];
  77. }
  78. UEINTX = 0x3A;
  79. SREG = intr_state;
  80. return 0;
  81. }