qmk_firmware

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

matrix.c (4871B)


      1 /*
      2 Copyright 2014 Kai Ryu <kai1103@gmail.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 /*
     19  * scan matrix
     20  */
     21 #include <stdint.h>
     22 #include <stdbool.h>
     23 #include <avr/io.h>
     24 #include <util/delay.h>
     25 #include "print.h"
     26 #include "debug.h"
     27 #include "util.h"
     28 #include "matrix.h"
     29 #ifdef UART_RGB_ENABLE
     30 #include "uart_rgb.h"
     31 #endif
     32 
     33 #ifndef DEBOUNCE
     34 #   define DEBOUNCE 5
     35 #endif
     36 static uint8_t debouncing = DEBOUNCE;
     37 
     38 /* matrix state(1:on, 0:off) */
     39 static matrix_row_t matrix[MATRIX_ROWS];
     40 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
     41 
     42 static matrix_row_t read_cols(void);
     43 static void init_cols(void);
     44 static void init_rows(void);
     45 static void unselect_rows(void);
     46 static void select_row(uint8_t row);
     47 
     48 inline
     49 uint8_t matrix_rows(void)
     50 {
     51     return MATRIX_ROWS;
     52 }
     53 
     54 inline
     55 uint8_t matrix_cols(void)
     56 {
     57     return MATRIX_COLS;
     58 }
     59 
     60 void matrix_init(void)
     61 {
     62 
     63 #ifdef UART_RGB_ENABLE
     64     uart_rgb_init();
     65 #endif
     66 
     67     // 85 REST
     68     gpio_set_pin_output(D7);
     69     gpio_write_pin_high(D7);
     70 
     71     // initialize row and col
     72     init_rows();
     73     init_cols();
     74 
     75     // initialize matrix state: all keys off
     76     for (uint8_t i=0; i < MATRIX_ROWS; i++) {
     77         matrix[i] = 0;
     78         matrix_debouncing[i] = 0;
     79     }
     80 }
     81 
     82 uint8_t matrix_scan(void)
     83 {
     84     for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
     85         select_row(i);
     86         _delay_us(30);  // without this wait read unstable value.
     87         matrix_row_t cols = read_cols();
     88         if (matrix_debouncing[i] != cols) {
     89             matrix_debouncing[i] = cols;
     90             if (debouncing) {
     91                 dprintf("bounce!: %02X\n", debouncing);
     92             }
     93             debouncing = DEBOUNCE;
     94         }
     95         unselect_rows();
     96     }
     97 
     98     if (debouncing) {
     99         if (--debouncing) {
    100             _delay_ms(1);
    101         } else {
    102             for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
    103                 matrix[i] = matrix_debouncing[i];
    104             }
    105         }
    106     }
    107 
    108     return 1;
    109 }
    110 
    111 inline
    112 bool matrix_is_on(uint8_t row, uint8_t col)
    113 {
    114     return (matrix[row] & ((matrix_row_t)1<<col));
    115 }
    116 
    117 inline
    118 matrix_row_t matrix_get_row(uint8_t row)
    119 {
    120     return matrix[row];
    121 }
    122 
    123 void matrix_print(void)
    124 {
    125     print("\nr/c 0123456789ABCDEF\n");
    126     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
    127         print_hex8(row); print(": ");
    128         print_bin_reverse16(matrix_get_row(row));
    129         print("\n");
    130     }
    131 }
    132 
    133 /* Column pin configuration
    134  * col: 0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
    135  * pin: F7  F6  F5  F4  F1  F0  E6  D7  D6  D5  D1  D0  B7  B6  B0  C7
    136  * */
    137 static void  init_cols(void)
    138 {
    139     // Input with pull-up(DDR:0, PORT:1)
    140     DDRF &= 0b00001100;
    141     PORTF |= 0b11110011;
    142 
    143     DDRD &= 0b00011100;
    144     PORTD |= 0b11100011;
    145 
    146     gpio_set_pin_input_high(B0);
    147     gpio_set_pin_input_high(B6);
    148     gpio_set_pin_input_high(B7);
    149 
    150     gpio_set_pin_input_high(E6);
    151 
    152     gpio_set_pin_input_high(C7);
    153 
    154 }
    155 
    156 static matrix_row_t read_cols(void)
    157 {
    158 
    159     return (gpio_read_pin(F7) ? 0 : (1<<0)) |
    160            (gpio_read_pin(F6) ? 0 : (1<<1)) |
    161            (gpio_read_pin(F5) ? 0 : (1<<2)) |
    162            (gpio_read_pin(F4) ? 0 : (1<<3)) |
    163            (gpio_read_pin(F1) ? 0 : (1<<4)) |
    164            (gpio_read_pin(F0) ? 0 : (1<<5)) |
    165            (gpio_read_pin(E6) ? 0 : (1<<6)) |
    166            (gpio_read_pin(D7) ? 0 : (1<<7)) |
    167            (gpio_read_pin(D6) ? 0 : (1<<8)) |
    168            (gpio_read_pin(D5) ? 0 : (1<<9)) |
    169            (gpio_read_pin(D1) ? 0 : (1<<10)) |
    170            (gpio_read_pin(D0) ? 0 : (1<<11)) |
    171            (gpio_read_pin(B7) ? 0 : (1<<12)) |
    172            (gpio_read_pin(B6) ? 0 : (1<<13)) |
    173            (gpio_read_pin(B0) ? 0 : (1<<14)) |
    174            (gpio_read_pin(C7) ? 0 : (1<<15));
    175 }
    176 
    177 /* Row pin configuration
    178  * row:     0   1   2   3   4   5   x
    179  * pin: B3  0   1   0   1   0   1   1
    180  *      B2  0   0   1   1   0   0   1
    181  *      B1  0   0   0   0   1   1   1
    182  */
    183 
    184 static void init_rows(void)
    185 {
    186     gpio_set_pin_input(B1);
    187     gpio_set_pin_input(B2);
    188     gpio_set_pin_input(B3);
    189 }
    190 
    191 static void unselect_rows(void)
    192 {
    193     // Hi-Z(DDR:0, PORT:0) to unselect
    194     gpio_write_pin_high(B1);
    195     gpio_write_pin_high(B2);
    196     gpio_write_pin_high(B3);
    197 }
    198 
    199 static void select_row(uint8_t row)
    200 {
    201     // Output low(DDR:1, PORT:0) to select
    202     gpio_write_pin(B3, row & (1<<0));
    203     gpio_write_pin(B2, row & (1<<1));
    204     gpio_write_pin(B1, row & (1<<2));
    205 }