qmk_firmware

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

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 }