qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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 }