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.

matrix.c 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. Copyright 2011 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 <stdbool.h>
  16. #include <avr/io.h>
  17. #include <util/delay.h>
  18. #include "print.h"
  19. #include "util.h"
  20. #include "debug.h"
  21. #include "ps2.h"
  22. #include "matrix.h"
  23. static void matrix_make(uint8_t code);
  24. static void matrix_break(uint8_t code);
  25. /*
  26. * Matrix Array usage:
  27. * 'Scan Code Set 3' is assigned into 17x8 cell matrix.
  28. *
  29. * 8bit wide
  30. * +---------+
  31. * 0| |
  32. * :| | 0x00-0x87
  33. * ;| |
  34. * 17| |
  35. * +---------+
  36. */
  37. static uint8_t matrix[MATRIX_ROWS];
  38. #define ROW(code) (code>>3)
  39. #define COL(code) (code&0x07)
  40. void matrix_init(void)
  41. {
  42. debug_enable = true;
  43. //debug_matrix = true;
  44. //debug_keyboard = true;
  45. //debug_mouse = false;
  46. ps2_host_init();
  47. // initialize matrix state: all keys off
  48. for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
  49. return;
  50. }
  51. uint8_t matrix_scan(void)
  52. {
  53. // scan code reading states
  54. static enum {
  55. RESET,
  56. RESET_RESPONSE,
  57. KBD_ID0,
  58. KBD_ID1,
  59. CONFIG,
  60. READY,
  61. F0,
  62. } state = RESET;
  63. uint8_t code;
  64. if ((code = ps2_host_recv())) {
  65. debug("r"); debug_hex(code); debug(" ");
  66. }
  67. switch (state) {
  68. case RESET:
  69. debug("wFF ");
  70. if (ps2_host_send(0xFF) == 0xFA) {
  71. debug("[ack]\nRESET_RESPONSE: ");
  72. state = RESET_RESPONSE;
  73. }
  74. break;
  75. case RESET_RESPONSE:
  76. if (code == 0xAA) {
  77. debug("[ok]\nKBD_ID: ");
  78. state = KBD_ID0;
  79. } else if (code) {
  80. debug("err\nRESET: ");
  81. state = RESET;
  82. }
  83. break;
  84. // after reset receive keyboad ID(2 bytes)
  85. case KBD_ID0:
  86. if (code) {
  87. state = KBD_ID1;
  88. }
  89. break;
  90. case KBD_ID1:
  91. if (code) {
  92. debug("\nCONFIG: ");
  93. state = CONFIG;
  94. }
  95. break;
  96. case CONFIG:
  97. debug("wF8 ");
  98. if (ps2_host_send(0xF8) == 0xFA) {
  99. debug("[ack]\nREADY\n");
  100. state = READY;
  101. }
  102. break;
  103. case READY:
  104. switch (code) {
  105. case 0x00:
  106. break;
  107. case 0xF0:
  108. state = F0;
  109. debug(" ");
  110. break;
  111. default: // normal key make
  112. if (code < 0x88) {
  113. matrix_make(code);
  114. } else {
  115. debug("unexpected scan code at READY: "); debug_hex(code); debug("\n");
  116. }
  117. state = READY;
  118. debug("\n");
  119. }
  120. break;
  121. case F0: // Break code
  122. switch (code) {
  123. case 0x00:
  124. break;
  125. default:
  126. if (code < 0x88) {
  127. matrix_break(code);
  128. } else {
  129. debug("unexpected scan code at F0: "); debug_hex(code); debug("\n");
  130. }
  131. state = READY;
  132. debug("\n");
  133. }
  134. break;
  135. }
  136. return 1;
  137. }
  138. inline
  139. uint8_t matrix_get_row(uint8_t row)
  140. {
  141. return matrix[row];
  142. }
  143. inline
  144. static void matrix_make(uint8_t code)
  145. {
  146. if (!matrix_is_on(ROW(code), COL(code))) {
  147. matrix[ROW(code)] |= 1<<COL(code);
  148. }
  149. }
  150. inline
  151. static void matrix_break(uint8_t code)
  152. {
  153. if (matrix_is_on(ROW(code), COL(code))) {
  154. matrix[ROW(code)] &= ~(1<<COL(code));
  155. }
  156. }