diff --git a/drivers/qwiic/qwiic_keyboard.c b/drivers/qwiic/qwiic_keyboard.c index 8e3591fd9..4c7e22fde 100644 --- a/drivers/qwiic/qwiic_keyboard.c +++ b/drivers/qwiic/qwiic_keyboard.c @@ -37,15 +37,15 @@ void qwiic_keyboard_write_keymap(uint8_t * pointer); void qwiic_keyboard_read_keymap(uint8_t * pointer); -bool qwiic_keyboard_master = false; -bool qwiic_keyboard_connected = false; -uint8_t qwiic_keyboard_handshake_message[QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE] = {0}; -uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_ROWS] = {0}; -twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received; +static bool qwiic_keyboard_master = false; +static bool qwiic_keyboard_connected = false; +static uint8_t qwiic_keyboard_handshake_message[QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE] = {0}; +static uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_ROWS] = {0}; +static qwiic_matrix_t matrix_prev[QWIIC_KEYBOARD_ROWS] = {0}; +static twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received; -uint16_t qwiic_keyboard_keymap[QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {{{0}}}; -uint8_t qwiic_keyboard_listening_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START; -uint8_t qwiic_keyboard_processing_slave = false; +static uint16_t qwiic_keyboard_keymap[QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {{{0}}}; +static uint8_t qwiic_keyboard_listening_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START; void qwiic_keyboard_init(void) { twi2c_init(); @@ -69,50 +69,10 @@ void qwiic_keyboard_task(void) { if (qwiic_keyboard_master) { if (qwiic_keyboard_connected) { // send empty message, expecting matrix info - if (MSG_OK == twi2c_transmit_receive(qwiic_keyboard_listening_address, + if (MSG_OK != twi2c_transmit_receive(qwiic_keyboard_listening_address, command, 1, qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE )) { - // majority of this is pulled from keyboard.c:keyboard_task() - static qwiic_matrix_t matrix_prev[QWIIC_KEYBOARD_ROWS]; - qwiic_matrix_t matrix_row = 0; - qwiic_matrix_t matrix_change = 0; - #ifdef QMK_KEYS_PER_SCAN - uint8_t keys_processed = 0; - #endif - for (uint8_t r = 0; r < QWIIC_KEYBOARD_ROWS; r++) { - matrix_row = qwiic_keyboard_matrix_message[r]; - matrix_change = matrix_row ^ matrix_prev[r]; - if (matrix_change) { - for (uint8_t c = 0; c < QWIIC_KEYBOARD_COLS; c++) { - if (matrix_change & ((qwiic_matrix_t)1<= QMK_KEYS_PER_SCAN) - #endif - // process a key per task call - goto QWIIC_MATRIX_LOOP_END; - } - } - } - } - // call with pseudo tick event when no real key event. - #ifdef QMK_KEYS_PER_SCAN - // we can get here with some keys processed now. - if (!keys_processed) - #endif - action_exec(TICK); - QWIIC_MATRIX_LOOP_END: - qwiic_keyboard_processing_slave = false; - } else { // disconnect // qwiic_keyboard_connected = false; } @@ -198,3 +158,32 @@ uint16_t keymap_key_to_keycode(uint8_t layer, keymatrix_t key) { return qwiic_keyboard_keymap[(layer)][(key.pos.row)][(key.pos.col)]; } } + +uint8_t multimatrix_get_num_matrices(void) { + return qwiic_keyboard_connected ? 1 : 0; +} + +uint8_t multimatrix_get_num_cols(uint8_t matrix) { + return QWIIC_KEYBOARD_COLS; +} + +uint8_t multimatrix_get_num_rows(uint8_t matrix) { + return QWIIC_KEYBOARD_ROWS; +} + +uint32_t multimatrix_get_row(uint8_t matrix, uint8_t row) { +return qwiic_keyboard_matrix_message[row]; +} + +uint32_t multimatrix_get_row_cache(uint8_t matrix, uint8_t row) { + return matrix_prev[row]; +} + +void multimatrix_set_row_cache(uint8_t matrix, uint8_t row, uint32_t value) { + matrix_prev[row] = value; +} + +uint8_t* multimatrix_get_source_layers_cache(uint8_t matrix) { + static uint8_t source_layers_cache[(QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS * MAX_LAYER_BITS + 7) / 8] = {0}; + return source_layers_cache; +} diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c index 6bcf3d935..f01a3d99d 100644 --- a/tmk_core/common/action_layer.c +++ b/tmk_core/common/action_layer.c @@ -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) diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h index 8f47fb0c9..c64d0df9d 100644 --- a/tmk_core/common/action_layer.h +++ b/tmk_core/common/action_layer.h @@ -93,6 +93,8 @@ uint32_t layer_state_set_kb(uint32_t state); #define MAX_LAYER_BITS 5 void update_source_layers_cache(keymatrix_t key, uint8_t layer); uint8_t read_source_layers_cache(keymatrix_t key); + +uint8_t get_source_layers_cache_size(uint8_t num_cols, uint8_t num_rows); #endif action_t store_or_get_action(bool pressed, keymatrix_t key); diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index c19661147..36f7f7670 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -145,6 +145,82 @@ bool is_keyboard_master(void) { return true; } +__attribute__((weak)) +uint8_t multimatrix_get_num_matrices(void) { + return 0; +} + +__attribute__((weak)) +uint8_t multimatrix_get_num_cols(uint8_t matrix) { + return 0; +} + +__attribute__((weak)) +uint8_t multimatrix_get_num_rows(uint8_t matrix) { + return 0; +} + +__attribute__((weak)) +uint32_t multimatrix_get_row(uint8_t matrix, uint8_t row) { + return 0; +} + +__attribute__((weak)) +uint32_t multimatrix_get_row_cache(uint8_t matrix, uint8_t row) { + return 0; +} + +__attribute__((weak)) +void multimatrix_set_row_cache(uint8_t matrix, uint8_t row, uint32_t value) { +} + +static uint8_t get_num_matrices(void) { + return 1 + multimatrix_get_num_matrices(); +} + +uint8_t keyboard_get_num_cols(uint8_t matrix) { + if (matrix == 0) { + return MATRIX_COLS; + } else { + return multimatrix_get_num_cols(matrix - 1); + } +} + +uint8_t keyboard_get_num_rows(uint8_t matrix) { + if (matrix == 0) { + return MATRIX_ROWS; + } else { + return multimatrix_get_num_rows(matrix - 1); + } +} + +static uint32_t get_row(uint8_t matrix, uint8_t row) { + if (matrix == 0) { + return matrix_get_row(row); + } else { + return multimatrix_get_row(matrix - 1, row); + } +} + +static matrix_row_t matrix_prev[MATRIX_ROWS]; + +static uint32_t get_row_cache(uint8_t matrix, uint8_t row) { + if (matrix == 0) { + return matrix_prev[row]; + } else { + return multimatrix_get_row_cache(matrix - 1, row); + } +} + +static void set_row_cache(uint8_t matrix, uint8_t row, uint32_t value) { + if (matrix == 0) { + matrix_prev[row] = value; + } else { + return multimatrix_set_row_cache(matrix - 1, row, value); + } +} + + /** \brief keyboard_init * * FIXME: needs doc @@ -203,54 +279,57 @@ void keyboard_init(void) { */ void keyboard_task(void) { - static matrix_row_t matrix_prev[MATRIX_ROWS]; -#ifdef MATRIX_HAS_GHOST - // static matrix_row_t matrix_ghost[MATRIX_ROWS]; -#endif static uint8_t led_status = 0; - matrix_row_t matrix_row = 0; - matrix_row_t matrix_change = 0; + uint32_t matrix_row = 0; + uint32_t matrix_change = 0; #ifdef QMK_KEYS_PER_SCAN uint8_t keys_processed = 0; #endif matrix_scan(); if (is_keyboard_master()) { - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - matrix_row = matrix_get_row(r); - matrix_change = matrix_row ^ matrix_prev[r]; - if (matrix_change) { + for (uint8_t m = 0; m < get_num_matrices(); m++) { + uint8_t num_cols = keyboard_get_num_cols(m); + uint8_t num_rows = keyboard_get_num_rows(m); + for (uint8_t r = 0; r < num_rows; r++) { + matrix_row = get_row(m, r); + uint32_t row_cache = get_row_cache(m, r); + matrix_change = matrix_row ^ row_cache; + if (matrix_change) { #ifdef MATRIX_HAS_GHOST - if (has_ghost_in_row(r, matrix_row)) { - /* Keep track of whether ghosted status has changed for - * debugging. But don't update matrix_prev until un-ghosted, or - * the last key would be lost. - */ - //if (debug_matrix && matrix_ghost[r] != matrix_row) { - // matrix_print(); - //} + //NOTE: The we support ghosting only for the main matrix, since it's only useful for old keyboards without diodes + if (has_ghost_in_row(r, matrix_row)) { + /* Keep track of whether ghosted status has changed for + * debugging. But don't update matrix_prev until un-ghosted, or + * the last key would be lost. + */ + //if (debug_matrix && matrix_ghost[r] != matrix_row) { + // matrix_print(); + //} + //matrix_ghost[r] = matrix_row; + continue; + } //matrix_ghost[r] = matrix_row; - continue; - } - //matrix_ghost[r] = matrix_row; #endif - if (debug_matrix) matrix_print(); - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - if (matrix_change & ((matrix_row_t)1<= QMK_KEYS_PER_SCAN) + // only jump out if we have processed "enough" keys. + if (++keys_processed >= QMK_KEYS_PER_SCAN) #endif - // process a key per task call - goto MATRIX_LOOP_END; + // process a key per task call + goto MATRIX_LOOP_END; + } } } } diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h index 08f997981..f3bbb1739 100644 --- a/tmk_core/common/keyboard.h +++ b/tmk_core/common/keyboard.h @@ -72,6 +72,9 @@ void keyboard_task(void); /* it runs when host LED status is updated */ void keyboard_set_leds(uint8_t leds); +uint8_t keyboard_get_num_cols(uint8_t matrix); +uint8_t keyboard_get_num_rows(uint8_t matrix); + #ifdef __cplusplus } #endif