forked from mirrors/qmk_userspace
		
	Changes lets_split to use timer based debouncing
The let's split code used delays in its debouncing algorithm which increases input latency. This commit copies and adapts the code from `quantum/matrix.c` to lets_split's `matrix.c`.
This commit is contained in:
		
					parent
					
						
							
								ac634aa455
							
						
					
				
			
			
				commit
				
					
						07cb997b6d
					
				
			
		
					 2 changed files with 200 additions and 50 deletions
				
			
		| 
						 | 
					@ -21,9 +21,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <avr/io.h>
 | 
					#include <avr/io.h>
 | 
				
			||||||
#include <avr/wdt.h>
 | 
					#include "wait.h"
 | 
				
			||||||
#include <avr/interrupt.h>
 | 
					 | 
				
			||||||
#include <util/delay.h>
 | 
					 | 
				
			||||||
#include "print.h"
 | 
					#include "print.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
| 
						 | 
					@ -31,6 +29,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#include "split_util.h"
 | 
					#include "split_util.h"
 | 
				
			||||||
#include "pro_micro.h"
 | 
					#include "pro_micro.h"
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_I2C
 | 
					#ifdef USE_I2C
 | 
				
			||||||
#  include "i2c.h"
 | 
					#  include "i2c.h"
 | 
				
			||||||
| 
						 | 
					@ -38,14 +37,29 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
#  include "serial.h"
 | 
					#  include "serial.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef DEBOUNCE
 | 
					#ifndef DEBOUNCING_DELAY
 | 
				
			||||||
#  define DEBOUNCE	5
 | 
					#   define DEBOUNCING_DELAY 5
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (DEBOUNCING_DELAY > 0)
 | 
				
			||||||
 | 
					    static uint16_t debouncing_time;
 | 
				
			||||||
 | 
					    static bool debouncing = false;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (MATRIX_COLS <= 8)
 | 
				
			||||||
 | 
					#    define print_matrix_header()  print("\nr/c 01234567\n")
 | 
				
			||||||
 | 
					#    define print_matrix_row(row)  print_bin_reverse8(matrix_get_row(row))
 | 
				
			||||||
 | 
					#    define matrix_bitpop(i)       bitpop(matrix[i])
 | 
				
			||||||
 | 
					#    define ROW_SHIFTER ((uint8_t)1)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#    error "Currently only supports 8 COLS"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					static matrix_row_t matrix_debouncing[MATRIX_ROWS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ERROR_DISCONNECT_COUNT 5
 | 
					#define ERROR_DISCONNECT_COUNT 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint8_t debouncing = DEBOUNCE;
 | 
					#define ROWS_PER_HAND (MATRIX_ROWS/2)
 | 
				
			||||||
static const int ROWS_PER_HAND = MATRIX_ROWS/2;
 | 
					
 | 
				
			||||||
static uint8_t error_count = 0;
 | 
					static uint8_t error_count = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
 | 
					static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
 | 
				
			||||||
| 
						 | 
					@ -55,11 +69,19 @@ static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
 | 
				
			||||||
static matrix_row_t matrix[MATRIX_ROWS];
 | 
					static matrix_row_t matrix[MATRIX_ROWS];
 | 
				
			||||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS];
 | 
					static matrix_row_t matrix_debouncing[MATRIX_ROWS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static matrix_row_t read_cols(void);
 | 
					#if (DIODE_DIRECTION == COL2ROW)
 | 
				
			||||||
static void init_cols(void);
 | 
					    static void init_cols(void);
 | 
				
			||||||
static void unselect_rows(void);
 | 
					    static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row);
 | 
				
			||||||
static void select_row(uint8_t row);
 | 
					    static void unselect_rows(void);
 | 
				
			||||||
 | 
					    static void select_row(uint8_t row);
 | 
				
			||||||
 | 
					    static void unselect_row(uint8_t row);
 | 
				
			||||||
 | 
					#elif (DIODE_DIRECTION == ROW2COL)
 | 
				
			||||||
 | 
					    static void init_rows(void);
 | 
				
			||||||
 | 
					    static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
 | 
				
			||||||
 | 
					    static void unselect_cols(void);
 | 
				
			||||||
 | 
					    static void unselect_col(uint8_t col);
 | 
				
			||||||
 | 
					    static void select_col(uint8_t col);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
__attribute__ ((weak))
 | 
					__attribute__ ((weak))
 | 
				
			||||||
void matrix_init_quantum(void) {
 | 
					void matrix_init_quantum(void) {
 | 
				
			||||||
    matrix_init_kb();
 | 
					    matrix_init_kb();
 | 
				
			||||||
| 
						 | 
					@ -118,33 +140,54 @@ void matrix_init(void)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    matrix_init_quantum();
 | 
					    matrix_init_quantum();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint8_t _matrix_scan(void)
 | 
					uint8_t _matrix_scan(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    // Right hand is stored after the left in the matirx so, we need to offset it
 | 
					 | 
				
			||||||
    int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
 | 
					    int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
 | 
				
			||||||
 | 
					#if (DIODE_DIRECTION == COL2ROW)
 | 
				
			||||||
 | 
					    // Set row, read cols
 | 
				
			||||||
 | 
					    for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) {
 | 
				
			||||||
 | 
					#       if (DEBOUNCING_DELAY > 0)
 | 
				
			||||||
 | 
					            bool matrix_changed = read_cols_on_row(matrix_debouncing+offset, current_row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (matrix_changed) {
 | 
				
			||||||
 | 
					                debouncing = true;
 | 
				
			||||||
 | 
					                debouncing_time = timer_read();
 | 
				
			||||||
 | 
					                PORTD ^= (1 << 2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#       else
 | 
				
			||||||
 | 
					            read_cols_on_row(matrix+offset, current_row);
 | 
				
			||||||
 | 
					#       endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
 | 
					 | 
				
			||||||
        select_row(i);
 | 
					 | 
				
			||||||
        _delay_us(30);  // without this wait read unstable value.
 | 
					 | 
				
			||||||
        matrix_row_t cols = read_cols();
 | 
					 | 
				
			||||||
        if (matrix_debouncing[i+offset] != cols) {
 | 
					 | 
				
			||||||
            matrix_debouncing[i+offset] = cols;
 | 
					 | 
				
			||||||
            debouncing = DEBOUNCE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        unselect_rows();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (debouncing) {
 | 
					#elif (DIODE_DIRECTION == ROW2COL)
 | 
				
			||||||
        if (--debouncing) {
 | 
					    // Set col, read rows
 | 
				
			||||||
            _delay_ms(1);
 | 
					    for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
 | 
				
			||||||
        } else {
 | 
					#       if (DEBOUNCING_DELAY > 0)
 | 
				
			||||||
 | 
					            bool matrix_changed = read_rows_on_col(matrix_debouncing+offset, current_col);
 | 
				
			||||||
 | 
					            if (matrix_changed) {
 | 
				
			||||||
 | 
					                debouncing = true;
 | 
				
			||||||
 | 
					                debouncing_time = timer_read();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#       else
 | 
				
			||||||
 | 
					             read_rows_on_col(matrix+offset, current_col);
 | 
				
			||||||
 | 
					#       endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#   if (DEBOUNCING_DELAY > 0)
 | 
				
			||||||
 | 
					        if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
 | 
				
			||||||
            for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
 | 
					            for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
 | 
				
			||||||
                matrix[i+offset] = matrix_debouncing[i+offset];
 | 
					                matrix[i+offset] = matrix_debouncing[i+offset];
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            debouncing = false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					#   endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -200,9 +243,7 @@ int serial_transaction(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint8_t matrix_scan(void)
 | 
					uint8_t matrix_scan(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int ret = _matrix_scan();
 | 
					    uint8_t ret = _matrix_scan();
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_I2C
 | 
					#ifdef USE_I2C
 | 
				
			||||||
    if( i2c_transaction() ) {
 | 
					    if( i2c_transaction() ) {
 | 
				
			||||||
| 
						 | 
					@ -233,11 +274,10 @@ uint8_t matrix_scan(void)
 | 
				
			||||||
void matrix_slave_scan(void) {
 | 
					void matrix_slave_scan(void) {
 | 
				
			||||||
    _matrix_scan();
 | 
					    _matrix_scan();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2);
 | 
					    int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_I2C
 | 
					#ifdef USE_I2C
 | 
				
			||||||
    for (int i = 0; i < ROWS_PER_HAND; ++i) {
 | 
					    for (int i = 0; i < ROWS_PER_HAND; ++i) {
 | 
				
			||||||
        /* i2c_slave_buffer[i] = matrix[offset+i]; */
 | 
					 | 
				
			||||||
        i2c_slave_buffer[i] = matrix[offset+i];
 | 
					        i2c_slave_buffer[i] = matrix[offset+i];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#else // USE_SERIAL
 | 
					#else // USE_SERIAL
 | 
				
			||||||
| 
						 | 
					@ -284,33 +324,141 @@ uint8_t matrix_key_count(void)
 | 
				
			||||||
    return count;
 | 
					    return count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void  init_cols(void)
 | 
					#if (DIODE_DIRECTION == COL2ROW)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void init_cols(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for(int x = 0; x < MATRIX_COLS; x++) {
 | 
					    for(uint8_t x = 0; x < MATRIX_COLS; x++) {
 | 
				
			||||||
        _SFR_IO8((col_pins[x] >> 4) + 1) &=  ~_BV(col_pins[x] & 0xF);
 | 
					        uint8_t pin = col_pins[x];
 | 
				
			||||||
        _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
 | 
					        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static matrix_row_t read_cols(void)
 | 
					static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    matrix_row_t result = 0;
 | 
					    // Store last value of row prior to reading
 | 
				
			||||||
    for(int x = 0; x < MATRIX_COLS; x++) {
 | 
					    matrix_row_t last_row_value = current_matrix[current_row];
 | 
				
			||||||
        result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void unselect_rows(void)
 | 
					    // Clear data in matrix row
 | 
				
			||||||
{
 | 
					    current_matrix[current_row] = 0;
 | 
				
			||||||
    for(int x = 0; x < ROWS_PER_HAND; x++) {
 | 
					
 | 
				
			||||||
        _SFR_IO8((row_pins[x] >> 4) + 1) &=  ~_BV(row_pins[x] & 0xF);
 | 
					    // Select row and wait for row selecton to stabilize
 | 
				
			||||||
        _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
 | 
					    select_row(current_row);
 | 
				
			||||||
 | 
					    wait_us(30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For each col...
 | 
				
			||||||
 | 
					    for(uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Select the col pin to read (active low)
 | 
				
			||||||
 | 
					        uint8_t pin = col_pins[col_index];
 | 
				
			||||||
 | 
					        uint8_t pin_state = (_SFR_IO8(pin >> 4) & _BV(pin & 0xF));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Populate the matrix row with the state of the col pin
 | 
				
			||||||
 | 
					        current_matrix[current_row] |=  pin_state ? 0 : (ROW_SHIFTER << col_index);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Unselect row
 | 
				
			||||||
 | 
					    unselect_row(current_row);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (last_row_value != current_matrix[current_row]);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void select_row(uint8_t row)
 | 
					static void select_row(uint8_t row)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _SFR_IO8((row_pins[row] >> 4) + 1) |=  _BV(row_pins[row] & 0xF);
 | 
					    uint8_t pin = row_pins[row];
 | 
				
			||||||
    _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
 | 
					    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unselect_row(uint8_t row)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t pin = row_pins[row];
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unselect_rows(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
 | 
				
			||||||
 | 
					        uint8_t pin = row_pins[x];
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#elif (DIODE_DIRECTION == ROW2COL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void init_rows(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(uint8_t x = 0; x < ROWS_PER_HAND; x++) {
 | 
				
			||||||
 | 
					        uint8_t pin = row_pins[x];
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool matrix_changed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Select col and wait for col selecton to stabilize
 | 
				
			||||||
 | 
					    select_col(current_col);
 | 
				
			||||||
 | 
					    wait_us(30);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For each row...
 | 
				
			||||||
 | 
					    for(uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Store last value of row prior to reading
 | 
				
			||||||
 | 
					        matrix_row_t last_row_value = current_matrix[row_index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Check row pin state
 | 
				
			||||||
 | 
					        if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)) == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Pin LO, set col bit
 | 
				
			||||||
 | 
					            current_matrix[row_index] |= (ROW_SHIFTER << current_col);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Pin HI, clear col bit
 | 
				
			||||||
 | 
					            current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Determine if the matrix changed state
 | 
				
			||||||
 | 
					        if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            matrix_changed = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Unselect col
 | 
				
			||||||
 | 
					    unselect_col(current_col);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return matrix_changed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void select_col(uint8_t col)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t pin = col_pins[col];
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 1) |=  _BV(pin & 0xF); // OUT
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF); // LOW
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unselect_col(uint8_t col)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t pin = col_pins[col];
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					    _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unselect_cols(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(uint8_t x = 0; x < MATRIX_COLS; x++) {
 | 
				
			||||||
 | 
					        uint8_t pin = col_pins[x];
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF); // IN
 | 
				
			||||||
 | 
					        _SFR_IO8((pin >> 4) + 2) |=  _BV(pin & 0xF); // HI
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
#include "matrix.h"
 | 
					#include "matrix.h"
 | 
				
			||||||
#include "keyboard.h"
 | 
					#include "keyboard.h"
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_I2C
 | 
					#ifdef USE_I2C
 | 
				
			||||||
#  include "i2c.h"
 | 
					#  include "i2c.h"
 | 
				
			||||||
| 
						 | 
					@ -42,6 +43,7 @@ static void keyboard_master_setup(void) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void keyboard_slave_setup(void) {
 | 
					static void keyboard_slave_setup(void) {
 | 
				
			||||||
 | 
					  timer_init();
 | 
				
			||||||
#ifdef USE_I2C
 | 
					#ifdef USE_I2C
 | 
				
			||||||
    i2c_slave_init(SLAVE_I2C_ADDRESS);
 | 
					    i2c_slave_init(SLAVE_I2C_ADDRESS);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue