Add proper multimatrix support

This commit is contained in:
Fred Sundvik 2018-06-29 20:48:08 +03:00
parent f9c61b1bbe
commit 6c68cccd90
5 changed files with 195 additions and 97 deletions

View file

@ -220,15 +220,32 @@ void layer_debug(void)
#endif
#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS * MAX_LAYER_BITS + 7) / 8] = {0};
static const uint8_t layer_cache_mask = (1u << MAX_LAYER_BITS) - 1;
__attribute__((weak))
uint8_t* multimatrix_get_source_layers_cache(uint8_t matrix) {
return 0;
}
static uint8_t* get_source_layers_cache(keymatrix_t key) {
if (key.matrix == 0) {
static uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS * MAX_LAYER_BITS + 7) / 8] = {0};
return source_layers_cache;
} else {
return multimatrix_get_source_layers_cache(key.matrix - 1);
}
}
void update_source_layers_cache(keymatrix_t key, uint8_t layer)
{
const uint16_t key_number = key.pos.col + (key.pos.row * MATRIX_COLS);
const uint8_t num_cols = keyboard_get_num_cols(key.matrix);
const uint8_t num_rows = keyboard_get_num_rows(key.matrix);
const uint16_t num_cache_bytes = get_source_layers_cache_size(num_cols, num_rows);
uint8_t* cache = get_source_layers_cache(key);
const uint16_t key_number = key.pos.col + (key.pos.row * num_cols);
const uint32_t bit_number = key_number * MAX_LAYER_BITS;
const uint16_t byte_number = bit_number / 8;
if (byte_number >= sizeof(source_layers_cache)) {
if (byte_number >= num_cache_bytes) {
return;
}
const uint8_t bit_position = bit_number % 8;
@ -239,9 +256,9 @@ void update_source_layers_cache(keymatrix_t key, uint8_t layer)
shift -= 8;
const uint8_t mask = layer_cache_mask << shift;
const uint8_t shifted_layer = layer << shift;
source_layers_cache[byte_number] = (shifted_layer & mask) | (source_layers_cache[byte_number] & (~mask));
cache[byte_number] = (shifted_layer & mask) | (cache[byte_number] & (~mask));
} else {
if (byte_number + 1 >= sizeof(source_layers_cache)) {
if (byte_number + 1 >= num_cache_bytes) {
return;
}
// We need to write two bytes
@ -254,19 +271,23 @@ void update_source_layers_cache(keymatrix_t key, uint8_t layer)
uint16_t inverse_mask = ~mask;
// This could potentially be done with a single write, but then we have to assume the endian
source_layers_cache[byte_number + 1] = masked_value | (source_layers_cache[byte_number + 1] & (inverse_mask));
cache[byte_number + 1] = masked_value | (cache[byte_number + 1] & (inverse_mask));
masked_value >>= 8;
inverse_mask >>= 8;
source_layers_cache[byte_number] = masked_value | (source_layers_cache[byte_number] & (inverse_mask));
cache[byte_number] = masked_value | (cache[byte_number] & (inverse_mask));
}
}
uint8_t read_source_layers_cache(keymatrix_t key)
{
const uint16_t key_number = key.pos.col + (key.pos.row * MATRIX_COLS);
const uint8_t num_cols = keyboard_get_num_cols(key.matrix);
const uint8_t num_rows = keyboard_get_num_rows(key.matrix);
const uint16_t num_cache_bytes = get_source_layers_cache_size(num_cols, num_rows);
uint8_t* cache = get_source_layers_cache(key);
const uint16_t key_number = key.pos.col + (key.pos.row * num_cols);
const uint32_t bit_number = key_number * MAX_LAYER_BITS;
const uint16_t byte_number = bit_number / 8;
if (byte_number >= sizeof(source_layers_cache)) {
if (byte_number >= num_cache_bytes) {
return 0;
}
const uint8_t bit_position = bit_number % 8;
@ -276,17 +297,21 @@ uint8_t read_source_layers_cache(keymatrix_t key)
if (shift > 8 ) {
// We need to read only one byte
shift -= 8;
return (source_layers_cache[byte_number] >> shift) & layer_cache_mask;
return (cache[byte_number] >> shift) & layer_cache_mask;
} else {
if (byte_number + 1 >= sizeof(source_layers_cache)) {
if (byte_number + 1 >= num_cache_bytes) {
return 0;
}
// Otherwise read two bytes
// This could potentially be done with a single read, but then we have to assume the endian
uint16_t value = source_layers_cache[byte_number] << 8 | source_layers_cache[byte_number + 1];
uint16_t value = cache[byte_number] << 8 | cache[byte_number + 1];
return (value >> shift) & layer_cache_mask;
}
}
uint8_t get_source_layers_cache_size(uint8_t num_cols, uint8_t num_rows) {
return (num_rows * num_cols * MAX_LAYER_BITS + 7) / 8;
}
#endif
/** \brief Store or get action (FIXME: Needs better summary)