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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* Copyright 2012 Jun Wako <[email protected]>
  2. *
  3. * This is heavily based on hid_liber/board.{c|h}.
  4. * https://github.com/BathroomEpiphanies/AVR-Keyboard
  5. *
  6. * Copyright (c) 2012 Fredrik Atmer, Bathroom Epiphanies Inc
  7. * http://bathroomepiphanies.com
  8. *
  9. * As for liscensing consult with the original files or its author.
  10. */
  11. #include <stdint.h>
  12. #include <stdbool.h>
  13. #include <avr/io.h>
  14. #include <util/delay.h>
  15. #include "print.h"
  16. #include "debug.h"
  17. #include "util.h"
  18. #include "matrix.h"
  19. #ifndef DEBOUNCE
  20. # define DEBOUNCE 0
  21. #endif
  22. static uint8_t debouncing = DEBOUNCE;
  23. // bit array of key state(1:on, 0:off)
  24. static matrix_row_t matrix[MATRIX_ROWS];
  25. static matrix_row_t matrix_debouncing[MATRIX_ROWS];
  26. #define _DDRA (uint8_t *const)&DDRA
  27. #define _DDRB (uint8_t *const)&DDRB
  28. #define _DDRC (uint8_t *const)&DDRC
  29. #define _DDRD (uint8_t *const)&DDRD
  30. #define _DDRE (uint8_t *const)&DDRE
  31. #define _DDRF (uint8_t *const)&DDRF
  32. #define _PINA (uint8_t *const)&PINA
  33. #define _PINB (uint8_t *const)&PINB
  34. #define _PINC (uint8_t *const)&PINC
  35. #define _PIND (uint8_t *const)&PIND
  36. #define _PINE (uint8_t *const)&PINE
  37. #define _PINF (uint8_t *const)&PINF
  38. #define _PORTA (uint8_t *const)&PORTA
  39. #define _PORTB (uint8_t *const)&PORTB
  40. #define _PORTC (uint8_t *const)&PORTC
  41. #define _PORTD (uint8_t *const)&PORTD
  42. #define _PORTE (uint8_t *const)&PORTE
  43. #define _PORTF (uint8_t *const)&PORTF
  44. #define _BIT0 0x01
  45. #define _BIT1 0x02
  46. #define _BIT2 0x04
  47. #define _BIT3 0x08
  48. #define _BIT4 0x10
  49. #define _BIT5 0x20
  50. #define _BIT6 0x40
  51. #define _BIT7 0x80
  52. /* Specifies the ports and pin numbers for the rows */
  53. static
  54. uint8_t *const row_ddr[MATRIX_ROWS] = {
  55. _DDRB, _DDRB,
  56. _DDRC, _DDRC,
  57. _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD, _DDRD,
  58. _DDRF, _DDRF, _DDRF, _DDRF, _DDRF, _DDRF};
  59. static
  60. uint8_t *const row_port[MATRIX_ROWS] = {
  61. _PORTB, _PORTB,
  62. _PORTC, _PORTC,
  63. _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD, _PORTD,
  64. _PORTF, _PORTF, _PORTF, _PORTF, _PORTF, _PORTF};
  65. static
  66. uint8_t *const row_pin[MATRIX_ROWS] = {
  67. _PINB, _PINB,
  68. _PINC, _PINC,
  69. _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND, _PIND,
  70. _PINF, _PINF, _PINF, _PINF, _PINF, _PINF};
  71. static
  72. const uint8_t row_bit[MATRIX_ROWS] = {
  73. _BIT4, _BIT7,
  74. _BIT6, _BIT7,
  75. _BIT0, _BIT1, _BIT2, _BIT3, _BIT4, _BIT5, _BIT6, _BIT7,
  76. _BIT0, _BIT1, _BIT4, _BIT5, _BIT6, _BIT7};
  77. static
  78. const uint8_t mask = 0x0E;
  79. /* Specifies the ports and pin numbers for the columns */
  80. static
  81. const uint8_t col_bit[MATRIX_COLS] = { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E};
  82. static
  83. inline void pull_column(int col) {
  84. PORTB = col_bit[col] | (PORTB & ~mask);
  85. }
  86. static
  87. inline void release_column(int col) {
  88. }
  89. /* PORTB is set as input with pull-up resistors
  90. PORTC,D,E,F are set to high output */
  91. static
  92. void setup_io_pins(void) {
  93. uint8_t row;
  94. DDRB |= 0x0E;
  95. PORTB &= ~0x0E;
  96. for(row = 0; row < MATRIX_ROWS; row++) {
  97. *row_ddr[row] &= ~row_bit[row];
  98. *row_port[row] &= ~row_bit[row];
  99. }
  100. }
  101. static
  102. void setup_leds(void) {
  103. DDRB |= 0x60;
  104. PORTB |= 0x60;
  105. }
  106. inline
  107. uint8_t matrix_rows(void)
  108. {
  109. return MATRIX_ROWS;
  110. }
  111. inline
  112. uint8_t matrix_cols(void)
  113. {
  114. return MATRIX_COLS;
  115. }
  116. void matrix_init(void)
  117. {
  118. // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
  119. MCUCR |= (1<<JTD);
  120. MCUCR |= (1<<JTD);
  121. // initialize row and col
  122. setup_io_pins();
  123. setup_leds();
  124. // initialize matrix state: all keys off
  125. for (uint8_t i=0; i < MATRIX_ROWS; i++) {
  126. matrix[i] = 0;
  127. matrix_debouncing[i] = 0;
  128. }
  129. }
  130. uint8_t matrix_scan(void)
  131. {
  132. for (uint8_t col = 0; col < MATRIX_COLS; col++) { // 0-7
  133. pull_column(col); // output hi on theline
  134. _delay_us(5); // without this wait it won't read stable value.
  135. for (uint8_t row = 0; row < MATRIX_ROWS; row++) { // 0-17
  136. bool prev_bit = matrix_debouncing[row] & (1<<col);
  137. bool curr_bit = *row_pin[row] & row_bit[row];
  138. if (prev_bit != curr_bit) {
  139. matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
  140. if (debouncing) {
  141. dprintf("bounce!: %02X\n", debouncing);
  142. }
  143. debouncing = DEBOUNCE;
  144. }
  145. }
  146. release_column(col);
  147. }
  148. if (debouncing) {
  149. if (--debouncing) {
  150. _delay_ms(1);
  151. } else {
  152. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  153. matrix[i] = matrix_debouncing[i];
  154. }
  155. }
  156. }
  157. return 1;
  158. }
  159. bool matrix_is_modified(void)
  160. {
  161. // NOTE: no longer used
  162. return true;
  163. }
  164. inline
  165. bool matrix_has_ghost(void)
  166. {
  167. return false;
  168. }
  169. inline
  170. bool matrix_is_on(uint8_t row, uint8_t col)
  171. {
  172. return (matrix[row] & ((matrix_row_t)1<<col));
  173. }
  174. inline
  175. matrix_row_t matrix_get_row(uint8_t row)
  176. {
  177. return matrix[row];
  178. }
  179. void matrix_print(void)
  180. {
  181. print("\nr/c 01234567\n");
  182. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  183. phex(row); print(": ");
  184. pbin_reverse(matrix_get_row(row));
  185. print("\n");
  186. }
  187. }
  188. uint8_t matrix_key_count(void)
  189. {
  190. uint8_t count = 0;
  191. for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
  192. for (uint8_t j = 0; j < MATRIX_COLS; j++) {
  193. if (matrix_is_on(i, j))
  194. count++;
  195. }
  196. }
  197. return count;
  198. }