Compare commits

..

8 Commits

Author SHA1 Message Date
Jack Humbert 47c27bb6b9 Merge pull request #3264 from fredizzimo/multimatrix
Add multi-matrix support and make the layer cache more efficient
2018-07-21 15:34:10 -04:00
Fred Sundvik 19e0bc852f Fix rgb matrix compilation 2018-06-29 22:59:23 +03:00
Fred Sundvik 32028cfc43 Fix SWAP_HANDS for multimatrix 2018-06-29 22:57:05 +03:00
Fred Sundvik 9ddb678fd0 Document some functions 2018-06-29 21:12:14 +03:00
Fred Sundvik 6c68cccd90 Add proper multimatrix support 2018-06-29 21:12:13 +03:00
Fred Sundvik f9c61b1bbe Add a keymatrix_t type
This contains both the matrix number and key position, in preparation
for multi-matrix support
2018-06-29 21:12:12 +03:00
Fred Sundvik c11c7948e6 Make the layer cache more efficient
Also change the internal representation to a one dimensional array
2018-06-29 21:12:11 +03:00
Fred Sundvik 3775c92ff8 Fix missing brackets warning 2018-06-23 00:14:22 +03:00
25 changed files with 699 additions and 497 deletions
+3 -14
View File
@@ -67,7 +67,7 @@ $(eval $(call NEXT_PATH_ELEMENT))
# It's really a very simple if else chain, if you squint enough,
# but the makefile syntax makes it very verbose.
# If we are in a subfolder of keyboards
#
#
# *** No longer needed **
#
# ifeq ($(CURRENT_PATH_ELEMENT),keyboards)
@@ -320,14 +320,6 @@ define PARSE_KEYBOARD
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/.)))
KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/.)))
# get subkeymaps too
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_1)/keymaps/*/*/.)))
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_2)/keymaps/*/*/.)))
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_3)/keymaps/*/*/.)))
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_4)/keymaps/*/*/.)))
KEYMAPS += $$(patsubst $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/%,%,$$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/keyboards/$$(KEYBOARD_FOLDER_PATH_5)/keymaps/*/*/.)))
# this might be needed, but in a different form
#KEYMAPS := $$(sort $$(filter-out $$(KEYBOARD_FOLDER_1) $$(KEYBOARD_FOLDER_2) \
$$(KEYBOARD_FOLDER_3) $$(KEYBOARD_FOLDER_4) $$(KEYBOARD_FOLDER_5), $$(KEYMAPS)))
@@ -361,11 +353,9 @@ define PARSE_KEYBOARD
LAYOUT_KEYMAPS :=
$$(foreach LAYOUT,$$(KEYBOARD_LAYOUTS),$$(eval LAYOUT_KEYMAPS += $$(notdir $$(patsubst %/.,%,$$(wildcard $(ROOT_DIR)/layouts/*/$$(LAYOUT)/*/.)))))
KEYMAPS := $$(sort $$(KEYMAPS) $$(LAYOUT_KEYMAPS))
# $$(eval $$(info $$(KEYMAPS)))
# if the rule after removing the start of it is empty (we haven't specified a kemap or target)
# compile all the keymaps
ifeq ($$(RULE),)
@@ -421,8 +411,7 @@ define PARSE_KEYMAP
MAKE_TARGET := $$(patsubst :%,%,$$(RULE))
# We need to generate an unique indentifer to append to the COMMANDS list
CURRENT_KB_UNDER := $$(subst /,_,$$(CURRENT_KB))
CURRENT_KM_UNDER := $$(subst /,_,$$(CURRENT_KM))
COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB_UNDER)_KEYMAP_$$(CURRENT_KM_UNDER)
COMMAND := COMMAND_KEYBOARD_$$(CURRENT_KB_UNDER)_KEYMAP_$$(CURRENT_KM)
# If we are compiling a keyboard without a subproject, we want to display just the name
# of the keyboard, otherwise keyboard/subproject
KB_SP := $$(CURRENT_KB)
+11 -39
View File
@@ -19,9 +19,8 @@ KEYBOARD_FOLDER_4 := $(notdir $(KEYBOARD_FOLDER_PATH_4))
KEYBOARD_FOLDER_5 := $(notdir $(KEYBOARD_FOLDER_PATH_5))
KEYBOARD_FILESAFE := $(subst /,_,$(KEYBOARD))
KEYMAP_FILESAFE := $(subst /,_,$(KEYMAP))
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP_FILESAFE)
TARGET ?= $(KEYBOARD_FILESAFE)_$(KEYMAP)
KEYBOARD_OUTPUT := $(BUILD_DIR)/obj_$(KEYBOARD_FILESAFE)
# Force expansion
@@ -177,44 +176,26 @@ MAIN_KEYMAP_PATH_3 := $(KEYBOARD_PATH_3)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_4 := $(KEYBOARD_PATH_4)/keymaps/$(KEYMAP)
MAIN_KEYMAP_PATH_5 := $(KEYBOARD_PATH_5)/keymaps/$(KEYMAP)
PARENT_MAIN_KEYMAP_PATH_1 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_1)))
PARENT_MAIN_KEYMAP_PATH_2 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_2)))
PARENT_MAIN_KEYMAP_PATH_3 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_3)))
PARENT_MAIN_KEYMAP_PATH_4 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_4)))
PARENT_MAIN_KEYMAP_PATH_5 := $(patsubst %/,%,$(dir $(MAIN_KEYMAP_PATH_5)))
# $(info $(PARENT_MAIN_KEYMAP_PATH_1))
ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_5)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_5)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_5)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_5)/keymap.c)","")
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_5)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_5)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_4)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_4)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_4)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_4)/keymap.c)","")
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_4)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_4)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_3)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_3)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_3)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_3)/keymap.c)","")
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_3)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_3)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_2)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_2)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_2)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_2)/keymap.c)","")
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_2)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_2)
else ifneq ("$(wildcard $(MAIN_KEYMAP_PATH_1)/keymap.c)","")
-include $(MAIN_KEYMAP_PATH_1)/rules.mk
KEYMAP_C := $(MAIN_KEYMAP_PATH_1)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
else ifneq ("$(wildcard $(PARENT_MAIN_KEYMAP_PATH_1)/keymap.c)","")
KEYMAP_C := $(PARENT_MAIN_KEYMAP_PATH_1)/keymap.c
KEYMAP_PATH := $(MAIN_KEYMAP_PATH_1)
else ifneq ($(LAYOUTS),)
include build_layout.mk
else
@@ -222,34 +203,26 @@ else
# this state should never be reached
endif
PARENT_KEYMAP_PATH := $(patsubst %/,%,$(dir $(KEYMAP_PATH)))
# User space stuff
ifeq ("$(USER_NAME)","")
USER_NAME := $(KEYMAP)
endif
USER_PATH := users/$(USER_NAME)
-include $(USER_PATH)/rules.mk
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
CONFIG_H += $(USER_PATH)/config.h
endif
# Object files directory
# To put object files in current directory, use a dot (.), do NOT make
# this an empty or blank macro!
KEYMAP_OUTPUT := $(BUILD_DIR)/obj_$(TARGET)
-include $(PARENT_KEYMAP_PATH)/rules.mk
-include $(KEYMAP_PATH)/rules.mk
-include $(USER_PATH)/rules.mk
ifneq ("$(wildcard $(PARENT_KEYMAP_PATH)/config.h)","")
CONFIG_H += $(PARENT_KEYMAP_PATH)/config.h
endif
ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
CONFIG_H += $(KEYMAP_PATH)/config.h
endif
ifneq ("$(wildcard $(USER_PATH)/config.h)","")
CONFIG_H += $(USER_PATH)/config.h
endif
# # project specific files
SRC += $(KEYBOARD_SRC) \
@@ -260,7 +233,6 @@ SRC += $(KEYBOARD_SRC) \
#EXTRALDFLAGS = -Wl,--relax
# Search Path
VPATH += $(PARENT_KEYMAP_PATH)
VPATH += $(KEYMAP_PATH)
VPATH += $(KEYBOARD_PATHS)
VPATH += $(COMMON_VPATH)
+2 -6
View File
@@ -3,15 +3,11 @@ LAYOUTS_REPOS := $(patsubst %/,%,$(sort $(dir $(wildcard $(LAYOUTS_PATH)/*/))))
define SEARCH_LAYOUTS_REPO
LAYOUT_KEYMAP_PATH := $$(LAYOUTS_REPO)/$$(LAYOUT)/$$(KEYMAP)
PARENT_LAYOUT_KEYMAP_PATH := $(patsubst %/,%,$(dir $(LAYOUT_KEYMAP_PATH)))
LAYOUT_KEYMAP_C := $$(LAYOUT_KEYMAP_PATH)/keymap.c
PARENT_LAYOUT_KEYMAP_C := $$(PARENT_LAYOUT_KEYMAP_PATH)/keymap.c
ifneq ("$$(wildcard $$(LAYOUT_KEYMAP_C))","")
-include $$(LAYOUT_KEYMAP_PATH)/rules.mk
KEYMAP_C := $$(LAYOUT_KEYMAP_C)
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
else ifneq ("$$(wildcard $$(PARENT_LAYOUT_KEYMAP_C))","")
KEYMAP_C := $$(PARENT_LAYOUT_KEYMAP_C)
KEYMAP_PATH := $$(LAYOUT_KEYMAP_PATH)
endif
endef
@@ -19,4 +15,4 @@ define SEARCH_LAYOUTS
$$(foreach LAYOUTS_REPO,$$(LAYOUTS_REPOS),$$(eval $$(call SEARCH_LAYOUTS_REPO)))
endef
$(foreach LAYOUT,$(LAYOUTS),$(eval $(call SEARCH_LAYOUTS)))
$(foreach LAYOUT,$(LAYOUTS),$(eval $(call SEARCH_LAYOUTS)))
+10 -25
View File
@@ -75,6 +75,11 @@ void twi2c_catch_error(I2CDriver *i2cp)
/**
* Callback after sending of response complete - restores default reply in case polled
*/
void twi2c_clear_after_send(I2CDriver *i2cp)
{
// echoReply.size = 0; // Clear receive message
// i2cSlaveReplyI(i2cp, &initialReply);
}
uint8_t twi2c_start(void) {
i2cStart(&I2C_DRIVER, &i2cconfig);
@@ -95,11 +100,11 @@ void twi2c_init(void) {
}
uint8_t twi2c_write(uint8_t data) {
return i2cMasterTransmitTimeout(&I2C_DRIVER, twi2c_address/2, &data, 1, NULL, 0, MS2ST(100));
return i2cMasterTransmitTimeout(&I2C_DRIVER, twi2c_address/2, &data, 1, 0, 0, MS2ST(100));
}
uint8_t twi2c_transmit(uint8_t address, uint8_t * data, uint16_t length) {
return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, data, length, NULL, 0, MS2ST(100));
return i2cMasterTransmitTimeout(&I2C_DRIVER, address/2, data, length, 0, 0, MS2ST(100));
}
uint8_t twi2c_receive(uint8_t address, uint8_t * data, uint16_t length) {
@@ -107,8 +112,8 @@ uint8_t twi2c_receive(uint8_t address, uint8_t * data, uint16_t length) {
}
uint8_t twi2c_incoming_body[50] = {0};
uint8_t twi2c_outgoing_body[1024] = {0};
uint8_t twi2c_incoming_body[50];
uint8_t twi2c_outgoing_body[1024];
// Response to received messages
I2CSlaveMsg twi2c_incoming_message = {
@@ -133,11 +138,6 @@ I2CSlaveMsg twi2c_outgoing_message = {
twi2c_catch_error
};
void twi2c_clear_after_send(I2CDriver *i2cp) {
twi2c_outgoing_message.size = 0; // Clear receive message
//i2cSlaveReplyI(i2cp, &initialReply);
}
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length) {
memcpy(twi2c_outgoing_body, data, length);
twi2c_outgoing_message.size = length;
@@ -157,26 +157,11 @@ uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback)
return 0;
}
uint8_t twi2c_remove_listening(uint8_t address) {
i2cUnmatchAddress(&I2C_DRIVER, address/2);
return 0;
}
uint8_t twi2c_add_listening(uint8_t address) {
uint8_t twi2c_restart_listening(uint8_t address) {
i2cMatchAddress(&I2C_DRIVER, address/2);
return 0;
}
uint8_t twi2c_remove_listening_i(uint8_t address) {
i2cUnmatchAddressI(&I2C_DRIVER, address/2);
return 0;
}
uint8_t twi2c_add_listening_i(uint8_t address) {
i2cMatchAddressI(&I2C_DRIVER, address/2);
return 0;
}
void twi2c_stop(void) {
i2cUnmatchAll(&I2C_DRIVER);
i2cStop(&I2C_DRIVER);
+1 -4
View File
@@ -43,9 +43,6 @@ void twi2c_stop(void);
uint8_t twi2c_reply(I2CDriver * i2cp, uint8_t * data, uint16_t length);
uint8_t twi2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length);
uint8_t twi2c_start_listening(uint8_t address, twi2c_message_received callback);
uint8_t twi2c_add_listening(uint8_t address);
uint8_t twi2c_remove_listening(uint8_t address);
uint8_t twi2c_add_listening_i(uint8_t address);
uint8_t twi2c_remove_listening_i(uint8_t address);
uint8_t twi2c_restart_listening(uint8_t address);
#endif
+100 -203
View File
@@ -24,45 +24,28 @@
#include "usb_driver.h"
#define QWIIC_KEYBOARD_LAYERS 16
#define QWIIC_KEYBOARD_ROWS 8
#define QWIIC_KEYBOARD_COLS 8
#define QWIIC_KEYBOARD_ROWS 8
#define QWIIC_KEYBOARD_COLS 8
#if (QWIIC_KEYBOARD_COLS <= 8)
typedef uint8_t qwiic_row_t;
#elif (QWIIC_KEYBOARD_COLS <= 16)
typedef uint16_t qwiic_row_t;
#elif (QWIIC_KEYBOARD_COLS <= 32)
typedef uint32_t qwiic_row_t;
#else
#error "QWIIC_KEYBOARD_COLS: invalid value"
#endif
#define qwiic_matrix_t uint8_t
#define QWIIC_KEYBOARD_HANDSHAKE_ADDRESS 0b01010100
#define QWIIC_KEYBOARD_LISTENING_ADDRESS_START 0b01010110
#define QWIIC_KEYBOARD_MAX_DEVICES 1
#define QWIIC_KEYBOARD_KEYMAP_MESSAGE_SIZE (QWIIC_KEYBOARD_LAYERS * QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS)
#define QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE (QWIIC_KEYBOARD_ROWS)
#define QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE (QWIIC_KEYBOARD_LAYERS * QWIIC_KEYBOARD_ROWS * QWIIC_KEYBOARD_COLS)
#define QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE MATRIX_ROWS
void qwiic_keyboard_write_keymap(uint8_t * pointer);
void qwiic_keyboard_read_keymap(uint8_t * pointer, uint8_t index);
void qwiic_keyboard_read_keymap(uint8_t * pointer);
bool qwiic_keyboard_master = false;
bool qwiic_keyboard_received_message = false;
bool qwiic_keyboard_connected[QWIIC_KEYBOARD_MAX_DEVICES] = { false };
uint8_t qwiic_keyboard_keymap_message[QWIIC_KEYBOARD_KEYMAP_MESSAGE_SIZE] = {0};
uint8_t qwiic_keyboard_matrix_message[QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE] = {0};
twi2c_message_received qwiic_keyboard_message_received_ptr = qwiic_keyboard_message_received;
float song_one_up[][2] = SONG(ONE_UP_SOUND);
float song_zelda[][2] = SONG(ZELDA_PUZZLE);
uint8_t first_message = 0;
uint8_t first_message_slave = 0;
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_MAX_DEVICES][QWIIC_KEYBOARD_LAYERS][QWIIC_KEYBOARD_ROWS][QWIIC_KEYBOARD_COLS] = {0};
bool qwiic_keyboard_keymap_initialised[QWIIC_KEYBOARD_MAX_DEVICES] = { false };
uint8_t qwiic_keyboard_listening_address[QWIIC_KEYBOARD_MAX_DEVICES] = { 0 };
#define QWIIC_KEYBOARD_NOT_PROCESSING 255
uint8_t qwiic_keyboard_processing_slave = QWIIC_KEYBOARD_NOT_PROCESSING;
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();
@@ -71,179 +54,66 @@ void qwiic_keyboard_init(void) {
}
void qwiic_keyboard_set_master(void) {
if (!qwiic_keyboard_received_message) {
twi2c_stop();
twi2c_start();
qwiic_keyboard_master = true;
if (first_message == 0) {
PLAY_SONG(song_one_up);
}
first_message += 1;
}
twi2c_stop();
twi2c_start();
qwiic_keyboard_master = true;
}
void qwiic_keyboard_set_slave(void) {
qwiic_keyboard_received_message = true;
if (first_message_slave == 0) {
PLAY_SONG(song_zelda);
}
first_message_slave += 1;
}
static uint8_t keymap_command[1] = { 0x01 };
static uint8_t matrix_command[1] = { 0x02 };
static uint8_t look_counter = 0;
// uint8_t get_available_device_index(void) {
// for (uint8_t i = 0; i < QWIIC_KEYBOARD_MAX_DEVICES; i++) {
// if (!qwiic_keyboard_connected[i])
// return i;
// }
// return 255;
// }
void qwiic_keyboard_get_matrix(uint8_t device_i) {
// msg_t ret = twi2c_transmit_receive(qwiic_keyboard_listening_address[device_i],
// matrix_command, 1,
// qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE
// );
twi2c_transmit(qwiic_keyboard_listening_address[device_i], matrix_command, 1);
msg_t ret = twi2c_receive(qwiic_keyboard_listening_address[device_i],
qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE
);
switch (ret) {
// majority of this is pulled from keyboard.c:keyboard_task()
case I2C_OK:
qwiic_keyboard_processing_slave = device_i;
static qwiic_row_t matrix_prev[QWIIC_KEYBOARD_ROWS];
qwiic_row_t matrix_row = 0;
qwiic_row_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_row_t)1<<c)) {
action_exec((keyevent_t){
.key = (keypos_t){ .row = r, .col = c },
.pressed = (matrix_row & ((qwiic_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
});
// record a processed key
matrix_prev[r] ^= ((qwiic_row_t)1<<c);
#ifdef 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 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 = QWIIC_KEYBOARD_NOT_PROCESSING;
// if (first_message == 100) {
// PLAY_SONG(song_one_up);
// }
// first_message += 1;
break;
case I2C_ERROR:
break;
default:
twi2c_start();
break;
}
}
uint8_t command[1] = { 0x00 };
void qwiic_keyboard_task(void) {
if (USB_DRIVER.state == USB_ACTIVE)
qwiic_keyboard_set_master();
qwiic_keyboard_master = true;
else
qwiic_keyboard_master = false;
if (qwiic_keyboard_master) {
for (uint8_t device_i = 0; device_i < QWIIC_KEYBOARD_MAX_DEVICES; device_i++) {
if (qwiic_keyboard_connected[device_i]) {
// send empty message, expecting matrix info
if (!qwiic_keyboard_keymap_initialised[device_i]) {
// if (MSG_OK == twi2c_transmit_receive(qwiic_keyboard_listening_address[device_i],
// keymap_command, 1,
// qwiic_keyboard_keymap_message, QWIIC_KEYBOARD_KEYMAP_MESSAGE_SIZE
// )) {
twi2c_transmit(qwiic_keyboard_listening_address[device_i], keymap_command, 1);
if (MSG_OK == twi2c_receive(qwiic_keyboard_listening_address[device_i],
qwiic_keyboard_keymap_message, QWIIC_KEYBOARD_KEYMAP_MESSAGE_SIZE
)) {
// load keymap into memory
qwiic_keyboard_keymap_initialised[device_i] = true;
qwiic_keyboard_read_keymap(qwiic_keyboard_keymap_message, device_i);
qwiic_keyboard_get_matrix(device_i);
}
} else {
qwiic_keyboard_get_matrix(device_i);
} // end else - not init
} else { // if not connected
//if (look_counter == 0) {
// send new address to listen on, expect back keymap
uint8_t new_address = QWIIC_KEYBOARD_LISTENING_ADDRESS_START + (device_i*2);
uint8_t address_copy = 0;
twi2c_transmit(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS, &new_address, 1);
if (MSG_OK == twi2c_receive(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS,
&address_copy, 1
)) {
// if (MSG_OK == twi2c_transmit_receive(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS,
// &new_address, 1,
// &address_copy, 1
// )) {
send_byte(address_copy);
//if (address_copy == new_address) {
PLAY_SONG(song_one_up);
qwiic_keyboard_connected[device_i] = true;
qwiic_keyboard_listening_address[device_i] = new_address;
//}
}
//} // end if - look for new
} // end else - connected
} // end for - devices
look_counter = ((look_counter + 1) % 150);
} // end if - master
if (qwiic_keyboard_connected) {
// send empty message, expecting matrix info
if (MSG_OK != twi2c_transmit_receive(qwiic_keyboard_listening_address,
command, 1,
qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE
)) {
// disconnect
// qwiic_keyboard_connected = false;
}
} else { // if not connected
// send new address to listen on, expect back keymap
if (MSG_OK == twi2c_transmit_receive(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS,
&qwiic_keyboard_listening_address, 1,
qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE
)) {
qwiic_keyboard_connected = true;
// load keymap into memory
qwiic_keyboard_read_keymap(qwiic_keyboard_handshake_message);
}
}
}
}
float song_one_up[][2] = SONG(ONE_UP_SOUND);
bool first_message = true;
void qwiic_keyboard_message_received(I2CDriver *i2cp, uint8_t * body, uint16_t size) {
qwiic_keyboard_set_slave();
switch (body[0]) {
// send keymap
case 0x01:
qwiic_keyboard_write_keymap(qwiic_keyboard_keymap_message);
twi2c_reply(i2cp, qwiic_keyboard_keymap_message, QWIIC_KEYBOARD_KEYMAP_MESSAGE_SIZE);
break;
// send matrix
case 0x02:
case 0x00:
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
if (row < MATRIX_ROWS) {
qwiic_keyboard_matrix_message[row] = matrix_get_row(row);
} else {
qwiic_keyboard_matrix_message[row] = 0;
}
if (qwiic_keyboard_connected) {
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
if (row < MATRIX_ROWS) {
qwiic_keyboard_matrix_message[row] = matrix_get_row(row);
} else {
qwiic_keyboard_matrix_message[row] = 0;
}
twi2c_reply(i2cp, qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE);
break;
default:
qwiic_keyboard_listening_address[0] = body[0];
twi2c_add_listening(body[0]);
twi2c_remove_listening(QWIIC_KEYBOARD_HANDSHAKE_ADDRESS);
qwiic_keyboard_connected[0] = true;
qwiic_keyboard_master = false;
twi2c_reply(i2cp, qwiic_keyboard_listening_address, 1);
break;
}
twi2c_reply(i2cp, qwiic_keyboard_matrix_message, QWIIC_KEYBOARD_MATRIX_MESSAGE_SIZE);
if (first_message) {
PLAY_SONG(song_one_up);
first_message = false;
}
} else {
qwiic_keyboard_connected = true;
qwiic_keyboard_master = false;
qwiic_keyboard_listening_address = body[0];
twi2c_restart_listening(qwiic_keyboard_listening_address);
qwiic_keyboard_write_keymap(qwiic_keyboard_handshake_message);
twi2c_reply(i2cp, qwiic_keyboard_handshake_message, QWIIC_KEYBOARD_HANDSHAKE_MESSAGE_SIZE);
}
}
@@ -254,8 +124,7 @@ void qwiic_keyboard_write_keymap(uint8_t * pointer) {
for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
uint16_t keycode = 0;
keycode = pgm_read_word(&keymaps[layer][row][col]);
uint16_t keycode = pgm_read_word(&keymaps[layer][row][col]);
*pointer++ = (keycode >> 8);
*pointer++ = (keycode & 0xFF);
}
@@ -263,13 +132,13 @@ void qwiic_keyboard_write_keymap(uint8_t * pointer) {
}
}
void qwiic_keyboard_read_keymap(uint8_t * pointer, uint8_t index) {
void qwiic_keyboard_read_keymap(uint8_t * pointer) {
for (uint8_t layer = 0; layer < QWIIC_KEYBOARD_LAYERS; layer++) {
for (uint8_t row = 0; row < QWIIC_KEYBOARD_ROWS; row++) {
for (uint8_t col = 0; col < QWIIC_KEYBOARD_COLS; col++) {
uint16_t keycode = ((*pointer++) << 8);
keycode |= (*pointer++);
qwiic_keyboard_keymap[index][layer][row][col] = keycode;
qwiic_keyboard_keymap[layer][row][col] = keycode;
}
}
}
@@ -281,12 +150,40 @@ bool is_keyboard_master(void) {
}
// overwrite the built-in function
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) {
if (qwiic_keyboard_processing_slave == QWIIC_KEYBOARD_NOT_PROCESSING) {
uint16_t keymap_key_to_keycode(uint8_t layer, keymatrix_t key) {
if (key.matrix == 0) {
// Read entire word (16bits)
return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
return pgm_read_word(&keymaps[(layer)][(key.pos.row)][(key.pos.col)]);
} else {
// trick the built-in handling to accept our replacement keymap
return qwiic_keyboard_keymap[qwiic_keyboard_processing_slave][(layer)][(key.row)][(key.col)];
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;
}
+3 -3
View File
@@ -141,11 +141,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// 0b1110111 AD <-> VCC
// 0b1110101 AD <-> SCL
// 0b1110110 AD <-> SDA
#define DRIVER_ADDR_1 0b1110111
#define DRIVER_ADDR_2 0b1110101
#define DRIVER_ADDR_1 0b1110100
#define DRIVER_ADDR_2 0b1110110
#define DRIVER_COUNT 2
#define DRIVER_1_LED_TOTAL 24
#define DRIVER_1_LED_TOTAL 25
#define DRIVER_2_LED_TOTAL 24
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
+62 -112
View File
@@ -43,123 +43,73 @@ const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x6(
0, 1, 2, 3, 4, 5
);
#ifdef RGB_MATRIX_ENABLE
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations
* driver
* | R location
* | | G location
* | | | B location
* | | | | */
{0, C1_3, C2_3, C3_3},
{0, C1_4, C2_4, C3_4},
{0, C1_5, C2_5, C3_5},
{0, C1_11, C2_11, C3_11},
{0, C1_12, C2_12, C3_12},
{0, C1_13, C2_13, C3_13},
{1, C1_3, C2_3, C3_3},
{1, C1_4, C2_4, C3_4},
{1, C1_5, C2_5, C3_5},
{1, C1_11, C2_11, C3_11},
{1, C1_12, C2_12, C3_12},
{1, C1_13, C2_13, C3_13},
// const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
// /* Refer to IS31 manual for these locations
// * driver
// * | R location
// * | | G location
// * | | | B location
// * | | | | */
// {0, C1_3, C2_3, C3_3},
// {0, C1_4, C2_4, C3_4},
// {0, C1_5, C2_5, C3_5},
// {0, C1_11, C2_11, C3_11},
// {0, C1_12, C2_12, C3_12},
// {0, C1_13, C2_13, C3_13},
{0, C1_6, C2_6, C3_6},
{0, C1_7, C2_7, C3_7},
{0, C1_8, C2_8, C3_8},
{0, C1_14, C2_14, C3_14},
{0, C1_15, C2_15, C3_15},
{0, C1_16, C2_16, C3_16},
{1, C1_6, C2_6, C3_6},
{1, C1_7, C2_7, C3_7},
{1, C1_8, C2_8, C3_8},
{1, C1_14, C2_14, C3_14},
{1, C1_15, C2_15, C3_15},
{1, C1_16, C2_16, C3_16},
// {0, C1_6, C2_6, C3_6},
// {0, C1_7, C2_7, C3_7},
// {0, C1_8, C2_8, C3_8},
// {0, C1_14, C2_14, C3_14},
// {0, C1_15, C2_15, C3_15},
// {0, C1_16, C2_16, C3_16},
{0, C9_1, C8_1, C7_1},
{0, C9_2, C8_2, C7_2},
{0, C9_3, C8_3, C7_3},
{0, C9_9, C8_9, C7_9},
{0, C9_10, C8_10, C7_10},
{0, C9_11, C8_11, C7_11},
{1, C9_1, C8_1, C7_1},
{1, C9_2, C8_2, C7_2},
{1, C9_3, C8_3, C7_3},
{1, C9_9, C8_9, C7_9},
{1, C9_10, C8_10, C7_10},
{1, C9_11, C8_11, C7_11},
// {0, C9_1, C8_1, C7_1},
// {0, C9_2, C8_2, C7_2},
// {0, C9_3, C8_3, C7_3},
// {0, C9_9, C8_9, C7_9},
// {0, C9_10, C8_10, C7_10},
// {0, C9_11, C8_11, C7_11},
{0, C9_4, C8_4, C7_4},
{0, C9_5, C8_5, C7_5},
{0, C9_6, C8_6, C7_6},
{0, C9_12, C8_12, C7_12},
{0, C9_13, C8_13, C7_13},
{0, C9_14, C8_14, C7_14},
{1, C9_4, C8_4, C7_4},
{1, C9_5, C8_5, C7_5},
{1, C9_6, C8_6, C7_6},
{1, C9_12, C8_12, C7_12},
{1, C9_13, C8_13, C7_13},
{1, C9_14, C8_14, C7_14}
};
// {0, C9_4, C8_4, C7_4},
// {0, C9_5, C8_5, C7_5},
// {0, C9_6, C8_6, C7_6},
// {0, C9_12, C8_12, C7_12},
// {0, C9_13, C8_13, C7_13},
// {0, C9_14, C8_14, C7_14}
// };
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
// const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
/*{row | col << 4}
| {x=0..224, y=0..64}
| | modifier
| | | */
{{0|(0<<4)}, {20.36*0, 21.33*0}, 1},
{{0|(1<<4)}, {20.36*1, 21.33*0}, 0},
{{0|(2<<4)}, {20.36*2, 21.33*0}, 0},
{{0|(3<<4)}, {20.36*3, 21.33*0}, 0},
{{0|(4<<4)}, {20.36*4, 21.33*0}, 0},
{{0|(5<<4)}, {20.36*5, 21.33*0}, 0},
{{0|(6<<4)}, {20.36*6, 21.33*0}, 0},
{{0|(7<<4)}, {20.36*7, 21.33*0}, 0},
{{0|(8<<4)}, {20.36*8, 21.33*0}, 0},
{{0|(9<<4)}, {20.36*9, 21.33*0}, 0},
{{0|(10<<4)}, {20.36*10,21.33*0}, 0},
{{0|(11<<4)}, {20.36*11,21.33*0}, 1},
// {row | col << 4}
// | {x=0..224, y=0..64}
// | | modifier
// | | |
// {{0|(0<<4)}, {20.36*0, 21.33*0}, 1},
// {{0|(1<<4)}, {20.36*1, 21.33*0}, 0},
// {{0|(2<<4)}, {20.36*2, 21.33*0}, 0},
// {{0|(3<<4)}, {20.36*3, 21.33*0}, 0},
// {{0|(4<<4)}, {20.36*4, 21.33*0}, 0},
// {{0|(5<<4)}, {20.36*5, 21.33*0}, 0},
{{1|(0<<4)}, {20.36*0, 21.33*1}, 1},
{{1|(1<<4)}, {20.36*1, 21.33*1}, 0},
{{1|(2<<4)}, {20.36*2, 21.33*1}, 0},
{{1|(3<<4)}, {20.36*3, 21.33*1}, 0},
{{1|(4<<4)}, {20.36*4, 21.33*1}, 0},
{{1|(5<<4)}, {20.36*5, 21.33*1}, 0},
{{1|(6<<4)}, {20.36*6, 21.33*1}, 0},
{{1|(7<<4)}, {20.36*7, 21.33*1}, 0},
{{1|(8<<4)}, {20.36*8, 21.33*1}, 0},
{{1|(9<<4)}, {20.36*9, 21.33*1}, 0},
{{1|(10<<4)}, {20.36*10,21.33*1}, 0},
{{1|(11<<4)}, {20.36*11,21.33*1}, 1},
// {{1|(0<<4)}, {20.36*0, 21.33*1}, 1},
// {{1|(1<<4)}, {20.36*1, 21.33*1}, 0},
// {{1|(2<<4)}, {20.36*2, 21.33*1}, 0},
// {{1|(3<<4)}, {20.36*3, 21.33*1}, 0},
// {{1|(4<<4)}, {20.36*4, 21.33*1}, 0},
// {{1|(5<<4)}, {20.36*5, 21.33*1}, 0},
{{2|(0<<4)}, {20.36*0, 21.33*2}, 1},
{{2|(1<<4)}, {20.36*1, 21.33*2}, 0},
{{2|(2<<4)}, {20.36*2, 21.33*2}, 0},
{{2|(3<<4)}, {20.36*3, 21.33*2}, 0},
{{2|(4<<4)}, {20.36*4, 21.33*2}, 0},
{{2|(5<<4)}, {20.36*5, 21.33*2}, 0},
{{2|(6<<4)}, {20.36*6, 21.33*2}, 0},
{{2|(7<<4)}, {20.36*7, 21.33*2}, 0},
{{2|(8<<4)}, {20.36*8, 21.33*2}, 0},
{{2|(9<<4)}, {20.36*9, 21.33*2}, 0},
{{2|(10<<4)}, {20.36*10,21.33*2}, 0},
{{2|(11<<4)}, {20.36*11,21.33*2}, 1},
// {{2|(0<<4)}, {20.36*0, 21.33*2}, 1},
// {{2|(1<<4)}, {20.36*1, 21.33*2}, 0},
// {{2|(2<<4)}, {20.36*2, 21.33*2}, 0},
// {{2|(3<<4)}, {20.36*3, 21.33*2}, 0},
// {{2|(4<<4)}, {20.36*4, 21.33*2}, 0},
// {{2|(5<<4)}, {20.36*5, 21.33*2}, 0},
{{3|(0<<4)}, {20.36*0, 21.33*3}, 1},
{{3|(1<<4)}, {20.36*1, 21.33*3}, 1},
{{3|(2<<4)}, {20.36*2, 21.33*3}, 1},
{{3|(3<<4)}, {20.36*3, 21.33*3}, 1},
{{3|(4<<4)}, {20.36*4, 21.33*3}, 1},
{{3|(5<<4)}, {20.36*5, 21.33*3}, 0},
{{3|(6<<4)}, {20.36*6, 21.33*3}, 0},
{{3|(7<<4)}, {20.36*7, 21.33*3}, 1},
{{3|(8<<4)}, {20.36*8, 21.33*3}, 1},
{{3|(9<<4)}, {20.36*9, 21.33*3}, 1},
{{3|(10<<4)}, {20.36*10,21.33*3}, 1},
{{3|(11<<4)}, {20.36*11,21.33*3}, 1}
};
#endif
// {{3|(0<<4)}, {20.36*0, 21.33*3}, 1},
// {{3|(1<<4)}, {20.36*1, 21.33*3}, 1},
// {{3|(2<<4)}, {20.36*2, 21.33*3}, 1},
// {{3|(3<<4)}, {20.36*3, 21.33*3}, 1},
// {{3|(4<<4)}, {20.36*4, 21.33*3}, 1},
// {{3|(5<<4)}, {20.36*5, 21.33*3}, 0}
// };
@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* translates key to keycode */
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
uint8_t keymap_key_to_keycode(uint8_t layer, keymatrix_t key)
{
return pgm_read_byte(&keymaps[(layer)][(key.row)][(key.col)]);
}
+1 -1
View File
@@ -44,7 +44,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "quantum_keycodes.h"
// translates key to keycode
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
uint16_t keymap_key_to_keycode(uint8_t layer, keymatrix_t key);
// translates function id to action
uint16_t keymap_function_id_to_action( uint16_t function_id );
+5 -3
View File
@@ -38,7 +38,7 @@ extern keymap_config_t keymap_config;
#include <inttypes.h>
/* converts key to action */
action_t action_for_key(uint8_t layer, keypos_t key)
action_t action_for_key(uint8_t layer, keymatrix_t key)
{
// 16bit keycodes - important
uint16_t keycode = keymap_key_to_keycode(layer, key);
@@ -184,10 +184,12 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
// translates key to keycode
__attribute__ ((weak))
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
uint16_t keymap_key_to_keycode(uint8_t layer, keymatrix_t key)
{
// Read entire word (16bits)
return pgm_read_word(&keymaps[(layer)][(key.row)][(key.col)]);
// The default implmention does not have multiple matrix support
// and therfore it ignores the matrix field of the key
return pgm_read_word(&keymaps[(layer)][(key.pos.row)][(key.pos.col)]);
}
// translates function id to action
+7 -6
View File
@@ -198,22 +198,23 @@ bool process_music(uint16_t keycode, keyrecord_t *record) {
}
uint8_t note = 36;
// Note: Multimatrix support is missing from this (it's probablly better to define it using keycodes)
#ifdef MUSIC_MAP
if (music_mode == MUSIC_MODE_CHROMATIC) {
note = music_starting_note + music_offset + 36 + music_map[record->event.key.row][record->event.key.col];
note = music_starting_note + music_offset + 36 + music_map[record->event.key.pos.row][record->event.key.pos.col];
} else {
uint8_t position = music_map[record->event.key.row][record->event.key.col];
uint8_t position = music_map[record->event.key.pos.row][record->event.key.pos.col];
note = music_starting_note + music_offset + 36 + SCALE[position % 12] + (position / 12)*12;
}
#else
if (music_mode == MUSIC_MODE_CHROMATIC)
note = (music_starting_note + record->event.key.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.row);
note = (music_starting_note + record->event.key.pos.col + music_offset - 3)+12*(MATRIX_ROWS - record->event.key.pos.row);
else if (music_mode == MUSIC_MODE_GUITAR)
note = (music_starting_note + record->event.key.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.row);
note = (music_starting_note + record->event.key.pos.col + music_offset + 32)+5*(MATRIX_ROWS - record->event.key.pos.row);
else if (music_mode == MUSIC_MODE_VIOLIN)
note = (music_starting_note + record->event.key.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.row);
note = (music_starting_note + record->event.key.pos.col + music_offset + 32)+7*(MATRIX_ROWS - record->event.key.pos.row);
else if (music_mode == MUSIC_MODE_MAJOR)
note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.row);
note = (music_starting_note + SCALE[record->event.key.pos.col + music_offset] - 3)+12*(MATRIX_ROWS - record->event.key.pos.row);
else
note = music_starting_note;
#endif
+1 -1
View File
@@ -190,7 +190,7 @@ static bool grave_esc_was_shifted = false;
bool process_record_quantum(keyrecord_t *record) {
/* This gets the keycode from the key pressed */
keypos_t key = record->event.key;
keymatrix_t key = record->event.key;
uint16_t keycode;
#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+2 -1
View File
@@ -119,7 +119,8 @@ void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) {
bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
if ( record->event.pressed ) {
uint8_t led[8], led_count;
map_row_column_to_led(record->event.key.row, record->event.key.col, led, &led_count);
// TODO: Support multi-matrix keyboards
map_row_column_to_led(record->event.key.pos.row, record->event.key.pos.col, led, &led_count);
if (led_count > 0) {
for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) {
g_last_led_hit[i - 1] = g_last_led_hit[i - 2];
+21
View File
@@ -0,0 +1,21 @@
/* Copyright 2018 Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define MATRIX_ROWS 2
#define MATRIX_COLS 2
#define PREVENT_STUCK_MODIFIERS
+24
View File
@@ -0,0 +1,24 @@
/* Copyright 2018 Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "quantum.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = {
{KC_A, KC_B},
{KC_C, KC_D},
}
};
+16
View File
@@ -0,0 +1,16 @@
# Copyright 2018 Fred Sundvik
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
CUSTOM_MATRIX=yes
+142
View File
@@ -0,0 +1,142 @@
/* Copyright 2018 Fred Sundvik
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "test_common.hpp"
#if MAX_LAYER_BITS != 5
#error "Tese tests assume that the MAX_LAYER_BITS is equal to 5"
// If this is changed, change the constants below
#endif
#if MATRIX_COLS != 2 || MATRIX_ROWS !=2
#error "These tests assume that the second row starts after the second column"
#endif
namespace
{
constexpr uint8_t max_layer_value = 0b11111;
constexpr uint8_t min_layer_value = 0;
constexpr uint8_t alternating_starting_with_1 = 0b10101;
constexpr uint8_t alternating_starting_with_0 = 0b01010;
uint8_t read_cache(uint8_t col, uint8_t row) {
keymatrix_t key;
key.pos.col = col;
key.pos.row = row;
key.matrix = 0;
return read_source_layers_cache(key);
}
void write_cache(uint8_t col, uint8_t row, uint8_t value) {
keymatrix_t key;
key.pos.col = col;
key.pos.row = row;
key.matrix = 0;
return update_source_layers_cache(key, value);
}
void fill_cache() {
for (int i=0; i < MATRIX_ROWS; i++) {
for (int j=0; j < MATRIX_COLS; j++) {
write_cache(j, i, max_layer_value);
}
}
}
void clear_cache() {
for (int i=0; i < MATRIX_ROWS; i++) {
for (int j=0; j < MATRIX_COLS; j++) {
write_cache(j, i, min_layer_value);
}
}
}
}
class LayerCache : public testing::Test
{
public:
LayerCache()
{
clear_cache();
}
};
TEST_F(LayerCache, LayerCacheIsInitializedToZero) {
for (int i=0; i < MATRIX_ROWS; i++) {
for (int j=0; j < MATRIX_COLS; j++) {
EXPECT_EQ(read_cache(j, i), min_layer_value);
}
}
}
TEST_F(LayerCache, FillAndClearCache) {
fill_cache();
clear_cache();
for (int i=0; i < MATRIX_ROWS; i++) {
for (int j=0; j < MATRIX_COLS; j++) {
EXPECT_EQ(read_cache(j, i), min_layer_value);
}
}
}
TEST_F(LayerCache, WriteAndReadFirstPosMaximumValue) {
write_cache(0, 0, max_layer_value);
EXPECT_EQ(read_cache(0, 0), max_layer_value);
// The second position should not be updated
EXPECT_EQ(read_cache(1, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
TEST_F(LayerCache, WriteAndReadSecondPosMaximumValue) {
write_cache(1, 0, max_layer_value);
EXPECT_EQ(read_cache(1, 0), max_layer_value);
// The surrounding positions should not be updated
EXPECT_EQ(read_cache(0, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
TEST_F(LayerCache, WriteAndReadFirstPosAlternatingBitsStartingWith1) {
write_cache(0, 0, alternating_starting_with_1);
EXPECT_EQ(read_cache(0, 0), alternating_starting_with_1);
// The second position should not be updated
EXPECT_EQ(read_cache(1, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
TEST_F(LayerCache, WriteAndReadSecondPosAlternatingBitsStartingWith1) {
write_cache(1, 0, alternating_starting_with_1);
EXPECT_EQ(read_cache(1, 0), alternating_starting_with_1);
// The surrounding positions should not be updated
EXPECT_EQ(read_cache(0, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
TEST_F(LayerCache, WriteAndReadFirstPosAlternatingBitsStartingWith0) {
write_cache(0, 0, alternating_starting_with_0);
EXPECT_EQ(read_cache(0, 0), alternating_starting_with_0);
// The second position should not be updated
EXPECT_EQ(read_cache(1, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
TEST_F(LayerCache, WriteAndReadSecondPosAlternatingBitsStartingWith0) {
write_cache(1, 0, alternating_starting_with_0);
EXPECT_EQ(read_cache(1, 0), alternating_starting_with_0);
// The surrounding positions should not be updated
EXPECT_EQ(read_cache(0, 0), min_layer_value);
EXPECT_EQ(read_cache(0, 1), min_layer_value);
}
+4 -3
View File
@@ -106,13 +106,14 @@ bool swap_held = false;
void process_hand_swap(keyevent_t *event) {
static swap_state_row_t swap_state[MATRIX_ROWS];
keypos_t pos = event->key;
// TODO: Properly support multimatrices, currenty this only works for single-matrix keyboards
keypos_t pos = event->key.pos;
swap_state_row_t col_bit = (swap_state_row_t)1<<pos.col;
bool do_swap = event->pressed ? swap_hands :
swap_state[pos.row] & (col_bit);
if (do_swap) {
event->key = hand_swap_config[pos.row][pos.col];
event->key.pos = hand_swap_config[pos.row][pos.col];
swap_state[pos.row] |= col_bit;
} else {
swap_state[pos.row] &= ~(col_bit);
@@ -892,7 +893,7 @@ void clear_keyboard_but_mods(void)
*
* FIXME: Needs documentation.
*/
bool is_tap_key(keypos_t key)
bool is_tap_key(keymatrix_t key)
{
action_t action = layer_switch_get_action(key);
+2 -2
View File
@@ -50,7 +50,7 @@ typedef struct {
void action_exec(keyevent_t event);
/* action for key */
action_t action_for_key(uint8_t layer, keypos_t key);
action_t action_for_key(uint8_t layer, keymatrix_t key);
/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
@@ -94,7 +94,7 @@ void unregister_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);
bool is_tap_key(keymatrix_t key);
#ifndef NO_ACTION_TAPPING
void process_record_tap_hint(keyrecord_t *record);
+92 -27
View File
@@ -220,37 +220,102 @@ void layer_debug(void)
#endif
#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
static const uint8_t layer_cache_mask = (1u << MAX_LAYER_BITS) - 1;
void update_source_layers_cache(keypos_t key, uint8_t layer)
{
const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
source_layers_cache[storage_row][bit_number] ^=
(-((layer & (1U << bit_number)) != 0)
^ source_layers_cache[storage_row][bit_number])
& (1U << storage_bit);
}
/** \brief Get the pointer to the source layer cache for a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
uint8_t* multimatrix_get_source_layers_cache(uint8_t matrix) {
return 0;
}
uint8_t read_source_layers_cache(keypos_t key)
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 uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
uint8_t layer = 0;
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 >= num_cache_bytes) {
return;
}
const uint8_t bit_position = bit_number % 8;
int8_t shift = 16 - MAX_LAYER_BITS - bit_position;
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
layer |=
((source_layers_cache[storage_row][bit_number]
& (1U << storage_bit)) != 0)
<< bit_number;
if (shift > 8 ) {
// We need to write only one byte
shift -= 8;
const uint8_t mask = layer_cache_mask << shift;
const uint8_t shifted_layer = layer << shift;
cache[byte_number] = (shifted_layer & mask) | (cache[byte_number] & (~mask));
} else {
if (byte_number + 1 >= num_cache_bytes) {
return;
}
// We need to write two bytes
uint16_t value = layer;
uint16_t mask = layer_cache_mask;
value <<= shift;
mask <<= shift;
return layer;
uint16_t masked_value = value & mask;
uint16_t inverse_mask = ~mask;
// This could potentially be done with a single write, but then we have to assume the endian
cache[byte_number + 1] = masked_value | (cache[byte_number + 1] & (inverse_mask));
masked_value >>= 8;
inverse_mask >>= 8;
cache[byte_number] = masked_value | (cache[byte_number] & (inverse_mask));
}
}
uint8_t read_source_layers_cache(keymatrix_t key)
{
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 >= num_cache_bytes) {
return 0;
}
const uint8_t bit_position = bit_number % 8;
int8_t shift = 16 - MAX_LAYER_BITS - bit_position;
if (shift > 8 ) {
// We need to read only one byte
shift -= 8;
return (cache[byte_number] >> shift) & layer_cache_mask;
} else {
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 = 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
@@ -261,7 +326,7 @@ uint8_t read_source_layers_cache(keypos_t key)
* when the layer is switched after the down event but before the up
* event as they may get stuck otherwise.
*/
action_t store_or_get_action(bool pressed, keypos_t key)
action_t store_or_get_action(bool pressed, keymatrix_t key)
{
#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
if (disable_action_cache) {
@@ -288,7 +353,7 @@ action_t store_or_get_action(bool pressed, keypos_t key)
*
* FIXME: Needs docs
*/
int8_t layer_switch_get_layer(keypos_t key)
int8_t layer_switch_get_layer(keymatrix_t key)
{
#ifndef NO_ACTION_LAYER
action_t action;
@@ -315,7 +380,7 @@ int8_t layer_switch_get_layer(keypos_t key)
*
* FIXME: Needs docs
*/
action_t layer_switch_get_action(keypos_t key)
action_t layer_switch_get_action(keymatrix_t key)
{
return action_for_key(layer_switch_get_layer(key), key);
}
+7 -5
View File
@@ -91,15 +91,17 @@ uint32_t layer_state_set_kb(uint32_t state);
#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
/* The number of bits needed to represent the layer number: log2(32). */
#define MAX_LAYER_BITS 5
void update_source_layers_cache(keypos_t key, uint8_t layer);
uint8_t read_source_layers_cache(keypos_t key);
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, keypos_t key);
action_t store_or_get_action(bool pressed, keymatrix_t key);
/* return the topmost non-transparent layer currently associated with key */
int8_t layer_switch_get_layer(keypos_t key);
int8_t layer_switch_get_layer(keymatrix_t key);
/* return action depending on current layer status */
action_t layer_switch_get_action(keypos_t key);
action_t layer_switch_get_action(keymatrix_t key);
#endif
+1 -1
View File
@@ -116,7 +116,7 @@ static bool scan_keycode(uint8_t keycode)
matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1<<c)) {
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
if (keycode == keymap_key_to_keycode(0, (keymatrix_t){ (keypos_t){.row = r, .col = c }, .matrix=0 })) {
return true;
}
}
+165 -35
View File
@@ -145,6 +145,132 @@ bool is_keyboard_master(void) {
return true;
}
/** \brief Get the number of currently connected matrices
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: It should return the number of additional matrices, the master is always implied.
*/
__attribute__((weak))
uint8_t multimatrix_get_num_matrices(void) {
return 0;
}
/** \brief Get the number of columns of a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
uint8_t multimatrix_get_num_cols(uint8_t matrix) {
return 0;
}
/** \brief Get the number of rows of a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
uint8_t multimatrix_get_num_rows(uint8_t matrix) {
return 0;
}
/** \brief Get the row status of a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
uint32_t multimatrix_get_row(uint8_t matrix, uint8_t row) {
return 0;
}
/** \brief Get the row cache of a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
uint32_t multimatrix_get_row_cache(uint8_t matrix, uint8_t row) {
return 0;
}
/** \brief Set the row cache of a connected matrix
*
* Implement this if you support multiple matrices, see qwiic_keyboard.c for an example
* NOTE: The matrix index 0 is the first remote matrix, the function is not called for the master
*/
__attribute__((weak))
void multimatrix_set_row_cache(uint8_t matrix, uint8_t row, uint32_t value) {
}
/** \brief Get the number of currently connected matrices
*
* For normal keyboards this usually returns 1, but for multi-matrix keyboards this will
* return the total number of connected keyboards/modules including the master
*/
uint8_t keyboard_get_num_matrices(void) {
return 1 + multimatrix_get_num_matrices();
}
/** \brief Get the number of columns of a connected matrix
*
* Specify the matrix index to query connected multi-matrix keyboards/modules
* 0 is always the master
*/
uint8_t keyboard_get_num_cols(uint8_t matrix) {
if (matrix == 0) {
return MATRIX_COLS;
} else {
return multimatrix_get_num_cols(matrix - 1);
}
}
/** \brief Get the number of rows of a connected matrix
*
* Specify the matrix index to query connected multi-matrix keyboards/modules
* 0 is always the master
*/
uint8_t keyboard_get_num_rows(uint8_t matrix) {
if (matrix == 0) {
return MATRIX_ROWS;
} else {
return multimatrix_get_num_rows(matrix - 1);
}
}
/** \brief Get the row status of a connected matrix
*
* Specify the matrix index to query connected multi-matrix keyboards/modules
* 0 is always the master
*/
uint32_t keyboard_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,53 +329,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 < keyboard_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 = keyboard_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<<c)) {
action_exec((keyevent_t){
.key = (keypos_t){ .row = r, .col = c },
.pressed = (matrix_row & ((matrix_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
});
// record a processed key
matrix_prev[r] ^= ((matrix_row_t)1<<c);
if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < num_cols; c++) {
if (matrix_change & (uint32_t)(1u<<c)) {
action_exec((keyevent_t){
// The main matrix is always 0
.key = (keymatrix_t){.pos = (keypos_t){ .row = r, .col = c }, .matrix = m},
.pressed = (matrix_row & ((uint32_t)1u<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
});
// record a processed key
row_cache ^= (uint32_t)(1u<<c);
set_row_cache(m, r, row_cache);
#ifdef QMK_KEYS_PER_SCAN
// only jump out if we have processed "enough" keys.
if (++keys_processed >= 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;
}
}
}
}
+16 -5
View File
@@ -32,27 +32,33 @@ typedef struct {
uint8_t row;
} keypos_t;
/* the key and matrix position */
typedef struct {
keypos_t pos;
uint8_t matrix;
} keymatrix_t;
/* key event */
typedef struct {
keypos_t key;
keymatrix_t key;
bool pressed;
uint16_t time;
} keyevent_t;
/* equivalent test of keypos_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
/* equivalent test of keymatrix_t */
#define KEYEQ(keya, keyb) (keya.pos.row == keyb.pos.row && keya.pos.col == keyb.pos.col && keya.matrix == keyb.matrix)
/* Rules for No Event:
* 1) (time == 0) to handle (keyevent_t){} as empty event
* 2) Matrix(255, 255) to make TICK event available
*/
static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.pos.row == 255 && event.key.pos.col == 255); }
static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
/* Tick event */
#define TICK (keyevent_t){ \
.key = (keypos_t){ .row = 255, .col = 255 }, \
.key = (keymatrix_t){ .pos = (keypos_t){.row = 255, .col = 255}, .matrix = 0 }, \
.pressed = false, \
.time = (timer_read() | 1) \
}
@@ -66,6 +72,11 @@ void keyboard_task(void);
/* it runs when host LED status is updated */
void keyboard_set_leds(uint8_t leds);
uint8_t keyboard_get_num_matrices(void);
uint8_t keyboard_get_num_cols(uint8_t matrix);
uint8_t keyboard_get_num_rows(uint8_t matrix);
uint32_t keyboard_get_row(uint8_t matrix, uint8_t row);
#ifdef __cplusplus
}
#endif