@ -4,6 +4,9 @@
@@ -4,6 +4,9 @@
* SPDX - License - Identifier : MIT
*/
# include <init.h>
# include <settings/settings.h>
# include <zmk/ble.h>
# include <zmk/endpoints.h>
# include <zmk/hid.h>
@ -16,21 +19,45 @@
@@ -16,21 +19,45 @@
# include <logging/log.h>
LOG_MODULE_DECLARE ( zmk , CONFIG_ZMK_LOG_LEVEL ) ;
enum endpoint {
ENDPOINT_USB ,
ENDPOINT_BLE ,
} ;
# define DEFAULT_ENDPOINT \
COND_CODE_1 ( IS_ENABLED ( CONFIG_ZMK_BLE ) , ( ZMK_ENDPOINT_BLE ) , ( ZMK_ENDPOINT_USB ) )
static enum zmk_endpoint current_endpoint = DEFAULT_ENDPOINT ;
static enum zmk_endpoint preferred_endpoint =
ZMK_ENDPOINT_USB ; /* Used if multiple endpoints are ready */
static void update_current_endpoint ( ) ;
int zmk_endpoints_select ( enum zmk_endpoint endpoint ) {
LOG_DBG ( " Selected endpoint %d " , endpoint ) ;
if ( preferred_endpoint = = endpoint ) {
return 0 ;
}
preferred_endpoint = endpoint ;
# if IS_ENABLED(CONFIG_SETTINGS)
settings_save_one ( " endpoints/preferred " , & preferred_endpoint , sizeof ( preferred_endpoint ) ) ;
# endif
update_current_endpoint ( ) ;
# define DEFAULT_ENDPOINT COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (ENDPOINT_BLE), (ENDPOINT_USB))
return 0 ;
}
static enum endpoint current_endpoint = DEFAULT_ENDPOINT ;
int zmk_endpoints_toggle ( ) {
enum zmk_endpoint new_endpoint =
( preferred_endpoint = = ZMK_ENDPOINT_USB ) ? ZMK_ENDPOINT_BLE : ZMK_ENDPOINT_USB ;
return zmk_endpoints_select ( new_endpoint ) ;
}
static int send_keypad_report ( ) {
struct zmk_hid_keypad_report * keypad_report = zmk_hid_get_keypad_report ( ) ;
switch ( current_endpoint ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
case ENDPOINT_USB : {
case ZMK_ ENDPOINT_USB: {
int err = zmk_usb_hid_send_report ( ( u8_t * ) keypad_report , sizeof ( * keypad_report ) ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER USB: %d " , err ) ;
@ -40,7 +67,7 @@ static int send_keypad_report() {
@@ -40,7 +67,7 @@ static int send_keypad_report() {
# endif /* IS_ENABLED(CONFIG_ZMK_USB) */
# if IS_ENABLED(CONFIG_ZMK_BLE)
case ENDPOINT_BLE : {
case ZMK_ ENDPOINT_BLE: {
int err = zmk_hog_send_keypad_report ( & keypad_report - > body ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
@ -60,7 +87,7 @@ static int send_consumer_report() {
@@ -60,7 +87,7 @@ static int send_consumer_report() {
switch ( current_endpoint ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
case ENDPOINT_USB : {
case ZMK_ ENDPOINT_USB: {
int err = zmk_usb_hid_send_report ( ( u8_t * ) consumer_report , sizeof ( * consumer_report ) ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER USB: %d " , err ) ;
@ -70,7 +97,7 @@ static int send_consumer_report() {
@@ -70,7 +97,7 @@ static int send_consumer_report() {
# endif /* IS_ENABLED(CONFIG_ZMK_USB) */
# if IS_ENABLED(CONFIG_ZMK_BLE)
case ENDPOINT_BLE : {
case ZMK_ ENDPOINT_BLE: {
int err = zmk_hog_send_consumer_report ( & consumer_report - > body ) ;
if ( err ) {
LOG_ERR ( " FAILED TO SEND OVER HOG: %d " , err ) ;
@ -99,6 +126,49 @@ int zmk_endpoints_send_report(u8_t usage_page) {
@@ -99,6 +126,49 @@ int zmk_endpoints_send_report(u8_t usage_page) {
}
}
# if IS_ENABLED(CONFIG_SETTINGS)
static int endpoints_handle_set ( const char * name , size_t len , settings_read_cb read_cb ,
void * cb_arg ) {
LOG_DBG ( " Setting endpoint value %s " , log_strdup ( name ) ) ;
if ( settings_name_steq ( name , " preferred " , NULL ) ) {
if ( len ! = sizeof ( enum zmk_endpoint ) ) {
LOG_ERR ( " Invalid endpoint size (got %d expected %d) " , len , sizeof ( enum zmk_endpoint ) ) ;
return - EINVAL ;
}
int err = read_cb ( cb_arg , & preferred_endpoint , sizeof ( enum zmk_endpoint ) ) ;
if ( err < = 0 ) {
LOG_ERR ( " Failed to read preferred endpoint from settings (err %d) " , err ) ;
return err ;
}
update_current_endpoint ( ) ;
}
return 0 ;
}
struct settings_handler endpoints_handler = { . name = " endpoints " , . h_set = endpoints_handle_set } ;
# endif /* IS_ENABLED(CONFIG_SETTINGS) */
static int zmk_endpoints_init ( struct device * _arg ) {
# if IS_ENABLED(CONFIG_SETTINGS)
settings_subsys_init ( ) ;
int err = settings_register ( & endpoints_handler ) ;
if ( err ) {
LOG_ERR ( " Failed to register the endpoints settings handler (err %d) " , err ) ;
return err ;
}
settings_load ( ) ;
# endif
return 0 ;
}
static bool is_usb_ready ( ) {
# if IS_ENABLED(CONFIG_ZMK_USB)
return zmk_usb_is_hid_ready ( ) ;
@ -115,21 +185,20 @@ static bool is_ble_ready() {
@@ -115,21 +185,20 @@ static bool is_ble_ready() {
# endif
}
static enum endpoint get_selected_endpoint ( ) {
static enum zmk_ endpoint get_selected_endpoint ( ) {
if ( is_ble_ready ( ) ) {
if ( is_usb_ready ( ) ) {
LOG_DBG ( " Both endpoints are ready. " ) ;
// TODO: add user setting to control this
return ENDPOINT_USB ;
LOG_DBG ( " Both endpoints are ready. Using %d " , preferred_endpoint ) ;
return preferred_endpoint ;
}
LOG_DBG ( " Only BLE is ready. " ) ;
return ENDPOINT_BLE ;
return ZMK_ ENDPOINT_BLE;
}
if ( is_usb_ready ( ) ) {
LOG_DBG ( " Only USB is ready. " ) ;
return ENDPOINT_USB ;
return ZMK_ ENDPOINT_USB;
}
LOG_DBG ( " No endpoints are ready. " ) ;
@ -144,8 +213,8 @@ static void disconnect_current_endpoint() {
@@ -144,8 +213,8 @@ static void disconnect_current_endpoint() {
zmk_endpoints_send_report ( USAGE_CONSUMER ) ;
}
static int endpoint_listener ( const struct zmk_event_header * eh ) {
enum endpoint new_endpoint = get_selected_endpoint ( ) ;
static void update_current_endpoint ( ) {
enum zmk_ endpoint new_endpoint = get_selected_endpoint ( ) ;
if ( new_endpoint ! = current_endpoint ) {
/* Cancel all current keypresses so keys don't stay held on the old endpoint. */
@ -154,7 +223,10 @@ static int endpoint_listener(const struct zmk_event_header *eh) {
@@ -154,7 +223,10 @@ static int endpoint_listener(const struct zmk_event_header *eh) {
current_endpoint = new_endpoint ;
LOG_INF ( " Endpoint changed: %d " , current_endpoint ) ;
}
}
static int endpoint_listener ( const struct zmk_event_header * eh ) {
update_current_endpoint ( ) ;
return 0 ;
}
@ -164,4 +236,6 @@ ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed);
@@ -164,4 +236,6 @@ ZMK_SUBSCRIPTION(endpoint_listener, usb_conn_state_changed);
# endif
# if IS_ENABLED(CONFIG_ZMK_BLE)
ZMK_SUBSCRIPTION ( endpoint_listener , ble_active_profile_changed ) ;
# endif
# endif
SYS_INIT ( zmk_endpoints_init , APPLICATION , CONFIG_APPLICATION_INIT_PRIORITY ) ;