logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

matrix.c (3215B)


  1. /* Copyright 2017-2019 Nikolaus Wittenstein <nikolaus.wittenstein@gmail.com>
  2. *
  3. * Permission to use, copy, modify, and/or distribute this software for any
  4. * purpose with or without fee is hereby granted, provided that the above
  5. * copyright notice and this permission notice appear in all copies.
  6. *
  7. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  8. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  9. * FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  12. * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. * PERFORMANCE OF THIS SOFTWARE.
  14. */
  15. #include "datahand.h"
  16. #include "matrix.h"
  17. #include "action.h"
  18. #include <stdint.h>
  19. #include <stdbool.h>
  20. #include <avr/io.h>
  21. static matrix_row_t matrix[MATRIX_ROWS];
  22. static matrix_row_t read_cols(void);
  23. static void select_row(uint8_t row);
  24. // user-defined overridable functions
  25. __attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
  26. __attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
  27. __attribute__((weak)) void matrix_init_user(void) {}
  28. __attribute__((weak)) void matrix_scan_user(void) {}
  29. // helper functions
  30. void matrix_init(void) {
  31. /* See datahand.h for more detail on pins. */
  32. /* 7 - matrix scan; 6-3 - mode LEDs */
  33. DDRB = 0b11111000;
  34. /* 1-0 - matrix scan */
  35. DDRD = 0b00000011;
  36. /* 6 - matrix scan */
  37. DDRE = 0b01000000;
  38. /* 7-4 - lock LEDs */
  39. DDRF = 0b11110000;
  40. /* Turn off the non-Normal LEDs (they're active low). */
  41. PORTB |= LED_TENKEY | LED_FN | LED_NAS;
  42. /* Turn off the lock LEDs. */
  43. PORTF |= LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_MOUSE_LOCK;
  44. matrix_init_kb();
  45. }
  46. uint8_t matrix_scan(void) {
  47. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  48. select_row(row);
  49. /* The default hardware works down to at least 100us, but I have a replacement
  50. * photodiode that responds a little more slowly. Cranking it up to 1000us fixes
  51. * shadowing issues.
  52. */
  53. _delay_us(1000);
  54. matrix[row] = read_cols();
  55. }
  56. matrix_scan_kb();
  57. return 1;
  58. }
  59. matrix_row_t matrix_get_row(uint8_t row) {
  60. return matrix[row];
  61. }
  62. void matrix_print(void) {
  63. print("\nr/c 01234567\n");
  64. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  65. print_hex8(row);
  66. print(": ");
  67. print_bin_reverse8(matrix_get_row(row));
  68. print("\n");
  69. }
  70. }
  71. static void select_row(uint8_t row) {
  72. /* Original 8051: P1 bits 0-3 (pins 1-4)
  73. * Teensy++: PE0, PB7, PD0, PD1
  74. */
  75. if (row & (1<<0)) {
  76. gpio_write_pin_high(E6);
  77. } else {
  78. gpio_write_pin_low(E6);
  79. }
  80. if (row & (1<<1)) {
  81. gpio_write_pin_high(B7);
  82. } else {
  83. gpio_write_pin_low(B7);
  84. }
  85. if (row & (1<<2)) {
  86. gpio_write_pin_high(D0);
  87. } else {
  88. gpio_write_pin_low(D0);
  89. }
  90. if (row & (1<<3)) {
  91. gpio_write_pin_high(D1);
  92. } else {
  93. gpio_write_pin_low(D1);
  94. }
  95. }
  96. static matrix_row_t read_cols(void) {
  97. /* Original 8051: P1 bits 4-7 (pins 5-8)
  98. * Teensy++: PD bits 2-5
  99. */
  100. return (PIND & 0b00111100) >> 2;
  101. }