#include "host.h" | #include "host.h" | ||||
#if (MATRIX_COLS > 16) | |||||
# error "MATRIX_COLS must not exceed 16" | |||||
#endif | |||||
#if (MATRIX_ROWS > 255) | |||||
# error "MATRIX_ROWS must not exceed 255" | |||||
#endif | |||||
static bool has_media_keys = false; | static bool has_media_keys = false; | ||||
static bool is_iso_layout = false; | static bool is_iso_layout = false; | ||||
static bool is_modified = false; | |||||
static report_mouse_t mouse_report = {}; | static report_mouse_t mouse_report = {}; | ||||
// matrix state buffer(1:on, 0:off) | // matrix state buffer(1:on, 0:off) | ||||
#if (MATRIX_COLS <= 8) | |||||
static uint8_t matrix[MATRIX_ROWS]; | |||||
#else | |||||
static uint16_t matrix[MATRIX_ROWS]; | |||||
#endif | |||||
static matrix_row_t matrix[MATRIX_ROWS]; | |||||
#ifdef MATRIX_HAS_GHOST | |||||
static bool matrix_has_ghost_in_row(uint8_t row); | |||||
#endif | |||||
static void register_key(uint8_t key); | static void register_key(uint8_t key); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
// LED on | // LED on | ||||
uint16_t codes; | uint16_t codes; | ||||
uint8_t key0, key1; | uint8_t key0, key1; | ||||
is_modified = false; | |||||
codes = extra_key; | codes = extra_key; | ||||
extra_key = 0xFFFF; | extra_key = 0xFFFF; | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
#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(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
#if (MATRIX_COLS <= 8) | |||||
uint8_t matrix_get_row(uint8_t row) | |||||
#else | |||||
uint16_t matrix_get_row(uint8_t row) | |||||
#endif | |||||
matrix_row_t matrix_get_row(uint8_t row) | |||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
if (!debug_matrix) return; | |||||
#if (MATRIX_COLS <= 8) | |||||
print("r/c 01234567\n"); | |||||
#else | |||||
print("r/c 0123456789ABCDEF\n"); | |||||
#endif | |||||
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"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
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 | |||||
if (((matrix[row] - 1) & matrix[row]) == 0) | |||||
return false; | |||||
// ghost exists in case same state as other row | |||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |||||
if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
#endif | |||||
inline | inline | ||||
static void register_key(uint8_t key) | static void register_key(uint8_t key) | ||||
{ | { | ||||
} else { | } else { | ||||
matrix[row] |= (1<<col); | matrix[row] |= (1<<col); | ||||
} | } | ||||
is_modified = true; | |||||
} | } |
#define COL(code) (code&0x07) | #define COL(code) (code&0x07) | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
static void enable_break(void) | static void enable_break(void) | ||||
{ | { | ||||
print("Enable break: "); | print("Enable break: "); | ||||
return 1; | return 1; | ||||
} | } | ||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
xprintf("%02X: %08b\n", row, bitrev(matrix_get_row(row))); | |||||
} | |||||
} | |||||
inline | inline | ||||
static void matrix_make(uint8_t code) | static void matrix_make(uint8_t code) | ||||
{ | { |
static void register_key(uint8_t key); | static void register_key(uint8_t key); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
m0110_init(); | m0110_init(); | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
return count; | |||||
} | |||||
inline | inline | ||||
static void register_key(uint8_t key) | static void register_key(uint8_t key) | ||||
{ | { |
#define ROW(code) ((code>>3)&0xF) | #define ROW(code) ((code>>3)&0xF) | ||||
#define COL(code) (code&0x07) | #define COL(code) (code&0x07) | ||||
static bool is_modified = false; | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
uint8_t matrix_scan(void) | uint8_t matrix_scan(void) | ||||
{ | { | ||||
is_modified = false; | |||||
uint8_t code; | uint8_t code; | ||||
code = news_recv(); | code = news_recv(); | ||||
if (code == 0) { | if (code == 0) { | ||||
// break code | // break code | ||||
if (matrix_is_on(ROW(code), COL(code))) { | if (matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] &= ~(1<<COL(code)); | matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} else { | } else { | ||||
// make code | // make code | ||||
if (!matrix_is_on(ROW(code), COL(code))) { | if (!matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] |= (1<<COL(code)); | matrix[ROW(code)] |= (1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
return code; | return code; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
return count; | |||||
} |
static bool is_modified = false; | static bool is_modified = false; | ||||
/* number of matrix rows */ | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
/* number of matrix columns */ | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
#ifndef NEXT_KBD_LED1_ON | #ifndef NEXT_KBD_LED1_ON | ||||
#define NEXT_KBD_LED1_ON | #define NEXT_KBD_LED1_ON | ||||
#endif | #endif | ||||
return 1; | return 1; | ||||
} | } | ||||
/* whether modified from previous scan. used after matrix_scan. */ | |||||
bool matrix_is_modified() | |||||
{ | |||||
return is_modified; | |||||
} | |||||
/* whether a switch is on */ | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
/* matrix state on row */ | /* matrix state on row */ | ||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
/* print matrix for debug */ | |||||
void matrix_print(void) | |||||
{ | |||||
} | |||||
inline | inline | ||||
static void matrix_make(uint8_t code) | static void matrix_make(uint8_t code) | ||||
{ | { |
#define ROW(code) ((code>>3)&0xF) | #define ROW(code) ((code>>3)&0xF) | ||||
#define COL(code) (code&0x07) | #define COL(code) (code&0x07) | ||||
static bool is_modified = false; | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
static void pc98_inhibit_repeat(void) | static void pc98_inhibit_repeat(void) | ||||
{ | { | ||||
uint8_t matrix_scan(void) | uint8_t matrix_scan(void) | ||||
{ | { | ||||
is_modified = false; | |||||
uint16_t code; | uint16_t code; | ||||
PC98_RDY_PORT |= (1<<PC98_RDY_BIT); | PC98_RDY_PORT |= (1<<PC98_RDY_BIT); | ||||
_delay_us(30); | _delay_us(30); | ||||
// break code | // break code | ||||
if (matrix_is_on(ROW(code), COL(code))) { | if (matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] &= ~(1<<COL(code)); | matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} else { | } else { | ||||
// make code | // make code | ||||
if (!matrix_is_on(ROW(code), COL(code))) { | if (!matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] |= (1<<COL(code)); | matrix[ROW(code)] |= (1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
return code; | return code; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
return count; | |||||
} |
#include "matrix.h" | #include "matrix.h" | ||||
#include "debug.h" | #include "debug.h" | ||||
#include "protocol/serial.h" | #include "protocol/serial.h" | ||||
#include "led.h" | |||||
#include "host.h" | |||||
/* | /* | ||||
#define ROW(code) ((code>>3)&0xF) | #define ROW(code) ((code>>3)&0xF) | ||||
#define COL(code) (code&0x07) | #define COL(code) (code&0x07) | ||||
static bool is_modified = false; | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
uint8_t matrix_scan(void) | uint8_t matrix_scan(void) | ||||
{ | { | ||||
is_modified = false; | |||||
uint8_t code; | uint8_t code; | ||||
code = serial_recv(); | code = serial_recv(); | ||||
if (!code) return 0; | if (!code) return 0; | ||||
// break code | // break code | ||||
if (matrix_is_on(ROW(code), COL(code))) { | if (matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] &= ~(1<<COL(code)); | matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} else { | } else { | ||||
// make code | // make code | ||||
if (!matrix_is_on(ROW(code), COL(code))) { | if (!matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] |= (1<<COL(code)); | matrix[ROW(code)] |= (1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
return code; | return code; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
return count; | |||||
} |
static void matrix_make(uint8_t code); | static void matrix_make(uint8_t code); | ||||
static void matrix_break(uint8_t code); | static void matrix_break(uint8_t code); | ||||
#ifdef MATRIX_HAS_GHOST | |||||
static bool matrix_has_ghost_in_row(uint8_t row); | |||||
#endif | |||||
/* | /* | ||||
#define ROW(code) (code>>3) | #define ROW(code) (code>>3) | ||||
#define COL(code) (code&0x07) | #define COL(code) (code&0x07) | ||||
static bool is_modified = false; | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
F0, | F0, | ||||
} state = RESET; | } state = RESET; | ||||
is_modified = false; | |||||
uint8_t code; | uint8_t code; | ||||
if ((code = ps2_host_recv())) { | if ((code = ps2_host_recv())) { | ||||
debug("r"); debug_hex(code); debug(" "); | debug("r"); debug_hex(code); debug(" "); | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
#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(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
#ifdef MATRIX_HAS_GHOST | |||||
if (matrix_has_ghost_in_row(row)) { | |||||
print(" <ghost"); | |||||
} | |||||
#endif | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
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 | |||||
if (((matrix[row] - 1) & matrix[row]) == 0) | |||||
return false; | |||||
// ghost exists in case same state as other row | |||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |||||
if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
#endif | |||||
inline | inline | ||||
static void matrix_make(uint8_t code) | static void matrix_make(uint8_t code) | ||||
{ | { | ||||
if (!matrix_is_on(ROW(code), COL(code))) { | if (!matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] |= 1<<COL(code); | matrix[ROW(code)] |= 1<<COL(code); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
if (matrix_is_on(ROW(code), COL(code))) { | if (matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] &= ~(1<<COL(code)); | matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} | } |
static bool is_modified = false; | static bool is_modified = false; | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
serial_init(); | serial_init(); | ||||
return code; | return code; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
return count; | |||||
} |
static void matrix_make(uint8_t code); | static void matrix_make(uint8_t code); | ||||
static void matrix_break(uint8_t code); | static void matrix_break(uint8_t code); | ||||
#ifdef MATRIX_HAS_GHOST | |||||
static bool matrix_has_ghost_in_row(uint8_t row); | |||||
#endif | |||||
static uint8_t matrix[MATRIX_ROWS]; | static uint8_t matrix[MATRIX_ROWS]; | ||||
#define ROW(code) (code>>3) | #define ROW(code) (code>>3) | ||||
#define PRINT_SCREEN (0x7C) | #define PRINT_SCREEN (0x7C) | ||||
#define PAUSE (0x7D) | #define PAUSE (0x7D) | ||||
static bool is_modified = false; | |||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
} state = INIT; | } state = INIT; | ||||
is_modified = false; | |||||
// 'pseudo break code' hack | // 'pseudo break code' hack | ||||
if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { | if (matrix_is_on(ROW(PAUSE), COL(PAUSE))) { | ||||
matrix_break(PAUSE); | matrix_break(PAUSE); | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
return is_modified; | |||||
} | |||||
inline | |||||
bool matrix_has_ghost(void) | |||||
{ | |||||
#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(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
uint8_t matrix_get_row(uint8_t row) | uint8_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
#ifdef MATRIX_HAS_GHOST | |||||
if (matrix_has_ghost_in_row(row)) { | |||||
print(" <ghost"); | |||||
} | |||||
#endif | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop(matrix[i]); | |||||
} | |||||
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 | |||||
if (((matrix[row] - 1) & matrix[row]) == 0) | |||||
return false; | |||||
// ghost exists in case same state as other row | |||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |||||
if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
#endif | |||||
inline | inline | ||||
static void matrix_make(uint8_t code) | static void matrix_make(uint8_t code) | ||||
{ | { | ||||
if (!matrix_is_on(ROW(code), COL(code))) { | if (!matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] |= 1<<COL(code); | matrix[ROW(code)] |= 1<<COL(code); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
if (matrix_is_on(ROW(code), COL(code))) { | if (matrix_is_on(ROW(code), COL(code))) { | ||||
matrix[ROW(code)] &= ~(1<<COL(code)); | matrix[ROW(code)] &= ~(1<<COL(code)); | ||||
is_modified = true; | |||||
} | } | ||||
} | } | ||||
static void select_row(uint8_t row); | static void select_row(uint8_t row); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
#define LED_ON() do { DDRC |= (1<<5); PORTC |= (1<<5); } while (0) | #define LED_ON() do { DDRC |= (1<<5); PORTC |= (1<<5); } while (0) | ||||
#define LED_OFF() do { DDRC &= ~(1<<5); PORTC &= ~(1<<5); } while (0) | #define LED_OFF() do { DDRC &= ~(1<<5); PORTC &= ~(1<<5); } while (0) | ||||
#define LED_TGL() do { DDRC |= (1<<5); PINC |= (1<<5); } while (0) | #define LED_TGL() do { DDRC |= (1<<5); PINC |= (1<<5); } while (0) | ||||
return 1; | return 1; | ||||
} | } | ||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & ((matrix_row_t)1<<col)); | |||||
} | |||||
inline | inline | ||||
matrix_row_t matrix_get_row(uint8_t row) | matrix_row_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 0123456789ABCDEF\n"); | |||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse16(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
/* Column pin configuration | /* Column pin configuration | ||||
* col: 0 1 2 3 4 5 6 7 | * col: 0 1 2 3 4 5 6 7 | ||||
* pin: B0 B1 B2 B3 B4 B5 B6 B7 | * pin: B0 B1 B2 B3 B4 B5 B6 B7 |
static void select_row(uint8_t row); | static void select_row(uint8_t row); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
// initialize row and col | // initialize row and col | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
if (debouncing) return false; | |||||
return true; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & ((matrix_row_t)1<<col)); | |||||
} | |||||
inline | inline | ||||
matrix_row_t matrix_get_row(uint8_t row) | matrix_row_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 0123456789ABCDEF\n"); | |||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse16(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop16(matrix[i]); | |||||
} | |||||
return count; | |||||
} | |||||
/* Column pin configuration | /* Column pin configuration | ||||
* col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 | * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 | ||||
* pin: F0 F1 E6 C7 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A) | * pin: F0 F1 E6 C7 C6 B6 D4 B1 B0 B5 B4 D7 D6 B3 (Rev.A) |
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]; | ||||
#ifdef MATRIX_HAS_GHOST | |||||
static bool matrix_has_ghost_in_row(uint8_t row); | |||||
#endif | |||||
static matrix_row_t read_cols(void); | static matrix_row_t read_cols(void); | ||||
static void unselect_rows(void); | static void unselect_rows(void); | ||||
static void select_row(uint8_t row); | static void select_row(uint8_t row); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
// JTAG disable for PORT F. write JTD bit twice within four cycles. | // JTAG disable for PORT F. write JTD bit twice within four cycles. | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
if (debouncing) return false; | |||||
return true; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & ((matrix_row_t)1<<col)); | |||||
} | |||||
inline | inline | ||||
matrix_row_t matrix_get_row(uint8_t row) | matrix_row_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse(matrix_get_row(row)); | |||||
#ifdef MATRIX_HAS_GHOST | |||||
if (matrix_has_ghost_in_row(row)) { | |||||
print(" <ghost"); | |||||
} | |||||
#endif | |||||
print("\n"); | |||||
} | |||||
} | |||||
#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 | |||||
if (((matrix[row] - 1) & matrix[row]) == 0) | |||||
return false; | |||||
// ghost exists in case same state as other row | |||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { | |||||
if (i != row && (matrix[i] & matrix[row])) | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
#endif | |||||
inline | inline | ||||
static matrix_row_t read_cols(void) | static matrix_row_t read_cols(void) | ||||
{ | { |
static matrix_row_t _matrix1[MATRIX_ROWS]; | static matrix_row_t _matrix1[MATRIX_ROWS]; | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
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) | |||||
{ | |||||
return false; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & (1<<col)); | |||||
} | |||||
inline | inline | ||||
matrix_row_t matrix_get_row(uint8_t row) | matrix_row_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 01234567\n"); | |||||
for (uint8_t row = 0; row < matrix_rows(); row++) { | |||||
xprintf("%02X: %08b\n", row, bitrev(matrix_get_row(row))); | |||||
} | |||||
} | |||||
void matrix_power_up(void) { | void matrix_power_up(void) { | ||||
KEY_POWER_ON(); | KEY_POWER_ON(); | ||||
} | } |
static void select_row(uint8_t row); | static void select_row(uint8_t row); | ||||
inline | |||||
uint8_t matrix_rows(void) | |||||
{ | |||||
return MATRIX_ROWS; | |||||
} | |||||
inline | |||||
uint8_t matrix_cols(void) | |||||
{ | |||||
return MATRIX_COLS; | |||||
} | |||||
void matrix_init(void) | void matrix_init(void) | ||||
{ | { | ||||
debug_enable = true; | debug_enable = true; | ||||
return 1; | return 1; | ||||
} | } | ||||
bool matrix_is_modified(void) | |||||
{ | |||||
if (debouncing) return false; | |||||
return true; | |||||
} | |||||
inline | |||||
bool matrix_is_on(uint8_t row, uint8_t col) | |||||
{ | |||||
return (matrix[row] & ((matrix_row_t)1<<col)); | |||||
} | |||||
inline | inline | ||||
matrix_row_t matrix_get_row(uint8_t row) | matrix_row_t matrix_get_row(uint8_t row) | ||||
{ | { | ||||
return matrix[row]; | return matrix[row]; | ||||
} | } | ||||
void matrix_print(void) | |||||
{ | |||||
print("\nr/c 0123456789ABCDEF\n"); | |||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||||
phex(row); print(": "); | |||||
pbin_reverse16(matrix_get_row(row)); | |||||
print("\n"); | |||||
} | |||||
} | |||||
uint8_t matrix_key_count(void) | |||||
{ | |||||
uint8_t count = 0; | |||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||||
count += bitpop16(matrix[i]); | |||||
} | |||||
return count; | |||||
} | |||||
/* Column pin configuration | /* Column pin configuration | ||||
* col: 0 | * col: 0 | ||||
* pin: B0 | * pin: B0 |