From 93029977a898c2bf6cbbfc61ae550c907c75e2e5 Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Thu, 31 Mar 2016 18:52:43 +0900 Subject: [PATCH] kimera: Improve matrix scanning frequency - Implement improved debounce algorithm - Change combining of keymap for two-headed kimera --- keyboard/kimera/kimera.c | 68 ++++++++++++++++-- keyboard/kimera/kimera.h | 15 +--- keyboard/kimera/matrix.c | 146 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 210 insertions(+), 19 deletions(-) diff --git a/keyboard/kimera/kimera.c b/keyboard/kimera/kimera.c index c4c42f8d..7082ab42 100644 --- a/keyboard/kimera/kimera.c +++ b/keyboard/kimera/kimera.c @@ -86,6 +86,17 @@ static matrix_row_t col_left_mask; static uint8_t data[EXP_COUNT][EXP_PORT_COUNT]; static uint8_t exp_status = 0; +static uint8_t read_matrix_mapping(void); +static void write_matrix_mapping(void); +static void expander_init(uint8_t exp); +static uint8_t expander_write(uint8_t exp, uint8_t command, uint8_t *data); +static uint8_t expander_read(uint8_t exp, uint8_t command, uint8_t *data); +static uint8_t expander_write_output(uint8_t exp, uint8_t *data); +static uint8_t expander_write_inversion(uint8_t exp, uint8_t *data); +static uint8_t expander_write_config(uint8_t exp, uint8_t *data); +static uint8_t expander_read_input(uint8_t exp, uint8_t *data); +static void init_data(uint8_t value); + void kimera_init(void) { /* read config */ @@ -130,7 +141,7 @@ uint8_t read_matrix_mapping(void) #ifdef TWO_HEADED_KIMERA row_left_count = (rows + 1) / 2; col_left_count = (cols + 1) / 2; - col_left_mask = (1 << row_left_count) - 1; + col_left_mask = (1 << col_left_count) - 1; #endif /* read row mapping */ @@ -200,30 +211,68 @@ void kimera_scan(void) } } +#define CHANGE_COMBINING 1 + inline uint8_t kimera_matrix_rows(void) { +#if CHANGE_COMBINING +#ifndef TWO_HEADED_KIMERA return row_count; +#else + return row_left_count; +#endif +#else + return row_count; +#endif } inline uint8_t kimera_matrix_cols(void) { +#if CHANGE_COMBINING + return col_count; +#else #ifndef TWO_HEADED_KIMERA return col_count; #else return col_left_count; #endif +#endif } -matrix_row_t kimera_read_cols(uint8_t row) +void kimera_read_cols(void) { - init_data(0xFF); - /* read all input registers */ + init_data(0xFF); for (uint8_t exp = 0; exp < EXP_COUNT; exp++) { expander_read_input(exp, data[exp]); } +} + +uint8_t kimera_get_col(uint8_t row, uint8_t col) +{ +#if CHANGE_COMBINING +#else +#ifdef TWO_HEADED_KIMERA + if (row >= row_left_count) { + col += col_left_count; + } +#endif +#endif + + uint8_t px = col_mapping[col]; + if (px != UNCONFIGURED) { + if (!(data[PX_TO_EXP(px)][PX_TO_PORT(px)] & (1 << PX_TO_PIN(px)))) { + return 1; + } + } + return 0; +} + +matrix_row_t kimera_read_row(uint8_t row) +{ + kimera_read_cols(); /* make cols */ matrix_row_t cols = 0; @@ -236,6 +285,8 @@ matrix_row_t kimera_read_cols(uint8_t row) } } +#if CHANGE_COMBINING +#else #ifdef TWO_HEADED_KIMERA if (row < row_left_count) { cols &= col_left_mask; @@ -243,6 +294,7 @@ matrix_row_t kimera_read_cols(uint8_t row) else { cols >>= col_left_count; } +#endif #endif return cols; @@ -267,6 +319,13 @@ void kimera_select_row(uint8_t row) data[exp][PX_TO_PORT(px)] &= ~(1 << PX_TO_PIN(px)); expander_write_config(exp, data[exp]); } +#if CHANGE_COMBINING +#ifdef TWO_HEADED_KIMERA + if (row < row_left_count) { + kimera_select_row(row + row_left_count); + } +#endif +#endif } void expander_init(uint8_t exp) @@ -349,6 +408,7 @@ uint8_t expander_write_config(uint8_t exp, uint8_t *data) { return expander_write(exp, EXP_COMM_CONFIG_0, data); } + inline uint8_t expander_read_input(uint8_t exp, uint8_t *data) { diff --git a/keyboard/kimera/kimera.h b/keyboard/kimera/kimera.h index 24d3c132..7769efe3 100644 --- a/keyboard/kimera/kimera.h +++ b/keyboard/kimera/kimera.h @@ -156,22 +156,13 @@ const uint16_t PROGMEM dummy[] = { /* Functions */ void kimera_init(void); -void wdt_init(void); -uint8_t read_matrix_mapping(void); -void write_matrix_mapping(void); void kimera_scan(void); uint8_t kimera_matrix_rows(void); uint8_t kimera_matrix_cols(void); -matrix_row_t kimera_read_cols(uint8_t row); +void kimera_read_cols(void); +uint8_t kimera_get_col(uint8_t row, uint8_t col); +matrix_row_t kimera_read_row(uint8_t row); void kimera_unselect_rows(void); void kimera_select_row(uint8_t row); -void expander_init(uint8_t exp); -uint8_t expander_write(uint8_t exp, uint8_t command, uint8_t *data); -uint8_t expander_read(uint8_t exp, uint8_t command, uint8_t *data); -uint8_t expander_write_output(uint8_t exp, uint8_t *data); -uint8_t expander_write_inversion(uint8_t exp, uint8_t *data); -uint8_t expander_write_config(uint8_t exp, uint8_t *data); -uint8_t expander_read_input(uint8_t exp, uint8_t *data); -void init_data(uint8_t value); #endif diff --git a/keyboard/kimera/matrix.c b/keyboard/kimera/matrix.c index bc7b9387..83d2975b 100644 --- a/keyboard/kimera/matrix.c +++ b/keyboard/kimera/matrix.c @@ -28,16 +28,29 @@ along with this program. If not, see . #include "matrix.h" #include "kimera.h" #include "keymap_in_eeprom.h" +#include "timer.h" #ifndef DEBOUNCE # define DEBOUNCE 5 #endif -static uint8_t debouncing = DEBOUNCE; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; + +#define IMPROVED_DEBOUNCE 1 + +#if IMPROVED_DEBOUNCE +#define DEBOUNCE_MASK ((1 << DEBOUNCE) - 1) +static uint8_t matrix_current_row; +static uint16_t matrix_row_timestamp[MATRIX_ROWS]; +static uint8_t matrix_debouncing[MATRIX_ROWS][MATRIX_COLS]; +#else +static uint8_t debouncing = DEBOUNCE; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; +#endif + +static uint16_t kimera_scan_timestamp; inline uint8_t matrix_rows(void) @@ -58,15 +71,27 @@ void matrix_init(void) MCUCR = (1<= 1000) { + xprintf("Scan, %u\n", kimera_scan_timestamp); + kimera_scan_timestamp = timer_read(); + kimera_scan(); + } + +#if IMPROVED_DEBOUNCE + uint16_t elapsed = timer_elapsed(matrix_row_timestamp[matrix_current_row]); + if (elapsed >= 1) { + matrix_row_timestamp[matrix_current_row] = timer_read(); + kimera_select_row(matrix_current_row); + _delay_us(30); + kimera_read_cols(); + for (uint8_t i = 0; i < matrix_cols(); i++) { + uint8_t *debounce = &matrix_debouncing[matrix_current_row][i]; + uint8_t col = kimera_get_col(matrix_current_row, i); + uint8_t count = elapsed; + do { + *debounce <<= 1; + *debounce |= col; + } while (--count); + matrix_row_t *row = &matrix[matrix_current_row]; + matrix_row_t mask = ((matrix_row_t)1 << i); + switch (*debounce & DEBOUNCE_MASK) { + case DEBOUNCE_MASK: +#if DEBOUNCE > 1 + case (DEBOUNCE_MASK >> 1): +#if DEBOUNCE > 2 + case (DEBOUNCE_MASK >> 2): +#if DEBOUNCE > 3 + case (DEBOUNCE_MASK >> 3): +#if DEBOUNCE > 4 + case (DEBOUNCE_MASK >> 4): +#if DEBOUNCE > 5 + case (DEBOUNCE_MASK >> 5): +#if DEBOUNCE > 6 + case (DEBOUNCE_MASK >> 6): +#if DEBOUNCE > 7 + case (DEBOUNCE_MASK >> 7): +#if DEBOUNCE > 8 + case (DEBOUNCE_MASK >> 8): +#if DEBOUNCE > 9 + case (DEBOUNCE_MASK >> 9): +#if DEBOUNCE > 10 + case (DEBOUNCE_MASK >> 10): +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif + if ((*row & mask) == 0) { + *row |= mask; + } + break; +#if DEBOUNCE > 1 + case ((DEBOUNCE_MASK << 1) & DEBOUNCE_MASK): +#if DEBOUNCE > 2 + case ((DEBOUNCE_MASK << 2) & DEBOUNCE_MASK): +#if DEBOUNCE > 3 + case ((DEBOUNCE_MASK << 3) & DEBOUNCE_MASK): +#if DEBOUNCE > 4 + case ((DEBOUNCE_MASK << 4) & DEBOUNCE_MASK): +#if DEBOUNCE > 5 + case ((DEBOUNCE_MASK << 5) & DEBOUNCE_MASK): +#if DEBOUNCE > 6 + case ((DEBOUNCE_MASK << 6) & DEBOUNCE_MASK): +#if DEBOUNCE > 7 + case ((DEBOUNCE_MASK << 7) & DEBOUNCE_MASK): +#if DEBOUNCE > 8 + case ((DEBOUNCE_MASK << 8) & DEBOUNCE_MASK): +#if DEBOUNCE > 9 + case ((DEBOUNCE_MASK << 9) & DEBOUNCE_MASK): +#if DEBOUNCE > 10 + case ((DEBOUNCE_MASK << 10) & DEBOUNCE_MASK): +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif +#endif + break; + case 0: + if ((*row & mask) != 0) { + *row &= ~mask; + } + break; + default: + debug("bounce!: "); + debug_bin8(*debounce & DEBOUNCE_MASK); + debug("\n"); + break; + } + } + kimera_unselect_rows(); + } + + matrix_current_row++; + if (matrix_current_row >= matrix_rows()) { + matrix_current_row = 0; + } +#else for (uint8_t i = 0; i < matrix_rows(); i++) { kimera_select_row(i); _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = kimera_read_cols(i); + matrix_row_t cols = kimera_read_row(i); if (matrix_debouncing[i] != cols) { matrix_debouncing[i] = cols; if (debouncing) { @@ -99,15 +235,19 @@ uint8_t matrix_scan(void) } } } +#endif return 1; } +#if IMPROVED_DEBOUNCE +#else bool matrix_is_modified(void) { if (debouncing) return false; return true; } +#endif inline bool matrix_is_on(uint8_t row, uint8_t col)