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 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. Copyright 2014 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 "action.h"
  19. #include "print.h"
  20. #include "debug.h"
  21. #include "util.h"
  22. #include "ibm4704.h"
  23. #include "matrix.h"
  24. static void matrix_make(uint8_t code);
  25. static void matrix_break(uint8_t code);
  26. /*
  27. * Matrix Array usage:
  28. * IBM 4704 scan codes are assigned into 128(16x8)-cell matrix.
  29. *
  30. * 8bit wide
  31. * +---------+
  32. * 0| |
  33. * :| XX | 00-7F
  34. * f| |
  35. * +---------+
  36. *
  37. * Exceptions:
  38. */
  39. static uint8_t matrix[MATRIX_ROWS];
  40. // scan code bits 7654 3210
  41. // R:row/C:column -RRR RCCC
  42. #define ROW(code) ((code>>3)&0x0f)
  43. #define COL(code) (code&0x07)
  44. static void enable_break(void)
  45. {
  46. print("Enable break: ");
  47. while (ibm4704_send(0xFC)) { _delay_ms(10); }
  48. // valid scancode: 00-79h
  49. for (uint8_t code = 0; code < 0x7F; code++) {
  50. while (ibm4704_send(0x80|code)) _delay_ms(10);
  51. _delay_ms(5); // wait for response
  52. // No response(FF) when ok, FD when out of bound
  53. xprintf("s%02X:r%02X ", code, ibm4704_recv());
  54. }
  55. while (ibm4704_send(0xFF)) { _delay_ms(10); } // End
  56. print("End\n");
  57. }
  58. void matrix_setup(void)
  59. {
  60. ibm4704_init();
  61. }
  62. void matrix_init(void)
  63. {
  64. debug_enable = true;
  65. print("IBM 4704 converter\n");
  66. matrix_clear();
  67. _delay_ms(2000); // wait for keyboard starting up
  68. xprintf("Keyboard ID: %02X\n", ibm4704_recv());
  69. enable_break();
  70. }
  71. /*
  72. * IBM 4704 Scan Code
  73. */
  74. uint8_t matrix_scan(void)
  75. {
  76. uint8_t code = ibm4704_recv();
  77. if (code==0xFF) {
  78. // Not receivd
  79. return 0;
  80. } else if ((code&0x7F) >= 0x7C) {
  81. // 0xFF-FC and 0x7F-7C is not scancode
  82. xprintf("Error: %02X\n", code);
  83. matrix_clear();
  84. return 0;
  85. } else if (code&0x80) {
  86. dprintf("%02X\n", code);
  87. matrix_make(code);
  88. } else {
  89. dprintf("%02X\n", code);
  90. matrix_break(code);
  91. }
  92. return 1;
  93. }
  94. inline
  95. uint8_t matrix_get_row(uint8_t row)
  96. {
  97. return matrix[row];
  98. }
  99. inline
  100. static void matrix_make(uint8_t code)
  101. {
  102. matrix[ROW(code)] |= 1<<COL(code);
  103. }
  104. inline
  105. static void matrix_break(uint8_t code)
  106. {
  107. matrix[ROW(code)] &= ~(1<<COL(code));
  108. }
  109. void matrix_clear(void)
  110. {
  111. for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
  112. }