added config option: MATRIX_HAS_GHOST and fixed some on matrix.c
ADD: Build option: MATRIX_HAS_GHOST to enable ghost blocking logic.
FIX: choose matrix buffer type(uint8_t/uint16_t) automatically
     depending on column size in matrix.c.
FIX: use uint8_t insted of int in matrix.c.
			
			
This commit is contained in:
		
							parent
							
								
									590235d4bc
								
							
						
					
					
						commit
						fd49c69d1a
					
				
					 7 changed files with 211 additions and 73 deletions
				
			
		| 
						 | 
				
			
			@ -1,18 +1,20 @@
 | 
			
		|||
#ifndef CONFIG_H
 | 
			
		||||
#define CONFIG_H
 | 
			
		||||
 | 
			
		||||
/* controller configuration */
 | 
			
		||||
#include "controller_teensy.h"
 | 
			
		||||
 | 
			
		||||
#define VENDOR_ID       0xFEED
 | 
			
		||||
#define PRODUCT_ID      0xBEE0
 | 
			
		||||
#define MANUFACTURER    t.m.k.
 | 
			
		||||
#define PRODUCT         Macway mod
 | 
			
		||||
#define DESCRIPTION     t.m.k. keyboard firmware for Macway mod
 | 
			
		||||
 | 
			
		||||
/* controller */
 | 
			
		||||
#include "controller_teensy.h"
 | 
			
		||||
 | 
			
		||||
/* matrix size */
 | 
			
		||||
#define MATRIX_ROWS 9
 | 
			
		||||
#define MATRIX_COLS 8
 | 
			
		||||
/* define if matrix has ghost */
 | 
			
		||||
#define MATRIX_HAS_GHOST
 | 
			
		||||
 | 
			
		||||
/* USB NKey Rollover */
 | 
			
		||||
#ifdef USB_NKRO_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@
 | 
			
		|||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
#include <avr/interrupt.h>
 | 
			
		||||
#include "usb_keyboard.h"
 | 
			
		||||
#include "usb_keycodes.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +12,8 @@
 | 
			
		|||
#include "keymap_skel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Convert physical keyboard layout to matrix array.
 | 
			
		||||
// This is a macro to define keymap easily in keyboard layout form.
 | 
			
		||||
#define KEYMAP( \
 | 
			
		||||
    R1C1, R1C0, R2C0, R3C0, R4C0, R4C1, R5C1, R5C0, R6C0, R7C0, R8C0, R8C1, R6C1, R0C2, \
 | 
			
		||||
    R1C2, R1C3, R2C3, R3C3, R4C3, R4C2, R5C2, R5C3, R6C3, R7C3, R8C3, R8C2, R6C2, \
 | 
			
		||||
| 
						 | 
				
			
			@ -34,17 +35,29 @@
 | 
			
		|||
#define KEYCODE(layer, row, col) (pgm_read_byte(&keymaps[(layer)][(row)][(col)]))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const uint8_t PROGMEM fn_layer[] = { 0, 1, 2, 3, 4, 0, 2, 3 };
 | 
			
		||||
// Assign Fn key(0-7) to a layer to which switch with the Fn key pressed.
 | 
			
		||||
