Browse Source

kimera: Improve matrix scanning frequency

- Implement improved debounce algorithm
- Change combining of keymap for two-headed kimera
master
Kai Ryu 8 years ago
parent
commit
93029977a8
3 changed files with 210 additions and 19 deletions
  1. 64
    4
      keyboard/kimera/kimera.c
  2. 3
    12
      keyboard/kimera/kimera.h
  3. 143
    3
      keyboard/kimera/matrix.c

+ 64
- 4
keyboard/kimera/kimera.c View File

@@ -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)
{

+ 3
- 12
keyboard/kimera/kimera.h View File

@@ -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

+ 143
- 3
keyboard/kimera/matrix.c View File

@@ -28,16 +28,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#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<<JTD);

kimera_init();
kimera_scan_timestamp = timer_read();

// initialize row and col
kimera_unselect_rows();

// initialize matrix state: all keys off
#if IMPROVED_DEBOUNCE
for (uint8_t i = 0; i < matrix_rows(); i++) {
matrix[i] = 0;
matrix_current_row = 0;
matrix_row_timestamp[i] = timer_read();
for (uint8_t j = 0; j < matrix_cols(); j++) {
matrix_debouncing[i][j] = 0;
}
}
#else
for (uint8_t i=0; i < matrix_rows(); i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
}
#endif

PORTD &= ~(1<<PD4);

@@ -74,12 +99,123 @@ void matrix_init(void)

uint8_t matrix_scan(void)
{
kimera_scan();

/* xprintf("Row: %d, %u\n", matrix_current_row, timer_read()); */

if (timer_elapsed(kimera_scan_timestamp) >= 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)