From 5c8b23ccffa0083752044f0459e6ac3114ce6e52 Mon Sep 17 00:00:00 2001 From: Takeshi ISHII <2170248+mtei@users.noreply.github.com> Date: Sat, 4 Jul 2020 23:04:47 +0900 Subject: [PATCH] add SPLIT_HAND_MATRIX_GRID support (#8685) Co-authored-by: Danny --- docs/config_options.md | 5 ++++- docs/feature_split_keyboard.md | 18 ++++++++++++++++++ quantum/split_common/split_util.c | 24 ++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/config_options.md b/docs/config_options.md index ab26fd46ce..21c9972e04 100644 --- a/docs/config_options.md +++ b/docs/config_options.md @@ -250,7 +250,10 @@ There are a few different ways to set handedness for split keyboards (listed in * `#define SPLIT_HAND_PIN B7` * For using high/low pin to determine handedness, low = right hand, high = left hand. Replace `B7` with the pin you are using. This is optional, and if you leave `SPLIT_HAND_PIN` undefined, then you can still use the EE_HANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses. -* `#define EE_HANDS` (only works if `SPLIT_HAND_PIN` is not defined) +* `#define SPLIT_HAND_MATRIX_GRID ,` + * The handedness is determined by using the intersection of the keyswitches in the key matrix, which does not exist. Normally, when this intersection is shorted (level low), it is considered left. If you define `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT`, it is determined to be right when the level is low. + +* `#define EE_HANDS` (only works if `SPLIT_HAND_PIN` and `SPLIT_HAND_MATRIX_GRID` are not defined) * Reads the handedness value stored in the EEPROM after `eeprom-lefthand.eep`/`eeprom-righthand.eep` has been flashed to their respective halves. * `#define MASTER_RIGHT` diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md index 63374a804e..ce470b9964 100644 --- a/docs/feature_split_keyboard.md +++ b/docs/feature_split_keyboard.md @@ -90,6 +90,24 @@ You can configure the firmware to read a pin on the controller to determine hand This will read the specified pin. If it's high, then the controller assumes it is the left hand, and if it's low, it's assumed to be the right side. +#### Handedness by Matrix Pin + +You can configure the firmware to read key matrix pins on the controller to determine handedness. To do this, add the following to your `config.h` file: + +```c +#define SPLIT_HAND_MATRIX_GRID D0, F1 +``` + +The first pin is the output pin and the second is the input pin. + +Some keyboards have unused intersections in the key matrix. This setting uses one of these unused intersections to determine the handness. + +Normally, when a diode is connected to an intersection, it is judged to be left. If you add the following definition, it will be judged to be right. + +```c +#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT +``` + #### Handedness by EEPROM This method sets the keyboard's handedness by setting a flag in the persistent storage (`EEPROM`). This is checked when the controller first starts up, and determines what half the keyboard is, and how to orient the keyboard layout. diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index afcd9d2aa5..90735eda44 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -5,6 +5,7 @@ #include "timer.h" #include "transport.h" #include "quantum.h" +#include "wait.h" #ifdef PROTOCOL_LUFA # include @@ -82,11 +83,34 @@ static inline bool usbIsActive(void) { static inline bool usbIsActive(void) { return true; } #endif +#ifdef SPLIT_HAND_MATRIX_GRID +void matrix_io_delay(void); + +static uint8_t peek_matrix_intersection(pin_t out_pin, pin_t in_pin) { + setPinInputHigh(in_pin); + setPinOutput(out_pin); + writePinLow(out_pin); + // It's almost unnecessary, but wait until it's down to low, just in case. + wait_us(1); + uint8_t pin_state = readPin(in_pin); + // Set out_pin to a setting that is less susceptible to noise. + setPinInputHigh(out_pin); + matrix_io_delay(); // Wait for the pull-up to go HIGH. + return pin_state; +} +#endif + __attribute__((weak)) bool is_keyboard_left(void) { #if defined(SPLIT_HAND_PIN) // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand setPinInput(SPLIT_HAND_PIN); return readPin(SPLIT_HAND_PIN); +#elif defined(SPLIT_HAND_MATRIX_GRID) +# ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT + return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); +# else + return !peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); +# endif #elif defined(EE_HANDS) return eeconfig_read_handedness(); #elif defined(MASTER_RIGHT)