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

11 лет назад
11 лет назад
13 лет назад
13 лет назад
13 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
13 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. Copyright 2011,2012,2013 Jun Wako <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include <stdint.h>
  15. #include <util/delay.h>
  16. #include "keyboard.h"
  17. #include "matrix.h"
  18. #include "keymap.h"
  19. #include "host.h"
  20. #include "led.h"
  21. #include "keycode.h"
  22. #include "timer.h"
  23. #include "print.h"
  24. #include "debug.h"
  25. #include "command.h"
  26. #include "util.h"
  27. #include "sendchar.h"
  28. #include "bootmagic.h"
  29. #include "eeconfig.h"
  30. #include "mousekey.h"
  31. #ifdef MATRIX_HAS_GHOST
  32. static bool has_ghost_in_row(uint8_t row)
  33. {
  34. matrix_row_t matrix_row = matrix_get_row(row);
  35. // No ghost exists when less than 2 keys are down on the row
  36. if (((matrix_row - 1) & matrix_row) == 0)
  37. return false;
  38. // Ghost occurs when the row shares column line with other row
  39. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  40. if (i != row && (matrix_get_row(i) & matrix_row))
  41. return true;
  42. }
  43. return false;
  44. }
  45. #endif
  46. void keyboard_init(void)
  47. {
  48. // TODO: configuration of sendchar impl
  49. print_sendchar_func = sendchar;
  50. timer_init();
  51. matrix_init();
  52. #ifdef PS2_MOUSE_ENABLE
  53. ps2_mouse_init();
  54. #endif
  55. #ifdef BOOTMAGIC_ENABLE
  56. bootmagic();
  57. if (eeconfig_is_enabled()) {
  58. uint8_t config;
  59. config = eeconfig_read_debug();
  60. // ignored if debug is enabled by program before.
  61. if (!debug_enable) debug_enable = (config & EECONFIG_DEBUG_ENABLE);
  62. if (!debug_matrix) debug_matrix = (config & EECONFIG_DEBUG_MATRIX);
  63. if (!debug_keyboard) debug_keyboard = (config & EECONFIG_DEBUG_KEYBOARD);
  64. if (!debug_mouse) debug_mouse = (config & EECONFIG_DEBUG_MOUSE);
  65. } else {
  66. eeconfig_init();
  67. }
  68. #endif
  69. }
  70. /*
  71. * Do keyboard routine jobs: scan mantrix, light LEDs, ...
  72. * This is repeatedly called as fast as possible.
  73. */
  74. void keyboard_task(void)
  75. {
  76. static matrix_row_t matrix_prev[MATRIX_ROWS];
  77. static uint8_t led_status = 0;
  78. matrix_row_t matrix_row = 0;
  79. matrix_row_t matrix_change = 0;
  80. matrix_scan();
  81. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  82. matrix_row = matrix_get_row(r);
  83. matrix_change = matrix_row ^ matrix_prev[r];
  84. if (matrix_change) {
  85. if (debug_matrix) matrix_print();
  86. #ifdef MATRIX_HAS_GHOST
  87. if (has_ghost_in_row(r)) {
  88. matrix_prev[r] = matrix_row;
  89. continue;
  90. }
  91. #endif
  92. for (uint8_t c = 0; c < MATRIX_COLS; c++) {
  93. if (matrix_change & ((matrix_row_t)1<<c)) {
  94. action_exec((keyevent_t){
  95. .key = (key_t){ .row = r, .col = c },
  96. .pressed = (matrix_row & ((matrix_row_t)1<<c)),
  97. .time = (timer_read() | 1) /* time should not be 0 */
  98. });
  99. // record a processed key
  100. matrix_prev[r] ^= ((matrix_row_t)1<<c);
  101. // process a key per task call
  102. goto MATRIX_LOOP_END;
  103. }
  104. }
  105. }
  106. }
  107. // call with pseudo tick event when no real key event.
  108. action_exec(TICK);
  109. MATRIX_LOOP_END:
  110. #ifdef MOUSEKEY_ENABLE
  111. // mousekey repeat & acceleration
  112. mousekey_task();
  113. #endif
  114. // update LED
  115. if (led_status != host_keyboard_leds()) {
  116. led_status = host_keyboard_leds();
  117. keyboard_set_leds(led_status);
  118. }
  119. }
  120. void keyboard_set_leds(uint8_t leds)
  121. {
  122. led_set(leds);
  123. }