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.

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