Added snap click, per-key/mixed rgb, custom debounce, wireless config feature
This commit is contained in:
@@ -1,4 +1,20 @@
|
||||
|
||||
/* Copyright 2023~2025 @ Keychron (https://www.keychron.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "quantum.h"
|
||||
#include "wireless.h"
|
||||
#include "indicator.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2022 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Copyright 2024 @ Keychron (https://www.keychron.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define EECONFIG_SIZE_WIRELESS_CONFIG 4 //sizeof(backlit_disable_time) + sizeof (connected_idle_time)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2023 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
@@ -60,6 +60,8 @@ enum {
|
||||
BACKLIGHT_ON_UNCONNECTED = 0x02,
|
||||
};
|
||||
|
||||
extern uint16_t backlit_disable_time;
|
||||
|
||||
static indicator_config_t pairing_config = INDICATOR_CONFIG_PARING;
|
||||
static indicator_config_t connected_config = INDICATOR_CONFIG_CONNECTD;
|
||||
static indicator_config_t reconnecting_config = INDICATOR_CONFIG_RECONNECTING;
|
||||
@@ -201,12 +203,13 @@ inline void indicator_disable(void) {
|
||||
LED_DRIVER_DISABLE_NOEEPROM();
|
||||
}
|
||||
|
||||
void indicator_set_backlit_timeout(uint32_t time) {
|
||||
LED_DRIVER_DISABLE_TIMEOUT_SET(time);
|
||||
void indicator_reset_backlit_time(void) {
|
||||
LED_DRIVER_DISABLE_TIME_RESET();
|
||||
}
|
||||
|
||||
static inline void indicator_reset_backlit_time(void) {
|
||||
LED_DRIVER_DISABLE_TIME_RESET();
|
||||
void indicator_set_backlit_timeout(uint32_t time) {
|
||||
LED_DRIVER_DISABLE_TIMEOUT_SET(time);
|
||||
indicator_reset_backlit_time();
|
||||
}
|
||||
|
||||
bool indicator_is_enabled(void) {
|
||||
@@ -443,7 +446,7 @@ void indicator_set(wt_state_t state, uint8_t host_index) {
|
||||
indicator_timer_cb((void *)&indicator_config.type);
|
||||
}
|
||||
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
|
||||
indicator_set_backlit_timeout(DECIDE_TIME(CONNECTED_BACKLIGHT_DISABLE_TIMEOUT * 1000, indicator_config.duration));
|
||||
indicator_set_backlit_timeout(DECIDE_TIME(backlit_disable_time * 1000, indicator_config.duration));
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -541,6 +544,9 @@ void indicator_battery_low_enable(bool enable) {
|
||||
} else {
|
||||
rtc_time = 0;
|
||||
bat_low_ind_state = 0;
|
||||
# if defined(BAT_LOW_LED_PIN)
|
||||
writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
|
||||
# endif
|
||||
# if defined(SPACE_KEY_LOW_BAT_IND)
|
||||
indicator_eeconfig_reload();
|
||||
if (!LED_DRIVER_IS_ENABLED()) indicator_disable();
|
||||
@@ -552,7 +558,8 @@ void indicator_battery_low_enable(bool enable) {
|
||||
void indicator_battery_low(void) {
|
||||
#if defined(BAT_LOW_LED_PIN) || defined(SPACE_KEY_LOW_BAT_IND)
|
||||
if (bat_low_ind_state) {
|
||||
if ((bat_low_ind_state & 0x0F) <= (LOW_BAT_LED_BLINK_TIMES) && timer_elapsed32(bat_low_backlit_indicator) > (LOW_BAT_LED_BLINK_PERIOD)) {
|
||||
if ((bat_low_ind_state & 0x0F) <= (LOW_BAT_LED_BLINK_TIMES) &&
|
||||
timer_elapsed32(bat_low_backlit_indicator) > (LOW_BAT_LED_BLINK_PERIOD)) {
|
||||
if (bat_low_ind_state & 0x80) {
|
||||
bat_low_ind_state &= 0x7F;
|
||||
bat_low_ind_state++;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2023 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
@@ -101,7 +101,7 @@ typedef struct {
|
||||
void indicator_init(void);
|
||||
void indicator_set(wt_state_t state, uint8_t host_index);
|
||||
void indicator_set_backlit_timeout(uint32_t time);
|
||||
void indicator_backlight_timer_reset(bool enable);
|
||||
void indicator_reset_backlit_time(void);
|
||||
bool indicator_hook_key(uint16_t keycode);
|
||||
void indicator_enable(void);
|
||||
void indicator_disable(void);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2022 @ Keychron (https://www.keychron.com)
|
||||
/* Copyright 2022~2025 @ Keychron (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
@@ -32,6 +32,7 @@ bool firstDisconnect = true;
|
||||
|
||||
static uint32_t pairing_key_timer;
|
||||
static uint8_t host_idx = 0;
|
||||
extern uint32_t connected_idle_time;
|
||||
|
||||
bool process_record_keychron_wireless(uint16_t keycode, keyrecord_t *record) {
|
||||
static uint8_t host_idx;
|
||||
@@ -84,7 +85,7 @@ void lkbt51_param_init(void) {
|
||||
// clang-format off
|
||||
/* Set bluetooth parameters */
|
||||
module_param_t param = {.event_mode = 0x02,
|
||||
.connected_idle_timeout = 7200,
|
||||
.connected_idle_timeout = connected_idle_time,
|
||||
.pairing_timeout = 180,
|
||||
.pairing_mode = 0,
|
||||
.reconnect_timeout = 5,
|
||||
|
||||
@@ -194,6 +194,11 @@ static inline void lpm_wakeup(void) {
|
||||
|
||||
halInit();
|
||||
|
||||
#if defined(DIP_SWITCH_PINS)
|
||||
/* Init dip switch as early as possible, and read it later. */
|
||||
dip_switch_init();
|
||||
#endif
|
||||
|
||||
#ifdef ENCODER_ENABLE
|
||||
encoder_cb_init();
|
||||
#endif
|
||||
@@ -227,15 +232,30 @@ static inline void lpm_wakeup(void) {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DIP_SWITCH_PINS)
|
||||
dip_switch_init();
|
||||
dip_switch_read(true);
|
||||
#endif
|
||||
|
||||
/* Call debounce_free() to avoiding memory leak of debounce_counters as debounce_init()
|
||||
invoked in matrix_init() alloc new memory to debounce_counters */
|
||||
debounce_free();
|
||||
matrix_init();
|
||||
|
||||
#ifdef ENABLE_RGB_MATRIX_PIXEL_RAIN
|
||||
extern void PIXEL_RAIN_init(void);
|
||||
PIXEL_RAIN_init();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RGB_MATRIX_PIXEL_FLOW
|
||||
extern void PIXEL_FLOW_init(void);
|
||||
PIXEL_FLOW_init();
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_RGB_MATRIX_PIXEL_FRACTAL
|
||||
extern void PIXEL_FRACTAL_init(void);
|
||||
PIXEL_FRACTAL_init();
|
||||
#endif
|
||||
|
||||
#if defined(DIP_SWITCH_PINS)
|
||||
dip_switch_read(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lpm_task(void) {
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "rtc_timer.h"
|
||||
#include "keychron_wireless_common.h"
|
||||
#include "keychron_task.h"
|
||||
#include "wireless_config.h"
|
||||
#include "keychron_raw_hid.h"
|
||||
|
||||
extern uint8_t pairing_indication;
|
||||
extern host_driver_t chibios_driver;
|
||||
@@ -39,6 +41,9 @@ static wt_state_t wireless_state = WT_RESET;
|
||||
static bool pincodeEntry = false;
|
||||
uint8_t wireless_report_protocol = true;
|
||||
|
||||
uint16_t backlit_disable_time = CONNECTED_BACKLIGHT_DISABLE_TIMEOUT;
|
||||
uint16_t connected_idle_time = CONNECTED_IDLE_TIME;
|
||||
|
||||
/* declarations */
|
||||
uint8_t wreless_keyboard_leds(void);
|
||||
void wireless_send_keyboard(report_keyboard_t *report);
|
||||
@@ -55,6 +60,8 @@ wireless_event_t wireless_event_queue[WT_EVENT_QUEUE_SIZE];
|
||||
uint8_t wireless_event_queue_head;
|
||||
uint8_t wireless_event_queue_tail;
|
||||
|
||||
bool wireless_lpm_set(uint8_t *data);
|
||||
|
||||
void wireless_event_queue_init(void) {
|
||||
// Initialise the event queue
|
||||
memset(&wireless_event_queue, 0, sizeof(wireless_event_queue));
|
||||
@@ -82,6 +89,41 @@ static inline bool wireless_event_dequeue(wireless_event_t *event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(EECONFIG_BASE_WIRELESS_CONFIG)
|
||||
void wireless_config_reset(void) {
|
||||
uint8_t data[4] = { 0 };
|
||||
|
||||
uint16_t backlit_disable_time = CONNECTED_BACKLIGHT_DISABLE_TIMEOUT;
|
||||
uint16_t connected_idle_time = CONNECTED_IDLE_TIME;
|
||||
|
||||
memcpy(&data[0], &backlit_disable_time, sizeof(backlit_disable_time));
|
||||
memcpy(&data[2], &connected_idle_time, sizeof(connected_idle_time));
|
||||
wireless_lpm_set(data);
|
||||
}
|
||||
|
||||
void wireless_config_load(void) {
|
||||
uint8_t offset = 0;
|
||||
eeprom_read_block(&backlit_disable_time, (uint8_t *)(EECONFIG_BASE_WIRELESS_CONFIG+offset), sizeof(backlit_disable_time));
|
||||
offset += sizeof(backlit_disable_time);
|
||||
eeprom_read_block(&connected_idle_time, (uint8_t *)(EECONFIG_BASE_WIRELESS_CONFIG+offset), sizeof(connected_idle_time));
|
||||
|
||||
if (backlit_disable_time == 0)
|
||||
backlit_disable_time = CONNECTED_BACKLIGHT_DISABLE_TIMEOUT;
|
||||
else if (backlit_disable_time < 5 ) backlit_disable_time = 5;
|
||||
|
||||
if (connected_idle_time == 0)
|
||||
connected_idle_time = CONNECTED_IDLE_TIME;
|
||||
else if (connected_idle_time < 30 ) connected_idle_time = 30;
|
||||
}
|
||||
|
||||
void wireless_config_save(void) {
|
||||
uint8_t offset = 0;
|
||||
eeprom_update_block(&backlit_disable_time, (uint8_t *)(EECONFIG_BASE_WIRELESS_CONFIG+offset), sizeof(backlit_disable_time));
|
||||
offset += sizeof(backlit_disable_time);
|
||||
eeprom_update_block(&connected_idle_time, (uint8_t *)(EECONFIG_BASE_WIRELESS_CONFIG+offset), sizeof(connected_idle_time));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bluetooth init.
|
||||
*/
|
||||
@@ -102,6 +144,10 @@ void wireless_init(void) {
|
||||
#if HAL_USE_RTC
|
||||
rtc_timer_init();
|
||||
#endif
|
||||
|
||||
#if defined(EECONFIG_BASE_WIRELESS_CONFIG)
|
||||
wireless_config_load();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -253,9 +299,10 @@ static void wireless_enter_disconnected(uint8_t host_idx, uint8_t reason) {
|
||||
indicator_set(WT_SUSPEND, host_idx);
|
||||
} else {
|
||||
indicator_set(wireless_state, host_idx);
|
||||
#if defined(RGB_MATRIX) || defined(LED_MATRIX)
|
||||
if (reason && (get_transport() & TRANSPORT_WIRELESS))
|
||||
#if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE)
|
||||
if (reason && (get_transport() & TRANSPORT_WIRELESS)) {
|
||||
indicator_set_backlit_timeout(DISCONNECTED_BACKLIGHT_DISABLE_TIMEOUT*1000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -539,3 +586,72 @@ bool process_record_wireless(uint16_t keycode, keyrecord_t *record) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(EECONFIG_BASE_WIRELESS_CONFIG)
|
||||
bool wireless_lpm_get(uint8_t *data) {
|
||||
uint8_t index = 1;
|
||||
memcpy(&data[index], &backlit_disable_time, sizeof(backlit_disable_time));
|
||||
index += sizeof(backlit_disable_time);
|
||||
memcpy(&data[index], &connected_idle_time, sizeof(connected_idle_time));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wireless_lpm_set(uint8_t *data) {
|
||||
uint8_t index = 0;
|
||||
|
||||
memcpy(&backlit_disable_time, &data[index], sizeof(backlit_disable_time));
|
||||
index += sizeof(backlit_disable_time);
|
||||
memcpy(&connected_idle_time, &data[index], sizeof(connected_idle_time));
|
||||
|
||||
if (backlit_disable_time < 5 || connected_idle_time < 60) {
|
||||
wireless_config_load();
|
||||
return false;
|
||||
}
|
||||
|
||||
wireless_config_save();
|
||||
|
||||
// Reset backlight timeout
|
||||
if ((get_transport() & TRANSPORT_WIRELESS) && wireless_state == WT_CONNECTED)
|
||||
{
|
||||
indicator_set_backlit_timeout(backlit_disable_time*1000);
|
||||
indicator_reset_backlit_time();
|
||||
|
||||
// Wiggle mouse to reset bluetooth module timer
|
||||
mousekey_on(KC_MS_LEFT);
|
||||
mousekey_send();
|
||||
wait_ms(10);
|
||||
mousekey_on(KC_MS_RIGHT);
|
||||
mousekey_send();
|
||||
wait_ms(10);
|
||||
mousekey_off((KC_MS_RIGHT));
|
||||
mousekey_send();
|
||||
wait_ms(10);
|
||||
}
|
||||
|
||||
// Update bluetooth module param
|
||||
lkbt51_param_init();
|
||||
return true;
|
||||
}
|
||||
|
||||
void wireless_raw_hid_rx(uint8_t *data, uint8_t length) {
|
||||
uint8_t cmd = data[1];
|
||||
bool success = true;
|
||||
|
||||
switch (cmd) {
|
||||
case WIRELESS_LPM_GET:
|
||||
success = wireless_lpm_get(&data[2]);
|
||||
break;
|
||||
|
||||
case WIRELESS_LPM_SET:
|
||||
success = wireless_lpm_set(&data[2]);
|
||||
break;
|
||||
|
||||
default:
|
||||
data[0] = 0xFF;
|
||||
break;
|
||||
}
|
||||
|
||||
data[2] = success ? 0 : 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2023 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
@@ -67,6 +67,8 @@ typedef struct {
|
||||
extern void register_wt_tasks(void);
|
||||
|
||||
void wireless_init(void);
|
||||
void wireless_config_reset(void);
|
||||
|
||||
void wireless_set_transport(wt_func_t *transport);
|
||||
void wireless(void);
|
||||
|
||||
@@ -99,3 +101,6 @@ wt_state_t wireless_get_state(void);
|
||||
void wireless_low_battery_shutdown(void);
|
||||
|
||||
bool process_record_wireless(uint16_t keycode, keyrecord_t *record);
|
||||
|
||||
void wireless_raw_hid_rx(uint8_t *data, uint8_t length);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
OPT_DEFS += -DLK_WIRELESS_ENABLE
|
||||
OPT_DEFS += -DLK_WIRELESS_ENABLE -DWIRELESS_CONFIG_ENABLE
|
||||
OPT_DEFS += -DNO_USB_STARTUP_CHECK
|
||||
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2023 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
@@ -25,12 +25,7 @@
|
||||
|
||||
#define P2P4G_HOST_DEVICES_COUNT 1
|
||||
|
||||
// Uint: Second
|
||||
#ifndef DISCONNECTED_BACKLIGHT_OFF_DELAY_TIME
|
||||
# define DISCONNECTED_BACKLIGHT_OFF_DELAY_TIME 40
|
||||
#endif
|
||||
|
||||
// Uint: Second, the timer restarts on key activities.
|
||||
#ifndef CONNECTED_BACKLIGHT_OFF_DELAY_TIME
|
||||
# define CONNECTED_BACKLIGHT_OFF_DELAY_TIME 600
|
||||
#ifndef CONNECTED_IDLE_TIME
|
||||
# define CONNECTED_IDLE_TIME 7200
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2023 @ lokher (https://www.keychron.com)
|
||||
/* Copyright 2023~2025 @ lokher (https://www.keychron.com)
|
||||
*
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user