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)