qmk_firmware

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

matrix.c (3256B)


      1 /*
      2 Copyright 2014 Ralf Schmitt <ralf@bunkertor.net>
      3 Modified by Ryan Skidmore <rskeys@ryanskidmore.co.uk> (@ryanskidmore)
      4 to support the rskeys100.
      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 
     20 #include "matrix.h"
     21 #include <util/delay.h>
     22 
     23 static const uint32_t col_values[24] = SHR_COLS;
     24 
     25 static uint8_t read_rows(void);
     26 static void    select_col(uint8_t col);
     27 
     28 static void    shift_pulse(void);
     29 static void    shift_out_single(uint8_t value);
     30 static void    shift_out(uint32_t value);
     31 
     32 void matrix_init_custom(void) {
     33   gpio_set_pin_input(ROW_A);
     34   gpio_set_pin_input(ROW_B);
     35   gpio_set_pin_input(ROW_C);
     36   gpio_set_pin_input(ROW_D);
     37   gpio_set_pin_input(ROW_E);
     38   gpio_set_pin_input(ROW_F);
     39 
     40   gpio_set_pin_output(SHR_DATA);
     41   gpio_set_pin_output(SHR_LATCH);
     42   gpio_set_pin_output(SHR_CLOCK);
     43 }
     44 
     45 bool matrix_scan_custom(matrix_row_t current_matrix[]) {
     46     bool changed = false;
     47 
     48     for (uint8_t col = 0; col < MATRIX_COLS; col++) {
     49         select_col(col);
     50         _delay_us(1);
     51         uint8_t rows = read_rows();
     52         for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
     53             bool prev_bit = ((uint32_t)(current_matrix[row]) & (matrix_row_t)(1UL << col)) ? 1 : 0;
     54             bool curr_bit = ((uint32_t)rows & (uint32_t)(1UL << row)) ? 1 : 0;
     55             if (prev_bit != curr_bit) {
     56                 current_matrix[row] = (uint32_t)(current_matrix[row]) ^ (uint32_t)(1UL << col);
     57                 changed = true;
     58             }
     59         }
     60     }
     61 
     62     return changed;
     63 }
     64 
     65 static uint8_t read_rows(void) {
     66   return (gpio_read_pin(ROW_F) << 5)
     67          | (gpio_read_pin(ROW_E) << 4)
     68          | (gpio_read_pin(ROW_D) << 3)
     69          | (gpio_read_pin(ROW_C) << 2)
     70          | (gpio_read_pin(ROW_B) << 1)
     71          | (gpio_read_pin(ROW_A) );
     72 }
     73 
     74 static void select_col(uint8_t col) {
     75     shift_out(col_values[col]);
     76 }
     77 
     78 static void shift_out(uint32_t value) {
     79   gpio_write_pin_low(SHR_LATCH);
     80   uint8_t first_byte  = (value >> 16) & 0xFF;
     81   uint8_t second_byte  = (value >> 8) & 0xFF;
     82   uint8_t third_byte = (uint8_t)(value & 0xFF);
     83 
     84   shift_out_single(first_byte);
     85   shift_out_single(second_byte);
     86   shift_out_single(third_byte);
     87   gpio_write_pin_high(SHR_LATCH);
     88   /* We delay here to prevent multiple consecutive keys being triggered with a single switch press */
     89   _delay_us(10);
     90 }
     91 
     92 static void shift_out_single(uint8_t value) {
     93     for (uint8_t i = 0; i < 8; i++) {
     94         if (value & 0b10000000) {
     95             gpio_write_pin_high(SHR_DATA);
     96         } else {
     97             gpio_write_pin_low(SHR_DATA);
     98         }
     99 
    100         shift_pulse();
    101         value = value << 1;
    102     }
    103 }
    104 
    105 static inline void shift_pulse(void) {
    106     gpio_write_pin_high(SHR_CLOCK);
    107     gpio_write_pin_low(SHR_CLOCK);
    108 }