Implement connection keycode logic (#25176)
This commit is contained in:
		
							parent
							
								
									ec324af22e
								
							
						
					
					
						commit
						c7cb7ba976
					
				| @ -892,8 +892,8 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) | |||||||
|     OPT_DEFS += -DBLUETOOTH_ENABLE |     OPT_DEFS += -DBLUETOOTH_ENABLE | ||||||
|     OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]')) |     OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]')) | ||||||
|     NO_USB_STARTUP_CHECK := yes |     NO_USB_STARTUP_CHECK := yes | ||||||
|  |     CONNECTION_ENABLE := yes | ||||||
|     COMMON_VPATH += $(DRIVER_PATH)/bluetooth |     COMMON_VPATH += $(DRIVER_PATH)/bluetooth | ||||||
|     SRC += outputselect.c process_connection.c |  | ||||||
| 
 | 
 | ||||||
|     ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le) |     ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le) | ||||||
|         SPI_DRIVER_REQUIRED = yes |         SPI_DRIVER_REQUIRED = yes | ||||||
|  | |||||||
| @ -25,6 +25,7 @@ GENERIC_FEATURES = \ | |||||||
|     CAPS_WORD \
 |     CAPS_WORD \
 | ||||||
|     COMBO \
 |     COMBO \
 | ||||||
|     COMMAND \
 |     COMMAND \
 | ||||||
|  |     CONNECTION \
 | ||||||
|     CRC \
 |     CRC \
 | ||||||
|     DEFERRED_EXEC \
 |     DEFERRED_EXEC \
 | ||||||
|     DIGITIZER \
 |     DIGITIZER \
 | ||||||
|  | |||||||
| @ -1,70 +0,0 @@ | |||||||
| /*
 |  | ||||||
| Copyright 2017 Priyadi Iman Nurcahyo |  | ||||||
| This program is free software: you can redistribute it and/or modify |  | ||||||
| it under the terms of the GNU General Public License as published by |  | ||||||
| the Free Software Foundation, either version 2 of the License, or |  | ||||||
| (at your option) any later version. |  | ||||||
| This program is distributed in the hope that it will be useful, |  | ||||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
| GNU General Public License for more details. |  | ||||||
| You should have received a copy of the GNU General Public License |  | ||||||
| along with this program.  If not, see <http://www.gnu.org/licenses/>.
 |  | ||||||
| */ |  | ||||||
| 
 |  | ||||||
| #include "outputselect.h" |  | ||||||
| #include "usb_util.h" |  | ||||||
| 
 |  | ||||||
| #ifdef BLUETOOTH_BLUEFRUIT_LE |  | ||||||
| #    include "bluefruit_le.h" |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| uint8_t desired_output = OUTPUT_DEFAULT; |  | ||||||
| 
 |  | ||||||
