Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
Это архивный репозиторий. Вы можете его клонировать или просматривать файлы, но не вносить изменения или открывать задачи/запросы на слияние.

11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
11 лет назад
10 лет назад
11 лет назад
10 лет назад
11 лет назад
10 лет назад
11 лет назад
10 лет назад
11 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /*
  2. Copyright 2012 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. /*
  15. * scan matrix
  16. */
  17. #include <stdint.h>
  18. #include <stdbool.h>
  19. #include <avr/io.h>
  20. #include <util/delay.h>
  21. #include "print.h"
  22. #include "debug.h"
  23. #include "util.h"
  24. #include "matrix.h"
  25. #ifdef PS2_MOUSE_ENABLE
  26. #include "ps2.h"
  27. #endif
  28. #ifndef DEBOUNCE
  29. # define DEBOUNCE 5
  30. #endif
  31. static uint8_t debouncing = DEBOUNCE;
  32. /* matrix state(1:on, 0:off) */
  33. static matrix_row_t matrix[MATRIX_ROWS];
  34. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  35. static matrix_row_t read_cols(void);
  36. static void init_cols(void);
  37. static void unselect_rows(void);
  38. static void select_row(uint8_t row);
  39. #ifdef PS2_MOUSE_ENABLE
  40. static uint8_t ps2_mouse_detected;
  41. uint8_t ps2_enabled(void)
  42. {
  43. return ps2_mouse_detected;
  44. }
  45. #endif
  46. inline
  47. uint8_t matrix_rows(void)
  48. {
  49. return MATRIX_ROWS;
  50. }
  51. inline
  52. uint8_t matrix_cols(void)
  53. {
  54. return MATRIX_COLS;
  55. }
  56. void matrix_init(void)
  57. {
  58. // disable JTAG
  59. MCUCR = (1<<JTD);
  60. MCUCR = (1<<JTD);
  61. #ifdef PS2_MOUSE_ENABLE
  62. // ps2 mouse detect
  63. DDRF &= ~(1<<PF5 | 1<<PF4);
  64. PORTF |= (1<<PF5 | 1<<PF4);
  65. if (PINF & (1<<PF5 | 1 <<PF4)) {
  66. ps2_mouse_detected = 0;
  67. }
  68. else {
  69. ps2_mouse_detected = 1;
  70. }
  71. DDRF |= (1<<PF5 | 1<<PF4);
  72. #endif
  73. // initialize row and col
  74. unselect_rows();
  75. init_cols();
  76. // initialize matrix state: all keys off
  77. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  78. matrix[i] = 0;
  79. matrix_debouncing[i] = 0;
  80. }
  81. }
  82. uint8_t matrix_scan(void)
  83. {
  84. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  85. select_row(i);
  86. #ifdef HYBRID_MATRIX
  87. init_cols();
  88. #endif
  89. _delay_us(30); // without this wait read unstable value.
  90. matrix_row_t cols = read_cols();
  91. if (matrix_debouncing[i] != cols) {
  92. matrix_debouncing[i] = cols;
  93. if (debouncing) {
  94. debug("bounce!: "); debug_hex(debouncing); debug("\n");
  95. }
  96. debouncing = DEBOUNCE;
  97. }
  98. unselect_rows();
  99. }
  100. if (debouncing) {
  101. if (--debouncing) {
  102. _delay_ms(1);
  103. } else {
  104. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  105. matrix[i] = matrix_debouncing[i];
  106. }
  107. }
  108. }
  109. return 1;
  110. }
  111. bool matrix_is_modified(void)
  112. {
  113. if (debouncing) return false;
  114. return true;
  115. }
  116. inline
  117. bool matrix_is_on(uint8_t row, uint8_t col)
  118. {
  119. return (matrix[row] & ((matrix_row_t)1<<col));
  120. }
  121. inline
  122. matrix_row_t matrix_get_row(uint8_t row)
  123. {
  124. return matrix[row];
  125. }
  126. void matrix_print(void)
  127. {
  128. print("\nr/c 0123456789ABCDEF\n");
  129. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  130. phex(row); print(": ");
  131. pbin_reverse16(matrix_get_row(row));
  132. print("\n");
  133. }
  134. }
  135. uint8_t matrix_key_count(void)
  136. {
  137. uint8_t count = 0;
  138. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  139. count += bitpop16(matrix[i]);
  140. }
  141. return count;
  142. }
  143. /* Column pin configuration
  144. * pin: F1 F0 E6 D7 D6 D4 C7 C6 B6 B5 B4 B3 B1 B0 (Rev.A)
  145. * pin: F1 F0 E6 D7 D6 D4 C7 C6 B7 B6 B5 B4 B3 B1 (Rev.B)
  146. * pin: F1 F0 E6 D7 D6 D4 C7 C6 B7 B5 B4 B3 B1 B0 (Rev.CHN/CNY)
  147. */
  148. static void init_cols(void)
  149. {
  150. // Input with pull-up(DDR:0, PORT:1)
  151. DDRF &= ~(1<<PF1 | 1<<PF0);
  152. PORTF |= (1<<PF1 | 1<<PF0);
  153. DDRE &= ~(1<<PE6);
  154. PORTE |= (1<<PE6);
  155. DDRD &= ~(1<<PD7 | 1<<PD6 | 1<<PD4);
  156. PORTD |= (1<<PD7 | 1<<PD6 | 1<<PD4);
  157. DDRC &= ~(1<<PC7 | 1<<PC6);
  158. PORTC |= (1<<PC7 | 1<<PC6);
  159. #if defined(GH60_REV_CHN) || defined(GH60_REV_CNY)
  160. DDRB &= ~(1<<PB7 | 1<<PB5 | 1<<PB4 | 1<<PB3 | 1<<PB1 | 1<<PB0);
  161. PORTB |= (1<<PB7 | 1<<PB5 | 1<<PB4 | 1<<PB3 | 1<<PB1 | 1<<PB0);
  162. #else
  163. DDRB &= ~(1<<PB7 | 1<<PB6 | 1<<PB5 | 1<<PB4 | 1<<PB3 | 1<<PB1 | 1<<PB0);
  164. PORTB |= (1<<PB7 | 1<<PB6 | 1<<PB5 | 1<<PB4 | 1<<PB3 | 1<<PB1 | 1<<PB0);
  165. #endif
  166. }
  167. /* Column pin configuration
  168. * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13
  169. * pin: F0 F1 E6 C7 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A)
  170. * pin: F0 F1 E6 C7 C6 B6 D4 B1 B7 B5 B4 D7 D6 B3 (Rev.B)
  171. * pin: F0 F1 E6 C7 C6 B7 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.CHN)
  172. * pin: F0 F1 E6 C7 C6 B7 D4 B0 B1 B5 B4 D7 D6 B3 (Rev.CNY)
  173. */
  174. static matrix_row_t read_cols(void)
  175. {
  176. #if defined(GH60_REV_CHN)
  177. return (PINF&(1<<PF0) ? 0 : (1<<0)) |
  178. (PINF&(1<<PF1) ? 0 : (1<<1)) |
  179. (PINE&(1<<PE6) ? 0 : (1<<2)) |
  180. (PINC&(1<<PC7) ? 0 : (1<<3)) |
  181. (PINC&(1<<PC6) ? 0 : (1<<4)) |
  182. (PINB&(1<<PB7) ? 0 : (1<<5)) |
  183. (PIND&(1<<PD4) ? 0 : (1<<6)) |
  184. (PINB&(1<<PB1) ? 0 : (1<<7)) |
  185. (PINB&(1<<PB0) ? 0 : (1<<8)) |
  186. (PINB&(1<<PB5) ? 0 : (1<<9)) |
  187. (PINB&(1<<PB4) ? 0 : (1<<10)) |
  188. (PIND&(1<<PD7) ? 0 : (1<<11)) |
  189. (PIND&(1<<PD6) ? 0 : (1<<12)) |
  190. (PINB&(1<<PB3) ? 0 : (1<<13));
  191. #elif defined(GH60_REV_CNY)
  192. return (PINF&(1<<PF0) ? 0 : (1<<0)) |
  193. (PINF&(1<<PF1) ? 0 : (1<<1)) |
  194. (PINE&(1<<PE6) ? 0 : (1<<2)) |
  195. (PINC&(1<<PC7) ? 0 : (1<<3)) |
  196. (PINC&(1<<PC6) ? 0 : (1<<4)) |
  197. (PINB&(1<<PB7) ? 0 : (1<<5)) |
  198. (PIND&(1<<PD4) ? 0 : (1<<6)) |
  199. (PINB&(1<<PB0) ? 0 : (1<<7)) |
  200. (PINB&(1<<PB1) ? 0 : (1<<8)) |
  201. (PINB&(1<<PB5) ? 0 : (1<<9)) |
  202. (PINB&(1<<PB4) ? 0 : (1<<10)) |
  203. (PIND&(1<<PD7) ? 0 : (1<<11)) |
  204. (PIND&(1<<PD6) ? 0 : (1<<12)) |
  205. (PINB&(1<<PB3) ? 0 : (1<<13));
  206. #else
  207. return (PINF&(1<<0) ? 0 : (1<<0)) |
  208. (PINF&(1<<1) ? 0 : (1<<1)) |
  209. (PINE&(1<<6) ? 0 : (1<<2)) |
  210. (PINC&(1<<7) ? 0 : (1<<3)) |
  211. (PINC&(1<<6) ? 0 : (1<<4)) |
  212. (PINB&(1<<6) ? 0 : (1<<5)) |
  213. (PIND&(1<<4) ? 0 : (1<<6)) |
  214. (PINB&(1<<1) ? 0 : (1<<7)) |
  215. ((PINB&(1<<0) && PINB&(1<<7)) ? 0 : (1<<8)) | // Rev.A and B
  216. (PINB&(1<<5) ? 0 : (1<<9)) |
  217. (PINB&(1<<4) ? 0 : (1<<10)) |
  218. (PIND&(1<<7) ? 0 : (1<<11)) |
  219. (PIND&(1<<6) ? 0 : (1<<12)) |
  220. (PINB&(1<<3) ? 0 : (1<<13));
  221. #endif
  222. }
  223. /* Row pin configuration
  224. * row: 0 1 2 3 4
  225. * pin: D0 D1 D2 D3 D5
  226. */
  227. static void unselect_rows(void)
  228. {
  229. // Hi-Z(DDR:0, PORT:0) to unselect
  230. DDRD &= ~0b00101111;
  231. PORTD &= ~0b00101111;
  232. }
  233. static void select_row(uint8_t row)
  234. {
  235. // Output low(DDR:1, PORT:0) to select
  236. switch (row) {
  237. case 0:
  238. DDRD |= (1<<0);
  239. PORTD &= ~(1<<0);
  240. break;
  241. case 1:
  242. DDRD |= (1<<1);
  243. PORTD &= ~(1<<1);
  244. break;
  245. case 2:
  246. DDRD |= (1<<2);
  247. PORTD &= ~(1<<2);
  248. break;
  249. case 3:
  250. DDRD |= (1<<3);
  251. PORTD &= ~(1<<3);
  252. break;
  253. case 4:
  254. DDRD |= (1<<5);
  255. PORTD &= ~(1<<5);
  256. break;
  257. }
  258. }