matrix.c (5283B)
1 /* 2 Copyright 2012 Jun Wako 3 Copyright 2014 Jack Humbert 4 Copyright 2019 @filoxo 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 #include <stdint.h> 20 #include <stdbool.h> 21 #if defined(__AVR__) 22 #include <avr/io.h> 23 #endif 24 #include "wait.h" 25 #include "print.h" 26 #include "debug.h" 27 #include "util.h" 28 #include "matrix.h" 29 #include "timer.h" 30 #include "honeycomb.h" 31 #include "pointing_device.h" 32 #include "report.h" 33 #include "uart.h" 34 35 #if (MATRIX_COLS <= 8) 36 # define print_matrix_header() print("\nr/c 01234567\n") 37 # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) 38 # define ROW_SHIFTER ((uint8_t)1) 39 #elif (MATRIX_COLS <= 16) 40 # define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") 41 # define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) 42 # define ROW_SHIFTER ((uint16_t)1) 43 #elif (MATRIX_COLS <= 32) 44 # define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") 45 # define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) 46 # define ROW_SHIFTER ((uint32_t)1) 47 #endif 48 49 #define UART_MATRIX_RESPONSE_TIMEOUT 10000 50 51 /* matrix state(1:on, 0:off) */ 52 static matrix_row_t matrix[MATRIX_ROWS]; 53 //extern int8_t encoderValue; 54 int8_t encoderValue = 0; 55 56 __attribute__ ((weak)) 57 void matrix_init_kb(void) { 58 matrix_init_user(); 59 } 60 61 __attribute__ ((weak)) 62 void matrix_scan_kb(void) { 63 matrix_scan_user(); 64 } 65 66 __attribute__ ((weak)) 67 void matrix_init_user(void) { 68 } 69 70 __attribute__ ((weak)) 71 void matrix_scan_user(void) { 72 } 73 74 inline 75 uint8_t matrix_rows(void) { 76 return MATRIX_ROWS; 77 } 78 79 inline 80 uint8_t matrix_cols(void) { 81 return MATRIX_COLS; 82 } 83 84 void matrix_init(void) { 85 86 matrix_init_kb(); 87 uart_init(1000000); 88 } 89 90 uint8_t matrix_scan(void) 91 { 92 uint32_t timeout = 0; 93 94 // The 's' character requests the RF slave to send the matrix 95 uart_write('s'); 96 97 // Trust the external keystates entirely, erase the last data 98 uint8_t uart_data[4] = {0}; 99 100 // There are 3 bytes corresponding to the data, and a checksum 101 for (uint8_t i = 0; i < 4; i++) { 102 // Wait for the serial data, timeout if it's been too long 103 // This only happened in testing with a loose wire, but does no 104 // harm to leave it in here 105 while(!uart_available()){ 106 timeout++; 107 if (timeout > UART_MATRIX_RESPONSE_TIMEOUT) { 108 break; 109 } 110 } 111 112 if (timeout < UART_MATRIX_RESPONSE_TIMEOUT) { 113 uart_data[i] = uart_read(); 114 } else { 115 uart_data[i] = 0x00; 116 } 117 } 118 119 // Check for the end packet, it's our checksum. 120 // Will only be a match if the correct bytes were recieved 121 if (uart_data[3] == (uart_data[0] ^ uart_data[1] ^ uart_data[2])) { // This is an arbitrary checksum calculated by XORing all the data. 122 // Transferring the keystates to the QMK matrix variable 123 /* ASSUMING MSB FIRST */ 124 matrix[0] = ((uint16_t) uart_data[0] << 8) | ((uint16_t) uart_data[1]); 125 encoderValue += (int8_t) uart_data[2]; 126 if ((uart_data[0] | uart_data[1] | uart_data[2])!=0){ 127 xprintf("\r\n0x%0X%02X%02X",uart_data[0],uart_data[1], uart_data[2]); 128 } 129 /* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */ 130 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 131 // I've unpacked these into the mirror image of what QMK expects them to be, so... 132 matrix[i] = bitrev16(matrix[i]); 133 // So I'll reverse it, and this should be fine now. 134 } 135 136 // A mouse report for scrolling would go here, but I don't plan on doing scrolling with the encoder. So. 137 138 report_mouse_t currentReport = {}; 139 /* 140 currentReport = pointing_device_get_report(); 141 //mouseReport.x = 127 max -127 min 142 currentReport.x = (int8_t) uart_data[6]; 143 //mouseReport.y = 127 max -127 min 144 currentReport.y = (int8_t) uart_data[7]; 145 //mouseReport.v = 127 max -127 min (scroll vertical) 146 currentReport.v = (int8_t) uart_data[8]; 147 //mouseReport.h = 127 max -127 min (scroll horizontal) 148 currentReport.h = (int8_t) uart_data[9]; 149 */ 150 /* 151 currentReport.x = 0; 152 currentReport.y = 0; 153 currentReport.v = 0; 154 currentReport.h = 0;*/ 155 156 pointing_device_set_report(currentReport); 157 } else { 158 xprintf("\r\nRequested packet, data 3 was %d",uart_data[3]); 159 } 160 161 matrix_scan_kb(); 162 return 1; 163 } 164 165 inline 166 bool matrix_is_on(uint8_t row, uint8_t col) 167 { 168 return (matrix[row] & ((matrix_row_t)1<col)); 169 } 170 171 inline 172 matrix_row_t matrix_get_row(uint8_t row) 173 { 174 return matrix[row]; 175 } 176 177 void matrix_print(void) 178 { 179 print_matrix_header(); 180 181 for (uint8_t row = 0; row < MATRIX_ROWS; row++) { 182 print_hex8(row); print(": "); 183 print_matrix_row(row); 184 print("\n"); 185 } 186 }