| /** \brief Set Output
 |  | ||||||
|  * |  | ||||||
|  * FIXME: Needs doc |  | ||||||
|  */ |  | ||||||
| void set_output(uint8_t output) { |  | ||||||
|     set_output_user(output); |  | ||||||
|     desired_output = output; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** \brief Set Output User
 |  | ||||||
|  * |  | ||||||
|  * FIXME: Needs doc |  | ||||||
|  */ |  | ||||||
| __attribute__((weak)) void set_output_user(uint8_t output) {} |  | ||||||
| 
 |  | ||||||
| /** \brief Auto Detect Output
 |  | ||||||
|  * |  | ||||||
|  * FIXME: Needs doc |  | ||||||
|  */ |  | ||||||
| uint8_t auto_detect_output(void) { |  | ||||||
|     if (usb_connected_state()) { |  | ||||||
|         return OUTPUT_USB; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| #ifdef BLUETOOTH_BLUEFRUIT_LE |  | ||||||
|     if (bluefruit_le_is_connected()) { |  | ||||||
|         return OUTPUT_BLUETOOTH; |  | ||||||
|     } |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #ifdef BLUETOOTH_ENABLE |  | ||||||
|     return OUTPUT_BLUETOOTH; // should check if BT is connected here
 |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
|     return OUTPUT_NONE; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** \brief Where To Send
 |  | ||||||
|  * |  | ||||||
|  * FIXME: Needs doc |  | ||||||
|  */ |  | ||||||
| uint8_t where_to_send(void) { |  | ||||||
|     if (desired_output == OUTPUT_AUTO) { |  | ||||||
|         return auto_detect_output(); |  | ||||||
|     } |  | ||||||
|     return desired_output; |  | ||||||
| } |  | ||||||
| @ -14,21 +14,17 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <stdint.h> | #include "connection.h" | ||||||
| 
 | 
 | ||||||
| enum outputs { | // DEPRECATED - DO NOT USE
 | ||||||
|     OUTPUT_AUTO, |  | ||||||
| 
 | 
 | ||||||
|     OUTPUT_NONE, | #define OUTPUT_AUTO CONNECTION_HOST_AUTO | ||||||
|     OUTPUT_USB, | #define OUTPUT_NONE CONNECTION_HOST_NONE | ||||||
|     OUTPUT_BLUETOOTH | #define OUTPUT_USB CONNECTION_HOST_USB | ||||||
| }; | #define OUTPUT_BLUETOOTH CONNECTION_HOST_BLUETOOTH | ||||||
| 
 | 
 | ||||||
| #ifndef OUTPUT_DEFAULT | #define set_output connection_set_host_noeeprom | ||||||
| #    define OUTPUT_DEFAULT OUTPUT_AUTO | #define where_to_send connection_get_host | ||||||
| #endif | #define auto_detect_output connection_auto_detect_host | ||||||
| 
 | 
 | ||||||
| void    set_output(uint8_t output); | void set_output_user(uint8_t output); | ||||||
| void    set_output_user(uint8_t output); |  | ||||||
| uint8_t auto_detect_output(void); |  | ||||||
| uint8_t where_to_send(void); |  | ||||||
|  | |||||||
							
								
								
									
										147
									
								
								quantum/connection/connection.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								quantum/connection/connection.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,147 @@ | |||||||
|  | // Copyright 2025 QMK
 | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||||
|  | #include "connection.h" | ||||||
|  | #include "eeconfig.h" | ||||||
|  | #include "usb_util.h" | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | // ======== DEPRECATED DEFINES - DO NOT USE ========
 | ||||||
|  | #ifdef OUTPUT_DEFAULT | ||||||
|  | #    undef CONNECTION_HOST_DEFAULT | ||||||
|  | #    define CONNECTION_HOST_DEFAULT OUTPUT_DEFAULT | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | __attribute__((weak)) void set_output_user(uint8_t output) {} | ||||||
|  | // ========
 | ||||||
|  | 
 | ||||||
|  | #ifdef BLUETOOTH_ENABLE | ||||||
|  | #    ifdef BLUETOOTH_BLUEFRUIT_LE | ||||||
|  | #        include "bluefruit_le.h" | ||||||
|  | #        define bluetooth_is_connected() bluefruit_le_is_connected() | ||||||
|  | #    else | ||||||
|  | // TODO: drivers should check if BT is connected here
 | ||||||
|  | #        define bluetooth_is_connected() true | ||||||
|  | #    endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define CONNECTION_HOST_INVALID 0xFF | ||||||
|  | 
 | ||||||
|  | #ifndef CONNECTION_HOST_DEFAULT | ||||||
|  | #    define CONNECTION_HOST_DEFAULT CONNECTION_HOST_AUTO | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static const connection_host_t host_candidates[] = { | ||||||
|  |     CONNECTION_HOST_AUTO, | ||||||
|  |     CONNECTION_HOST_USB, | ||||||
|  | #ifdef BLUETOOTH_ENABLE | ||||||
|  |     CONNECTION_HOST_BLUETOOTH, | ||||||
|  | #endif | ||||||
|  | #if 0 | ||||||
|  |     CONNECTION_HOST_2P4GHZ, | ||||||
|  | #endif | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define HOST_CANDIDATES_COUNT ARRAY_SIZE(host_candidates) | ||||||
|  | 
 | ||||||
|  | static connection_config_t config = {.desired_host = CONNECTION_HOST_INVALID}; | ||||||
|  | 
 | ||||||
|  | void eeconfig_update_connection_default(void) { | ||||||
|  |     config.desired_host = CONNECTION_HOST_DEFAULT; | ||||||
|  | 
 | ||||||
|  |     eeconfig_update_connection(&config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_init(void) { | ||||||
|  |     eeconfig_read_connection(&config); | ||||||
|  |     if (config.desired_host == CONNECTION_HOST_INVALID) { | ||||||
|  |         eeconfig_update_connection_default(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __attribute__((weak)) void connection_host_changed_user(connection_host_t host) {} | ||||||
|  | __attribute__((weak)) void connection_host_changed_kb(connection_host_t host) {} | ||||||
|  | 
 | ||||||
|  | static void handle_host_changed(void) { | ||||||
|  |     connection_host_changed_user(config.desired_host); | ||||||
|  |     connection_host_changed_kb(config.desired_host); | ||||||
|  | 
 | ||||||
|  |     // TODO: Remove deprecated callback
 | ||||||
|  |     set_output_user(config.desired_host); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_set_host_noeeprom(connection_host_t host) { | ||||||
|  |     if (config.desired_host == host) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     config.desired_host = host; | ||||||
|  | 
 | ||||||
|  |     handle_host_changed(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_set_host(connection_host_t host) { | ||||||
|  |     connection_set_host_noeeprom(host); | ||||||
|  | 
 | ||||||
|  |     eeconfig_update_connection(&config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_next_host_noeeprom(void) { | ||||||
|  |     uint8_t next = 0; | ||||||
|  |     for (uint8_t i = 0; i < HOST_CANDIDATES_COUNT; i++) { | ||||||
|  |         if (host_candidates[i] == config.desired_host) { | ||||||
|  |             next = i == HOST_CANDIDATES_COUNT - 1 ? 0 : i + 1; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     connection_set_host_noeeprom(host_candidates[next]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_next_host(void) { | ||||||
|  |     connection_next_host_noeeprom(); | ||||||
|  | 
 | ||||||
|  |     eeconfig_update_connection(&config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_prev_host_noeeprom(void) { | ||||||
|  |     uint8_t next = 0; | ||||||
|  |     for (uint8_t i = 0; i < HOST_CANDIDATES_COUNT; i++) { | ||||||
|  |         if (host_candidates[i] == config.desired_host) { | ||||||
|  |             next = i == 0 ? HOST_CANDIDATES_COUNT - 1 : i - 1; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     connection_set_host_noeeprom(host_candidates[next]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void connection_prev_host(void) { | ||||||
|  |     connection_prev_host_noeeprom(); | ||||||
|  | 
 | ||||||
|  |     eeconfig_update_connection(&config); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | connection_host_t connection_get_host_raw(void) { | ||||||
|  |     return config.desired_host; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | connection_host_t connection_auto_detect_host(void) { | ||||||
|  |     if (usb_connected_state()) { | ||||||
|  |         return CONNECTION_HOST_USB; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | #ifdef BLUETOOTH_ENABLE | ||||||
|  |     if (bluetooth_is_connected()) { | ||||||
|  |         return CONNECTION_HOST_BLUETOOTH; | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     return CONNECTION_HOST_NONE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | connection_host_t connection_get_host(void) { | ||||||
|  |     if (config.desired_host == CONNECTION_HOST_AUTO) { | ||||||
|  |         return connection_auto_detect_host(); | ||||||
|  |     } | ||||||
|  |     return config.desired_host; | ||||||
|  | } | ||||||
							
								
								
									
										110
									
								
								quantum/connection/connection.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								quantum/connection/connection.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | |||||||
|  | // Copyright 2025 QMK
 | ||||||
|  | // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <stdint.h> | ||||||
|  | #include "util.h" | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \enum connection_host_t | ||||||
|  |  * | ||||||
|  |  * An enumeration of the possible hosts. | ||||||
|  |  */ | ||||||
|  | typedef enum connection_host_t { | ||||||
|  |     CONNECTION_HOST_AUTO, | ||||||
|  | 
 | ||||||
|  |     CONNECTION_HOST_NONE, | ||||||
|  |     CONNECTION_HOST_USB, | ||||||
|  |     CONNECTION_HOST_BLUETOOTH, | ||||||
|  |     CONNECTION_HOST_2P4GHZ | ||||||
|  | } connection_host_t; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \union connection_config_t | ||||||
|  |  * | ||||||
|  |  * Configuration structure for the connection subsystem. | ||||||
|  |  */ | ||||||
|  | typedef union connection_config_t { | ||||||
|  |     uint8_t           raw; | ||||||
|  |     connection_host_t desired_host : 8; | ||||||
|  | } PACKED connection_config_t; | ||||||
|  | 
 | ||||||
|  | _Static_assert(sizeof(connection_config_t) == sizeof(uint8_t), "Connection EECONFIG out of spec."); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Initialize the subsystem. | ||||||
|  |  * | ||||||
|  |  * This function must be called only once, before any of the below functions can be called. | ||||||
|  |  */ | ||||||
|  | void connection_init(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Get currently configured host. Does not resolve 'CONNECTION_HOST_AUTO'. | ||||||
|  |  * | ||||||
|  |  * \return 'connection_host_t' of the configured host. | ||||||
|  |  */ | ||||||
|  | connection_host_t connection_get_host_raw(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Get current active host. | ||||||
|  |  * | ||||||
|  |  * \return 'connection_host_t' of the configured host. | ||||||
|  |  */ | ||||||
|  | connection_host_t connection_auto_detect_host(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Get currently configured host. Resolves 'CONNECTION_HOST_AUTO' using 'connection_auto_detect_host()'. | ||||||
|  |  * | ||||||
|  |  * \return 'connection_host_t' of the configured host. | ||||||
|  |  */ | ||||||
|  | connection_host_t connection_get_host(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Get current host. New state is not written to EEPROM. | ||||||
|  |  * | ||||||
|  |  * \param host The host to configure. | ||||||
|  |  */ | ||||||
|  | void connection_set_host_noeeprom(connection_host_t host); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Get current host. | ||||||
|  |  * | ||||||
|  |  * \param host The host to configure. | ||||||
|  |  */ | ||||||
|  | void connection_set_host(connection_host_t host); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Move to the next potential host. New state is not written to EEPROM. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_next_host_noeeprom(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Move to the next potential host. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_next_host(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Move to the previous potential host. New state is not written to EEPROM. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_prev_host_noeeprom(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief Move to the previous potential host. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_prev_host(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief user hook called when changing configured host | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_host_changed_user(connection_host_t host); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * \brief keyboard hook called when changing configured host | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | void connection_host_changed_kb(connection_host_t host); | ||||||
| @ -35,6 +35,10 @@ | |||||||
| #    include "haptic.h" | #    include "haptic.h" | ||||||
| #endif // HAPTIC_ENABLE
 | #endif // HAPTIC_ENABLE
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | #    include "connection.h" | ||||||
|  | #endif // CONNECTION_ENABLE
 | ||||||
|  | 
 | ||||||
| #ifdef VIA_ENABLE | #ifdef VIA_ENABLE | ||||||
| bool via_eeprom_is_valid(void); | bool via_eeprom_is_valid(void); | ||||||
| void via_eeprom_set_valid(bool valid); | void via_eeprom_set_valid(bool valid); | ||||||
| @ -127,6 +131,11 @@ void eeconfig_init_quantum(void) { | |||||||
|     haptic_reset(); |     haptic_reset(); | ||||||
| #endif // HAPTIC_ENABLE
 | #endif // HAPTIC_ENABLE
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  |     extern void eeconfig_update_connection_default(void); | ||||||
|  |     eeconfig_update_connection_default(); | ||||||
|  | #endif // CONNECTION_ENABLE
 | ||||||
|  | 
 | ||||||
| #if (EECONFIG_KB_DATA_SIZE) > 0 | #if (EECONFIG_KB_DATA_SIZE) > 0 | ||||||
|     eeconfig_init_kb_datablock(); |     eeconfig_init_kb_datablock(); | ||||||
| #endif // (EECONFIG_KB_DATA_SIZE) > 0
 | #endif // (EECONFIG_KB_DATA_SIZE) > 0
 | ||||||
| @ -299,6 +308,15 @@ void eeconfig_update_haptic(const haptic_config_t *haptic_config) { | |||||||
| } | } | ||||||
| #endif // HAPTIC_ENABLE
 | #endif // HAPTIC_ENABLE
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | void eeconfig_read_connection(connection_config_t *config) { | ||||||
|  |     nvm_eeconfig_read_connection(config); | ||||||
|  | } | ||||||
|  | void eeconfig_update_connection(const connection_config_t *config) { | ||||||
|  |     nvm_eeconfig_update_connection(config); | ||||||
|  | } | ||||||
|  | #endif // CONNECTION_ENABLE
 | ||||||
|  | 
 | ||||||
| bool eeconfig_read_handedness(void) { | bool eeconfig_read_handedness(void) { | ||||||
|     return nvm_eeconfig_read_handedness(); |     return nvm_eeconfig_read_handedness(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -131,6 +131,12 @@ void                          eeconfig_read_haptic(haptic_config_t *haptic_confi | |||||||
| void                          eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull)); | void                          eeconfig_update_haptic(const haptic_config_t *haptic_config) __attribute__((nonnull)); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | typedef union connection_config_t connection_config_t; | ||||||
|  | void                              eeconfig_read_connection(connection_config_t *config); | ||||||
|  | void                              eeconfig_update_connection(const connection_config_t *config); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| bool eeconfig_read_handedness(void); | bool eeconfig_read_handedness(void); | ||||||
| void eeconfig_update_handedness(bool val); | void eeconfig_update_handedness(bool val); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -146,6 +146,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| #ifdef LAYER_LOCK_ENABLE | #ifdef LAYER_LOCK_ENABLE | ||||||
| #    include "layer_lock.h" | #    include "layer_lock.h" | ||||||
| #endif | #endif | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | #    include "connection.h" | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| static uint32_t last_input_modification_time = 0; | static uint32_t last_input_modification_time = 0; | ||||||
| uint32_t        last_input_activity_time(void) { | uint32_t        last_input_activity_time(void) { | ||||||
| @ -465,6 +468,9 @@ void keyboard_init(void) { | |||||||
| #endif | #endif | ||||||
|     matrix_init(); |     matrix_init(); | ||||||
|     quantum_init(); |     quantum_init(); | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  |     connection_init(); | ||||||
|  | #endif | ||||||
|     led_init_ports(); |     led_init_ports(); | ||||||
| #ifdef BACKLIGHT_ENABLE | #ifdef BACKLIGHT_ENABLE | ||||||
|     backlight_init_ports(); |     backlight_init_ports(); | ||||||
|  | |||||||
| @ -41,6 +41,10 @@ | |||||||
| #    include "haptic.h" | #    include "haptic.h" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | #    include "connection.h" | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| void nvm_eeconfig_erase(void) { | void nvm_eeconfig_erase(void) { | ||||||
| #ifdef EEPROM_DRIVER | #ifdef EEPROM_DRIVER | ||||||
|     eeprom_driver_format(false); |     eeprom_driver_format(false); | ||||||
| @ -196,6 +200,15 @@ void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config) { | |||||||
| } | } | ||||||
| #endif // HAPTIC_ENABLE
 | #endif // HAPTIC_ENABLE
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | void nvm_eeconfig_read_connection(connection_config_t *config) { | ||||||
|  |     config->raw = eeprom_read_byte(EECONFIG_CONNECTION); | ||||||
|  | } | ||||||
|  | void nvm_eeconfig_update_connection(const connection_config_t *config) { | ||||||
|  |     eeprom_update_byte(EECONFIG_CONNECTION, config->raw); | ||||||
|  | } | ||||||
|  | #endif // CONNECTION_ENABLE
 | ||||||
|  | 
 | ||||||
| bool nvm_eeconfig_read_handedness(void) { | bool nvm_eeconfig_read_handedness(void) { | ||||||
|     return !!eeprom_read_byte(EECONFIG_HANDEDNESS); |     return !!eeprom_read_byte(EECONFIG_HANDEDNESS); | ||||||
| } | } | ||||||
|  | |||||||
| @ -27,6 +27,7 @@ typedef struct PACKED { | |||||||
|     }; |     }; | ||||||
|     uint32_t haptic; |     uint32_t haptic; | ||||||
|     uint8_t  rgblight_ext; |     uint8_t  rgblight_ext; | ||||||
|  |     uint8_t  connection; | ||||||
| } eeprom_core_t; | } eeprom_core_t; | ||||||
| 
 | 
 | ||||||
| /* EEPROM parameter address */ | /* EEPROM parameter address */ | ||||||
| @ -46,6 +47,7 @@ typedef struct PACKED { | |||||||
| #define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix)) | #define EECONFIG_RGB_MATRIX (uint64_t *)(offsetof(eeprom_core_t, rgb_matrix)) | ||||||
| #define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic)) | #define EECONFIG_HAPTIC (uint32_t *)(offsetof(eeprom_core_t, haptic)) | ||||||
| #define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext)) | #define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)(offsetof(eeprom_core_t, rgblight_ext)) | ||||||
|  | #define EECONFIG_CONNECTION (uint8_t *)(offsetof(eeprom_core_t, connection)) | ||||||
| 
 | 
 | ||||||
| // Size of EEPROM being used for core data storage
 | // Size of EEPROM being used for core data storage
 | ||||||
| #define EECONFIG_BASE_SIZE ((uint8_t)sizeof(eeprom_core_t)) | #define EECONFIG_BASE_SIZE ((uint8_t)sizeof(eeprom_core_t)) | ||||||
|  | |||||||
| @ -87,6 +87,12 @@ void                          nvm_eeconfig_read_haptic(haptic_config_t *haptic_c | |||||||
| void                          nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config); | void                          nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config); | ||||||
| #endif // HAPTIC_ENABLE
 | #endif // HAPTIC_ENABLE
 | ||||||
| 
 | 
 | ||||||
|  | #ifdef CONNECTION_ENABLE | ||||||
|  | typedef union connection_config_t connection_config_t; | ||||||
|  | void                              nvm_eeconfig_read_connection(connection_config_t *config); | ||||||
|  | void                              nvm_eeconfig_update_connection(const connection_config_t *config); | ||||||
|  | #endif // CONNECTION_ENABLE
 | ||||||
|  | 
 | ||||||
| bool nvm_eeconfig_read_handedness(void); | bool nvm_eeconfig_read_handedness(void); | ||||||
| void nvm_eeconfig_update_handedness(bool val); | void nvm_eeconfig_update_handedness(bool val); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,24 +1,34 @@ | |||||||
| // Copyright 2024 Nick Brassel (@tzarc)
 | // Copyright 2024 Nick Brassel (@tzarc)
 | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||||
| #include "outputselect.h" | #include "connection.h" | ||||||
| #include "process_connection.h" | #include "process_connection.h" | ||||||
| 
 | 
 | ||||||
| bool process_connection(uint16_t keycode, keyrecord_t *record) { | bool process_connection(uint16_t keycode, keyrecord_t *record) { | ||||||
|     if (record->event.pressed) { |     if (record->event.pressed) { | ||||||
|         switch (keycode) { |         switch (keycode) { | ||||||
|             case QK_OUTPUT_NEXT: |             case QK_OUTPUT_NEXT: | ||||||
|                 set_output(OUTPUT_AUTO); // This should cycle through the outputs going forward. Ensure `docs/keycodes.md`, `docs/features/bluetooth.md` are updated when it does.
 |                 connection_next_host(); | ||||||
|                 return false; |                 return false; | ||||||
|             case QK_OUTPUT_USB: |             case QK_OUTPUT_PREV: | ||||||
|                 set_output(OUTPUT_USB); |                 connection_prev_host(); | ||||||
|                 return false; |  | ||||||
|             case QK_OUTPUT_BLUETOOTH: |  | ||||||
|                 set_output(OUTPUT_BLUETOOTH); |  | ||||||
|                 return false; |                 return false; | ||||||
| 
 | 
 | ||||||
|             case QK_OUTPUT_PREV: |             case QK_OUTPUT_AUTO: | ||||||
|  |                 connection_set_host(CONNECTION_HOST_AUTO); | ||||||
|  |                 return false; | ||||||
|             case QK_OUTPUT_NONE: |             case QK_OUTPUT_NONE: | ||||||
|  |                 connection_set_host(CONNECTION_HOST_NONE); | ||||||
|  |                 return false; | ||||||
|  |             case QK_OUTPUT_USB: | ||||||
|  |                 connection_set_host(CONNECTION_HOST_USB); | ||||||
|  |                 return false; | ||||||
|  |             case QK_OUTPUT_BLUETOOTH: | ||||||
|  |                 connection_set_host(CONNECTION_HOST_BLUETOOTH); | ||||||
|  |                 return false; | ||||||
|             case QK_OUTPUT_2P4GHZ: |             case QK_OUTPUT_2P4GHZ: | ||||||
|  |                 connection_set_host(CONNECTION_HOST_2P4GHZ); | ||||||
|  |                 return false; | ||||||
|  | 
 | ||||||
|             case QK_BLUETOOTH_PROFILE_NEXT: |             case QK_BLUETOOTH_PROFILE_NEXT: | ||||||
|             case QK_BLUETOOTH_PROFILE_PREV: |             case QK_BLUETOOTH_PROFILE_PREV: | ||||||
|             case QK_BLUETOOTH_UNPAIR: |             case QK_BLUETOOTH_UNPAIR: | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ | |||||||
| #    include "process_backlight.h" | #    include "process_backlight.h" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef CONNECTION_ENABLE | ||||||
| #    include "process_connection.h" | #    include "process_connection.h" | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @ -436,7 +436,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||||||
| #ifdef LAYER_LOCK_ENABLE | #ifdef LAYER_LOCK_ENABLE | ||||||
|             process_layer_lock(keycode, record) && |             process_layer_lock(keycode, record) && | ||||||
| #endif | #endif | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef CONNECTION_ENABLE | ||||||
|             process_connection(keycode, record) && |             process_connection(keycode, record) && | ||||||
| #endif | #endif | ||||||
|             true)) { |             true)) { | ||||||
|  | |||||||
| @ -31,8 +31,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef BLUETOOTH_ENABLE | ||||||
|  | #    ifndef CONNECTION_ENABLE | ||||||
|  | #        error CONNECTION_ENABLE required and not enabled | ||||||
|  | #    endif | ||||||
|  | #    include "connection.h" | ||||||
| #    include "bluetooth.h" | #    include "bluetooth.h" | ||||||
| #    include "outputselect.h" |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef NKRO_ENABLE | #ifdef NKRO_ENABLE | ||||||
| @ -74,7 +77,7 @@ led_t host_keyboard_led_state(void) { | |||||||
| /* send report */ | /* send report */ | ||||||
| void host_keyboard_send(report_keyboard_t *report) { | void host_keyboard_send(report_keyboard_t *report) { | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef BLUETOOTH_ENABLE | ||||||
|     if (where_to_send() == OUTPUT_BLUETOOTH) { |     if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) { | ||||||
|         bluetooth_send_keyboard(report); |         bluetooth_send_keyboard(report); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @ -111,7 +114,7 @@ void host_nkro_send(report_nkro_t *report) { | |||||||
| 
 | 
 | ||||||
| void host_mouse_send(report_mouse_t *report) { | void host_mouse_send(report_mouse_t *report) { | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef BLUETOOTH_ENABLE | ||||||
|     if (where_to_send() == OUTPUT_BLUETOOTH) { |     if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) { | ||||||
|         bluetooth_send_mouse(report); |         bluetooth_send_mouse(report); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @ -147,7 +150,7 @@ void host_consumer_send(uint16_t usage) { | |||||||
|     last_consumer_usage = usage; |     last_consumer_usage = usage; | ||||||
| 
 | 
 | ||||||
| #ifdef BLUETOOTH_ENABLE | #ifdef BLUETOOTH_ENABLE | ||||||
|     if (where_to_send() == OUTPUT_BLUETOOTH) { |     if (connection_get_host() == CONNECTION_HOST_BLUETOOTH) { | ||||||
|         bluetooth_send_consumer(usage); |         bluetooth_send_consumer(usage); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user