Browse Source

add anti-ghost logic

tags/v1.9
tmk 13 years ago
parent
commit
82309deefc
4 changed files with 110 additions and 59 deletions
  1. 4
    0
      README
  2. 58
    20
      matrix.c
  3. 5
    1
      matrix.h
  4. 43
    38
      mykey.c

+ 4
- 0
README View File

clean source clean source
debouncing debouncing
anti-ghost anti-ghost
sleep&wakeup
boot keyboard support
mouse key
keymap layer keymap layer
key combination switch key combination switch
toggle siwtch toggle siwtch
debug console debug console
keymap setting keymap setting
matrix display matrix display
PS/2 keyboard mode
HHKB support HHKB support
Trackpoint(PS/2) support Trackpoint(PS/2) support
Thinkpad keyboard support Thinkpad keyboard support

+ 58
- 20
matrix.c View File

#include "matrix.h" #include "matrix.h"
#include "print.h" #include "print.h"


// matrix is active low. (key on: 0/key off: 1)
// row: Hi-Z(unselected)/low output(selected)
// PD:0,1,2,3,6,7/PC:6,7/PF:7
// col: input w/pullup
// PB:0-8

// matrix state buffer
uint8_t *matrix; uint8_t *matrix;
uint8_t *prev_matrix;
uint8_t *matrix_prev;
static uint8_t _matrix0[MATRIX_ROWS]; static uint8_t _matrix0[MATRIX_ROWS];
static uint8_t _matrix1[MATRIX_ROWS]; static uint8_t _matrix1[MATRIX_ROWS];


static uint8_t read_col(void); static uint8_t read_col(void);
static void unselect_rows(void);
static void select_row(uint8_t row); static void select_row(uint8_t row);




// this must be called once before matrix_scan.
void matrix_init(void) void matrix_init(void)
{ {
// Column: input w/pullup
// initialize row and col
unselect_rows();
DDRB = 0x00; DDRB = 0x00;
PORTB = 0xFF; PORTB = 0xFF;


// Row: Hi-Z(unselected)
// PD:0,1,2,3,6,7
// PC:6,7
// PF:7
DDRD = 0x00;
PORTD = 0x00;
DDRC = 0x00;
PORTC = 0x00;
DDRF = 0x00;
PORTF = 0x00;

for (int i=0; i < MATRIX_ROWS; i++) {
_matrix0[i] = 0xFF;
_matrix1[i] = 0xFF;
}
// initialize matrix state: all keys off
for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0xFF;
for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0xFF;
matrix = _matrix0; matrix = _matrix0;
prev_matrix = _matrix1;
matrix_prev = _matrix1;
} }


uint8_t matrix_scan(void) uint8_t matrix_scan(void)
uint8_t row, state; uint8_t row, state;
uint8_t *tmp; uint8_t *tmp;


tmp = prev_matrix;
prev_matrix = matrix;
tmp = matrix_prev;
matrix_prev = matrix;
matrix = tmp; matrix = tmp;


for (row = 0; row < MATRIX_ROWS; row++) { for (row = 0; row < MATRIX_ROWS; row++) {
select_row(row); select_row(row);
_delay_us(30); // without this wait read unstable value. _delay_us(30); // without this wait read unstable value.
state = read_col(); state = read_col();
unselect_rows();


matrix[row] = state; matrix[row] = state;
} }
return 1; return 1;
} }


bool matrix_is_modified(void) {
for (int i=0; i <MATRIX_ROWS; i++) {
if (matrix[i] != matrix_prev[i])
return true;
}
return false;
}

bool matrix_has_ghost(void) {
for (int i=0; i <MATRIX_ROWS; i++) {
if (matrix_has_ghost_in_row(i))
return true;
}
return false;
}

bool matrix_has_ghost_in_row(uint8_t row) {
uint8_t state = ~matrix[row];
// no ghost exists in case less than 2 keys on
if (((state - 1) & state) == 0)
return false;

// ghost exists in case same state as other row
for (int i=0; i < MATRIX_ROWS; i++) {
if (i == row) continue;
if ((~matrix[i] & state) == state) return true;
}
return false;
}

static uint8_t read_col(void) static uint8_t read_col(void)
{ {
return PINB; return PINB;
} }