static const uint8_t PROGMEM fn_layer[] = {
 | 
			
		||||
    0,              // FN_0
 | 
			
		||||
    1,              // FN_1
 | 
			
		||||
    2,              // FN_2
 | 
			
		||||
    3,              // FN_3
 | 
			
		||||
    4,              // FN_4
 | 
			
		||||
    0,              // FN_5
 | 
			
		||||
    2,              // FN_6
 | 
			
		||||
    3               // FN_7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Assign Fn key(0-7) to a keycode sent when release Fn key without use of the layer.
 | 
			
		||||
// See layer.c for details.
 | 
			
		||||
static const uint8_t PROGMEM fn_keycode[] = {
 | 
			
		||||
    KB_NO,          // FN_0 [NOT USED]
 | 
			
		||||
    KB_NO,          // FN_1 layer 1
 | 
			
		||||
    KB_SLSH,        // FN_2 layer 2
 | 
			
		||||
    KB_SCLN,        // FN_3 layer 3
 | 
			
		||||
    KB_SPC,         // FN_4 layer 4
 | 
			
		||||
    KB_NO,          // FN_5 [NOT USED]
 | 
			
		||||
    KB_NO,          // FN_6 layer 2
 | 
			
		||||
    KB_NO           // FN_7 layer 3
 | 
			
		||||
    KB_NO,          // FN_0
 | 
			
		||||
    KB_NO,          // FN_1
 | 
			
		||||
    KB_SLSH,        // FN_2
 | 
			
		||||
    KB_SCLN,        // FN_3
 | 
			
		||||
    KB_SPC,         // FN_4
 | 
			
		||||
    KB_NO,          // FN_5
 | 
			
		||||
    KB_NO,          // FN_6
 | 
			
		||||
    KB_NO           // FN_7
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +168,7 @@ uint8_t keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t col)
 | 
			
		|||
    return KEYCODE(layer, row, col);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int keymap_fn_layer(uint8_t fn_bits)
 | 
			
		||||
uint8_t keymap_fn_layer(uint8_t fn_bits)
 | 
			
		||||
{
 | 
			
		||||
    return pgm_read_byte(&fn_layer[biton(fn_bits)]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -165,6 +178,7 @@ uint8_t keymap_fn_keycode(uint8_t fn_bits)
 | 
			
		|||
    return pgm_read_byte(&fn_keycode[(biton(fn_bits))]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// define a condition to enter special function mode
 | 
			
		||||
bool keymap_is_special_mode(uint8_t fn_bits)
 | 
			
		||||
{
 | 
			
		||||
    //return (usb_keyboard_mods == (BIT_LCTRL | BIT_LSHIFT | BIT_LALT | BIT_LGUI));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,31 +10,47 @@
 | 
			
		|||
#include "matrix_skel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// matrix state buffer (key on: 1/key off: 0)
 | 
			
		||||
#if (MATRIX_COLS > 16)
 | 
			
		||||
#   error "MATRIX_COLS must not exceed 16"
 | 
			
		||||
#endif
 | 
			
		||||
#if (MATRIX_ROWS > 255)
 | 
			
		||||
#   error "MATRIX_ROWS must not exceed 255"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// matrix state buffer(1:on, 0:off)
 | 
			
		||||
#if (MATRIX_COLS <= 8)
 | 
			
		||||
static uint8_t *matrix;
 | 
			
		||||
static uint8_t *matrix_prev;
 | 
			
		||||
static uint8_t _matrix0[MATRIX_ROWS];
 | 
			
		||||
static uint8_t _matrix1[MATRIX_ROWS];
 | 
			
		||||
#else
 | 
			
		||||
static uint16_t *matrix;
 | 
			
		||||
static uint16_t *matrix_prev;
 | 
			
		||||
static uint16_t _matrix0[MATRIX_ROWS];
 | 
			
		||||
static uint16_t _matrix1[MATRIX_ROWS];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
static bool matrix_has_ghost_in_row(uint8_t row);
 | 
			
		||||
#endif
 | 
			
		||||
static uint8_t read_col(void);
 | 
			
		||||
static void unselect_rows(void);
 | 
			
		||||
static void select_row(uint8_t row);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
int matrix_rows(void)
 | 
			
		||||
uint8_t matrix_rows(void)
 | 
			
		||||
{
 | 
			
		||||
    return MATRIX_ROWS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
int matrix_cols(void)
 | 
			
		||||
uint8_t matrix_cols(void)
 | 
			
		||||
{
 | 
			
		||||
    return MATRIX_COLS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// this must be called once before matrix_scan.
 | 
			
		||||
void matrix_init(void)
 | 
			
		||||
{
 | 
			
		||||
    // initialize row and col
 | 
			
		||||
| 
						 | 
				
			
			@ -44,13 +60,13 @@ void matrix_init(void)
 | 
			
		|||
    PORTB = 0xFF;
 | 
			
		||||
 | 
			
		||||
    // initialize matrix state: all keys off
 | 
			
		||||
    for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
 | 
			
		||||
    for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
 | 
			
		||||
    for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00;
 | 
			
		||||
    for (uint8_t i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00;
 | 
			
		||||
    matrix = _matrix0;
 | 
			
		||||
    matrix_prev = _matrix1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int matrix_scan(void)
 | 
			
		||||
uint8_t matrix_scan(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *tmp;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +74,7 @@ int matrix_scan(void)
 | 
			
		|||
    matrix_prev = matrix;
 | 
			
		||||
    matrix = tmp;
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
        unselect_rows();
 | 
			
		||||
        select_row(i);
 | 
			
		||||
        _delay_us(30);  // without this wait read unstable value.
 | 
			
		||||
| 
						 | 
				
			
			@ -70,30 +86,37 @@ int matrix_scan(void)
 | 
			
		|||
 | 
			
		||||
bool matrix_is_modified(void)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
        if (matrix[i] != matrix_prev[i])
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
bool matrix_has_ghost(void)
 | 
			
		||||
{
 | 
			
		||||
    for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
        if (matrix_has_ghost_in_row(i))
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
bool matrix_is_on(int row, int col)
 | 
			
		||||
bool matrix_is_on(uint8_t row, uint8_t col)
 | 
			
		||||
{
 | 
			
		||||
    return (matrix[row] & (1<<col));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
uint16_t matrix_get_row(int row)
 | 
			
		||||
#if (MATRIX_COLS <= 8)
 | 
			
		||||
uint8_t matrix_get_row(uint8_t row)
 | 
			
		||||
#else
 | 
			
		||||
uint16_t matrix_get_row(uint8_t row)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
    return matrix[row];
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -101,25 +124,37 @@ uint16_t matrix_get_row(int row)
 | 
			
		|||
void matrix_print(void)
 | 
			
		||||
{
 | 
			
		||||
    print("\nr/c 01234567\n");
 | 
			
		||||
    for (int row = 0; row < matrix_rows(); row++) {
 | 
			
		||||
    for (uint8_t row = 0; row < matrix_rows(); row++) {
 | 
			
		||||
        phex(row); print(": ");
 | 
			
		||||
#if (MATRIX_COLS <= 8)
 | 
			
		||||
        pbin_reverse(matrix_get_row(row));
 | 
			
		||||
#else
 | 
			
		||||
        pbin_reverse16(matrix_get_row(row));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
        if (matrix_has_ghost_in_row(row)) {
 | 
			
		||||
            print(" <ghost");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
        print("\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int matrix_key_count(void)
 | 
			
		||||
uint8_t matrix_key_count(void)
 | 
			
		||||
{
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    for (int i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
    uint8_t count = 0;
 | 
			
		||||
    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
#if (MATRIX_COLS <= 8)
 | 
			
		||||
        count += bitpop(matrix[i]);
 | 
			
		||||
#else
 | 
			
		||||
        count += bitpop16(matrix[i]);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
inline
 | 
			
		||||
static bool matrix_has_ghost_in_row(uint8_t row)
 | 
			
		||||
{
 | 
			
		||||
    // no ghost exists in case less than 2 keys on
 | 
			
		||||
| 
						 | 
				
			
			@ -127,18 +162,21 @@ static bool matrix_has_ghost_in_row(uint8_t row)
 | 
			
		|||
        return false;
 | 
			
		||||
 | 
			
		||||
    // ghost exists in case same state as other row
 | 
			
		||||
    for (int i=0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
 | 
			
		||||
        if (i != row && (matrix[i] & matrix[row]) == matrix[row])
 | 
			
		||||
            return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
static uint8_t read_col(void)
 | 
			
		||||
{
 | 
			
		||||
    return PINB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
static void unselect_rows(void)
 | 
			
		||||
{
 | 
			
		||||
    // Hi-Z(DDR:0, PORT:0) to unselect
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +188,7 @@ static void unselect_rows(void)
 | 
			
		|||
    PORTF &= ~0b11000000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline
 | 
			
		||||
static void select_row(uint8_t row)
 | 
			
		||||
{
 | 
			
		||||
    // Output low(DDR:1, PORT:0) to select
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue