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 16 #include "datahand.h" 17 18 #include "matrix.h" 19 #include "action.h" 20 21 #include <stdint.h> 22 #include <stdbool.h> 23 #include <avr/io.h> 24 25 static matrix_row_t matrix[MATRIX_ROWS]; 26 27 static matrix_row_t read_cols(void); 28 static void select_row(uint8_t row); 29 30 // user-defined overridable functions 31 32 __attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } 33 34 __attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } 35 36 __attribute__((weak)) void matrix_init_user(void) {} 37 38 __attribute__((weak)) void matrix_scan_user(void) {} 39 40 // helper functions 41 void matrix_init(void) { 42 /* See datahand.h for more detail on pins. */ 43 44 /* 7 - matrix scan; 6-3 - mode LEDs */ 45 DDRB = 0b11111000; 46 47 /* 1-0 - matrix scan */ 48 DDRD = 0b00000011; 49 50 /* 6 - matrix scan */ 51 DDRE = 0b01000000; 52 53 /* 7-4 - lock LEDs */ 54 DDRF = 0b11110000; 55 56 /* Turn off the non-Normal LEDs (they're active low). */ 57 PORTB |= LED_TENKEY | LED_FN | LED_NAS; 58 59 /* Turn off the lock LEDs. */ 60 PORTF |= LED_CAPS_LOCK | LED_NUM_LOCK | LED_SCROLL_LOCK | LED_MOUSE_LOCK; 61 62 matrix_init_kb(); 63 } 64 65 uint8_t matrix_scan(void) { 66 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 67 select_row(row); 68 /* The default hardware works down to at least 100us, but I have a replacement 69 * photodiode that responds a little more slowly. Cranking it up to 1000us fixes 70 * shadowing issues. 71 */ 72 _delay_us(1000); 73 matrix[row] = read_cols(); 74 } 75 76 matrix_scan_kb(); 77 78 return 1; 79 } 80 81 matrix_row_t matrix_get_row(uint8_t row) { 82 return matrix[row]; 83 } 84 85 void matrix_print(void) { 86 print("\nr/c 01234567\n"); 87 88 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 89 print_hex8(row); 90 print(": "); 91 print_bin_reverse8(matrix_get_row(row)); 92 print("\n"); 93 } 94 } 95 96 static void select_row(uint8_t row) { 97 /* Original 8051: P1 bits 0-3 (pins 1-4) 98 * Teensy++: PE0, PB7, PD0, PD1 99 */ 100 101 if (row & (1<<0)) { 102 gpio_write_pin_high(E6); 103 } else { 104 gpio_write_pin_low(E6); 105 } 106 107 if (row & (1<<1)) { 108 gpio_write_pin_high(B7); 109 } else { 110 gpio_write_pin_low(B7); 111 } 112 113 if (row & (1<<2)) { 114 gpio_write_pin_high(D0); 115 } else { 116 gpio_write_pin_low(D0); 117 } 118 119 if (row & (1<<3)) { 120 gpio_write_pin_high(D1); 121 } else { 122 gpio_write_pin_low(D1); 123 } 124 } 125 126 static matrix_row_t read_cols(void) { 127 /* Original 8051: P1 bits 4-7 (pins 5-8) 128 * Teensy++: PD bits 2-5 129 */ 130 131 return (PIND & 0b00111100) >> 2; 132 }