static void unselect_rows(void) {
DDRD = 0x00;
PORTD = 0x00;
DDRC = 0x00;
PORTC = 0x00;
DDRF = 0x00;
PORTF = 0x00;
}

static void select_row(uint8_t row) static void select_row(uint8_t row)
{ {
switch (row) { switch (row) {

+ 5
- 1
matrix.h View File

#include <stdbool.h>


extern uint8_t *matrix; extern uint8_t *matrix;
extern uint8_t *prev_matrix;
extern uint8_t *matrix_prev;


void matrix_init(void); void matrix_init(void);
uint8_t matrix_scan(void); uint8_t matrix_scan(void);
bool matrix_is_modified(void);
bool matrix_has_ghost(void);
bool matrix_has_ghost_in_row(uint8_t row);

+ 43
- 38
mykey.c View File

* THE SOFTWARE. * THE SOFTWARE.
*/ */


#include <stdbool.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <util/delay.h> #include <util/delay.h>

#include "usb_keyboard_debug.h" #include "usb_keyboard_debug.h"
#include "print.h" #include "print.h"
#include "matrix.h" #include "matrix.h"


int main(void) int main(void)
{ {
uint8_t modified = 0;
bool modified = false;
bool has_ghost = false;
uint8_t key_index = 0; uint8_t key_index = 0;


// set for 16 MHz clock // set for 16 MHz clock
while (1) { while (1) {
uint8_t row, col, code; uint8_t row, col, code;


modified = 0;

matrix_scan(); matrix_scan();


keyboard_modifier_keys = 0;
for (int i = 0; i < 6; i++)
keyboard_keys[i] = KB_NO;
key_index = 0;
modified = matrix_is_modified();
has_ghost = matrix_has_ghost();


for (row = 0; row < MATRIX_ROWS; row++) {
if (matrix[row] != prev_matrix[row]) {
modified = 1;
}
// doesnt send keys during ghost occurs
if (modified && !has_ghost) {
key_index = 0;
keyboard_modifier_keys = 0;
for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;


for (col = 0; col < MATRIX_COLS; col++) {
if (matrix[row] & 1<<col) continue;
code = get_keycode(row, col);
// Modifier keycode: 0xE0-0xE7
if (KB_LCTRL <= code && code <= KB_RGUI) {
keyboard_modifier_keys |= 1<<(code&0x07);
} else {
if (key_index < 6) {
keyboard_keys[key_index] = code;
for (row = 0; row < MATRIX_ROWS; row++) {
for (col = 0; col < MATRIX_COLS; col++) {
if (matrix[row] & 1<<col) continue;

code = get_keycode(row, col);
if (KB_LCTRL <= code && code <= KB_RGUI) {
// modifier keycode: 0xE0-0xE7
keyboard_modifier_keys |= 1<<(code & 0x07);
} else {
if (key_index < 6)
keyboard_keys[key_index] = code;
key_index++;
} }
key_index++;
} }
}


if (key_index > 6) {
//Rollover
} }
}


if (key_index > 6) {
//Rollover
}
usb_keyboard_send();




// if any keypresses were detected, reset the idle counter
// variables shared with interrupt routines must be
// accessed carefully so the interrupt routine doesn't
// try to use the variable in the middle of our access
cli();
idle_count = 0;
sei();
}

// print matrix state for debug
if (modified) { if (modified) {
print(" 01234567\n");
print("r/c 01234567\n");
for (row = 0; row < MATRIX_ROWS; row++) { for (row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": "); pbin_reverse(matrix[row]); print("\n");
phex(row); print(": ");
pbin_reverse(matrix[row]);
if (matrix_has_ghost_in_row(row)) {
print(" <ghost");
}
print("\n");
} }
print("keys: "); print("keys: ");
for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); } for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); }
print("\n"); print("\n");
print("mod: "); phex(keyboard_modifier_keys); print("\n"); print("mod: "); phex(keyboard_modifier_keys); print("\n");
usb_keyboard_send();

// variables shared with interrupt routines must be
// accessed carefully so the interrupt routine doesn't
// try to use the variable in the middle of our access
cli();
idle_count = 0;
sei();
} }


// now the current pins will be the previous, and // now the current pins will be the previous, and

Loading…
Cancel
Save