qmk_firmware

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

matrix.c (4572B)


      1 /*
      2   Copyright 2017 Gabriel Young <gabeplaysdrums@live.com>
      3 
      4   This program is free software: you can redistribute it and/or modify
      5   it under the terms of the GNU General Public License as published by
      6   the Free Software Foundation, either version 2 of the License, or
      7   (at your option) any later version.
      8 
      9   This program is distributed in the hope that it will be useful,
     10   but WITHOUT ANY WARRANTY; without even the implied warranty of
     11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12   GNU General Public License for more details.
     13 
     14   You should have received a copy of the GNU General Public License
     15   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     16 */
     17 
     18 #include <stdint.h>
     19 #include <stdbool.h>
     20 #include <avr/io.h>
     21 #include <util/delay.h>
     22 #include "print.h"
     23 #include "debug.h"
     24 #include "util.h"
     25 #include "matrix.h"
     26 
     27 #ifndef DEBOUNCE
     28 #   define DEBOUNCE 5
     29 #endif
     30 static uint8_t debouncing = DEBOUNCE;
     31 
     32 static matrix_row_t matrix[MATRIX_ROWS];
     33 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
     34 
     35 __attribute__ ((weak))
     36 void matrix_init_kb(void) {
     37     matrix_init_user();
     38 }
     39 
     40 __attribute__ ((weak))
     41 void matrix_scan_kb(void) {
     42     matrix_scan_user();
     43 }
     44 
     45 __attribute__ ((weak))
     46 void matrix_init_user(void) {
     47 }
     48 
     49 __attribute__ ((weak))
     50 void matrix_scan_user(void) {
     51 }
     52 
     53 static matrix_row_t scan_col(void) {
     54     return (
     55 		(PINC&(1<<2) ? 0 : ((matrix_row_t)1<<0)) | \
     56 		(PINB&(1<<3) ? 0 : ((matrix_row_t)1<<1)) | \
     57 		(PINB&(1<<4) ? 0 : ((matrix_row_t)1<<2)) | \
     58 		(PINB&(1<<2) ? 0 : ((matrix_row_t)1<<3)) | \
     59 		(PINB&(1<<1) ? 0 : ((matrix_row_t)1<<4)) | \
     60 		(PINC&(1<<7) ? 0 : ((matrix_row_t)1<<5)) | \
     61 		(PINB&(1<<6) ? 0 : ((matrix_row_t)1<<6)) | \
     62 		(PINB&(1<<5) ? 0 : ((matrix_row_t)1<<7))
     63 	);
     64 }
     65 
     66 static void select_col(uint8_t col) {
     67     switch (col) {
     68         case  0: PORTD = (PORTD & ~0b01110111) | 0b01110110; break; \
     69 		case  1: PORTD = (PORTD & ~0b01110111) | 0b01100001; break; \
     70 		case  2: PORTD = (PORTD & ~0b01110111) | 0b01100101; break; \
     71 		case  3: PORTD = (PORTD & ~0b01110111) | 0b00000011; break; \
     72 		case  4: PORTD = (PORTD & ~0b01110111) | 0b00000111; break; \
     73 		case  5: PORTD = (PORTD & ~0b01110111) | 0b00010011; break; \
     74 		case  6: PORTD = (PORTD & ~0b01110111) | 0b00010111; break; \
     75 		case  7: PORTD = (PORTD & ~0b01110111) | 0b00100011; break; \
     76 		case  8: PORTD = (PORTD & ~0b01110111) | 0b00100111; break; \
     77 		case  9: PORTD = (PORTD & ~0b01110111) | 0b00110011; break; \
     78 		case 10: PORTD = (PORTD & ~0b01110111) | 0b01110010; break; \
     79 		case 11: PORTD = (PORTD & ~0b01110111) | 0b01100110; break; \
     80 		case 12: PORTD = (PORTD & ~0b01110111) | 0b01110000; break; \
     81 		case 13: PORTD = (PORTD & ~0b01110111) | 0b01100100; break; \
     82 		case 14: PORTD = (PORTD & ~0b01110111) | 0b01100000; break; \
     83 		case 15: PORTD = (PORTD & ~0b01110111) | 0b01000111; break; \
     84 		case 16: PORTD = (PORTD & ~0b01110111) | 0b01000011; break; \
     85 		case 17: PORTD = (PORTD & ~0b01110111) | 0b00110111; break;
     86     }
     87 }
     88 
     89 void matrix_init(void) {
     90     /* Column output pins */ \
     91 	DDRD  |=  0b01110111;    \
     92 	/* Row input pins */     \
     93 	DDRC  &= ~0b10000100;    \
     94 	DDRB  &= ~0b01111110;    \
     95 	PORTC |=  0b10000100;    \
     96 	PORTB |=  0b01111110;
     97 
     98     for (uint8_t i=0; i < MATRIX_ROWS; i++)
     99         matrix[i] = matrix_debouncing[i] = 0;
    100 
    101     matrix_init_kb();
    102 }
    103 
    104 uint8_t matrix_scan(void) {
    105     for (uint8_t col = 0; col < MATRIX_COLS; col++) {
    106         select_col(col);
    107         _delay_us(3);
    108         matrix_row_t col_scan = scan_col();
    109         for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    110             bool prev_bit = matrix_debouncing[row] & ((matrix_row_t)1<<col);
    111             bool curr_bit = col_scan & (1<<row);
    112             if (prev_bit != curr_bit) {
    113                 matrix_debouncing[row] ^= ((matrix_row_t)1<<col);
    114                 debouncing = DEBOUNCE;
    115             }
    116         }
    117     }
    118 
    119     if (debouncing) {
    120         if (--debouncing)
    121             _delay_ms(1);
    122         else
    123             for (uint8_t i = 0; i < MATRIX_ROWS; i++)
    124                 matrix[i] = matrix_debouncing[i];
    125     }
    126 
    127     matrix_scan_kb();
    128     return 1;
    129 }
    130 
    131 inline matrix_row_t matrix_get_row(uint8_t row) {
    132     return matrix[row];
    133 }
    134 
    135 void matrix_print(void) {
    136 	#ifndef NO_PRINT
    137     print("\nr\\c ABCDEFGHIJKLMNOPQR\n");
    138     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    139         matrix_row_t matrix_row = matrix_get_row(row);
    140         xprintf("%02X: ", row);
    141         for (uint8_t col = 0; col < MATRIX_COLS; col++) {
    142             bool curr_bit = matrix_row & (1<<col);
    143             xprintf("%c", curr_bit ? '*' : '.');
    144         }
    145         print("\n");
    146     }
    147 	#endif
    148 }