From 5ba4391cf29ce624f17593417212b3dbca1609ad Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sun, 28 Feb 2021 15:52:58 +0000 Subject: Refactor of USB code within split_common (#11890) * Initial refactor of usb code within split_common * Add headers * Correct disable condition * Format * Align func name --- quantum/split_common/split_util.c | 70 ++++++++++++++------------------------- 1 file changed, 24 insertions(+), 46 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 2ae44e6e15..9e75e19ce0 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -1,3 +1,18 @@ +/* Copyright 2021 QMK + * + * 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 3 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 . + */ #include "split_util.h" #include "matrix.h" #include "keyboard.h" @@ -6,14 +21,7 @@ #include "transport.h" #include "quantum.h" #include "wait.h" - -#ifdef PROTOCOL_LUFA -# include -#endif - -#ifdef PROTOCOL_VUSB -# include -#endif +#include "usb_util.h" #ifdef EE_HANDS # include "eeconfig.h" @@ -31,56 +39,21 @@ # define SPLIT_USB_TIMEOUT_POLL 10 #endif -#ifdef PROTOCOL_CHIBIOS -# define SPLIT_USB_DETECT // Force this on for now -#endif - volatile bool isLeftHand = true; #if defined(SPLIT_USB_DETECT) -# if defined(PROTOCOL_LUFA) -static inline bool usbHasActiveConnection(void) { return USB_Device_IsAddressSet(); } -static inline void usbDisable(void) { - USB_Disable(); - USB_DeviceState = DEVICE_STATE_Unattached; -} -# elif defined(PROTOCOL_CHIBIOS) -static inline bool usbHasActiveConnection(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; } -static inline void usbDisable(void) { usbStop(&USBD1); } -# elif defined(PROTOCOL_VUSB) -static inline bool usbHasActiveConnection(void) { - usbPoll(); - return usbConfiguration; -} -static inline void usbDisable(void) { usbDeviceDisconnect(); } -# else -static inline bool usbHasActiveConnection(void) { return true; } -static inline void usbDisable(void) {} -# endif - -bool usbIsActive(void) { +static bool usbIsActive(void) { for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) { // This will return true if a USB connection has been established - if (usbHasActiveConnection()) { + if (usb_connected_state()) { return true; } wait_ms(SPLIT_USB_TIMEOUT_POLL); } - - // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow - usbDisable(); - return false; } -#elif defined(PROTOCOL_LUFA) && defined(OTGPADE) -static inline bool usbIsActive(void) { - USB_OTGPAD_On(); // enables VBUS pad - wait_us(5); - - return USB_VBUS_GetStatus(); // checks state of VBUS -} #else -static inline bool usbIsActive(void) { return true; } +static inline bool usbIsActive(void) { return usb_vbus_state(); } #endif #ifdef SPLIT_HAND_MATRIX_GRID @@ -126,6 +99,11 @@ __attribute__((weak)) bool is_keyboard_master(void) { // only check once, as this is called often if (usbstate == UNKNOWN) { usbstate = usbIsActive() ? MASTER : SLAVE; + + // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow + if (usbstate == SLAVE) { + usb_disable(); + } } return (usbstate == MASTER); -- cgit v1.2.3 From cde2859a6591b1274da20978bd158f20229faa88 Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Tue, 2 Mar 2021 14:32:15 -0600 Subject: Split RGB Matrix (#11055) * Split RGB Matrix * Suspend State sync for rgb matrix --- quantum/split_common/transport.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 61b61ea08c..daa60bb734 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -22,6 +22,10 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A; # define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) #endif +#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) +# include "rgb_matrix.h" +#endif + #if defined(USE_I2C) # include "i2c_master.h" @@ -54,6 +58,10 @@ typedef struct _I2C_slave_buffer_t { # ifdef WPM_ENABLE uint8_t current_wpm; # endif +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + rgb_config_t rgb_matrix; + bool rgb_suspend_state; +# endif } I2C_slave_buffer_t; static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; @@ -68,6 +76,8 @@ static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_re # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) # define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) +# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix) +# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state) # define TIMEOUT 100 @@ -141,6 +151,11 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # endif +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT); + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); +# endif + # ifndef DISABLE_SYNC_TIMER i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT); @@ -186,6 +201,11 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) set_oneshot_mods(i2c_buffer->oneshot_mods); # endif # endif + +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + memcpy((void*)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); + memcpy((void*)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state)); +# endif } void transport_master_init(void) { i2c_init(); } @@ -226,6 +246,10 @@ typedef struct _Serial_m2s_buffer_t { # ifdef WPM_ENABLE uint8_t current_wpm; # endif +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + rgb_config_t rgb_matrix; + bool rgb_suspend_state; +# endif } Serial_m2s_buffer_t; # if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) @@ -343,6 +367,12 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); # endif # endif + +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + serial_m2s_buffer.rgb_matrix = rgb_matrix_config; + serial_m2s_buffer.rgb_suspend_state = g_suspend_state; +# endif + # ifndef DISABLE_SYNC_TIMER serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; # endif @@ -381,6 +411,11 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) set_oneshot_mods(serial_m2s_buffer.oneshot_mods); # endif # endif + +# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + rgb_matrix_config = serial_m2s_buffer.rgb_matrix; + g_suspend_state = serial_m2s_buffer.rgb_suspend_state; +# endif } #endif -- cgit v1.2.3 From d950b97115269a4e7e149bf1eb9b4c6ead13cf7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Mar 2021 07:54:11 +1100 Subject: Format code according to conventions (#12088) Co-authored-by: QMK Bot --- quantum/split_common/transport.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index daa60bb734..27a1c0d3a4 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -203,8 +203,8 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - memcpy((void*)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); - memcpy((void*)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state)); + memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); + memcpy((void *)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state)); # endif } @@ -357,24 +357,24 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # ifdef WPM_ENABLE // Write wpm to slave - serial_m2s_buffer.current_wpm = get_current_wpm(); + serial_m2s_buffer.current_wpm = get_current_wpm(); # endif # ifdef SPLIT_MODS_ENABLE - serial_m2s_buffer.real_mods = get_mods(); - serial_m2s_buffer.weak_mods = get_weak_mods(); + serial_m2s_buffer.real_mods = get_mods(); + serial_m2s_buffer.weak_mods = get_weak_mods(); # ifndef NO_ACTION_ONESHOT - serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); + serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); # endif # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - serial_m2s_buffer.rgb_matrix = rgb_matrix_config; + serial_m2s_buffer.rgb_matrix = rgb_matrix_config; serial_m2s_buffer.rgb_suspend_state = g_suspend_state; # endif # ifndef DISABLE_SYNC_TIMER - serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; + serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; # endif return true; } @@ -414,7 +414,7 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) rgb_matrix_config = serial_m2s_buffer.rgb_matrix; - g_suspend_state = serial_m2s_buffer.rgb_suspend_state; + g_suspend_state = serial_m2s_buffer.rgb_suspend_state; # endif } -- cgit v1.2.3 From ff41c22fdccd30cdba44ba840d68261f74f45135 Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Thu, 25 Mar 2021 06:33:18 -0500 Subject: Adding keyboard level weak function for slave matrix scan (#12317) --- quantum/split_common/matrix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index d6636b886a..f8de17809d 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -43,6 +43,7 @@ extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values uint8_t thisHand, thatHand; // user-defined overridable functions +__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); } __attribute__((weak)) void matrix_slave_scan_user(void) {} static inline void setPinOutput_writeLow(pin_t pin) { @@ -284,7 +285,7 @@ bool matrix_post_scan(void) { } else { transport_slave(matrix + thatHand, matrix + thisHand); - matrix_slave_scan_user(); + matrix_slave_scan_kb(); } return changed; -- cgit v1.2.3 From d6ab908272e7f8f391b19aee0c8a9dce9b24f511 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 22 Apr 2021 19:21:13 +1000 Subject: LED Matrix: Split (#12633) --- quantum/split_common/transport.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 27a1c0d3a4..7ea925b513 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -22,6 +22,9 @@ static pin_t encoders_pad[] = ENCODERS_PAD_A; # define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) #endif +#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) +# include "led_matrix.h" +#endif #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) # include "rgb_matrix.h" #endif @@ -58,6 +61,10 @@ typedef struct _I2C_slave_buffer_t { # ifdef WPM_ENABLE uint8_t current_wpm; # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + led_eeconfig_t led_matrix; + bool led_suspend_state; +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) rgb_config_t rgb_matrix; bool rgb_suspend_state; @@ -76,6 +83,8 @@ static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_re # define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) # define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) # define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) +# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix) +# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state) # define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix) # define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state) @@ -151,6 +160,10 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT); + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT); +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT); i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); @@ -202,6 +215,10 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + memcpy((void*)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); + memcpy((void*)i2c_buffer->led_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state)); +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); memcpy((void *)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state)); @@ -246,6 +263,10 @@ typedef struct _Serial_m2s_buffer_t { # ifdef WPM_ENABLE uint8_t current_wpm; # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + led_eeconfig_t led_matrix; + bool led_suspend_state; +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) rgb_config_t rgb_matrix; bool rgb_suspend_state; @@ -368,6 +389,10 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + serial_m2s_buffer.led_matrix = led_matrix_econfig; + serial_m2s_buffer.led_suspend_state = g_suspend_state; +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) serial_m2s_buffer.rgb_matrix = rgb_matrix_config; serial_m2s_buffer.rgb_suspend_state = g_suspend_state; @@ -412,6 +437,10 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # endif +# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + led_matrix_eeconfig = serial_m2s_buffer.led_matrix; + g_suspend_state = serial_m2s_buffer.led_suspend_state; +# endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) rgb_matrix_config = serial_m2s_buffer.rgb_matrix; g_suspend_state = serial_m2s_buffer.rgb_suspend_state; -- cgit v1.2.3 From 15ff1927dbb01542de895cf8c6c91b69591893ca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 19:26:17 +1000 Subject: [CI] Format code according to conventions (#12650) Co-authored-by: QMK Bot --- quantum/split_common/transport.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 7ea925b513..b67702f150 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -216,8 +216,8 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - memcpy((void*)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); - memcpy((void*)i2c_buffer->led_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state)); + memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); + memcpy((void *)i2c_buffer->led_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state)); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); @@ -245,31 +245,31 @@ typedef struct _Serial_s2m_buffer_t { typedef struct _Serial_m2s_buffer_t { # ifdef SPLIT_MODS_ENABLE - uint8_t real_mods; - uint8_t weak_mods; + uint8_t real_mods; + uint8_t weak_mods; # ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; + uint8_t oneshot_mods; # endif # endif # ifndef DISABLE_SYNC_TIMER - uint32_t sync_timer; + uint32_t sync_timer; # endif # ifdef SPLIT_TRANSPORT_MIRROR - matrix_row_t mmatrix[ROWS_PER_HAND]; + matrix_row_t mmatrix[ROWS_PER_HAND]; # endif # ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; + uint8_t backlight_level; # endif # ifdef WPM_ENABLE - uint8_t current_wpm; + uint8_t current_wpm; # endif # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) led_eeconfig_t led_matrix; bool led_suspend_state; # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_config_t rgb_matrix; - bool rgb_suspend_state; + rgb_config_t rgb_matrix; + bool rgb_suspend_state; # endif } Serial_m2s_buffer_t; @@ -390,7 +390,7 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - serial_m2s_buffer.led_matrix = led_matrix_econfig; + serial_m2s_buffer.led_matrix = led_matrix_econfig; serial_m2s_buffer.led_suspend_state = g_suspend_state; # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) @@ -439,11 +439,11 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) led_matrix_eeconfig = serial_m2s_buffer.led_matrix; - g_suspend_state = serial_m2s_buffer.led_suspend_state; + g_suspend_state = serial_m2s_buffer.led_suspend_state; # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_matrix_config = serial_m2s_buffer.rgb_matrix; - g_suspend_state = serial_m2s_buffer.rgb_suspend_state; + rgb_matrix_config = serial_m2s_buffer.rgb_matrix; + g_suspend_state = serial_m2s_buffer.rgb_suspend_state; # endif } -- cgit v1.2.3 From 3c2e69af79e09d27cf799370685ee8a89ff45a5d Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Sat, 1 May 2021 14:14:17 -0500 Subject: Fixing transport's led/rgb matrix suspend state logic (#12770) --- quantum/split_common/transport.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index b67702f150..b29e58d589 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -162,11 +162,13 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT); - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT); + bool suspend_state = led_matrix_get_suspend_state(); + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT); - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); + bool suspend_state = rgb_matrix_get_suspend_state(); + i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); # endif # ifndef DISABLE_SYNC_TIMER @@ -217,11 +219,11 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); - memcpy((void *)i2c_buffer->led_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->led_suspend_state)); + led_matrix_set_suspend_state(i2c_buffer->led_suspend_state); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); - memcpy((void *)i2c_buffer->rgb_suspend_state, (void *)g_suspend_state, sizeof(i2c_buffer->rgb_suspend_state)); + rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state); # endif } @@ -391,11 +393,11 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) serial_m2s_buffer.led_matrix = led_matrix_econfig; - serial_m2s_buffer.led_suspend_state = g_suspend_state; + serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state(); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) serial_m2s_buffer.rgb_matrix = rgb_matrix_config; - serial_m2s_buffer.rgb_suspend_state = g_suspend_state; + serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state(); # endif # ifndef DISABLE_SYNC_TIMER @@ -439,11 +441,11 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) led_matrix_eeconfig = serial_m2s_buffer.led_matrix; - g_suspend_state = serial_m2s_buffer.led_suspend_state; + led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) rgb_matrix_config = serial_m2s_buffer.rgb_matrix; - g_suspend_state = serial_m2s_buffer.rgb_suspend_state; + rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state); # endif } -- cgit v1.2.3 From f5b6bef4b3db6fcc6b9190411607c4dc198b7152 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 2 May 2021 05:15:50 +1000 Subject: [CI] Format code according to conventions (#12772) Co-authored-by: QMK Bot --- quantum/split_common/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index b29e58d589..9b3f70ed06 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -444,7 +444,7 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_matrix_config = serial_m2s_buffer.rgb_matrix; + rgb_matrix_config = serial_m2s_buffer.rgb_matrix; rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state); # endif } -- cgit v1.2.3 From cbdc3fb81b88ea83949fd55305d1b068225972ac Mon Sep 17 00:00:00 2001 From: Joakim Tufvegren Date: Thu, 13 May 2021 19:37:24 +0200 Subject: Fix spelling mistake regarding LED Matrix in split_common. (#12888) --- quantum/split_common/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 9b3f70ed06..bf942c5260 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -392,7 +392,7 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - serial_m2s_buffer.led_matrix = led_matrix_econfig; + serial_m2s_buffer.led_matrix = led_matrix_eeconfig; serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state(); # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) -- cgit v1.2.3 From 82aa9ad4a567695d1f7d0b1e36bf8563d2967813 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Wed, 19 May 2021 22:43:36 +0200 Subject: matrix: wait for row signal to go HIGH for every row (#12945) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I noticed this discrepancy (last row of the matrix treated differently than the others) when optimizing the input latency of my keyboard controller, see also https://michael.stapelberg.ch/posts/2021-05-08-keyboard-input-latency-qmk-kinesis/ Before this commit, when tuning the delays I noticed ghost key presses when pressing the F2 key, which is on the last row of the keyboard matrix: the dead_grave key, which is on the first row of the keyboard matrix, would be incorrectly detected as pressed. After this commit, all keyboard matrix rows are interpreted correctly. I suspect that my setup is more susceptible to this nuance than others because I use GPIO_INPUT_PIN_DELAY=0 and hence don’t have another delay that might mask the problem. --- quantum/split_common/matrix.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index f8de17809d..039e7d9773 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -130,9 +130,7 @@ static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) // Unselect row unselect_row(current_row); - if (current_row + 1 < MATRIX_ROWS) { - matrix_output_unselect_delay(); // wait for row signal to go HIGH - } + matrix_output_unselect_delay(); // wait for all Col signals to go HIGH // If the row has changed, store the row and return the changed flag. if (current_matrix[current_row] != current_row_value) { @@ -192,9 +190,7 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) // Unselect col unselect_col(current_col); - if (current_col + 1 < MATRIX_COLS) { - matrix_output_unselect_delay(); // wait for col signal to go HIGH - } + matrix_output_unselect_delay(); // wait for all Row signals to go HIGH return matrix_changed; } -- cgit v1.2.3 From 7d1194de01ea94f065bd5176607b4d66279ef51b Mon Sep 17 00:00:00 2001 From: James Young <18669334+noroadsleft@users.noreply.github.com> Date: Sat, 29 May 2021 13:53:10 -0700 Subject: run: qmk cformat --core-only --- quantum/split_common/transport.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index bf942c5260..9ed0f7591b 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -240,38 +240,38 @@ typedef struct _Serial_s2m_buffer_t { matrix_row_t smatrix[ROWS_PER_HAND]; # ifdef ENCODER_ENABLE - uint8_t encoder_state[NUMBER_OF_ENCODERS]; + uint8_t encoder_state[NUMBER_OF_ENCODERS]; # endif } Serial_s2m_buffer_t; typedef struct _Serial_m2s_buffer_t { # ifdef SPLIT_MODS_ENABLE - uint8_t real_mods; - uint8_t weak_mods; + uint8_t real_mods; + uint8_t weak_mods; # ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; + uint8_t oneshot_mods; # endif # endif # ifndef DISABLE_SYNC_TIMER - uint32_t sync_timer; + uint32_t sync_timer; # endif # ifdef SPLIT_TRANSPORT_MIRROR - matrix_row_t mmatrix[ROWS_PER_HAND]; + matrix_row_t mmatrix[ROWS_PER_HAND]; # endif # ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; + uint8_t backlight_level; # endif # ifdef WPM_ENABLE - uint8_t current_wpm; + uint8_t current_wpm; # endif # if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) led_eeconfig_t led_matrix; bool led_suspend_state; # endif # if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_config_t rgb_matrix; - bool rgb_suspend_state; + rgb_config_t rgb_matrix; + bool rgb_suspend_state; # endif } Serial_m2s_buffer_t; @@ -363,7 +363,7 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) // TODO: if MATRIX_COLS > 8 change to unpack() for (int i = 0; i < ROWS_PER_HAND; ++i) { - slave_matrix[i] = serial_s2m_buffer.smatrix[i]; + slave_matrix[i] = serial_s2m_buffer.smatrix[i]; # ifdef SPLIT_TRANSPORT_MIRROR serial_m2s_buffer.mmatrix[i] = master_matrix[i]; # endif @@ -380,14 +380,14 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # ifdef WPM_ENABLE // Write wpm to slave - serial_m2s_buffer.current_wpm = get_current_wpm(); + serial_m2s_buffer.current_wpm = get_current_wpm(); # endif # ifdef SPLIT_MODS_ENABLE - serial_m2s_buffer.real_mods = get_mods(); - serial_m2s_buffer.weak_mods = get_weak_mods(); + serial_m2s_buffer.real_mods = get_mods(); + serial_m2s_buffer.weak_mods = get_weak_mods(); # ifndef NO_ACTION_ONESHOT - serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); + serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); # endif # endif @@ -401,7 +401,7 @@ bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) # endif # ifndef DISABLE_SYNC_TIMER - serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; + serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; # endif return true; } @@ -416,7 +416,7 @@ void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_s2m_buffer.smatrix[i] = slave_matrix[i]; # ifdef SPLIT_TRANSPORT_MIRROR - master_matrix[i] = serial_m2s_buffer.mmatrix[i]; + master_matrix[i] = serial_m2s_buffer.mmatrix[i]; # endif } # ifdef BACKLIGHT_ENABLE -- cgit v1.2.3 From e5d3e5a98969e59d702fefb2690ec582699e129b Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Tue, 1 Jun 2021 15:10:39 +1000 Subject: Add weak refs on reading rows/cols. (#13062) --- quantum/split_common/matrix.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 039e7d9773..a54ea90b3f 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -61,7 +61,7 @@ static inline void setPinInputHigh_atomic(pin_t pin) { #ifdef DIRECT_PINS -static void init_pins(void) { +__attribute__((weak)) void matrix_init_pins(void) { for (int row = 0; row < MATRIX_ROWS; row++) { for (int col = 0; col < MATRIX_COLS; col++) { pin_t pin = direct_pins[row][col]; @@ -72,7 +72,7 @@ static void init_pins(void) { } } -static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { +__attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { // Start with a clear matrix row matrix_row_t current_row_value = 0; @@ -104,14 +104,14 @@ static void unselect_rows(void) { } } -static void init_pins(void) { +__attribute__((weak)) void matrix_init_pins(void) { unselect_rows(); for (uint8_t x = 0; x < MATRIX_COLS; x++) { setPinInputHigh_atomic(col_pins[x]); } } -static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { +__attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { // Start with a clear matrix row matrix_row_t current_row_value = 0; @@ -152,14 +152,14 @@ static void unselect_cols(void) { } } -static void init_pins(void) { +__attribute__((weak)) void matrix_init_pins(void) { unselect_cols(); for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { setPinInputHigh_atomic(row_pins[x]); } } -static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { +__attribute__((weak)) bool matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { bool matrix_changed = false; // Select col @@ -233,7 +233,7 @@ void matrix_init(void) { thatHand = ROWS_PER_HAND - thisHand; // initialize key pins - init_pins(); + matrix_init_pins(); // initialize matrix state: all keys off for (uint8_t i = 0; i < MATRIX_ROWS; i++) { @@ -293,12 +293,12 @@ uint8_t matrix_scan(void) { #if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) // Set row, read cols for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { - local_changed |= read_cols_on_row(raw_matrix, current_row); + local_changed |= matrix_read_cols_on_row(raw_matrix, current_row); } #elif (DIODE_DIRECTION == ROW2COL) // Set col, read rows for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { - local_changed |= read_rows_on_col(raw_matrix, current_col); + local_changed |= matrix_read_rows_on_col(raw_matrix, current_col); } #endif -- cgit v1.2.3 From f287597c19dc926c7c28cefa32ffc3f0b4fdba7f Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Wed, 9 Jun 2021 17:19:42 +1000 Subject: Use single memcmp to determine if matrix changed. (#13064) * Use memcmp to determine if matrix changed. * Firmware size issues. * Add documentation for the lack of need of MATRIX_ROW_PINS/MATRIX_COL_PINS, when overriding low-level matrix functions. --- quantum/split_common/matrix.c | 69 +++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 39 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index a54ea90b3f..2cf7b70582 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -16,6 +16,7 @@ along with this program. If not, see . */ #include #include +#include #include "util.h" #include "matrix.h" #include "debounce.h" @@ -31,8 +32,12 @@ along with this program. If not, see . #ifdef DIRECT_PINS static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; #elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) +# ifdef MATRIX_ROW_PINS static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +# endif // MATRIX_ROW_PINS +# ifdef MATRIX_COL_PINS static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +# endif // MATRIX_COL_PINS #endif /* matrix state(1:on, 0:off) */ @@ -45,6 +50,9 @@ uint8_t thisHand, thatHand; // user-defined overridable functions __attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); } __attribute__((weak)) void matrix_slave_scan_user(void) {} +__attribute__((weak)) void matrix_init_pins(void); +__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); static inline void setPinOutput_writeLow(pin_t pin) { ATOMIC_BLOCK_FORCEON { @@ -72,7 +80,7 @@ __attribute__((weak)) void matrix_init_pins(void) { } } -__attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { +__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { // Start with a clear matrix row matrix_row_t current_row_value = 0; @@ -83,16 +91,13 @@ __attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[] } } - // If the row has changed, store the row and return the changed flag. - if (current_matrix[current_row] != current_row_value) { - current_matrix[current_row] = current_row_value; - return true; - } - return false; + // Update the matrix + current_matrix[current_row] = current_row_value; } #elif defined(DIODE_DIRECTION) -# if (DIODE_DIRECTION == COL2ROW) +# if defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) +# if (DIODE_DIRECTION == COL2ROW) static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); } @@ -111,7 +116,7 @@ __attribute__((weak)) void matrix_init_pins(void) { } } -__attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { +__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { // Start with a clear matrix row matrix_row_t current_row_value = 0; @@ -132,15 +137,11 @@ __attribute__((weak)) bool matrix_read_cols_on_row(matrix_row_t current_matrix[] unselect_row(current_row); matrix_output_unselect_delay(); // wait for all Col signals to go HIGH - // If the row has changed, store the row and return the changed flag. - if (current_matrix[current_row] != current_row_value) { - current_matrix[current_row] = current_row_value; - return true; - } - return false; + // Update the matrix + current_matrix[current_row] = current_row_value; } -# elif (DIODE_DIRECTION == ROW2COL) +# elif (DIODE_DIRECTION == ROW2COL) static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); } @@ -159,45 +160,32 @@ __attribute__((weak)) void matrix_init_pins(void) { } } -__attribute__((weak)) bool matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { - bool matrix_changed = false; - +__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { // Select col select_col(current_col); matrix_output_select_delay(); // For each row... for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { - // Store last value of row prior to reading - matrix_row_t last_row_value = current_matrix[row_index]; - matrix_row_t current_row_value = last_row_value; - // Check row pin state if (readPin(row_pins[row_index]) == 0) { // Pin LO, set col bit - current_row_value |= (MATRIX_ROW_SHIFTER << current_col); + current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); } else { // Pin HI, clear col bit - current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col); - } - - // Determine if the matrix changed state - if ((last_row_value != current_row_value)) { - matrix_changed |= true; - current_matrix[row_index] = current_row_value; + current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); } } // Unselect col unselect_col(current_col); matrix_output_unselect_delay(); // wait for all Row signals to go HIGH - - return matrix_changed; } -# else -# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL! -# endif +# else +# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL! +# endif +# endif // defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) #else # error DIODE_DIRECTION is not defined! #endif @@ -288,20 +276,23 @@ bool matrix_post_scan(void) { } uint8_t matrix_scan(void) { - bool local_changed = false; + matrix_row_t curr_matrix[MATRIX_ROWS] = {0}; #if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) // Set row, read cols for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { - local_changed |= matrix_read_cols_on_row(raw_matrix, current_row); + matrix_read_cols_on_row(curr_matrix, current_row); } #elif (DIODE_DIRECTION == ROW2COL) // Set col, read rows for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { - local_changed |= matrix_read_rows_on_col(raw_matrix, current_col); + matrix_read_rows_on_col(curr_matrix, current_col); } #endif + bool local_changed = memcmp(raw_matrix, curr_matrix, sizeof(curr_matrix)) != 0; + if (local_changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix)); + debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed); bool remote_changed = matrix_post_scan(); -- cgit v1.2.3 From 172e6a703041363decd6fc829542f33180c13beb Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Fri, 18 Jun 2021 09:10:06 +1000 Subject: Extensible split data sync (#11930) * Extensible split data sync capability through transactions. - Split common transport has been split up between the transport layer and data layer. - Split "transactions" model used, with convergence between I2C and serial data definitions. - Slave matrix "generation count" is used to determine if the full slave matrix needs to be retrieved. - Encoders get the same "generation count" treatment. - All other blocks of data are synchronised when a change is detected. - All transmissions have a globally-configurable deadline before a transmission is forced (`FORCED_SYNC_THROTTLE_MS`, default 100ms). - Added atomicity for all core-synced data, preventing partial updates - Added retries to AVR i2c_master's i2c_start, to minimise the number of failed transactions when interrupts are disabled on the slave due to atomicity checks. - Some keyboards have had slight modifications made in order to ensure that they still build due to firmware size restrictions. * Fixup LED_MATRIX compile. * Parameterise ERROR_DISCONNECT_COUNT. --- quantum/split_common/matrix.c | 6 +- quantum/split_common/post_config.h | 9 - quantum/split_common/transaction_id_define.h | 94 ++++ quantum/split_common/transactions.c | 670 +++++++++++++++++++++++++++ quantum/split_common/transactions.h | 54 +++ quantum/split_common/transport.c | 484 +++---------------- quantum/split_common/transport.h | 165 +++++++ 7 files changed, 1062 insertions(+), 420 deletions(-) create mode 100644 quantum/split_common/transaction_id_define.h create mode 100644 quantum/split_common/transactions.c create mode 100644 quantum/split_common/transactions.h (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 2cf7b70582..56d91b07fe 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -23,9 +23,11 @@ along with this program. If not, see . #include "quantum.h" #include "split_util.h" #include "config.h" -#include "transport.h" +#include "transactions.h" -#define ERROR_DISCONNECT_COUNT 5 +#ifndef ERROR_DISCONNECT_COUNT +# define ERROR_DISCONNECT_COUNT 5 +#endif // ERROR_DISCONNECT_COUNT #define ROWS_PER_HAND (MATRIX_ROWS / 2) diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h index 4ae1d52732..a4c0a1956b 100644 --- a/quantum/split_common/post_config.h +++ b/quantum/split_common/post_config.h @@ -7,13 +7,4 @@ # ifndef F_SCL # define F_SCL 100000UL // SCL frequency # endif - -#else // use serial -// When using serial, the user must define RGBLIGHT_SPLIT explicitly -// in config.h as needed. -// see quantum/rgblight_post_config.h -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) -// When using serial and RGBLIGHT_SPLIT need separate transaction -# define SERIAL_USE_MULTI_TRANSACTION -# endif #endif diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h new file mode 100644 index 0000000000..464c73478a --- /dev/null +++ b/quantum/split_common/transaction_id_define.h @@ -0,0 +1,94 @@ +/* Copyright 2021 QMK + * + * 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 . + */ + +#pragma once + +enum serial_transaction_id { +#ifdef USE_I2C + I2C_EXECUTE_CALLBACK, +#endif // USE_I2C + + GET_SLAVE_MATRIX_CHECKSUM, + GET_SLAVE_MATRIX_DATA, + +#ifdef SPLIT_TRANSPORT_MIRROR + PUT_MASTER_MATRIX, +#endif // SPLIT_TRANSPORT_MIRROR + +#ifdef ENCODER_ENABLE + GET_ENCODERS_CHECKSUM, + GET_ENCODERS_DATA, +#endif // ENCODER_ENABLE + +#ifndef DISABLE_SYNC_TIMER + PUT_SYNC_TIMER, +#endif // DISABLE_SYNC_TIMER + +#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + PUT_LAYER_STATE, + PUT_DEFAULT_LAYER_STATE, +#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +#ifdef SPLIT_LED_STATE_ENABLE + PUT_LED_STATE, +#endif // SPLIT_LED_STATE_ENABLE + +#ifdef SPLIT_MODS_ENABLE + PUT_MODS, +#endif // SPLIT_MODS_ENABLE + +#ifdef BACKLIGHT_ENABLE + PUT_BACKLIGHT, +#endif // BACKLIGHT_ENABLE + +#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + PUT_RGBLIGHT, +#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + PUT_LED_MATRIX, +#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + PUT_RGB_MATRIX, +#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + PUT_WPM, +#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + PUT_RPC_INFO, + PUT_RPC_REQ_DATA, + EXECUTE_RPC, + GET_RPC_RESP_DATA, +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + +// keyboard-specific +#ifdef SPLIT_TRANSACTION_IDS_KB + SPLIT_TRANSACTION_IDS_KB, +#endif // SPLIT_TRANSACTION_IDS_KB + +// user/keymap-specific +#ifdef SPLIT_TRANSACTION_IDS_USER + SPLIT_TRANSACTION_IDS_USER, +#endif // SPLIT_TRANSACTION_IDS_USER + + NUM_TOTAL_TRANSACTIONS +}; + +// Ensure we only use 5 bits for transaction +_Static_assert(NUM_TOTAL_TRANSACTIONS <= (1 << 5), "Max number of usable transactions exceeded"); diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c new file mode 100644 index 0000000000..99a8623b3c --- /dev/null +++ b/quantum/split_common/transactions.c @@ -0,0 +1,670 @@ +/* Copyright 2021 QMK + * + * 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 . + */ + +#include +#include + +#include "debug.h" +#include "matrix.h" +#include "quantum.h" +#include "transactions.h" +#include "transport.h" +#include "transaction_id_define.h" + +#define SYNC_TIMER_OFFSET 2 + +#ifndef FORCED_SYNC_THROTTLE_MS +# define FORCED_SYNC_THROTTLE_MS 100 +#endif // FORCED_SYNC_THROTTLE_MS + +#define sizeof_member(type, member) sizeof(((type *)NULL)->member) + +#define trans_initiator2target_initializer_cb(member, cb) \ + { &dummy, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), 0, 0, cb } +#define trans_initiator2target_initializer(member) trans_initiator2target_initializer_cb(member, NULL) + +#define trans_target2initiator_initializer_cb(member, cb) \ + { &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } +#define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) + +#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) +#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) + +static uint8_t crc8(const void *data, size_t len) { + const uint8_t *p = (const uint8_t *)data; + uint8_t crc = 0xff; + size_t i, j; + for (i = 0; i < len; i++) { + crc ^= p[i]; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ 0x31); + else + crc <<= 1; + } + } + return crc; +} + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) +// Forward-declare the RPC callback handlers +void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); +void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + +//////////////////////////////////////////////////// +// Helpers + +bool transaction_handler_master(bool okay, matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) { + if (okay) { + bool this_okay = true; + for (int iter = 1; iter <= 10; ++iter) { + if (!this_okay) { + for (int i = 0; i < iter * iter; ++i) { + wait_us(10); + } + } + ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); }; + if (this_okay) break; + } + okay &= this_okay; + if (!okay) { + dprintf("Failed to execute %s\n", prefix); + } + } + return okay; +} + +#define TRANSACTION_HANDLER_MASTER(prefix) \ + do { \ + okay &= transaction_handler_master(okay, master_matrix, slave_matrix, #prefix, &prefix##_master); \ + } while (0) + +#define TRANSACTION_HANDLER_SLAVE(prefix) \ + do { \ + ATOMIC_BLOCK_FORCEON { prefix##_slave(master_matrix, slave_matrix); }; \ + } while (0) + +inline static bool read_if_checksum_mismatch(int8_t trans_id_checksum, int8_t trans_id_retrieve, uint32_t *last_update, void *destination, const void *equiv_shmem, size_t length) { + uint8_t curr_checksum; + bool okay = transport_read(trans_id_checksum, &curr_checksum, sizeof(curr_checksum)); + if (okay && (timer_elapsed32(*last_update) >= FORCED_SYNC_THROTTLE_MS || curr_checksum != crc8(equiv_shmem, length))) { + okay &= transport_read(trans_id_retrieve, destination, length); + okay &= curr_checksum == crc8(equiv_shmem, length); + if (okay) { + *last_update = timer_read32(); + } + } else { + memcpy(destination, equiv_shmem, length); + } + return okay; +} + +inline static bool send_if_condition(int8_t trans_id, uint32_t *last_update, bool condition, void *source, size_t length) { + bool okay = true; + if (timer_elapsed32(*last_update) >= FORCED_SYNC_THROTTLE_MS || condition) { + okay &= transport_write(trans_id, source, length); + if (okay) { + *last_update = timer_read32(); + } + } + return okay; +} + +inline static bool send_if_data_mismatch(int8_t trans_id, uint32_t *last_update, void *source, const void *equiv_shmem, size_t length) { + // Just run a memcmp to compare the source and equivalent shmem location + return send_if_condition(trans_id, last_update, (memcmp(source, equiv_shmem, length) != 0), source, length); +} + +//////////////////////////////////////////////////// +// Slave matrix + +static bool slave_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + static matrix_row_t last_matrix[(MATRIX_ROWS) / 2] = {0}; // last successfully-read matrix, so we can replicate if there are checksum errors + matrix_row_t temp_matrix[(MATRIX_ROWS) / 2]; // holding area while we test whether or not checksum is correct + + bool okay = read_if_checksum_mismatch(GET_SLAVE_MATRIX_CHECKSUM, GET_SLAVE_MATRIX_DATA, &last_update, temp_matrix, split_shmem->smatrix.matrix, sizeof(split_shmem->smatrix.matrix)); + if (okay) { + // Checksum matches the received data, save as the last matrix state + memcpy(last_matrix, temp_matrix, sizeof(temp_matrix)); + } + // Copy out the last-known-good matrix state to the slave matrix + memcpy(slave_matrix, last_matrix, sizeof(last_matrix)); + return okay; +} + +static void slave_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + memcpy(split_shmem->smatrix.matrix, slave_matrix, sizeof(split_shmem->smatrix.matrix)); + split_shmem->smatrix.checksum = crc8(split_shmem->smatrix.matrix, sizeof(split_shmem->smatrix.matrix)); +} + +// clang-format off +#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix_handlers) +#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix_handlers) +#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \ + [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \ + [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix), +// clang-format on + +//////////////////////////////////////////////////// +// Master matrix + +#ifdef SPLIT_TRANSPORT_MIRROR + +static bool master_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + return send_if_data_mismatch(PUT_MASTER_MATRIX, &last_update, master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); +} + +static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + // Always copy to the master matrix + memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); +} + +# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers) +# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers) +# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), + +#else // SPLIT_TRANSPORT_MIRROR + +# define TRANSACTIONS_MASTER_MATRIX_MASTER() +# define TRANSACTIONS_MASTER_MATRIX_SLAVE() +# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS + +#endif // SPLIT_TRANSPORT_MIRROR + +//////////////////////////////////////////////////// +// Encoders + +#ifdef ENCODER_ENABLE + +static bool encoder_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + uint8_t temp_state[NUMBER_OF_ENCODERS]; + + bool okay = read_if_checksum_mismatch(GET_ENCODERS_CHECKSUM, GET_ENCODERS_DATA, &last_update, temp_state, split_shmem->encoders.state, sizeof(temp_state)); + if (okay) encoder_update_raw(temp_state); + return okay; +} + +static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + uint8_t encoder_state[NUMBER_OF_ENCODERS]; + encoder_state_raw(encoder_state); + // Always prepare the encoder state for read. + memcpy(split_shmem->encoders.state, encoder_state, sizeof(encoder_state)); + // Now update the checksum given that the encoders has been written to + split_shmem->encoders.checksum = crc8(encoder_state, sizeof(encoder_state)); +} + +// clang-format off +# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder_handlers) +# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder_handlers) +# define TRANSACTIONS_ENCODERS_REGISTRATIONS \ + [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ + [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state), +// clang-format on + +#else // ENCODER_ENABLE + +# define TRANSACTIONS_ENCODERS_MASTER() +# define TRANSACTIONS_ENCODERS_SLAVE() +# define TRANSACTIONS_ENCODERS_REGISTRATIONS + +#endif // ENCODER_ENABLE + +//////////////////////////////////////////////////// +// Sync timer + +#ifndef DISABLE_SYNC_TIMER + +static bool sync_timer_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + + bool okay = true; + if (timer_elapsed32(last_update) >= FORCED_SYNC_THROTTLE_MS) { + uint32_t sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; + okay &= transport_write(PUT_SYNC_TIMER, &sync_timer, sizeof(sync_timer)); + if (okay) { + last_update = timer_read32(); + } + } + return okay; +} + +static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_sync_timer = 0; + if (last_sync_timer != split_shmem->sync_timer) { + last_sync_timer = split_shmem->sync_timer; + sync_timer_update(last_sync_timer); + } +} + +# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers) +# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers) +# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), + +#else // DISABLE_SYNC_TIMER + +# define TRANSACTIONS_SYNC_TIMER_MASTER() +# define TRANSACTIONS_SYNC_TIMER_SLAVE() +# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS + +#endif // DISABLE_SYNC_TIMER + +//////////////////////////////////////////////////// +// Layer state + +#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +static bool layer_state_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_layer_state_update = 0; + static uint32_t last_default_layer_state_update = 0; + + bool okay = send_if_condition(PUT_LAYER_STATE, &last_layer_state_update, (layer_state != split_shmem->layers.layer_state), &layer_state, sizeof(layer_state)); + if (okay) { + okay &= send_if_condition(PUT_DEFAULT_LAYER_STATE, &last_default_layer_state_update, (default_layer_state != split_shmem->layers.default_layer_state), &default_layer_state, sizeof(default_layer_state)); + } + return okay; +} + +static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + layer_state = split_shmem->layers.layer_state; + default_layer_state = split_shmem->layers.default_layer_state; +} + +// clang-format off +# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state_handlers) +# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state_handlers) +# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \ + [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \ + [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state), +// clang-format on + +#else // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +# define TRANSACTIONS_LAYER_STATE_MASTER() +# define TRANSACTIONS_LAYER_STATE_SLAVE() +# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS + +#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +//////////////////////////////////////////////////// +// LED state + +#ifdef SPLIT_LED_STATE_ENABLE + +static bool led_state_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + uint8_t led_state = host_keyboard_leds(); + return send_if_data_mismatch(PUT_LED_STATE, &last_update, &led_state, &split_shmem->led_state, sizeof(led_state)); +} + +static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + void set_split_host_keyboard_leds(uint8_t led_state); + set_split_host_keyboard_leds(split_shmem->led_state); +} + +# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers) +# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers) +# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), + +#else // SPLIT_LED_STATE_ENABLE + +# define TRANSACTIONS_LED_STATE_MASTER() +# define TRANSACTIONS_LED_STATE_SLAVE() +# define TRANSACTIONS_LED_STATE_REGISTRATIONS + +#endif // SPLIT_LED_STATE_ENABLE + +//////////////////////////////////////////////////// +// Mods + +#ifdef SPLIT_MODS_ENABLE + +static bool mods_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + bool mods_need_sync = timer_elapsed32(last_update) >= FORCED_SYNC_THROTTLE_MS; + split_mods_sync_t new_mods; + new_mods.real_mods = get_mods(); + if (!mods_need_sync && new_mods.real_mods != split_shmem->mods.real_mods) { + mods_need_sync = true; + } + + new_mods.weak_mods = get_weak_mods(); + if (!mods_need_sync && new_mods.weak_mods != split_shmem->mods.weak_mods) { + mods_need_sync = true; + } + +# ifndef NO_ACTION_ONESHOT + new_mods.oneshot_mods = get_oneshot_mods(); + if (!mods_need_sync && new_mods.oneshot_mods != split_shmem->mods.oneshot_mods) { + mods_need_sync = true; + } +# endif // NO_ACTION_ONESHOT + + bool okay = true; + if (mods_need_sync) { + okay &= transport_write(PUT_MODS, &new_mods, sizeof(new_mods)); + if (okay) { + last_update = timer_read32(); + } + } + + return okay; +} + +static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + set_mods(split_shmem->mods.real_mods); + set_weak_mods(split_shmem->mods.weak_mods); +# ifndef NO_ACTION_ONESHOT + set_oneshot_mods(split_shmem->mods.oneshot_mods); +# endif +} + +# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers) +# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers) +# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), + +#else // SPLIT_MODS_ENABLE + +# define TRANSACTIONS_MODS_MASTER() +# define TRANSACTIONS_MODS_SLAVE() +# define TRANSACTIONS_MODS_REGISTRATIONS + +#endif // SPLIT_MODS_ENABLE + +//////////////////////////////////////////////////// +// Backlight + +#ifdef BACKLIGHT_ENABLE + +static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; + return send_if_condition(PUT_BACKLIGHT, &last_update, (level != split_shmem->backlight_level), &level, sizeof(level)); +} + +static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } + +# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers) +# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers) +# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), + +#else // BACKLIGHT_ENABLE + +# define TRANSACTIONS_BACKLIGHT_MASTER() +# define TRANSACTIONS_BACKLIGHT_SLAVE() +# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS + +#endif // BACKLIGHT_ENABLE + +//////////////////////////////////////////////////// +// RGBLIGHT + +#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +static bool rgblight_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + rgblight_syncinfo_t rgblight_sync; + rgblight_get_syncinfo(&rgblight_sync); + if (send_if_condition(PUT_RGBLIGHT, &last_update, (rgblight_sync.status.change_flags != 0), &rgblight_sync, sizeof(rgblight_sync))) { + rgblight_clear_change_flags(); + } else { + return false; + } + return true; +} + +static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + // Update the RGB with the new data + if (split_shmem->rgblight_sync.status.change_flags != 0) { + rgblight_update_sync(&split_shmem->rgblight_sync, false); + split_shmem->rgblight_sync.status.change_flags = 0; + } +} + +# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers) +# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers) +# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), + +#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +# define TRANSACTIONS_RGBLIGHT_MASTER() +# define TRANSACTIONS_RGBLIGHT_SLAVE() +# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS + +#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +//////////////////////////////////////////////////// +// LED Matrix + +#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +static bool led_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + led_matrix_sync_t led_matrix_sync; + memcpy(&led_matrix_sync.led_matrix, &led_matrix_eeconfig, sizeof(led_eeconfig_t)); + led_matrix_sync.led_suspend_state = led_matrix_get_suspend_state(); + return send_if_data_mismatch(PUT_LED_MATRIX, &last_update, &led_matrix_sync, &split_shmem->led_matrix_sync, sizeof(led_matrix_sync)); +} + +static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + memcpy(&led_matrix_eeconfig, &split_shmem->led_matrix_sync.led_matrix, sizeof(led_eeconfig_t)); + led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); +} + +# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers) +# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers) +# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), + +#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +# define TRANSACTIONS_LED_MATRIX_MASTER() +# define TRANSACTIONS_LED_MATRIX_SLAVE() +# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS + +#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +//////////////////////////////////////////////////// +// RGB Matrix + +#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + +static bool rgb_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + rgb_matrix_sync_t rgb_matrix_sync; + memcpy(&rgb_matrix_sync.rgb_matrix, &rgb_matrix_config, sizeof(rgb_config_t)); + rgb_matrix_sync.rgb_suspend_state = rgb_matrix_get_suspend_state(); + return send_if_data_mismatch(PUT_RGB_MATRIX, &last_update, &rgb_matrix_sync, &split_shmem->rgb_matrix_sync, sizeof(rgb_matrix_sync)); +} + +static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + memcpy(&rgb_matrix_config, &split_shmem->rgb_matrix_sync.rgb_matrix, sizeof(rgb_config_t)); + rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); +} + +# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers) +# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers) +# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), + +#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + +# define TRANSACTIONS_RGB_MATRIX_MASTER() +# define TRANSACTIONS_RGB_MATRIX_SLAVE() +# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS + +#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + +//////////////////////////////////////////////////// +// WPM + +#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + +static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + uint8_t current_wpm = get_current_wpm(); + return send_if_condition(PUT_WPM, &last_update, (current_wpm != split_shmem->current_wpm), ¤t_wpm, sizeof(current_wpm)); +} + +static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } + +# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers) +# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers) +# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), + +#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + +# define TRANSACTIONS_WPM_MASTER() +# define TRANSACTIONS_WPM_SLAVE() +# define TRANSACTIONS_WPM_REGISTRATIONS + +#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + +//////////////////////////////////////////////////// + +uint8_t dummy; +split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { + // Set defaults + [0 ...(NUM_TOTAL_TRANSACTIONS - 1)] = {NULL, 0, 0, 0, 0, 0}, + +#ifdef USE_I2C + [I2C_EXECUTE_CALLBACK] = trans_initiator2target_initializer(transaction_id), +#endif // USE_I2C + + // clang-format off + TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS + TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS + TRANSACTIONS_ENCODERS_REGISTRATIONS + TRANSACTIONS_SYNC_TIMER_REGISTRATIONS + TRANSACTIONS_LAYER_STATE_REGISTRATIONS + TRANSACTIONS_LED_STATE_REGISTRATIONS + TRANSACTIONS_MODS_REGISTRATIONS + TRANSACTIONS_BACKLIGHT_REGISTRATIONS + TRANSACTIONS_RGBLIGHT_REGISTRATIONS + TRANSACTIONS_LED_MATRIX_REGISTRATIONS + TRANSACTIONS_RGB_MATRIX_REGISTRATIONS + TRANSACTIONS_WPM_REGISTRATIONS +// clang-format on + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + [PUT_RPC_INFO] = trans_initiator2target_initializer_cb(rpc_info, slave_rpc_info_callback), + [PUT_RPC_REQ_DATA] = trans_initiator2target_initializer(rpc_m2s_buffer), + [EXECUTE_RPC] = trans_initiator2target_initializer_cb(rpc_info.transaction_id, slave_rpc_exec_callback), + [GET_RPC_RESP_DATA] = trans_target2initiator_initializer(rpc_s2m_buffer), +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) +}; + +bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + bool okay = true; + TRANSACTIONS_SLAVE_MATRIX_MASTER(); + TRANSACTIONS_MASTER_MATRIX_MASTER(); + TRANSACTIONS_ENCODERS_MASTER(); + TRANSACTIONS_SYNC_TIMER_MASTER(); + TRANSACTIONS_LAYER_STATE_MASTER(); + TRANSACTIONS_LED_STATE_MASTER(); + TRANSACTIONS_MODS_MASTER(); + TRANSACTIONS_BACKLIGHT_MASTER(); + TRANSACTIONS_RGBLIGHT_MASTER(); + TRANSACTIONS_LED_MATRIX_MASTER(); + TRANSACTIONS_RGB_MATRIX_MASTER(); + TRANSACTIONS_WPM_MASTER(); + return okay; +} + +void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + TRANSACTIONS_SLAVE_MATRIX_SLAVE(); + TRANSACTIONS_MASTER_MATRIX_SLAVE(); + TRANSACTIONS_ENCODERS_SLAVE(); + TRANSACTIONS_SYNC_TIMER_SLAVE(); + TRANSACTIONS_LAYER_STATE_SLAVE(); + TRANSACTIONS_LED_STATE_SLAVE(); + TRANSACTIONS_MODS_SLAVE(); + TRANSACTIONS_BACKLIGHT_SLAVE(); + TRANSACTIONS_RGBLIGHT_SLAVE(); + TRANSACTIONS_LED_MATRIX_SLAVE(); + TRANSACTIONS_RGB_MATRIX_SLAVE(); + TRANSACTIONS_WPM_SLAVE(); +} + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + +void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback) { + // Prevent invoking RPC on QMK core sync data + if (transaction_id <= GET_RPC_RESP_DATA) return; + + // Set the callback + split_transaction_table[transaction_id].slave_callback = callback; + split_transaction_table[transaction_id].initiator2target_offset = offsetof(split_shared_memory_t, rpc_m2s_buffer); + split_transaction_table[transaction_id].target2initiator_offset = offsetof(split_shared_memory_t, rpc_s2m_buffer); +} + +bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { + // Prevent invoking RPC on QMK core sync data + if (transaction_id <= GET_RPC_RESP_DATA) return false; + // Prevent sizing issues + if (initiator2target_buffer_size > RPC_M2S_BUFFER_SIZE) return false; + if (target2initiator_buffer_size > RPC_S2M_BUFFER_SIZE) return false; + + // Prepare the metadata block + rpc_sync_info_t info = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}; + + // Make sure the local side knows that we're not sending the full block of data + split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = initiator2target_buffer_size; + split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = target2initiator_buffer_size; + + // Run through the sequence: + // * set the transaction ID and lengths + // * send the request data + // * execute RPC callback + // * retrieve the response data + if (!transport_write(PUT_RPC_INFO, &info, sizeof(info))) { + return false; + } + if (!transport_write(PUT_RPC_REQ_DATA, initiator2target_buffer, initiator2target_buffer_size)) { + return false; + } + if (!transport_write(EXECUTE_RPC, &transaction_id, sizeof(transaction_id))) { + return false; + } + if (!transport_read(GET_RPC_RESP_DATA, target2initiator_buffer, target2initiator_buffer_size)) { + return false; + } + return true; +} + +void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { + // The RPC info block contains the intended transaction ID, as well as the sizes for both inbound and outbound data. + // Ignore the args -- the `split_shmem` already has the info, we just need to act upon it. + // We must keep the `split_transaction_table` non-const, so that it is able to be modified at runtime. + + split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = split_shmem->rpc_info.m2s_length; + split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.s2m_length; +} + +void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { + // We can assume that the buffer lengths are correctly set, now, given that sequentially the rpc_info callback was already executed. + // Go through the rpc_info and execute _that_ transaction's callback, with the scratch buffers as inputs. + int8_t transaction_id = split_shmem->rpc_info.transaction_id; + if (transaction_id < NUM_TOTAL_TRANSACTIONS) { + split_transaction_desc_t *trans = &split_transaction_table[transaction_id]; + if (trans->slave_callback) { + trans->slave_callback(split_shmem->rpc_info.m2s_length, split_shmem->rpc_m2s_buffer, split_shmem->rpc_info.s2m_length, split_shmem->rpc_s2m_buffer); + } + } +} + +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) diff --git a/quantum/split_common/transactions.h b/quantum/split_common/transactions.h new file mode 100644 index 0000000000..4306ba1d87 --- /dev/null +++ b/quantum/split_common/transactions.h @@ -0,0 +1,54 @@ +/* Copyright 2021 QMK + * + * 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 . + */ + +#pragma once + +#include "stdint.h" +#include "stdbool.h" + +#include "matrix.h" +#include "transaction_id_define.h" +#include "transport.h" + +typedef void (*slave_callback_t)(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); + +// Split transaction Descriptor +typedef struct _split_transaction_desc_t { + uint8_t * status; + uint8_t initiator2target_buffer_size; + uint16_t initiator2target_offset; + uint8_t target2initiator_buffer_size; + uint16_t target2initiator_offset; + slave_callback_t slave_callback; +} split_transaction_desc_t; + +// Forward declaration for the split transactions +extern split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS]; + +#define split_shmem_offset_ptr(offset) ((void *)(((uint8_t *)split_shmem) + (offset))) +#define split_trans_initiator2target_buffer(trans) (split_shmem_offset_ptr((trans)->initiator2target_offset)) +#define split_trans_target2initiator_buffer(trans) (split_shmem_offset_ptr((trans)->target2initiator_offset)) + +// returns false if valid data not received from slave +bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); +void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); + +void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback); + +bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); + +#define transaction_rpc_send(transaction_id, initiator2target_buffer_size, initiator2target_buffer) transaction_rpc_exec(transaction_id, initiator2target_buffer_size, initiator2target_buffer, 0, NULL) +#define transaction_rpc_recv(transaction_id, target2initiator_buffer_size, target2initiator_buffer) transaction_rpc_exec(transaction_id, 0, NULL, target2initiator_buffer_size, target2initiator_buffer) diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index 9ed0f7591b..a711ef85f0 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -1,452 +1,118 @@ -#include -#include - -#include "config.h" -#include "matrix.h" -#include "quantum.h" - -#define ROWS_PER_HAND (MATRIX_ROWS / 2) -#define SYNC_TIMER_OFFSET 2 - -#ifdef RGBLIGHT_ENABLE -# include "rgblight.h" -#endif - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef ENCODER_ENABLE -# include "encoder.h" -static pin_t encoders_pad[] = ENCODERS_PAD_A; -# define NUMBER_OF_ENCODERS (sizeof(encoders_pad) / sizeof(pin_t)) -#endif - -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) -# include "led_matrix.h" -#endif -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) -# include "rgb_matrix.h" -#endif - -#if defined(USE_I2C) +/* Copyright 2021 QMK + * + * 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 . + */ -# include "i2c_master.h" -# include "i2c_slave.h" - -typedef struct _I2C_slave_buffer_t { -# ifndef DISABLE_SYNC_TIMER - uint32_t sync_timer; -# endif -# ifdef SPLIT_TRANSPORT_MIRROR - matrix_row_t mmatrix[ROWS_PER_HAND]; -# endif - matrix_row_t smatrix[ROWS_PER_HAND]; -# ifdef SPLIT_MODS_ENABLE - uint8_t real_mods; - uint8_t weak_mods; -# ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; -# endif -# endif -# ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; -# endif -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - rgblight_syncinfo_t rgblight_sync; -# endif -# ifdef ENCODER_ENABLE - uint8_t encoder_state[NUMBER_OF_ENCODERS]; -# endif -# ifdef WPM_ENABLE - uint8_t current_wpm; -# endif -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - led_eeconfig_t led_matrix; - bool led_suspend_state; -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_config_t rgb_matrix; - bool rgb_suspend_state; -# endif -} I2C_slave_buffer_t; +#include +#include -static I2C_slave_buffer_t *const i2c_buffer = (I2C_slave_buffer_t *)i2c_slave_reg; +#include "transactions.h" +#include "transport.h" +#include "transaction_id_define.h" +#include "atomic_util.h" -# define I2C_SYNC_TIME_START offsetof(I2C_slave_buffer_t, sync_timer) -# define I2C_KEYMAP_MASTER_START offsetof(I2C_slave_buffer_t, mmatrix) -# define I2C_KEYMAP_SLAVE_START offsetof(I2C_slave_buffer_t, smatrix) -# define I2C_REAL_MODS_START offsetof(I2C_slave_buffer_t, real_mods) -# define I2C_WEAK_MODS_START offsetof(I2C_slave_buffer_t, weak_mods) -# define I2C_ONESHOT_MODS_START offsetof(I2C_slave_buffer_t, oneshot_mods) -# define I2C_BACKLIGHT_START offsetof(I2C_slave_buffer_t, backlight_level) -# define I2C_RGB_START offsetof(I2C_slave_buffer_t, rgblight_sync) -# define I2C_ENCODER_START offsetof(I2C_slave_buffer_t, encoder_state) -# define I2C_WPM_START offsetof(I2C_slave_buffer_t, current_wpm) -# define I2C_LED_MATRIX_START offsetof(I2C_slave_buffer_t, led_matrix) -# define I2C_LED_SUSPEND_START offsetof(I2C_slave_buffer_t, led_suspend_state) -# define I2C_RGB_MATRIX_START offsetof(I2C_slave_buffer_t, rgb_matrix) -# define I2C_RGB_SUSPEND_START offsetof(I2C_slave_buffer_t, rgb_suspend_state) +#ifdef USE_I2C -# define TIMEOUT 100 +# ifndef SLAVE_I2C_TIMEOUT +# define SLAVE_I2C_TIMEOUT 100 +# endif // SLAVE_I2C_TIMEOUT # ifndef SLAVE_I2C_ADDRESS # define SLAVE_I2C_ADDRESS 0x32 # endif -// Get rows from other half over i2c -bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - i2c_readReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_SLAVE_START, (void *)slave_matrix, sizeof(i2c_buffer->smatrix), TIMEOUT); -# ifdef SPLIT_TRANSPORT_MIRROR - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_KEYMAP_MASTER_START, (void *)master_matrix, sizeof(i2c_buffer->mmatrix), TIMEOUT); -# endif +# include "i2c_master.h" +# include "i2c_slave.h" - // write backlight info -# ifdef BACKLIGHT_ENABLE - uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; - if (level != i2c_buffer->backlight_level) { - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_BACKLIGHT_START, (void *)&level, sizeof(level), TIMEOUT) >= 0) { - i2c_buffer->backlight_level = level; - } - } -# endif +// Ensure the I2C buffer has enough space +_Static_assert(sizeof(split_shared_memory_t) <= I2C_SLAVE_REG_COUNT, "split_shared_memory_t too large for I2C_SLAVE_REG_COUNT"); -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - if (rgblight_get_change_flags()) { - rgblight_syncinfo_t rgblight_sync; - rgblight_get_syncinfo(&rgblight_sync); - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_START, (void *)&rgblight_sync, sizeof(rgblight_sync), TIMEOUT) >= 0) { - rgblight_clear_change_flags(); - } - } -# endif +split_shared_memory_t *const split_shmem = (split_shared_memory_t *)i2c_slave_reg; -# ifdef ENCODER_ENABLE - i2c_readReg(SLAVE_I2C_ADDRESS, I2C_ENCODER_START, (void *)i2c_buffer->encoder_state, sizeof(i2c_buffer->encoder_state), TIMEOUT); - encoder_update_raw(i2c_buffer->encoder_state); -# endif +void transport_master_init(void) { i2c_init(); } +void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } -# ifdef WPM_ENABLE - uint8_t current_wpm = get_current_wpm(); - if (current_wpm != i2c_buffer->current_wpm) { - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WPM_START, (void *)¤t_wpm, sizeof(current_wpm), TIMEOUT) >= 0) { - i2c_buffer->current_wpm = current_wpm; - } +i2c_status_t transport_trigger_callback(int8_t id) { + // If there's no callback, indicate that we were successful + if (!split_transaction_table[id].slave_callback) { + return I2C_STATUS_SUCCESS; } -# endif -# ifdef SPLIT_MODS_ENABLE - uint8_t real_mods = get_mods(); - if (real_mods != i2c_buffer->real_mods) { - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_REAL_MODS_START, (void *)&real_mods, sizeof(real_mods), TIMEOUT) >= 0) { - i2c_buffer->real_mods = real_mods; + // Kick off the "callback executor", now that data has been written to the slave + split_shmem->transaction_id = id; + split_transaction_desc_t *trans = &split_transaction_table[I2C_EXECUTE_CALLBACK]; + return i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, SLAVE_I2C_TIMEOUT); +} + +bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) { + i2c_status_t status; + split_transaction_desc_t *trans = &split_transaction_table[id]; + if (initiator2target_length > 0) { + size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length; + memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len); + if ((status = i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) { + return false; } } - uint8_t weak_mods = get_weak_mods(); - if (weak_mods != i2c_buffer->weak_mods) { - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_WEAK_MODS_START, (void *)&weak_mods, sizeof(weak_mods), TIMEOUT) >= 0) { - i2c_buffer->weak_mods = weak_mods; - } + // If we need to execute a callback on the slave, do so + if ((status = transport_trigger_callback(id)) < 0) { + return false; } -# ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods = get_oneshot_mods(); - if (oneshot_mods != i2c_buffer->oneshot_mods) { - if (i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_ONESHOT_MODS_START, (void *)&oneshot_mods, sizeof(oneshot_mods), TIMEOUT) >= 0) { - i2c_buffer->oneshot_mods = oneshot_mods; + if (target2initiator_length > 0) { + size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length; + if ((status = i2c_readReg(SLAVE_I2C_ADDRESS, trans->target2initiator_offset, split_trans_target2initiator_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) { + return false; } + memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len); } -# endif -# endif -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_MATRIX_START, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix), TIMEOUT); - bool suspend_state = led_matrix_get_suspend_state(); - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_LED_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->led_suspend_state), TIMEOUT); -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_MATRIX_START, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix), TIMEOUT); - bool suspend_state = rgb_matrix_get_suspend_state(); - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_RGB_SUSPEND_START, (void *)suspend_state, sizeof(i2c_buffer->rgb_suspend_state), TIMEOUT); -# endif - -# ifndef DISABLE_SYNC_TIMER - i2c_buffer->sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; - i2c_writeReg(SLAVE_I2C_ADDRESS, I2C_SYNC_TIME_START, (void *)&i2c_buffer->sync_timer, sizeof(i2c_buffer->sync_timer), TIMEOUT); -# endif return true; } -void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { -# ifndef DISABLE_SYNC_TIMER - sync_timer_update(i2c_buffer->sync_timer); -# endif - // Copy matrix to I2C buffer - memcpy((void *)i2c_buffer->smatrix, (void *)slave_matrix, sizeof(i2c_buffer->smatrix)); -# ifdef SPLIT_TRANSPORT_MIRROR - memcpy((void *)master_matrix, (void *)i2c_buffer->mmatrix, sizeof(i2c_buffer->mmatrix)); -# endif - -// Read Backlight Info -# ifdef BACKLIGHT_ENABLE - backlight_set(i2c_buffer->backlight_level); -# endif - -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - // Update the RGB with the new data - if (i2c_buffer->rgblight_sync.status.change_flags != 0) { - rgblight_update_sync(&i2c_buffer->rgblight_sync, false); - i2c_buffer->rgblight_sync.status.change_flags = 0; - } -# endif - -# ifdef ENCODER_ENABLE - encoder_state_raw(i2c_buffer->encoder_state); -# endif - -# ifdef WPM_ENABLE - set_current_wpm(i2c_buffer->current_wpm); -# endif - -# ifdef SPLIT_MODS_ENABLE - set_mods(i2c_buffer->real_mods); - set_weak_mods(i2c_buffer->weak_mods); -# ifndef NO_ACTION_ONESHOT - set_oneshot_mods(i2c_buffer->oneshot_mods); -# endif -# endif - -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - memcpy((void *)i2c_buffer->led_matrix, (void *)led_matrix_eeconfig, sizeof(i2c_buffer->led_matrix)); - led_matrix_set_suspend_state(i2c_buffer->led_suspend_state); -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - memcpy((void *)i2c_buffer->rgb_matrix, (void *)rgb_matrix_config, sizeof(i2c_buffer->rgb_matrix)); - rgb_matrix_set_suspend_state(i2c_buffer->rgb_suspend_state); -# endif -} - -void transport_master_init(void) { i2c_init(); } - -void transport_slave_init(void) { i2c_slave_init(SLAVE_I2C_ADDRESS); } - -#else // USE_SERIAL +#else // USE_I2C # include "serial.h" -typedef struct _Serial_s2m_buffer_t { - // TODO: if MATRIX_COLS > 8 change to uint8_t packed_matrix[] for pack/unpack - matrix_row_t smatrix[ROWS_PER_HAND]; - -# ifdef ENCODER_ENABLE - uint8_t encoder_state[NUMBER_OF_ENCODERS]; -# endif - -} Serial_s2m_buffer_t; - -typedef struct _Serial_m2s_buffer_t { -# ifdef SPLIT_MODS_ENABLE - uint8_t real_mods; - uint8_t weak_mods; -# ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; -# endif -# endif -# ifndef DISABLE_SYNC_TIMER - uint32_t sync_timer; -# endif -# ifdef SPLIT_TRANSPORT_MIRROR - matrix_row_t mmatrix[ROWS_PER_HAND]; -# endif -# ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; -# endif -# ifdef WPM_ENABLE - uint8_t current_wpm; -# endif -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - led_eeconfig_t led_matrix; - bool led_suspend_state; -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_config_t rgb_matrix; - bool rgb_suspend_state; -# endif -} Serial_m2s_buffer_t; - -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) -// When MCUs on both sides drive their respective RGB LED chains, -// it is necessary to synchronize, so it is necessary to communicate RGB -// information. In that case, define RGBLIGHT_SPLIT with info on the number -// of LEDs on each half. -// -// Otherwise, if the master side MCU drives both sides RGB LED chains, -// there is no need to communicate. - -typedef struct _Serial_rgblight_t { - rgblight_syncinfo_t rgblight_sync; -} Serial_rgblight_t; +static split_shared_memory_t shared_memory; +split_shared_memory_t *const split_shmem = &shared_memory; -volatile Serial_rgblight_t serial_rgblight = {}; -uint8_t volatile status_rgblight = 0; -# endif - -volatile Serial_s2m_buffer_t serial_s2m_buffer = {}; -volatile Serial_m2s_buffer_t serial_m2s_buffer = {}; -uint8_t volatile status0 = 0; - -enum serial_transaction_id { - GET_SLAVE_MATRIX = 0, -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - PUT_RGBLIGHT, -# endif -}; - -SSTD_t transactions[] = { - [GET_SLAVE_MATRIX] = - { - (uint8_t *)&status0, - sizeof(serial_m2s_buffer), - (uint8_t *)&serial_m2s_buffer, - sizeof(serial_s2m_buffer), - (uint8_t *)&serial_s2m_buffer, - }, -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - [PUT_RGBLIGHT] = - { - (uint8_t *)&status_rgblight, sizeof(serial_rgblight), (uint8_t *)&serial_rgblight, 0, NULL // no slave to master transfer - }, -# endif -}; - -void transport_master_init(void) { soft_serial_initiator_init(transactions, TID_LIMIT(transactions)); } - -void transport_slave_init(void) { soft_serial_target_init(transactions, TID_LIMIT(transactions)); } +void transport_master_init(void) { soft_serial_initiator_init(); } +void transport_slave_init(void) { soft_serial_target_init(); } -# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -// rgblight synchronization information communication. - -void transport_rgblight_master(void) { - if (rgblight_get_change_flags()) { - rgblight_get_syncinfo((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync); - if (soft_serial_transaction(PUT_RGBLIGHT) == TRANSACTION_END) { - rgblight_clear_change_flags(); - } - } -} - -void transport_rgblight_slave(void) { - if (status_rgblight == TRANSACTION_ACCEPTED) { - rgblight_update_sync((rgblight_syncinfo_t *)&serial_rgblight.rgblight_sync, false); - status_rgblight = TRANSACTION_END; +bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) { + split_transaction_desc_t *trans = &split_transaction_table[id]; + if (initiator2target_length > 0) { + size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length; + memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len); } -} -# else -# define transport_rgblight_master() -# define transport_rgblight_slave() -# endif - -bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { -# ifndef SERIAL_USE_MULTI_TRANSACTION - if (soft_serial_transaction() != TRANSACTION_END) { - return false; - } -# else - transport_rgblight_master(); - if (soft_serial_transaction(GET_SLAVE_MATRIX) != TRANSACTION_END) { + if (soft_serial_transaction(id) != TRANSACTION_END) { return false; } -# endif - // TODO: if MATRIX_COLS > 8 change to unpack() - for (int i = 0; i < ROWS_PER_HAND; ++i) { - slave_matrix[i] = serial_s2m_buffer.smatrix[i]; -# ifdef SPLIT_TRANSPORT_MIRROR - serial_m2s_buffer.mmatrix[i] = master_matrix[i]; -# endif + if (target2initiator_length > 0) { + size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length; + memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len); } -# ifdef BACKLIGHT_ENABLE - // Write backlight level for slave to read - serial_m2s_buffer.backlight_level = is_backlight_enabled() ? get_backlight_level() : 0; -# endif - -# ifdef ENCODER_ENABLE - encoder_update_raw((uint8_t *)serial_s2m_buffer.encoder_state); -# endif - -# ifdef WPM_ENABLE - // Write wpm to slave - serial_m2s_buffer.current_wpm = get_current_wpm(); -# endif - -# ifdef SPLIT_MODS_ENABLE - serial_m2s_buffer.real_mods = get_mods(); - serial_m2s_buffer.weak_mods = get_weak_mods(); -# ifndef NO_ACTION_ONESHOT - serial_m2s_buffer.oneshot_mods = get_oneshot_mods(); -# endif -# endif - -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - serial_m2s_buffer.led_matrix = led_matrix_eeconfig; - serial_m2s_buffer.led_suspend_state = led_matrix_get_suspend_state(); -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - serial_m2s_buffer.rgb_matrix = rgb_matrix_config; - serial_m2s_buffer.rgb_suspend_state = rgb_matrix_get_suspend_state(); -# endif - -# ifndef DISABLE_SYNC_TIMER - serial_m2s_buffer.sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; -# endif return true; } -void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - transport_rgblight_slave(); -# ifndef DISABLE_SYNC_TIMER - sync_timer_update(serial_m2s_buffer.sync_timer); -# endif - - // TODO: if MATRIX_COLS > 8 change to pack() - for (int i = 0; i < ROWS_PER_HAND; ++i) { - serial_s2m_buffer.smatrix[i] = slave_matrix[i]; -# ifdef SPLIT_TRANSPORT_MIRROR - master_matrix[i] = serial_m2s_buffer.mmatrix[i]; -# endif - } -# ifdef BACKLIGHT_ENABLE - backlight_set(serial_m2s_buffer.backlight_level); -# endif - -# ifdef ENCODER_ENABLE - encoder_state_raw((uint8_t *)serial_s2m_buffer.encoder_state); -# endif +#endif // USE_I2C -# ifdef WPM_ENABLE - set_current_wpm(serial_m2s_buffer.current_wpm); -# endif - -# ifdef SPLIT_MODS_ENABLE - set_mods(serial_m2s_buffer.real_mods); - set_weak_mods(serial_m2s_buffer.weak_mods); -# ifndef NO_ACTION_ONESHOT - set_oneshot_mods(serial_m2s_buffer.oneshot_mods); -# endif -# endif - -# if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - led_matrix_eeconfig = serial_m2s_buffer.led_matrix; - led_matrix_set_suspend_state(serial_m2s_buffer.led_suspend_state); -# endif -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_matrix_config = serial_m2s_buffer.rgb_matrix; - rgb_matrix_set_suspend_state(serial_m2s_buffer.rgb_suspend_state); -# endif -} +bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); } -#endif +void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); } \ No newline at end of file diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index a9f66301bf..2e07f6b25c 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -1,10 +1,175 @@ +/* Copyright 2021 QMK + * + * 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 . + */ + #pragma once +#include "stdint.h" +#include "stdbool.h" + +#include "progmem.h" +#include "action_layer.h" #include "matrix.h" +#ifndef RPC_M2S_BUFFER_SIZE +# define RPC_M2S_BUFFER_SIZE 32 +#endif // RPC_M2S_BUFFER_SIZE + +#ifndef RPC_S2M_BUFFER_SIZE +# define RPC_S2M_BUFFER_SIZE 32 +#endif // RPC_S2M_BUFFER_SIZE + void transport_master_init(void); void transport_slave_init(void); // returns false if valid data not received from slave bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); + +bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length); + +#ifdef ENCODER_ENABLE +# include "encoder.h" +# define NUMBER_OF_ENCODERS (sizeof((pin_t[])ENCODERS_PAD_A) / sizeof(pin_t)) +#endif // ENCODER_ENABLE + +#ifdef BACKLIGHT_ENABLE +# include "backlight.h" +#endif // BACKLIGHT_ENABLE + +#ifdef RGBLIGHT_ENABLE +# include "rgblight.h" +#endif // RGBLIGHT_ENABLE + +typedef struct _split_slave_matrix_sync_t { + uint8_t checksum; + matrix_row_t matrix[(MATRIX_ROWS) / 2]; +} split_slave_matrix_sync_t; + +#ifdef SPLIT_TRANSPORT_MIRROR +typedef struct _split_master_matrix_sync_t { + matrix_row_t matrix[(MATRIX_ROWS) / 2]; +} split_master_matrix_sync_t; +#endif // SPLIT_TRANSPORT_MIRROR + +#ifdef ENCODER_ENABLE +typedef struct _split_slave_encoder_sync_t { + uint8_t checksum; + uint8_t state[NUMBER_OF_ENCODERS]; +} split_slave_encoder_sync_t; +#endif // ENCODER_ENABLE + +#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) +typedef struct _split_layers_sync_t { + layer_state_t layer_state; + layer_state_t default_layer_state; +} split_layers_sync_t; +#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) +# include "led_matrix.h" + +typedef struct _led_matrix_sync_t { + led_eeconfig_t led_matrix; + bool led_suspend_state; +} led_matrix_sync_t; +#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) +# include "rgb_matrix.h" + +typedef struct _rgb_matrix_sync_t { + rgb_config_t rgb_matrix; + bool rgb_suspend_state; +} rgb_matrix_sync_t; +#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + +#ifdef SPLIT_MODS_ENABLE +typedef struct _split_mods_sync_t { + uint8_t real_mods; + uint8_t weak_mods; +# ifndef NO_ACTION_ONESHOT + uint8_t oneshot_mods; +# endif // NO_ACTION_ONESHOT +} split_mods_sync_t; +#endif // SPLIT_MODS_ENABLE + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) +typedef struct _rpc_sync_info_t { + int8_t transaction_id; + uint8_t m2s_length; + uint8_t s2m_length; +} rpc_sync_info_t; +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + +typedef struct _split_shared_memory_t { +#ifdef USE_I2C + int8_t transaction_id; +#endif // USE_I2C + + split_slave_matrix_sync_t smatrix; + +#ifdef SPLIT_TRANSPORT_MIRROR + split_master_matrix_sync_t mmatrix; +#endif // SPLIT_TRANSPORT_MIRROR + +#ifdef ENCODER_ENABLE + split_slave_encoder_sync_t encoders; +#endif // ENCODER_ENABLE + +#ifndef DISABLE_SYNC_TIMER + uint32_t sync_timer; +#endif // DISABLE_SYNC_TIMER + +#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + split_layers_sync_t layers; +#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) + +#ifdef SPLIT_LED_STATE_ENABLE + uint8_t led_state; +#endif // SPLIT_LED_STATE_ENABLE + +#ifdef SPLIT_MODS_ENABLE + split_mods_sync_t mods; +#endif // SPLIT_MODS_ENABLE + +#ifdef BACKLIGHT_ENABLE + uint8_t backlight_level; +#endif // BACKLIGHT_ENABLE + +#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + rgblight_syncinfo_t rgblight_sync; +#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) + +#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + led_matrix_sync_t led_matrix_sync; +#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) + +#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + rgb_matrix_sync_t rgb_matrix_sync; +#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) + +#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + uint8_t current_wpm; +#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) + +#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) + rpc_sync_info_t rpc_info; + uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE]; + uint8_t rpc_s2m_buffer[RPC_S2M_BUFFER_SIZE]; +#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) +} split_shared_memory_t; + +extern split_shared_memory_t *const split_shmem; \ No newline at end of file -- cgit v1.2.3 From 04bc74d8f52370a01f1f67a5de8ae751e307e8c9 Mon Sep 17 00:00:00 2001 From: Stefan Kerkmann Date: Fri, 2 Jul 2021 23:28:32 +0200 Subject: Switch split_common to CRC subsystem (#13418) --- quantum/split_common/transactions.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 99a8623b3c..abad626e00 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -17,6 +17,7 @@ #include #include +#include "crc.h" #include "debug.h" #include "matrix.h" #include "quantum.h" @@ -43,22 +44,6 @@ #define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) #define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) -static uint8_t crc8(const void *data, size_t len) { - const uint8_t *p = (const uint8_t *)data; - uint8_t crc = 0xff; - size_t i, j; - for (i = 0; i < len; i++) { - crc ^= p[i]; - for (j = 0; j < 8; j++) { - if ((crc & 0x80) != 0) - crc = (uint8_t)((crc << 1) ^ 0x31); - else - crc <<= 1; - } - } - return crc; -} - #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) // Forward-declare the RPC callback handlers void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); -- cgit v1.2.3 From 3ab805fc67e95dfb23188bf63c7f5fbb2edcf038 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 3 Jul 2021 00:20:11 -0700 Subject: Add support for NO_PIN to all matrix types (#12238) Co-authored-by: Nick Brassel --- quantum/split_common/matrix.c | 66 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c index 56d91b07fe..d8e078e9bb 100644 --- a/quantum/split_common/matrix.c +++ b/quantum/split_common/matrix.c @@ -67,6 +67,14 @@ static inline void setPinInputHigh_atomic(pin_t pin) { ATOMIC_BLOCK_FORCEON { setPinInputHigh(pin); } } +static inline uint8_t readMatrixPin(pin_t pin) { + if (pin != NO_PIN) { + return readPin(pin); + } else { + return 1; + } +} + // matrix code #ifdef DIRECT_PINS @@ -101,20 +109,34 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] # if defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) # if (DIODE_DIRECTION == COL2ROW) -static void select_row(uint8_t row) { setPinOutput_writeLow(row_pins[row]); } +static bool select_row(uint8_t row) { + pin_t pin = row_pins[row]; + if (pin != NO_PIN) { + setPinOutput_writeLow(pin); + return true; + } + return false; +} -static void unselect_row(uint8_t row) { setPinInputHigh_atomic(row_pins[row]); } +static void unselect_row(uint8_t row) { + pin_t pin = row_pins[row]; + if (pin != NO_PIN) { + setPinInputHigh_atomic(pin); + } +} static void unselect_rows(void) { for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - setPinInputHigh_atomic(row_pins[x]); + unselect_row(x); } } __attribute__((weak)) void matrix_init_pins(void) { unselect_rows(); for (uint8_t x = 0; x < MATRIX_COLS; x++) { - setPinInputHigh_atomic(col_pins[x]); + if (col_pins[x] != NO_PIN) { + setPinInputHigh_atomic(col_pins[x]); + } } } @@ -122,14 +144,14 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] // Start with a clear matrix row matrix_row_t current_row_value = 0; - // Select row - select_row(current_row); + if (!select_row(current_row)) { // Select row + return; // skip NO_PIN row + } matrix_output_select_delay(); // For each col... for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { - // Select the col pin to read (active low) - uint8_t pin_state = readPin(col_pins[col_index]); + uint8_t pin_state = readMatrixPin(col_pins[col_index]); // Populate the matrix row with the state of the col pin current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); @@ -145,32 +167,48 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] # elif (DIODE_DIRECTION == ROW2COL) -static void select_col(uint8_t col) { setPinOutput_writeLow(col_pins[col]); } +static bool select_col(uint8_t col) { + pin_t pin = col_pins[col]; + if (pin != NO_PIN) { + setPinOutput_writeLow(pin); + return true; + } + return false; +} -static void unselect_col(uint8_t col) { setPinInputHigh_atomic(col_pins[col]); } +static void unselect_col(uint8_t col) { + pin_t pin = col_pins[col]; + if (pin != NO_PIN) { + setPinInputHigh_atomic(pin); + } +} static void unselect_cols(void) { for (uint8_t x = 0; x < MATRIX_COLS; x++) { - setPinInputHigh_atomic(col_pins[x]); + unselect_col(x); } } __attribute__((weak)) void matrix_init_pins(void) { unselect_cols(); for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - setPinInputHigh_atomic(row_pins[x]); + if (row_pins[x] != NO_PIN) { + setPinInputHigh_atomic(row_pins[x]); + } } } __attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { // Select col - select_col(current_col); + if (!select_col(current_col)) { // select col + return; // skip NO_PIN col + } matrix_output_select_delay(); // For each row... for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { // Check row pin state - if (readPin(row_pins[row_index]) == 0) { + if (readMatrixPin(row_pins[row_index]) == 0) { // Pin LO, set col bit current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); } else { -- cgit v1.2.3 From 550d9253b03c4273065b212d0b856a9ad07132df Mon Sep 17 00:00:00 2001 From: Jameson Thatcher Date: Mon, 5 Jul 2021 00:06:40 +0100 Subject: Allow invert of SPLIT_HAND_PIN logic (#13433) * added support for inverting the hand pin for split keyboards * Added docs about SPLIT_HAND_LOW_IS_LEFT * Update docs/feature_split_keyboard.md bring #define for split hand pin low for left half name in line with grid pin define Co-authored-by: Joel Challis * Update quantum/split_common/split_util.c update split hand pin low is left name to match split hand grid define Co-authored-by: Joel Challis Co-authored-by: Joel Challis --- quantum/split_common/split_util.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'quantum/split_common') diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 9e75e19ce0..989829d2dc 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -77,7 +77,11 @@ __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); +# ifdef SPLIT_HAND_PIN_LOW_IS_LEFT + return !readPin(SPLIT_HAND_PIN); +# else return readPin(SPLIT_HAND_PIN); +# endif #elif defined(SPLIT_HAND_MATRIX_GRID) # ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); -- cgit v1.2.3 From ccc0b23a75f30f0ee9e1c6440dd3d56c99d38ea2 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 11 Jul 2021 14:31:35 -0700 Subject: Unify matrix for split common and regular matrix (#13330) --- quantum/split_common/matrix.c | 340 ------------------------------------------ 1 file changed, 340 deletions(-) delete mode 100644 quantum/split_common/matrix.c (limited to 'quantum/split_common') diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c deleted file mode 100644 index d8e078e9bb..0000000000 --- a/quantum/split_common/matrix.c +++ /dev/null @@ -1,340 +0,0 @@ -/* -Copyright 2012 Jun Wako - -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 . -*/ -#include -#include -#include -#include "util.h" -#include "matrix.h" -#include "debounce.h" -#include "quantum.h" -#include "split_util.h" -#include "config.h" -#include "transactions.h" - -#ifndef ERROR_DISCONNECT_COUNT -# define ERROR_DISCONNECT_COUNT 5 -#endif // ERROR_DISCONNECT_COUNT - -#define ROWS_PER_HAND (MATRIX_ROWS / 2) - -#ifdef DIRECT_PINS -static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS; -#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) -# ifdef MATRIX_ROW_PINS -static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; -# endif // MATRIX_ROW_PINS -# ifdef MATRIX_COL_PINS -static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -# endif // MATRIX_COL_PINS -#endif - -/* matrix state(1:on, 0:off) */ -extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values -extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values - -// row offsets for each hand -uint8_t thisHand, thatHand; - -// user-defined overridable functions -__attribute__((weak)) void matrix_slave_scan_kb(void) { matrix_slave_scan_user(); } -__attribute__((weak)) void matrix_slave_scan_user(void) {} -__attribute__((weak)) void matrix_init_pins(void); -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); - -static inline void setPinOutput_writeLow(pin_t pin) { - ATOMIC_BLOCK_FORCEON { - setPinOutput(pin); - writePinLow(pin); - } -} - -static inline void setPinInputHigh_atomic(pin_t pin) { - ATOMIC_BLOCK_FORCEON { setPinInputHigh(pin); } -} - -static inline uint8_t readMatrixPin(pin_t pin) { - if (pin != NO_PIN) { - return readPin(pin); - } else { - return 1; - } -} - -// matrix code - -#ifdef DIRECT_PINS - -__attribute__((weak)) void matrix_init_pins(void) { - for (int row = 0; row < MATRIX_ROWS; row++) { - for (int col = 0; col < MATRIX_COLS; col++) { - pin_t pin = direct_pins[row][col]; - if (pin != NO_PIN) { - setPinInputHigh(pin); - } - } - } -} - -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { - // Start with a clear matrix row - matrix_row_t current_row_value = 0; - - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { - pin_t pin = direct_pins[current_row][col_index]; - if (pin != NO_PIN) { - current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index); - } - } - - // Update the matrix - current_matrix[current_row] = current_row_value; -} - -#elif defined(DIODE_DIRECTION) -# if defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) -# if (DIODE_DIRECTION == COL2ROW) - -static bool select_row(uint8_t row) { - pin_t pin = row_pins[row]; - if (pin != NO_PIN) { - setPinOutput_writeLow(pin); - return true; - } - return false; -} - -static void unselect_row(uint8_t row) { - pin_t pin = row_pins[row]; - if (pin != NO_PIN) { - setPinInputHigh_atomic(pin); - } -} - -static void unselect_rows(void) { - for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - unselect_row(x); - } -} - -__attribute__((weak)) void matrix_init_pins(void) { - unselect_rows(); - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - if (col_pins[x] != NO_PIN) { - setPinInputHigh_atomic(col_pins[x]); - } - } -} - -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { - // Start with a clear matrix row - matrix_row_t current_row_value = 0; - - if (!select_row(current_row)) { // Select row - return; // skip NO_PIN row - } - matrix_output_select_delay(); - - // For each col... - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) { - uint8_t pin_state = readMatrixPin(col_pins[col_index]); - - // Populate the matrix row with the state of the col pin - current_row_value |= pin_state ? 0 : (MATRIX_ROW_SHIFTER << col_index); - } - - // Unselect row - unselect_row(current_row); - matrix_output_unselect_delay(); // wait for all Col signals to go HIGH - - // Update the matrix - current_matrix[current_row] = current_row_value; -} - -# elif (DIODE_DIRECTION == ROW2COL) - -static bool select_col(uint8_t col) { - pin_t pin = col_pins[col]; - if (pin != NO_PIN) { - setPinOutput_writeLow(pin); - return true; - } - return false; -} - -static void unselect_col(uint8_t col) { - pin_t pin = col_pins[col]; - if (pin != NO_PIN) { - setPinInputHigh_atomic(pin); - } -} - -static void unselect_cols(void) { - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - unselect_col(x); - } -} - -__attribute__((weak)) void matrix_init_pins(void) { - unselect_cols(); - for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - if (row_pins[x] != NO_PIN) { - setPinInputHigh_atomic(row_pins[x]); - } - } -} - -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) { - // Select col - if (!select_col(current_col)) { // select col - return; // skip NO_PIN col - } - matrix_output_select_delay(); - - // For each row... - for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { - // Check row pin state - if (readMatrixPin(row_pins[row_index]) == 0) { - // Pin LO, set col bit - current_matrix[row_index] |= (MATRIX_ROW_SHIFTER << current_col); - } else { - // Pin HI, clear col bit - current_matrix[row_index] &= ~(MATRIX_ROW_SHIFTER << current_col); - } - } - - // Unselect col - unselect_col(current_col); - matrix_output_unselect_delay(); // wait for all Row signals to go HIGH -} - -# else -# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL! -# endif -# endif // defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) -#else -# error DIODE_DIRECTION is not defined! -#endif - -void matrix_init(void) { - split_pre_init(); - - // Set pinout for right half if pinout for that half is defined - if (!isLeftHand) { -#ifdef DIRECT_PINS_RIGHT - const pin_t direct_pins_right[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS_RIGHT; - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - for (uint8_t j = 0; j < MATRIX_COLS; j++) { - direct_pins[i][j] = direct_pins_right[i][j]; - } - } -#endif -#ifdef MATRIX_ROW_PINS_RIGHT - const pin_t row_pins_right[MATRIX_ROWS] = MATRIX_ROW_PINS_RIGHT; - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - row_pins[i] = row_pins_right[i]; - } -#endif -#ifdef MATRIX_COL_PINS_RIGHT - const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT; - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - col_pins[i] = col_pins_right[i]; - } -#endif - } - - thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); - thatHand = ROWS_PER_HAND - thisHand; - - // initialize key pins - matrix_init_pins(); - - // initialize matrix state: all keys off - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - raw_matrix[i] = 0; - matrix[i] = 0; - } - - debounce_init(ROWS_PER_HAND); - - matrix_init_quantum(); - - split_post_init(); -} - -bool matrix_post_scan(void) { - bool changed = false; - if (is_keyboard_master()) { - static uint8_t error_count; - - matrix_row_t slave_matrix[ROWS_PER_HAND] = {0}; - if (!transport_master(matrix + thisHand, slave_matrix)) { - error_count++; - - if (error_count > ERROR_DISCONNECT_COUNT) { - // reset other half if disconnected - for (int i = 0; i < ROWS_PER_HAND; ++i) { - matrix[thatHand + i] = 0; - slave_matrix[i] = 0; - } - - changed = true; - } - } else { - error_count = 0; - - for (int i = 0; i < ROWS_PER_HAND; ++i) { - if (matrix[thatHand + i] != slave_matrix[i]) { - matrix[thatHand + i] = slave_matrix[i]; - changed = true; - } - } - } - - matrix_scan_quantum(); - } else { - transport_slave(matrix + thatHand, matrix + thisHand); - - matrix_slave_scan_kb(); - } - - return changed; -} - -uint8_t matrix_scan(void) { - matrix_row_t curr_matrix[MATRIX_ROWS] = {0}; - -#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) - // Set row, read cols - for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { - matrix_read_cols_on_row(curr_matrix, current_row); - } -#elif (DIODE_DIRECTION == ROW2COL) - // Set col, read rows - for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { - matrix_read_rows_on_col(curr_matrix, current_col); - } -#endif - - bool local_changed = memcmp(raw_matrix, curr_matrix, sizeof(curr_matrix)) != 0; - if (local_changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix)); - - debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, local_changed); - - bool remote_changed = matrix_post_scan(); - return (uint8_t)(local_changed || remote_changed); -} -- cgit v1.2.3 From 567da49ed027a936a6f56aa069aad0db4605a198 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Sat, 24 Jul 2021 12:13:06 +0100 Subject: Avoid LTO conficts on arm_atsam (#13676) --- quantum/split_common/split_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 989829d2dc..8d414f6fe6 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -106,7 +106,7 @@ __attribute__((weak)) bool is_keyboard_master(void) { // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow if (usbstate == SLAVE) { - usb_disable(); + usb_disconnect(); } } -- cgit v1.2.3 From 65e376085356c18382d6a5d8dc54c8461144152e Mon Sep 17 00:00:00 2001 From: Nick Brassel Date: Mon, 9 Aug 2021 13:20:15 +1000 Subject: Fix compilation issue. (#13926) --- quantum/split_common/transactions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transactions.h b/quantum/split_common/transactions.h index 4306ba1d87..53610d6f8e 100644 --- a/quantum/split_common/transactions.h +++ b/quantum/split_common/transactions.h @@ -38,7 +38,7 @@ typedef struct _split_transaction_desc_t { // Forward declaration for the split transactions extern split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS]; -#define split_shmem_offset_ptr(offset) ((void *)(((uint8_t *)split_shmem) + (offset))) +#define split_shmem_offset_ptr(offset) (((uint8_t *)split_shmem) + (offset)) #define split_trans_initiator2target_buffer(trans) (split_shmem_offset_ptr((trans)->initiator2target_offset)) #define split_trans_target2initiator_buffer(trans) (split_shmem_offset_ptr((trans)->target2initiator_offset)) -- cgit v1.2.3 From 488aaa0980b113240a461d6d7878c62f5663f5c6 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 14 Aug 2021 22:39:08 -0700 Subject: Enable sync of OLED/ST7565 display on/off state on Splits (#13542) * Enable sync of OLED/ST7565 display on/off state on Splits * Only send if states are not matched Co-authored-by: Nick Brassel Co-authored-by: Nick Brassel --- quantum/split_common/transaction_id_define.h | 8 ++ quantum/split_common/transactions.c | 108 ++++++++++++++++++++++----- quantum/split_common/transport.h | 10 ++- 3 files changed, 105 insertions(+), 21 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h index 464c73478a..3b78402d4c 100644 --- a/quantum/split_common/transaction_id_define.h +++ b/quantum/split_common/transaction_id_define.h @@ -70,6 +70,14 @@ enum serial_transaction_id { PUT_WPM, #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + PUT_OLED, +#endif // defined(WPM_ENABLE) && defined(SPLIT_OLED_ENABLE) + +#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + PUT_ST7565, +#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) PUT_RPC_INFO, PUT_RPC_REQ_DATA, diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index abad626e00..de42882df3 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -41,8 +41,8 @@ { &dummy, 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) -#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) -#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) +#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) +#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) // Forward-declare the RPC callback handlers @@ -160,8 +160,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); } -# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers) -# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers) +# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers) +# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers) # define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), #else // SPLIT_TRANSPORT_MIRROR @@ -238,8 +238,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t } } -# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers) -# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers) +# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers) +# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers) # define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), #else // DISABLE_SYNC_TIMER @@ -303,8 +303,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t set_split_host_keyboard_leds(split_shmem->led_state); } -# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers) -# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers) +# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers) +# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers) # define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), #else // SPLIT_LED_STATE_ENABLE @@ -360,8 +360,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave # endif } -# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers) -# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers) +# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers) +# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers) # define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), #else // SPLIT_MODS_ENABLE @@ -385,8 +385,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } -# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers) -# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers) +# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers) +# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers) # define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), #else // BACKLIGHT_ENABLE @@ -422,8 +422,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s } } -# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers) -# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers) +# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers) +# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers) # define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), #else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) @@ -452,8 +452,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); } -# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers) -# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers) +# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers) +# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers) # define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), #else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) @@ -482,8 +482,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); } -# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers) -# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers) +# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers) +# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers) # define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), #else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) @@ -507,8 +507,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } -# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers) -# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers) +# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers) +# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers) # define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), #else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) @@ -519,6 +519,68 @@ static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_ #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) +//////////////////////////////////////////////////// +// OLED + +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + +static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + bool current_oled_state = is_oled_on(); + return send_if_condition(PUT_OLED, &last_update, (current_oled_state != split_shmem->current_oled_state), ¤t_oled_state, sizeof(current_oled_state)); +} + +static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + if (split_shmem->current_oled_state) { + oled_on(); + } else { + oled_off(); + } +} + +# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled_handlers) +# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers) +# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), + +#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + +# define TRANSACTIONS_OLED_MASTER() +# define TRANSACTIONS_OLED_SLAVE() +# define TRANSACTIONS_OLED_REGISTRATIONS + +#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + +//////////////////////////////////////////////////// +// ST7565 + +#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + +static bool st7565_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + static uint32_t last_update = 0; + bool current_st7565_state = st7565_is_on(); + return send_if_condition(PUT_ST7565, &last_update, (current_st7565_state != split_shmem->current_st7565_state), ¤t_st7565_state, sizeof(current_st7565_state)); +} + +static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { + if (split_shmem->current_st7565_state) { + st7565_on(); + } else { + st7565_off(); + } +} + +# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565_handlers) +# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565_handlers) +# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), + +#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + +# define TRANSACTIONS_ST7565_MASTER() +# define TRANSACTIONS_ST7565_SLAVE() +# define TRANSACTIONS_ST7565_REGISTRATIONS + +#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + //////////////////////////////////////////////////// uint8_t dummy; @@ -543,6 +605,8 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { TRANSACTIONS_LED_MATRIX_REGISTRATIONS TRANSACTIONS_RGB_MATRIX_REGISTRATIONS TRANSACTIONS_WPM_REGISTRATIONS + TRANSACTIONS_OLED_REGISTRATIONS + TRANSACTIONS_ST7565_REGISTRATIONS // clang-format on #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) @@ -567,6 +631,8 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix TRANSACTIONS_LED_MATRIX_MASTER(); TRANSACTIONS_RGB_MATRIX_MASTER(); TRANSACTIONS_WPM_MASTER(); + TRANSACTIONS_OLED_MASTER(); + TRANSACTIONS_ST7565_MASTER(); return okay; } @@ -583,6 +649,8 @@ void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[ TRANSACTIONS_LED_MATRIX_SLAVE(); TRANSACTIONS_RGB_MATRIX_SLAVE(); TRANSACTIONS_WPM_SLAVE(); + TRANSACTIONS_OLED_SLAVE(); + TRANSACTIONS_ST7565_SLAVE(); } #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index 2e07f6b25c..1d4f6ed0cd 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -165,6 +165,14 @@ typedef struct _split_shared_memory_t { uint8_t current_wpm; #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + uint8_t current_oled_state; +#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) + +#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) + uint8_t current_st7565_state; +#endif // ST7565_ENABLE(OLED_ENABLE) && defined(SPLIT_ST7565_ENABLE) + #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) rpc_sync_info_t rpc_info; uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE]; @@ -172,4 +180,4 @@ typedef struct _split_shared_memory_t { #endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) } split_shared_memory_t; -extern split_shared_memory_t *const split_shmem; \ No newline at end of file +extern split_shared_memory_t *const split_shmem; -- cgit v1.2.3 From f56c202fb31ad7cdfdbcb4083dd5dad54d2b508f Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sun, 15 Aug 2021 00:54:08 -0700 Subject: Fix ifdefs for OLED split sync code (#14017) --- quantum/split_common/transaction_id_define.h | 4 ++-- quantum/split_common/transactions.c | 4 ++-- quantum/split_common/transport.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h index 3b78402d4c..8dd2cd065f 100644 --- a/quantum/split_common/transaction_id_define.h +++ b/quantum/split_common/transaction_id_define.h @@ -70,9 +70,9 @@ enum serial_transaction_id { PUT_WPM, #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) PUT_OLED, -#endif // defined(WPM_ENABLE) && defined(SPLIT_OLED_ENABLE) +#endif // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) #if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) PUT_ST7565, diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index de42882df3..7eb3eca3e7 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -522,7 +522,7 @@ static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_ //////////////////////////////////////////////////// // OLED -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { static uint32_t last_update = 0; @@ -542,7 +542,7 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave # define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers) # define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), -#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) +#else // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) # define TRANSACTIONS_OLED_MASTER() # define TRANSACTIONS_OLED_SLAVE() diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index 1d4f6ed0cd..f7abb9979e 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -165,9 +165,9 @@ typedef struct _split_shared_memory_t { uint8_t current_wpm; #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) uint8_t current_oled_state; -#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) +#endif // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) #if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) uint8_t current_st7565_state; -- cgit v1.2.3 From 0ae20e74578ae4420af3e684f7ad9fcbd7beee94 Mon Sep 17 00:00:00 2001 From: Joakim Tufvegren Date: Sun, 22 Aug 2021 02:51:17 +0200 Subject: Make solo half of split keyboards (more) usable. (#13523) * Make solo half of split keyboards (more) usable. Using only one half of a split keyboard (that's using the split_common framework to communicate) is not a great experience, since several read timeouts per scan cycle cause an unusably slow scan rate. This change blocks all split communication attempts for 500 ms (configurable) after an error occurs, causing the scan rate to become at least _more_ usable, but might need some tweaking to work fully on most keyboards. One read timeout still needs to occur after the 500 ms has passed, and if that timeout isn't low enough, some scan cycles may still be too slow. * Fix lint complaint. * Require 25 consecutive comm errors to see comms as disconnected. The number of max errors can be overridden by defining `SPLIT_MAX_CONNECTION_ERRORS`. * Add comments to new defines, and ability to disable disconnection check. Also increase `SPLIT_MAX_CONNECTION_ERRORS` to 40, since it's divisible by most relevant numbers for the description. * Make lint happy ...again * Only update `connection_check_timer` when needed. * Add new defines to split keyboard documentation. * Move connection timeout logic to transport.c, add `is_transport_connected`. * Use split_common disconnection logic in matrix.c. Instead of doing more or less the same thing twice. * Move disconnection logic to `transport_master`. Is a cleaner implementation, and causes the scan rate while disconnected to increase instead of decrease. * Lint fixes. * Lower default `SERIAL_USART_TIMEOUT` to 20 ms. The read timeout must be low enough to not cause exessively long scan cycles when using a solo split half. 10 ms was determined from testing to work fine even with the slowest defined baudrate of 19200 (5 ms was too low for that case), so 20 ms should be fine for most cases. * Remove `SERIAL_USART_TIMEOUT` from ergodox_infinity/config.h Was somewhat mistakenly included in an earlier PR. * Fix building with `USE_I2C`. * Reduce built firmware size. Not really sure why this works, the idea was taken from tzarc's work on split disconnection. * Tweak and improve opt-out for split disconnection logic. There are now two ways to opt out from this feature: * Set `SPLIT_MAX_CONNECTION_ERRORS` to 0. This will completely disable the connection status checks (also affects the slave matrix reset logic in matrix.c, though). * Set `SPLIT_CONNECTION_CHECK_TIMEOUT` to 0. This will only disable the communication throttling while disconnected. Will make the firmware smaller. * Make split disconnection logic work with custom transports. Includes a fallback implementation for keyboards using a custom split_util.c but not a custom matrix.c (currently no such keyboard seems to be merged, though). * Remove unnecessary include of timer.h Co-authored-by: Joel Challis Co-authored-by: Joel Challis --- quantum/split_common/split_util.c | 51 ++++++++++++++++++ quantum/split_common/split_util.h | 5 ++ quantum/split_common/transactions.c | 102 ++++++++++++++++++------------------ quantum/split_common/transport.c | 2 +- 4 files changed, 108 insertions(+), 52 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c index 8d414f6fe6..35f0a9d181 100644 --- a/quantum/split_common/split_util.c +++ b/quantum/split_common/split_util.c @@ -39,6 +39,21 @@ # define SPLIT_USB_TIMEOUT_POLL 10 #endif +// Max number of consecutive failed communications (one per scan cycle) before the communication is seen as disconnected. +// Set to 0 to disable the disconnection check altogether. +#ifndef SPLIT_MAX_CONNECTION_ERRORS +# define SPLIT_MAX_CONNECTION_ERRORS 10 +#endif // SPLIT_MAX_CONNECTION_ERRORS + +// How long (in milliseconds) to block all connection attempts after the communication has been flagged as disconnected. +// One communication attempt will be allowed everytime this amount of time has passed since the last attempt. If that attempt succeeds, the communication is seen as working again. +// Set to 0 to disable communication throttling while disconnected +#ifndef SPLIT_CONNECTION_CHECK_TIMEOUT +# define SPLIT_CONNECTION_CHECK_TIMEOUT 500 +#endif // SPLIT_CONNECTION_CHECK_TIMEOUT + +static uint8_t connection_errors = 0; + volatile bool isLeftHand = true; #if defined(SPLIT_USB_DETECT) @@ -142,3 +157,39 @@ void split_post_init(void) { transport_slave_init(); } } + +bool is_transport_connected(void) { return connection_errors < SPLIT_MAX_CONNECTION_ERRORS; } + +bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { +#if SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 + // Throttle transaction attempts if target doesn't seem to be connected + // Without this, a solo half becomes unusable due to constant read timeouts + static uint16_t connection_check_timer = 0; + const bool is_disconnected = !is_transport_connected(); + if (is_disconnected && timer_elapsed(connection_check_timer) < SPLIT_CONNECTION_CHECK_TIMEOUT) { + return false; + } +#endif // SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 + + __attribute__((unused)) bool okay = transport_master(master_matrix, slave_matrix); +#if SPLIT_MAX_CONNECTION_ERRORS > 0 + if (!okay) { + if (connection_errors < UINT8_MAX) { + connection_errors++; + } +# if SPLIT_CONNECTION_CHECK_TIMEOUT > 0 + bool connected = is_transport_connected(); + if (!connected) { + connection_check_timer = timer_read(); + dprintln("Target disconnected, throttling connection attempts"); + } + return connected; + } else if (is_disconnected) { + dprintln("Target connected"); +# endif // SPLIT_CONNECTION_CHECK_TIMEOUT > 0 + } + + connection_errors = 0; +#endif // SPLIT_MAX_CONNECTION_ERRORS > 0 + return true; +} diff --git a/quantum/split_common/split_util.h b/quantum/split_common/split_util.h index a4c12519e0..ef72043bb7 100644 --- a/quantum/split_common/split_util.h +++ b/quantum/split_common/split_util.h @@ -5,8 +5,13 @@ #include #include +#include "matrix.h" + extern volatile bool isLeftHand; void matrix_master_OLED_init(void); void split_pre_init(void); void split_post_init(void); + +bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); +bool is_transport_connected(void); diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 7eb3eca3e7..28ea4ef6d8 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -23,6 +23,7 @@ #include "quantum.h" #include "transactions.h" #include "transport.h" +#include "split_util.h" #include "transaction_id_define.h" #define SYNC_TIMER_OFFSET 2 @@ -53,34 +54,30 @@ void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *i //////////////////////////////////////////////////// // Helpers -bool transaction_handler_master(bool okay, matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) { - if (okay) { - bool this_okay = true; - for (int iter = 1; iter <= 10; ++iter) { - if (!this_okay) { - for (int i = 0; i < iter * iter; ++i) { - wait_us(10); - } +static bool transaction_handler_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) { + int num_retries = is_transport_connected() ? 10 : 1; + for (int iter = 1; iter <= num_retries; ++iter) { + if (iter > 1) { + for (int i = 0; i < iter * iter; ++i) { + wait_us(10); } - ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); }; - if (this_okay) break; - } - okay &= this_okay; - if (!okay) { - dprintf("Failed to execute %s\n", prefix); } + bool this_okay = true; + ATOMIC_BLOCK_FORCEON { this_okay = handler(master_matrix, slave_matrix); }; + if (this_okay) return true; } - return okay; + dprintf("Failed to execute %s\n", prefix); + return false; } -#define TRANSACTION_HANDLER_MASTER(prefix) \ - do { \ - okay &= transaction_handler_master(okay, master_matrix, slave_matrix, #prefix, &prefix##_master); \ +#define TRANSACTION_HANDLER_MASTER(prefix) \ + do { \ + if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \ } while (0) -#define TRANSACTION_HANDLER_SLAVE(prefix) \ - do { \ - ATOMIC_BLOCK_FORCEON { prefix##_slave(master_matrix, slave_matrix); }; \ +#define TRANSACTION_HANDLER_SLAVE(prefix) \ + do { \ + ATOMIC_BLOCK_FORCEON { prefix##_handlers_slave(master_matrix, slave_matrix); }; \ } while (0) inline static bool read_if_checksum_mismatch(int8_t trans_id_checksum, int8_t trans_id_retrieve, uint32_t *last_update, void *destination, const void *equiv_shmem, size_t length) { @@ -138,8 +135,8 @@ static void slave_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row } // clang-format off -#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix_handlers) -#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix_handlers) +#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix) +#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(slave_matrix) #define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \ [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \ [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix), @@ -160,8 +157,8 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); } -# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix_handlers) -# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix_handlers) +# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix) +# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(master_matrix) # define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), #else // SPLIT_TRANSPORT_MIRROR @@ -196,8 +193,8 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl } // clang-format off -# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder_handlers) -# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder_handlers) +# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder) +# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE(encoder) # define TRANSACTIONS_ENCODERS_REGISTRATIONS \ [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state), @@ -238,8 +235,8 @@ static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t } } -# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer_handlers) -# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer_handlers) +# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer) +# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE(sync_timer) # define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), #else // DISABLE_SYNC_TIMER @@ -272,8 +269,8 @@ static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_ } // clang-format off -# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state_handlers) -# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state_handlers) +# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state) +# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(layer_state) # define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \ [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \ [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state), @@ -303,8 +300,8 @@ static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t set_split_host_keyboard_leds(split_shmem->led_state); } -# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state_handlers) -# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state_handlers) +# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state) +# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE(led_state) # define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), #else // SPLIT_LED_STATE_ENABLE @@ -360,8 +357,8 @@ static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave # endif } -# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods_handlers) -# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods_handlers) +# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods) +# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods) # define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), #else // SPLIT_MODS_ENABLE @@ -385,8 +382,8 @@ static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { backlight_set(split_shmem->backlight_level); } -# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight_handlers) -# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight_handlers) +# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight) +# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight) # define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), #else // BACKLIGHT_ENABLE @@ -422,8 +419,8 @@ static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t s } } -# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight_handlers) -# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight_handlers) +# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight) +# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight) # define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), #else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) @@ -452,8 +449,8 @@ static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t led_matrix_set_suspend_state(split_shmem->led_matrix_sync.led_suspend_state); } -# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix_handlers) -# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix_handlers) +# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix) +# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix) # define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), #else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) @@ -482,8 +479,8 @@ static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t rgb_matrix_set_suspend_state(split_shmem->rgb_matrix_sync.rgb_suspend_state); } -# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix_handlers) -# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix_handlers) +# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix) +# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix) # define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), #else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) @@ -507,8 +504,8 @@ static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { set_current_wpm(split_shmem->current_wpm); } -# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm_handlers) -# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm_handlers) +# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm) +# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE(wpm) # define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), #else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) @@ -538,8 +535,8 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave } } -# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled_handlers) -# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled_handlers) +# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled) +# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled) # define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), #else // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) @@ -569,8 +566,8 @@ static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sla } } -# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565_handlers) -# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565_handlers) +# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565) +# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565) # define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), #else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) @@ -618,7 +615,6 @@ split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { }; bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - bool okay = true; TRANSACTIONS_SLAVE_MATRIX_MASTER(); TRANSACTIONS_MASTER_MATRIX_MASTER(); TRANSACTIONS_ENCODERS_MASTER(); @@ -633,7 +629,7 @@ bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix TRANSACTIONS_WPM_MASTER(); TRANSACTIONS_OLED_MASTER(); TRANSACTIONS_ST7565_MASTER(); - return okay; + return true; } void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { @@ -666,6 +662,10 @@ void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback) } bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { + // Prevent transaction attempts while transport is disconnected + if (!is_transport_connected()) { + return false; + } // Prevent invoking RPC on QMK core sync data if (transaction_id <= GET_RPC_RESP_DATA) return false; // Prevent sizing issues diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c index a711ef85f0..bcc0261417 100644 --- a/quantum/split_common/transport.c +++ b/quantum/split_common/transport.c @@ -115,4 +115,4 @@ bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { return transactions_master(master_matrix, slave_matrix); } -void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); } \ No newline at end of file +void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { transactions_slave(master_matrix, slave_matrix); } -- cgit v1.2.3 From 4e1c5887c5c08ebd2cf7868c8d9292aa728e7bf0 Mon Sep 17 00:00:00 2001 From: Xelus22 <17491233+Xelus22@users.noreply.github.com> Date: Tue, 24 Aug 2021 16:28:26 +1000 Subject: [Core] Refactor OLED to allow easy addition of other types (#13454) * add docs * core changes * update keyboards to new OLED * updated users to new OLED * update layouts to new OLED * fixup docs * drashna's suggestion * fix up docs * new keyboards with oled * core split changes * remaining keyboard files * Fix The Helix keyboards oled options * reflect develop Co-authored-by: Drashna Jaelre Co-authored-by: mtei <2170248+mtei@users.noreply.github.com> --- quantum/split_common/transaction_id_define.h | 4 ++-- quantum/split_common/transactions.c | 4 ++-- quantum/split_common/transport.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'quantum/split_common') diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h index 8dd2cd065f..535bc21aea 100644 --- a/quantum/split_common/transaction_id_define.h +++ b/quantum/split_common/transaction_id_define.h @@ -70,9 +70,9 @@ enum serial_transaction_id { PUT_WPM, #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) -#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) PUT_OLED, -#endif // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) #if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) PUT_ST7565, diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 28ea4ef6d8..fd676f0729 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c @@ -519,7 +519,7 @@ static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_ //////////////////////////////////////////////////// // OLED -#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { static uint32_t last_update = 0; @@ -539,7 +539,7 @@ static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave # define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled) # define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), -#else // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) # define TRANSACTIONS_OLED_MASTER() # define TRANSACTIONS_OLED_SLAVE() diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h index f7abb9979e..1d4f6ed0cd 100644 --- a/quantum/split_common/transport.h +++ b/quantum/split_common/transport.h @@ -165,9 +165,9 @@ typedef struct _split_shared_memory_t { uint8_t current_wpm; #endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) -#if defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) uint8_t current_oled_state; -#endif // defined(OLED_DRIVER_ENABLE) && defined(SPLIT_OLED_ENABLE) +#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) #if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) uint8_t current_st7565_state; -- cgit v1.2.3