diff --git a/.gitmodules b/.gitmodules
index 7cd8281fa1..448217af5e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,7 +4,7 @@
branch = master
[submodule "lib/chibios-contrib"]
path = lib/chibios-contrib
- url = https://github.com/qmk/ChibiOS-Contrib
+ url = https://github.com/Keychron/ChibiOS-Contrib
branch = master
[submodule "lib/googletest"]
path = lib/googletest
diff --git a/keyboards/lemokey/common/factory_test.c b/keyboards/lemokey/common/factory_test.c
index b376165e1c..fb54958041 100644
--- a/keyboards/lemokey/common/factory_test.c
+++ b/keyboards/lemokey/common/factory_test.c
@@ -1,4 +1,4 @@
-/* Copyright 2021 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -176,6 +176,7 @@ bool process_record_factory_test(uint16_t keycode, keyrecord_t *record) {
factory_reset_timer = 0;
}
break;
+
case KC_Z:
#if defined(FN_Z_KEY)
case FN_Z_KEY:
@@ -195,6 +196,7 @@ bool process_record_factory_test(uint16_t keycode, keyrecord_t *record) {
}
}
break;
+
#if defined(BL_CYCLE_KEY) || defined(BL_CYCLE_KEY_2)
# if defined(BL_CYCLE_KEY)
case BL_CYCLE_KEY:
diff --git a/keyboards/lemokey/common/factory_test.h b/keyboards/lemokey/common/factory_test.h
index a98d10043c..278f1dad4c 100644
--- a/keyboards/lemokey/common/factory_test.h
+++ b/keyboards/lemokey/common/factory_test.h
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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,7 +25,6 @@ void factory_test_init(void);
bool factory_test_indicator(void);
#endif
-//void process_record_factory_test(uint16_t keycode, keyrecord_t *record);
bool factory_reset_indicating(void);
void factory_test_task(void);
void factory_test_rx(uint8_t *data, uint8_t length);
diff --git a/keyboards/lemokey/common/lemokey_common.c b/keyboards/lemokey/common/lemokey_common.c
index 5710442345..1f8be8e084 100644
--- a/keyboards/lemokey/common/lemokey_common.c
+++ b/keyboards/lemokey/common/lemokey_common.c
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -34,6 +34,16 @@ static key_combination_t key_comb_list[3] = {
{2, {KC_LWIN, KC_L}},
};
+#if defined(WIN_LOCK_HOLD_TIME)
+static uint32_t winlock_timer = 0;
+#endif
+
+void gui_toggle(void) {
+ keymap_config.no_gui = !keymap_config.no_gui;
+ eeconfig_update_keymap(keymap_config.raw);
+ led_update_kb(host_keyboard_led_state());
+}
+
bool process_record_lemokey_common(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case KC_TASK_VIEW:
@@ -49,6 +59,7 @@ bool process_record_lemokey_common(uint16_t keycode, keyrecord_t *record) {
}
}
return false; // Skip all further processing of this key
+
case KC_MCTRL:
if (record->event.pressed) {
register_code(KC_MISSION_CONTROL);
@@ -56,13 +67,15 @@ bool process_record_lemokey_common(uint16_t keycode, keyrecord_t *record) {
unregister_code(KC_MISSION_CONTROL);
}
return false; // Skip all further processing of this key
- case KC_LANCH:
+
+ case KC_LNPAD:
if (record->event.pressed) {
register_code(KC_LAUNCHPAD);
} else {
unregister_code(KC_LAUNCHPAD);
}
return false; // Skip all further processing of this key
+
case KC_LOPTN:
case KC_ROPTN:
case KC_LCMMD:
@@ -73,59 +86,73 @@ bool process_record_lemokey_common(uint16_t keycode, keyrecord_t *record) {
unregister_code(mac_keycode[keycode - KC_LOPTN]);
}
return false; // Skip all further processing of this key
+
+#if defined(WIN_LOCK_HOLD_TIME) || defined(WIN_LOCK_LED_PIN) || defined(WINLOCK_LED_LIST)
+ case GU_TOGG:
+# if defined(WIN_LOCK_HOLD_TIME)
+ if (record->event.pressed) {
+ winlock_timer = timer_read32();
+ } else {
+ winlock_timer = 0;
+ }
+# else
+ if (record->event.pressed) gui_toggle();
+# endif
+ return false;
+#endif
default:
return true; // Process all other keycodes normally
}
}
-void lemokey_common_task(void) {}
+void lemokey_common_task(void) {
+#if defined(WIN_LOCK_HOLD_TIME)
+ if (winlock_timer) {
+ if (keymap_config.no_gui) {
+ winlock_timer = 0;
+ gui_toggle();
+ } else if (timer_elapsed32(winlock_timer) > WIN_LOCK_HOLD_TIME) {
+ winlock_timer = 0;
+ gui_toggle();
+ }
+ }
+#endif
+}
#ifdef ENCODER_ENABLE
-static void encoder0_pad_cb(void *param) {
- (void)param;
- encoder_inerrupt_read(0);
+static void encoder_pad_cb(void *param) {
+ uint8_t index = (uint32_t)param;
+ encoder_inerrupt_read(index);
}
void encoder_cb_init(void) {
pin_t encoders_pad_a[] = ENCODERS_PAD_A;
pin_t encoders_pad_b[] = ENCODERS_PAD_B;
- palEnableLineEvent(encoders_pad_a[0], PAL_EVENT_MODE_BOTH_EDGES);
- palEnableLineEvent(encoders_pad_b[0], PAL_EVENT_MODE_BOTH_EDGES);
- palSetLineCallback(encoders_pad_a[0], encoder0_pad_cb, NULL);
- palSetLineCallback(encoders_pad_b[0], encoder0_pad_cb, NULL);
-}
-#endif
-
-//__attribute__((weak)) bool raw_hid_receive_lemokey(uint8_t *data, uint8_t length) { return true; }
-
-bool via_command_kb(uint8_t *data, uint8_t length) {
- // if (!raw_hid_receive_lemokey(data, length))
- // return false;
-
- switch (data[0]) {
-#ifdef LK_WIRELESS_ENABLE
- case 0xAA:
- lkbt51_dfu_rx(data, length);
- break;
-#endif
-#ifdef FACTORY_TEST_ENABLE
- case 0xAB:
- factory_test_rx(data, length);
- break;
-#endif
- default:
- return false;
- }
-
- return true;
-}
-
-#if !defined(VIA_ENABLE)
-void raw_hid_receive(uint8_t *data, uint8_t length) {
- switch (data[0]) {
- case RAW_HID_CMD:
- via_command_kb(data, length);
- break;
+ for (uint32_t i=0; i.
+ */
+
+#include QMK_KEYBOARD_H
+#include "lemokey_common.h"
+#include "raw_hid.h"
+#include "version.h"
+#ifdef FACTORY_TEST_ENABLE
+# include "factory_test.h"
+#endif
+#ifdef LK_WIRELESS_ENABLE
+# include "lkbt51.h"
+#endif
+#ifdef ANANLOG_MATRIX
+# include "analog_matrix.h"
+#endif
+
+#define PROTOCOL_VERSION 0x02
+
+enum {
+ KC_GET_PROTOCOL_VERSION = 0xA0,
+ KC_GET_FIRMWARE_VERSION = 0xA1,
+ KC_GET_SUPPORT_FEATURE = 0xA2,
+ KC_GET_DEFAULT_LAYER = 0xA3,
+};
+
+enum {
+ FEATURE_DEFAULT_LAYER = 0x01 << 0,
+ FEATURE_BLUETOOTH = 0x01 << 1,
+ FEATURE_P2P4G = 0x01 << 2,
+ FEATURE_ANALOG_MATRIX = 0x01 << 3,
+};
+
+void get_support_feature(uint8_t *data) {
+ data[1] = FEATURE_DEFAULT_LAYER
+#ifdef KC_BLUETOOTH_ENABLE
+ | FEATURE_BLUETOOTH
+#endif
+#ifdef LK_WIRELESS_ENABLE
+ | FEATURE_BLUETOOTH | FEATURE_P2P4G
+#endif
+#ifdef ANANLOG_MATRIX
+ | FEATURE_ANALOG_MATRIX
+#endif
+ ;
+}
+
+bool lemokey_raw_hid_rx(uint8_t *data, uint8_t length) {
+ switch (data[0]) {
+ case KC_GET_PROTOCOL_VERSION:
+ data[1] = PROTOCOL_VERSION;
+ break;
+
+ case KC_GET_FIRMWARE_VERSION: {
+ uint8_t i = 1;
+ data[i++] = 'v';
+ if ((DEVICE_VER & 0xF000) != 0) itoa((DEVICE_VER >> 12), (char *)&data[i++], 16);
+ itoa((DEVICE_VER >> 8) & 0xF, (char *)&data[i++], 16);
+ data[i++] = '.';
+ itoa((DEVICE_VER >> 4) & 0xF, (char *)&data[i++], 16);
+ data[i++] = '.';
+ itoa(DEVICE_VER & 0xF, (char *)&data[i++], 16);
+ data[i++] = ' ';
+ memcpy(&data[i], QMK_BUILDDATE, sizeof(QMK_BUILDDATE));
+ i += sizeof(QMK_BUILDDATE);
+ } break;
+
+ case KC_GET_SUPPORT_FEATURE:
+ get_support_feature(&data[1]);
+ break;
+
+ case KC_GET_DEFAULT_LAYER:
+ data[1] = get_highest_layer(default_layer_state);
+ break;
+
+#ifdef ANANLOG_MATRIX
+ case 0xA9:
+ analog_matrix_rx(data, length);
+ return true;
+#endif
+#ifdef LK_WIRELESS_ENABLE
+ case 0xAA:
+ lkbt51_dfu_rx(data, length);
+ return true;
+#endif
+#ifdef FACTORY_TEST_ENABLE
+ case 0xAB:
+ factory_test_rx(data, length);
+ return true;
+#endif
+ default:
+ return false;
+ }
+
+ raw_hid_send(data, length);
+ return true;
+}
+
+#if defined(VIA_ENABLE)
+bool via_command_kb(uint8_t *data, uint8_t length) {
+ return lemokey_raw_hid_rx(data, length);
+}
+#else
+void raw_hid_receive(uint8_t *data, uint8_t length) {
+ lemokey_raw_hid_rx(data, length);
+}
+#endif
diff --git a/keyboards/lemokey/common/lemokey_task.c b/keyboards/lemokey/common/lemokey_task.c
index 53146b1827..a27ae6041d 100644
--- a/keyboards/lemokey/common/lemokey_task.c
+++ b/keyboards/lemokey/common/lemokey_task.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -34,7 +34,6 @@ bool process_record_lemokey(uint16_t keycode, keyrecord_t *record) {
#ifdef FACTORY_TEST_ENABLE
if (!process_record_factory_test(keycode, record)) return false;
#endif
- // extern bool process_record_lemokey_kb(uint16_t keycode, keyrecord_t *record);
if (!process_record_lemokey_kb(keycode, record)) return false;
diff --git a/keyboards/lemokey/common/lemokey_task.h b/keyboards/lemokey/common/lemokey_task.h
index 9230c5592c..c01fc14167 100644
--- a/keyboards/lemokey/common/lemokey_task.h
+++ b/keyboards/lemokey/common/lemokey_task.h
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ Keychron (https://www.lemokey.com)
+/* Copyright 2022~2024 @ Keychron (https://www.lemokey.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
diff --git a/keyboards/lemokey/common/wireless/bat_level_animation.c b/keyboards/lemokey/common/wireless/bat_level_animation.c
index 2c63ec6cf7..01632ffaa3 100644
--- a/keyboards/lemokey/common/wireless/bat_level_animation.c
+++ b/keyboards/lemokey/common/wireless/bat_level_animation.c
@@ -1,4 +1,20 @@
+/* Copyright 2022~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 .
+ */
+
#include "quantum.h"
#include "wireless.h"
#include "indicator.h"
@@ -10,8 +26,6 @@
#endif
#include "eeprom.h"
-#if (defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(BAT_LEVEL_LED_LIST)
-
#ifndef BAT_LEVEL_GROWING_INTERVAL
# define BAT_LEVEL_GROWING_INTERVAL 150
#endif
@@ -35,7 +49,7 @@ enum {
BAT_LVL_ANI_BLINK_ON,
};
-static uint8_t animation_state = 0;
+static uint8_t animation_state = 0;
static uint32_t bat_lvl_ani_timer_buffer = 0;
static uint8_t bat_percentage;
static uint8_t cur_percentage;
@@ -47,21 +61,64 @@ static uint8_t r, g, b;
extern indicator_config_t indicator_config;
extern backlight_state_t original_backlight_state;
+#ifdef INDICATOR_LED_PINS
+void bat_level_stop(void) {
+ pin_t bat_lvl_led_pin_list[] = INDICATOR_LED_PINS;
+ for (uint8_t i = 0; i < INDICATOR_LED_COUNT; i++) {
+ writePin(bat_lvl_led_pin_list[i], !LED_PIN_ON_STATE);
+ }
+ animation_state = BAT_LVL_ANI_NONE;
+}
+
+__attribute__((weak)) void bat_level_indication(uint8_t percentage) {
+ pin_t bat_lvl_led_pin_list[] = INDICATOR_LED_PINS;
+ uint8_t led_cnt = sizeof(bat_lvl_led_pin_list) / sizeof(bat_lvl_led_pin_list[0]);
+
+ bat_level_stop();
+ animation_state = BAT_LVL_ANI_BLINK_ON;
+ cur_percentage = 0;
+ time_interval = 3000;
+
+ if ((percentage / 10) >= 8)
+ cur_percentage = 4;
+ else if ((percentage / 10) >= 6)
+ cur_percentage = 3;
+ else if ((percentage / 10) >= 3)
+ cur_percentage = 2;
+ else
+ cur_percentage = 1;
+
+ for (uint8_t i = 0; i < cur_percentage && i < led_cnt; i++) {
+ writePin(bat_lvl_led_pin_list[i], LED_PIN_ON_STATE);
+ }
+}
+#endif
+
void bat_level_animiation_start(uint8_t percentage) {
/* Turn on backlight mode for indicator */
+ animation_state = BAT_LVL_ANI_GROWING;
+ bat_lvl_ani_timer_buffer = timer_read32();
+#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
indicator_enable();
- animation_state = BAT_LVL_ANI_GROWING;
- bat_percentage = percentage;
- bat_lvl_ani_timer_buffer = timer_read32();
- cur_percentage = 0;
- time_interval = BAT_LEVEL_GROWING_INTERVAL;
-#ifdef RGB_MATRIX_ENABLE
+ bat_percentage = percentage;
+ cur_percentage = 0;
+ time_interval = BAT_LEVEL_GROWING_INTERVAL;
+# ifdef RGB_MATRIX_ENABLE
r = g = b = 255;
+# endif
+#else
+ bat_level_indication(percentage);
#endif
}
void bat_level_animiation_stop(void) {
+#if !defined(LED_MATRIX_ENABLE) && !defined(RGB_MATRIX_ENABLE)
+ pin_t bat_lvl_led_pin_list[INDICATOR_LED_COUNT] = INDICATOR_LED_PINS;
+ for (uint8_t i = 0; i < INDICATOR_LED_COUNT; i++) {
+ writePin(bat_lvl_led_pin_list[i], !INDICATORS_LED_PIN_ON_STATE);
+ }
+#endif
animation_state = BAT_LVL_ANI_NONE;
}
@@ -71,7 +128,7 @@ bool bat_level_animiation_actived(void) {
void bat_level_animiation_indicate(void) {
#ifdef LED_MATRIX_ENABLE
- uint8_t bat_lvl_led_list[10] = BAT_LEVEL_LED_LIST;
+ uint8_t bat_lvl_led_list[10] = BAT_LEVEL_LED_LIST;
for (uint8_t i = 0; i <= LED_MATRIX_LED_COUNT; i++) {
led_matrix_set_value(i, 0);
@@ -83,7 +140,7 @@ void bat_level_animiation_indicate(void) {
#endif
#ifdef RGB_MATRIX_ENABLE
- uint8_t bat_lvl_led_list[10] = BAT_LEVEL_LED_LIST;
+ uint8_t bat_lvl_led_list[10] = BAT_LEVEL_LED_LIST;
for (uint8_t i = 0; i <= RGB_MATRIX_LED_COUNT; i++) {
rgb_matrix_set_color(i, 0, 0, 0);
@@ -124,10 +181,12 @@ void bat_level_animiation_update(void) {
case BAT_LVL_ANI_BLINK_ON:
animation_state = BAT_LVL_ANI_NONE;
+#if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE)
indicator_eeconfig_reload();
if (indicator_config.value == 0 && !LED_DRIVER_IS_ENABLED()) {
indicator_disable();
}
+#endif
lpm_timer_reset();
break;
@@ -140,8 +199,10 @@ void bat_level_animiation_update(void) {
void bat_level_animiation_task(void) {
if (animation_state && sync_timer_elapsed32(bat_lvl_ani_timer_buffer) > time_interval) {
+#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
bat_level_animiation_update();
+#else
+ bat_level_stop();
+#endif
}
}
-
-#endif
diff --git a/keyboards/lemokey/common/wireless/bat_level_animation.h b/keyboards/lemokey/common/wireless/bat_level_animation.h
index 716e924103..97a089621a 100644
--- a/keyboards/lemokey/common/wireless/bat_level_animation.h
+++ b/keyboards/lemokey/common/wireless/bat_level_animation.h
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -21,3 +21,4 @@ void bat_level_animiation_stop(void);
bool bat_level_animiation_actived(void);
void bat_level_animiation_indicate(void);
void bat_level_animiation_task(void);
+void bat_level_indication(uint8_t percentage);
diff --git a/keyboards/lemokey/common/wireless/battery.c b/keyboards/lemokey/common/wireless/battery.c
index 36b537f006..e359054d17 100644
--- a/keyboards/lemokey/common/wireless/battery.c
+++ b/keyboards/lemokey/common/wireless/battery.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.lemokey.com)
+/* Copyright 2022~2024 @ 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
@@ -167,12 +167,7 @@ void battery_check_empty(void) {
if (voltage < EMPTY_VOLTAGE_VALUE) {
if (bat_empty <= BATTERY_EMPTY_COUNT) {
if (++bat_empty > BATTERY_EMPTY_COUNT) {
-#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(true);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(true);
-#endif
power_on_sample = VOLTAGE_POWER_ON_MEASURE_COUNT;
}
}
@@ -229,11 +224,6 @@ void battery_task(void) {
if ((bat_empty || critical_low) && usb_power_connected()) {
bat_empty = false;
critical_low = false;
-#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(false);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(false);
-#endif
}
}
diff --git a/keyboards/lemokey/common/wireless/battery.h b/keyboards/lemokey/common/wireless/battery.h
index 95ba4558b3..a30301b9d8 100644
--- a/keyboards/lemokey/common/wireless/battery.h
+++ b/keyboards/lemokey/common/wireless/battery.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.lemokey.com)
+/* Copyright 2022~2024 @ 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
@@ -15,6 +15,7 @@
*/
#pragma once
+#include "config.h"
enum {
BAT_NOT_CHARGING = 0,
@@ -54,7 +55,6 @@ void battery_calculate_voltage(bool vol_src_bt, uint16_t value);
void battery_set_voltage(uint16_t value);
uint16_t battery_get_voltage(void);
uint8_t battery_get_percentage(void);
-void indicator_battery_low_enable(bool enable);
bool battery_is_empty(void);
bool battery_is_critical_low(void);
bool battery_power_on_sample(void);
diff --git a/keyboards/lemokey/common/wireless/indicator.c b/keyboards/lemokey/common/wireless/indicator.c
index b969f80179..48ace64f89 100644
--- a/keyboards/lemokey/common/wireless/indicator.c
+++ b/keyboards/lemokey/common/wireless/indicator.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -28,7 +28,6 @@
# include "factory_test.h"
#endif
#include "lpm.h"
-
#include "lemokey_task.h"
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
# ifdef LED_MATRIX_ENABLE
@@ -37,15 +36,16 @@
# ifdef RGB_MATRIX_ENABLE
# include "rgb_matrix.h"
# endif
-# include "bat_level_animation.h"
-# include "eeprom.h"
#endif
+#include "bat_level_animation.h"
-#define HOST_INDEX_MASK 0x0F
-#define HOST_P2P4G 0x10
+#define INDEX_MASK 0x0F
+#define P24G_IND_MASK 0x10
+#define USB_IND_MASK 0x20
#define LED_ON 0x80
-// #define RGB_MATRIX_TIMEOUT_INFINITE 0xFFFFFFFF
+#define IND_VAL_MASK (USB_IND_MASK | P24G_IND_MASK | INDEX_MASK)
+
#ifdef LED_MATRIX_ENABLE
# define DECIDE_TIME(t, duration) (duration == 0 ? LED_MATRIX_TIMEOUT_INFINITE : ((t > duration) ? t : duration))
#endif
@@ -71,12 +71,7 @@ static uint16_t next_period;
static indicator_type_t type;
static uint32_t indicator_timer_buffer = 0;
-#if defined(BAT_LOW_LED_PIN)
-static uint32_t bat_low_pin_indicator = 0;
-static uint32_t bat_low_blink_duration = 0;
-#endif
-
-#if defined(LOW_BAT_IND_INDEX)
+#if defined(BAT_LOW_LED_PIN) || defined(SPACE_KEY_LOW_BAT_IND)
static uint32_t bat_low_backlit_indicator = 0;
static uint8_t bat_low_ind_state = 0;
static uint32_t rtc_time = 0;
@@ -85,22 +80,13 @@ static uint32_t rtc_time = 0;
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
backlight_state_t original_backlight_state;
-# ifdef BT_HOST_LED_MATRIX_LIST
-static uint8_t bt_host_led_matrix_list[BT_HOST_DEVICES_COUNT] = BT_HOST_LED_MATRIX_LIST;
+# ifdef BT_INDICATION_LED_LIST
+static uint8_t bt_host_led_matrix_list[BT_HOST_DEVICES_COUNT] = BT_INDICATION_LED_LIST;
# endif
-
-# ifdef P2P4G_HOST_LED_MATRIX_LIST
-static uint8_t p2p4g_host_led_matrix_list[P2P4G_HOST_DEVICES_COUNT] = P2P4G_HOST_LED_MATRIX_LIST;
-# endif
-
#endif
-#ifdef BT_HOST_LED_PIN_LIST
-static pin_t bt_led_pin_list[BT_HOST_DEVICES_COUNT] = BT_HOST_LED_PIN_LIST;
-#endif
-
-#ifdef P24G_HOST_LED_PIN_LIST
-static pin_t p24g_led_pin_list[P24G_HOST_DEVICES_COUNT] = P24G_HOST_LED_PIN_LIST;
+#ifdef BT_INDICATION_LED_PIN_LIST
+static pin_t bt_led_pin_list[BT_HOST_DEVICES_COUNT] = BT_INDICATION_LED_PIN_LIST;
#endif
#ifdef LED_MATRIX_ENABLE
@@ -111,9 +97,9 @@ static pin_t p24g_led_pin_list[P24G_HOST_DEVICES_COUNT] = P24G_HOST_LED_PIN_LIST
# define SET_ALL_LED_OFF() led_matrix_set_value_all(0)
# define SET_LED_OFF(idx) led_matrix_set_value(idx, 0)
# define SET_LED_ON(idx) led_matrix_set_value(idx, 255)
-# define SET_LED_BT(idx) led_matrix_set_value(idx, 255)
-# define SET_LED_P24G(idx) led_matrix_set_value(idx, 255)
-# define SET_LED_LOW_BAT(idx) led_matrix_set_value(idx, 255)
+# define SET_LED_BT SET_LED_ON
+# define SET_LED_P24G SET_LED_ON
+# define SET_LED_LOW_BAT SET_LED_ON
# define LED_DRIVER_IS_ENABLED led_matrix_is_enabled
# define LED_DRIVER_EECONFIG_RELOAD() \
eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); \
@@ -157,29 +143,41 @@ static pin_t p24g_led_pin_list[P24G_HOST_DEVICES_COUNT] = P24G_HOST_LED_PIN_LIST
# define LED_DRIVER_TIMEOUTED rgb_matrix_timeouted
#endif
+#ifdef WINLOCK_LED_LIST
+# define SET_LED_WINLOCK(idx) rgb_matrix_set_color(idx, 255, 0, 0)
+#endif
+
bool LED_INDICATORS_KB(void);
void indicator_init(void) {
memset(&indicator_config, 0, sizeof(indicator_config));
-#ifdef BT_HOST_LED_PIN_LIST
+#ifdef BT_INDICATION_LED_PIN_LIST
for (uint8_t i = 0; i < BT_HOST_DEVICES_COUNT; i++) {
setPinOutput(bt_led_pin_list[i]);
- writePin(bt_led_pin_list[i], !HOST_LED_PIN_ON_STATE);
+ writePin(bt_led_pin_list[i], !BT_INDICATION_LED_ON_STATE);
}
#endif
-#ifdef P24G_HOST_LED_PIN_LIST
- for (uint8_t i = 0; i < P24G_HOST_DEVICES_COUNT; i++) {
- setPinOutput(p24g_led_pin_list[i]);
- writePin(p24g_led_pin_list[i], !HOST_LED_PIN_ON_STATE);
- }
+#ifdef COMMON_BT_LED_PIN
+ setPinOutput(COMMON_BT_LED_PIN);
+ writePin(COMMON_BT_LED_PIN, !COMMON_BT_LED_PIN_ON_STATE);
+#endif
+
+#ifdef P24G_INDICATION_LED_PIN
+ setPinOutput(P24G_INDICATION_LED_PIN);
+ writePin(P24G_INDICATION_LED_PIN, !BT_INDICATION_LED_ON_STATE);
#endif
#ifdef BAT_LOW_LED_PIN
setPinOutput(BAT_LOW_LED_PIN);
writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
#endif
+
+#ifdef WIN_LOCK_LED_PIN
+ setPinOutput(WIN_LOCK_LED_PIN);
+ writePin(WIN_LOCK_LED_PIN, keymap_config.no_gui);
+#endif
}
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
@@ -213,10 +211,7 @@ void indicator_eeconfig_reload(void) {
bool indicator_is_running(void) {
return
-#if defined(BAT_LOW_LED_PIN)
- bat_low_blink_duration ||
-#endif
-#if defined(LOW_BAT_IND_INDEX)
+#if defined(BAT_LOW_LED_PIN) || defined(SPACE_KEY_LOW_BAT_IND)
bat_low_ind_state ||
#endif
!!indicator_config.value;
@@ -253,7 +248,7 @@ static void indicator_timer_cb(void *arg) {
indicator_config.value |= LED_ON;
next_period = indicator_config.on_time;
} else {
- indicator_config.value = indicator_config.value & 0x1F;
+ indicator_config.value = indicator_config.value & IND_VAL_MASK;
next_period = indicator_config.duration - indicator_config.on_time;
}
@@ -268,7 +263,7 @@ static void indicator_timer_cb(void *arg) {
case INDICATOR_BLINK:
if (indicator_config.value) {
if (indicator_config.value & LED_ON) {
- indicator_config.value = indicator_config.value & 0x1F;
+ indicator_config.value = indicator_config.value & IND_VAL_MASK;
next_period = indicator_config.off_time;
} else {
indicator_config.value |= LED_ON;
@@ -289,32 +284,38 @@ static void indicator_timer_cb(void *arg) {
break;
}
-#if defined(BT_HOST_LED_PIN_LIST) || defined(P24G_HOST_LED_PIN_LIST)
+#if defined(BT_INDICATION_LED_PIN_LIST) || defined(P24G_INDICATION_LED_PIN) || defined(COMMON_BT_LED_PIN)
if (indicator_config.value) {
- uint8_t idx = (indicator_config.value & HOST_INDEX_MASK) - 1;
-
- pin_t *led_lin_list = NULL;
- uint8_t led_count;
-# if defined(P24G_HOST_LED_PIN_LIST)
- if (indicator_config.value & HOST_P2P4G) {
- if (idx < P24G_HOST_DEVICES_COUNT) led_lin_list = p24g_led_pin_list;
- led_count = P24G_HOST_DEVICES_COUNT;
+# if defined(P24G_INDICATION_LED_PIN)
+ if (indicator_config.value & P24G_IND_MASK) {
+ if ((indicator_config.value & LED_ON) && !time_up) {
+ writePin(P24G_INDICATION_LED_PIN, BT_INDICATION_LED_ON_STATE);
+ } else {
+ writePin(P24G_INDICATION_LED_PIN, !BT_INDICATION_LED_ON_STATE);
+ }
} else
# endif
{
- if (idx < BT_HOST_DEVICES_COUNT) led_lin_list = bt_led_pin_list;
- led_count = BT_HOST_DEVICES_COUNT;
- }
-
- for (uint8_t i = 0; i < led_count; i++) {
- if (i != idx) writePin(led_lin_list[idx], !HOST_LED_PIN_ON_STATE);
- }
-
- if (led_lin_list) {
+ uint8_t idx = (indicator_config.value & INDEX_MASK) - 1;
+#ifdef BT_INDICATION_LED_PIN_LIST
+ for (uint8_t i = 0; i < BT_HOST_DEVICES_COUNT; i++) {
+ if (i != idx) writePin(bt_led_pin_list[idx], !BT_INDICATION_LED_ON_STATE);
+ }
+#endif
if ((indicator_config.value & LED_ON) && !time_up) {
- writePin(led_lin_list[idx], HOST_LED_PIN_ON_STATE);
+#ifdef BT_INDICATION_LED_PIN_LIST
+ writePin(bt_led_pin_list[idx], BT_INDICATION_LED_ON_STATE);
+#endif
+#ifdef COMMON_BT_LED_PIN
+ writePin(COMMON_BT_LED_PIN, COMMON_BT_LED_PIN_ON_STATE);
+#endif
} else {
- writePin(led_lin_list[idx], !HOST_LED_PIN_ON_STATE);
+#ifdef BT_INDICATION_LED_PIN_LIST
+ writePin(bt_led_pin_list[idx], !BT_INDICATION_LED_ON_STATE);
+#endif
+#ifdef COMMON_BT_LED_PIN
+ writePin(COMMON_BT_LED_PIN, !COMMON_BT_LED_PIN_ON_STATE);
+#endif
}
}
}
@@ -322,7 +323,7 @@ static void indicator_timer_cb(void *arg) {
if (time_up) {
/* Set indicator to off on timeup, avoid keeping light up until next update in raindrop effect */
- indicator_config.value = indicator_config.value & 0x1F;
+ indicator_config.value = indicator_config.value & IND_VAL_MASK;
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
LED_INDICATORS_KB();
#endif
@@ -342,11 +343,18 @@ static void indicator_timer_cb(void *arg) {
void indicator_set(wt_state_t state, uint8_t host_index) {
if (get_transport() == TRANSPORT_USB) return;
+#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
+ static uint8_t pre_state = 0;
+#endif
static uint8_t current_state = 0;
static uint8_t current_host = 0;
bool host_index_changed = false;
- if (host_index == 24) host_index = HOST_P2P4G | 0x01;
+ if (host_index == P24G_HOST_INDEX)
+ host_index = P24G_IND_MASK | 0x01;
+
+ else if (host_index == USB_HOST_INDEX)
+ host_index = USB_IND_MASK | 0x01;
if (current_host != host_index && state != WT_DISCONNECTED) {
host_index_changed = true;
@@ -354,6 +362,11 @@ void indicator_set(wt_state_t state, uint8_t host_index) {
}
if (current_state != state || host_index_changed || state == WT_RECONNECTING) {
+ // Some BT chips need to reset to enter sleep mode, ignore it.
+ if (current_state == WT_SUSPEND && state == WT_DISCONNECTED) return;
+#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
+ pre_state = current_state;
+#endif
current_state = state;
} else {
return;
@@ -366,15 +379,25 @@ void indicator_set(wt_state_t state, uint8_t host_index) {
indicator_enable();
indicator_reset_backlit_time();
#endif
+#if defined(BT_INDICATION_LED_PIN_LIST)
+ for (uint8_t i = 0; i < BT_HOST_DEVICES_COUNT; i++)
+ writePin(bt_led_pin_list[i], !BT_INDICATION_LED_ON_STATE);
+#endif
+#if defined(P24G_INDICATION_LED_PIN)
+ writePin(P24G_INDICATION_LED_PIN, !BT_INDICATION_LED_ON_STATE);
+#endif
+#ifdef COMMON_BT_LED_PIN
+ writePin(COMMON_BT_LED_PIN, !COMMON_BT_LED_PIN_ON_STATE);
+#endif
switch (state) {
case WT_DISCONNECTED:
-#if defined(BT_HOST_LED_PIN_LIST)
- if ((host_index & HOST_P2P4G) != HOST_P2P4G) writePin(bt_led_pin_list[(host_index & HOST_INDEX_MASK) - 1], !HOST_LED_PIN_ON_STATE);
+#if defined(BT_INDICATION_LED_PIN_LIST)
+ if ((host_index & P24G_IND_MASK) != P24G_IND_MASK) writePin(bt_led_pin_list[(host_index & INDEX_MASK) - 1], !BT_INDICATION_LED_ON_STATE);
#endif
-#if defined(P24G_HOST_LED_PIN_LIST)
- if (host_index & HOST_P2P4G) writePin(p24g_led_pin_list[(host_index & HOST_INDEX_MASK) - 1], !HOST_LED_PIN_ON_STATE);
+#if defined(P24G_INDICATION_LED_PIN)
+ writePin(P24G_INDICATION_LED_PIN, !BT_INDICATION_LED_ON_STATE);
#endif
INDICATOR_SET(disconnected);
@@ -385,6 +408,11 @@ void indicator_set(wt_state_t state, uint8_t host_index) {
indicator_set_backlit_timeout(1000);
} else {
+#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
+ if (pre_state == WT_CONNECTED)
+ indicator_set_backlit_timeout(1000);
+ else
+#endif
/* Set timer so that user has chance to turn on the backlight when is off */
indicator_set_backlit_timeout(DECIDE_TIME(DISCONNECTED_BACKLIGHT_DISABLE_TIMEOUT * 1000, indicator_config.duration));
}
@@ -435,14 +463,19 @@ void indicator_set(wt_state_t state, uint8_t host_index) {
}
#endif
-#if defined(BT_HOST_LED_PIN_LIST)
+#if defined(BT_INDICATION_LED_PIN_LIST)
for (uint8_t i = 0; i < BT_HOST_DEVICES_COUNT; i++)
- writePin(bt_led_pin_list[i], !HOST_LED_PIN_ON_STATE);
+ writePin(bt_led_pin_list[i], !BT_INDICATION_LED_ON_STATE);
#endif
-#if defined(P24G_HOST_LED_PIN_LIST)
- for (uint8_t i = 0; i < P24G_HOST_DEVICES_COUNT; i++)
- writePin(p24g_led_pin_list[i], !HOST_LED_PIN_ON_STATE);
+#if defined(P24G_INDICATION_LED_PIN)
+ writePin(P24G_INDICATION_LED_PIN, !BT_INDICATION_LED_ON_STATE);
#endif
+#ifdef COMMON_BT_LED_PIN
+ writePin(COMMON_BT_LED_PIN, !COMMON_BT_LED_PIN_ON_STATE);
+#endif
+# if defined(BAT_LOW_LED_PIN)
+ writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
+# endif
break;
default:
@@ -465,22 +498,11 @@ void indicator_stop(void) {
#endif
}
-#ifdef BAT_LOW_LED_PIN
void indicator_battery_low_enable(bool enable) {
- if (enable) {
- if (bat_low_blink_duration == 0) {
- bat_low_blink_duration = bat_low_pin_indicator = timer_read32();
- } else
- bat_low_blink_duration = timer_read32();
- } else
- writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
-}
-#endif
-
-#if defined(LOW_BAT_IND_INDEX)
-void indicator_battery_low_backlit_enable(bool enable) {
+#if defined(BAT_LOW_LED_PIN) || defined(SPACE_KEY_LOW_BAT_IND)
if (enable) {
uint32_t t = rtc_timer_read_ms();
+
/* Check overflow */
if (rtc_time > t) {
if (bat_low_ind_state == 0)
@@ -489,55 +511,62 @@ void indicator_battery_low_backlit_enable(bool enable) {
rtc_time += t;
}
}
+
/* Indicating at first time or after the interval */
if ((rtc_time == 0 || t - rtc_time > LOW_BAT_LED_TRIG_INTERVAL) && bat_low_ind_state == 0) {
bat_low_backlit_indicator = enable ? timer_read32() : 0;
rtc_time = rtc_timer_read_ms();
bat_low_ind_state = 1;
-
+# if defined(SPACE_KEY_LOW_BAT_IND)
indicator_enable();
+# endif
}
} else {
rtc_time = 0;
bat_low_ind_state = 0;
-
+# if defined(SPACE_KEY_LOW_BAT_IND)
indicator_eeconfig_reload();
if (!LED_DRIVER_IS_ENABLED()) indicator_disable();
+# endif
}
-}
#endif
+}
void indicator_battery_low(void) {
-#ifdef BAT_LOW_LED_PIN
- if (bat_low_pin_indicator && timer_elapsed32(bat_low_pin_indicator) > (LOW_BAT_LED_BLINK_PERIOD)) {
- togglePin(BAT_LOW_LED_PIN);
- bat_low_pin_indicator = timer_read32();
- // Turn off low battery indication if we reach the duration
- if (timer_elapsed32(bat_low_blink_duration) > LOW_BAT_LED_BLINK_DURATION && palReadLine(BAT_LOW_LED_PIN) != BAT_LOW_LED_PIN_ON_STATE) {
- bat_low_blink_duration = bat_low_pin_indicator = 0;
- }
- }
-#endif
-#if defined(LOW_BAT_IND_INDEX)
+#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 & 0x80) {
bat_low_ind_state &= 0x7F;
bat_low_ind_state++;
+# if defined(BAT_LOW_LED_PIN)
+ writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
+# endif
} else {
bat_low_ind_state |= 0x80;
+# if defined(BAT_LOW_LED_PIN)
+ writePin(BAT_LOW_LED_PIN, BAT_LOW_LED_PIN_ON_STATE);
+# endif
}
bat_low_backlit_indicator = timer_read32();
/* Restore backligth state */
if ((bat_low_ind_state & 0x0F) > (LOW_BAT_LED_BLINK_TIMES)) {
-# if defined(NUM_LOCK_INDEX) || defined(CAPS_LOCK_INDEX) || defined(SCROLL_LOCK_INDEX) || defined(COMPOSE_LOCK_INDEX) || defined(KANA_LOCK_INDEX)
- if (LED_DRIVER_ALLOW_SHUTDOWN())
+# 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)
+# if defined(NUM_LOCK_INDEX) || defined(CAPS_LOCK_INDEX) || defined(SCROLL_LOCK_INDEX) || defined(COMPOSE_LOCK_INDEX) || defined(KANA_LOCK_INDEX)
+ if (LED_DRIVER_ALLOW_SHUTDOWN())
+# endif
indicator_disable();
+# endif
}
} else if ((bat_low_ind_state & 0x0F) > (LOW_BAT_LED_BLINK_TIMES)) {
+# if defined(BAT_LOW_LED_PIN)
+ writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
+# endif
bat_low_ind_state = 0;
lpm_timer_reset();
}
@@ -546,9 +575,7 @@ void indicator_battery_low(void) {
}
void indicator_task(void) {
-#if (defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(BAT_LEVEL_LED_LIST)
bat_level_animiation_task();
-#endif
if (indicator_config.value && timer_elapsed32(indicator_timer_buffer) >= next_period) {
indicator_timer_cb((void *)&type);
indicator_timer_buffer = timer_read32();
@@ -592,6 +619,32 @@ __attribute__((weak)) void os_state_indicate(void) {
SET_LED_ON(KANA_LOCK_INDEX);
}
# endif
+
+# if defined(WIN_LOCK_LED_PIN) || defined(WINLOCK_LED_LIST)
+ /* TODO: move to common.c */
+ if (keymap_config.no_gui && (((get_transport() & TRANSPORT_WIRELESS) && wireless_get_state() == WT_CONNECTED) || (get_transport() == TRANSPORT_USB && USBD1.state == USB_ACTIVE))) {
+# ifdef WINLOCK_LED_LIST
+ if (keymap_config.no_gui) {
+ uint8_t led_list[] = WINLOCK_LED_LIST;
+ uint8_t led_cnt = ARRAY_SIZE(led_list);
+ for (uint8_t i = 0; i < led_cnt; i++) {
+# if defined(DIM_WIN_LOCK)
+ SET_LED_OFF(led_list[i]);
+# else
+ SET_LED_WINLOCK(led_list[i]);
+# endif
+ }
+ }
+# endif
+# ifdef WIN_LOCK_LED_PIN
+ writePin(WIN_LOCK_LED_PIN, WIN_LOCK_LED_ON_LEVEL);
+# endif
+ } else {
+# ifdef WIN_LOCK_LED_PIN
+ writePin(WIN_LOCK_LED_PIN, !WIN_LOCK_LED_ON_LEVEL);
+# endif
+ }
+# endif
}
bool LED_INDICATORS_KB(void) {
@@ -602,9 +655,8 @@ bool LED_INDICATORS_KB(void) {
return true;
}
-# if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
if (battery_is_empty()) SET_ALL_LED_OFF();
-# if defined(LOW_BAT_IND_INDEX)
+# if defined(LOW_BAT_IND_INDEX)
if (bat_low_ind_state && (bat_low_ind_state & 0x0F) <= LOW_BAT_LED_BLINK_TIMES) {
uint8_t idx_list[] = LOW_BAT_IND_INDEX;
for (uint8_t i = 0; i < sizeof(idx_list); i++) {
@@ -615,8 +667,8 @@ bool LED_INDICATORS_KB(void) {
}
}
}
-# endif
# endif
+
# if (defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(BAT_LEVEL_LED_LIST)
if (bat_level_animiation_actived()) {
bat_level_animiation_indicate();
@@ -625,39 +677,40 @@ bool LED_INDICATORS_KB(void) {
static uint8_t last_host_index = 0xFF;
if (indicator_config.value) {
- uint8_t host_index = indicator_config.value & HOST_INDEX_MASK;
+ uint8_t host_index = indicator_config.value & INDEX_MASK;
if (indicator_config.highlight) {
SET_ALL_LED_OFF();
} else if (last_host_index != host_index) {
- if (indicator_config.value & HOST_P2P4G)
- SET_LED_OFF(p2p4g_host_led_matrix_list[host_index - 1]);
+# ifdef P24G_INDICATION_LED_INDEX
+ if (indicator_config.value & P24G_IND_MASK)
+ SET_LED_OFF(P24G_INDICATION_LED_INDEX);
else
+# endif
SET_LED_OFF(bt_host_led_matrix_list[host_index - 1]);
last_host_index = host_index;
}
if (indicator_config.value & LED_ON) {
-# ifdef P2P4G_HOST_LED_MATRIX_LIST
- if (indicator_config.value & HOST_P2P4G)
- SET_LED_P24G(p2p4g_host_led_matrix_list[host_index - 1]);
+# ifdef P24G_INDICATION_LED_INDEX
+ if (indicator_config.value & P24G_IND_MASK)
+ SET_LED_P24G(P24G_INDICATION_LED_INDEX);
else
# endif
SET_LED_BT(bt_host_led_matrix_list[host_index - 1]);
} else {
-# ifdef P2P4G_HOST_LED_MATRIX_LIST
- if (indicator_config.value & HOST_P2P4G)
- SET_LED_OFF(p2p4g_host_led_matrix_list[host_index - 1]);
+# ifdef P24G_INDICATION_LED_INDEX
+ if (indicator_config.value & P24G_IND_MASK)
+ SET_LED_OFF(P24G_INDICATION_LED_INDEX);
else
# endif
SET_LED_OFF(bt_host_led_matrix_list[host_index - 1]);
}
} else
os_state_indicate();
-
- } else
- os_state_indicate();
+ }
+ if (get_transport() == TRANSPORT_USB) os_state_indicate();
if (!LED_INDICATORS_USER()) return true;
@@ -686,10 +739,7 @@ bool led_update_kb(led_t led_state) {
}
void LED_NONE_INDICATORS_KB(void) {
-# if defined(RGB_DISABLE_WHEN_USB_SUSPENDED)
- if (get_transport() == TRANSPORT_USB && USB_DRIVER.state == USB_SUSPENDED) return;
-# endif
-# if defined(LED_DISABLE_WHEN_USB_SUSPENDED)
+# if defined(RGB_DISABLE_WHEN_USB_SUSPENDED) || defined(LED_DISABLE_WHEN_USB_SUSPENDED)
if (get_transport() == TRANSPORT_USB && USB_DRIVER.state == USB_SUSPENDED) return;
# endif
@@ -713,8 +763,11 @@ bool LED_DRIVER_ALLOW_SHUTDOWN(void) {
# if defined(KANA_LOCK_INDEX)
if (host_keyboard_led_state().kana) return false;
# endif
+# if defined(WINLOCK_LED_LIST) && !defined(WIN_LOCK_LED_PIN)
+ if (keymap_config.no_gui && (wireless_get_state() == WT_CONNECTED || get_transport()==TRANSPORT_USB)) return false;
+# endif
+
return true;
}
# endif
-
#endif
diff --git a/keyboards/lemokey/common/wireless/indicator.h b/keyboards/lemokey/common/wireless/indicator.h
index f731d9ee0d..b4c60e0261 100644
--- a/keyboards/lemokey/common/wireless/indicator.h
+++ b/keyboards/lemokey/common/wireless/indicator.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -19,6 +19,9 @@
#include "config.h"
#include "wireless.h"
+#define P24G_HOST_INDEX 24
+#define USB_HOST_INDEX 34
+
/* Indication of pairing */
#ifndef INDICATOR_CONFIG_PARING
# define INDICATOR_CONFIG_PARING {INDICATOR_BLINK, 1000, 1000, 0, true, 0};
@@ -41,45 +44,43 @@
/* Uint: Second */
#ifndef DISCONNECTED_BACKLIGHT_DISABLE_TIMEOUT
-# define DISCONNECTED_BACKLIGHT_OFF_DELAY_TIME 40
+# define DISCONNECTED_BACKLIGHT_DISABLE_TIMEOUT 40
#endif
/* Uint: Second, the timer restarts on key activities. */
#ifndef CONNECTED_BACKLIGHT_DISABLE_TIMEOUT
-# define CONNECTED_BACKLIGHT_OFF_DELAY_TIME 600
+# define CONNECTED_BACKLIGHT_DISABLE_TIMEOUT 600
#endif
-#ifdef BAT_LOW_LED_PIN
/* Uint: ms */
-# ifndef LOW_BAT_LED_BLINK_PERIOD
-# define LOW_BAT_LED_BLINK_PERIOD 1000
-# endif
-
-# ifndef LOW_BAT_LED_BLINK_DURATION
-# define LOW_BAT_LED_BLINK_DURATION 10000
-# endif
+#ifndef LOW_BAT_LED_BLINK_PERIOD
+# define LOW_BAT_LED_BLINK_PERIOD 1000
#endif
-#ifdef LOW_BAT_IND_INDEX
-/* Uint: ms */
-# ifndef LOW_BAT_LED_BLINK_PERIOD
-# define LOW_BAT_LED_BLINK_PERIOD 500
-# endif
+#ifndef LOW_BAT_LED_BLINK_TIMES
+# define LOW_BAT_LED_BLINK_TIMES 5
+#endif
-# ifndef LOW_BAT_LED_BLINK_TIMES
-# define LOW_BAT_LED_BLINK_TIMES 3
-# endif
+#ifndef LOW_BAT_LED_TRIG_INTERVAL
+# define LOW_BAT_LED_TRIG_INTERVAL 30000
+#endif
-# ifndef LOW_BAT_LED_TRIG_INTERVAL
-# define LOW_BAT_LED_TRIG_INTERVAL 30000
-# endif
+#if ((defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(LOW_BAT_IND_INDEX))
+# define SPACE_KEY_LOW_BAT_IND
#endif
#if BT_HOST_MAX_COUNT > 6
# pragma error("HOST_COUNT max value is 6")
#endif
-typedef enum { INDICATOR_NONE, INDICATOR_OFF, INDICATOR_ON, INDICATOR_ON_OFF, INDICATOR_BLINK, INDICATOR_LAST } indicator_type_t;
+typedef enum {
+ INDICATOR_NONE,
+ INDICATOR_OFF,
+ INDICATOR_ON,
+ INDICATOR_ON_OFF,
+ INDICATOR_BLINK,
+ INDICATOR_LAST,
+} indicator_type_t;
typedef struct PACKED {
indicator_type_t type;
@@ -98,6 +99,7 @@ typedef struct PACKED {
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);
bool indicator_hook_key(uint16_t keycode);
void indicator_enable(void);
@@ -106,12 +108,6 @@ void indicator_stop(void);
void indicator_eeconfig_reload(void);
bool indicator_is_enabled(void);
bool indicator_is_running(void);
-
-#ifdef BAT_LOW_LED_PIN
void indicator_battery_low_enable(bool enable);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
-void indicator_battery_low_backlit_enable(bool enable);
-#endif
void indicator_task(void);
diff --git a/keyboards/lemokey/common/wireless/lkbt51.c b/keyboards/lemokey/common/wireless/lkbt51.c
index 56db438727..686ca32858 100644
--- a/keyboards/lemokey/common/wireless/lkbt51.c
+++ b/keyboards/lemokey/common/wireless/lkbt51.c
@@ -1,4 +1,4 @@
-/* Copyright 2021 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -25,9 +25,9 @@
extern void factory_test_send(uint8_t* payload, uint8_t length);
-# ifndef RAW_EPSIZE
-# define RAW_EPSIZE 32
-# endif
+#ifndef RAW_EPSIZE
+# define RAW_EPSIZE 32
+#endif
#ifndef SPI_SCK_PIN
# define SPI_SCK_PIN A5
@@ -141,12 +141,12 @@ enum{
};
// clang-format on
-
static uint8_t payload[PACKET_MAX_LEN];
static uint8_t reg_offset = 0xFF;
static uint8_t expect_len = 22;
static uint16_t connection_interval = 1;
static uint32_t wake_time;
+static uint32_t factory_reset = 0;
// clang-format off
wt_func_t wireless_transport = {
@@ -164,6 +164,7 @@ wt_func_t wireless_transport = {
};
// clang-format on
+#if defined(MCU_STM32)
/* Init SPI */
const SPIConfig spicfg = {
.circular = false,
@@ -175,6 +176,18 @@ const SPIConfig spicfg = {
.cr1 = SPI_CR1_MSTR | SPI_CR1_BR_1 | SPI_CR1_BR_0,
.cr2 = 0U,
};
+#endif
+
+#if defined(WB32F3G71xx)
+/* Init SPI */
+const SPIConfig spicfg = {
+ .ssport = PAL_PORT(BLUETOOTH_INT_OUTPUT_PIN),
+ .sspad = PAL_PAD(BLUETOOTH_INT_OUTPUT_PIN),
+ .SPI_CPOL = 0U,
+ .SPI_CPHA = 0U,
+ .SPI_BaudRatePrescaler = 32U,
+};
+#endif
void lkbt51_init(bool wakeup_from_low_power_mode) {
#ifdef LKBT51_RESET_PIN
@@ -187,14 +200,11 @@ void lkbt51_init(bool wakeup_from_low_power_mode) {
#endif
#if (HAL_USE_SPI == TRUE)
+ palSetLineMode(SPI_SCK_PIN, PAL_MODE_ALTERNATE(SPI_CLK_PAL_MODE));
+ palSetLineMode(SPI_MISO_PIN, PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE));
+ palSetLineMode(SPI_MOSI_PIN, PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE));
+
if (WT_DRIVER.state == SPI_UNINIT) {
- setPinOutput(SPI_SCK_PIN);
- writePinHigh(SPI_SCK_PIN);
-
- palSetLineMode(SPI_SCK_PIN, PAL_MODE_ALTERNATE(SPI_CLK_PAL_MODE));
- palSetLineMode(SPI_MISO_PIN, PAL_MODE_ALTERNATE(SPI_MISO_PAL_MODE));
- palSetLineMode(SPI_MOSI_PIN, PAL_MODE_ALTERNATE(SPI_MOSI_PAL_MODE));
-
if (wakeup_from_low_power_mode) {
spiInit();
return;
@@ -367,9 +377,9 @@ void lkbt51_send_mouse(uint8_t* report) {
payload[i++] = LKBT51_CMD_SEND_MOUSE; // Cmd type
payload[i++] = report[1]; // Button
payload[i++] = report[2]; // X
- payload[i++] = (report[2] & 0x80) ? 0xff : 0x00; // ckbt51 use 16bit report, set high byte
+ payload[i++] = (report[2] & 0x80) ? 0xff : 0x00; // lkbt51 use 16bit report, set high byte
payload[i++] = report[3]; // Y
- payload[i++] = (report[3] & 0x80) ? 0xff : 0x00; // ckbt51 use 16bit report, set high byte
+ payload[i++] = (report[3] & 0x80) ? 0xff : 0x00; // lkbt51 use 16bit report, set high byte
payload[i++] = report[4]; // V wheel
payload[i++] = report[5]; // H wheel
@@ -434,7 +444,8 @@ void lkbt51_disconnect(void) {
payload[i++] = LKBT51_CMD_DISCONNECT;
payload[i++] = 0; // Sleep mode
- spiSelect(&SPID1);
+ if (WT_DRIVER.state != SPI_READY) spiStart(&WT_DRIVER, &spicfg);
+
wait_ms(30);
// spiUnselect(&SPID1);
wait_ms(70);
@@ -539,6 +550,7 @@ void lkbt51_factory_reset(uint8_t p2p4g_clr_msk) {
lkbt51_wake();
lkbt51_send_cmd(payload, i, false, false);
+ factory_reset = timer_read32();
}
void lkbt51_int_pin_test(bool enable) {
@@ -610,9 +622,9 @@ void lkbt51_write_customize_data(uint8_t* data, uint8_t len) {
}
#ifdef RAW_ENABLE
void lkbt51_dfu_tx(uint8_t rsp, uint8_t* data, uint8_t len, uint8_t sn) {
- uint16_t checksum = 0;
- uint8_t buf[RAW_EPSIZE] = {0};
- uint8_t i = 0;
+ uint16_t checksum = 0;
+ uint8_t buf[RAW_EPSIZE] = {0};
+ uint8_t i = 0;
buf[i++] = 0x03;
buf[i++] = 0xAA;
@@ -791,6 +803,10 @@ void lkbt51_task(void) {
break;
case LKBT51_DISCONNECTED:
event.evt_type = EVT_DISCONNECTED;
+ if (factory_reset && timer_elapsed32(factory_reset) < 3000) {
+ factory_reset = 0;
+ event.data = 1;
+ }
break;
case LKBT51_PINCODE_ENTRY:
event.evt_type = EVT_BT_PINCODE_ENTRY;
diff --git a/keyboards/lemokey/common/wireless/lkbt51.h b/keyboards/lemokey/common/wireless/lkbt51.h
index f5380f12be..ca5bcdff9a 100644
--- a/keyboards/lemokey/common/wireless/lkbt51.h
+++ b/keyboards/lemokey/common/wireless/lkbt51.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -18,18 +18,23 @@
#include "stdint.h"
#include "hal.h"
-
-#ifndef WT_DRIVER
-# define WT_DRIVER SPID1
-#endif
+#include "config.h"
// Error checking
#if HAL_USE_SPI == FALSE
# error "Please enable SPI to use LKBT51"
#endif
-#if !STM32_SPI_USE_SPI1 && !STM32_SPI_USE_SPI2 && !STM32_SPI_USE_SPI3
-# error "WT driver activated but no SPI peripheral assigned"
+#if defined(WB32F3G71xx)
+# ifndef WT_DRIVER
+# define WT_DRIVER SPIDQ
+# endif
+#endif
+
+#if defined(MCU_STM32)
+# ifndef WT_DRIVER
+# define WT_DRIVER SPID1
+# endif
#endif
#define PACKECT_HEADER_LEN 5
diff --git a/keyboards/lemokey/common/wireless/lpm.c b/keyboards/lemokey/common/wireless/lpm.c
index d124722d9c..6334cf22d3 100644
--- a/keyboards/lemokey/common/wireless/lpm.c
+++ b/keyboards/lemokey/common/wireless/lpm.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -32,6 +32,7 @@
#include "lpm.h"
#include "transport.h"
#include "battery.h"
+#include "bat_level_animation.h"
#include "report_buffer.h"
#include "lemokey_common.h"
@@ -46,7 +47,6 @@ static matrix_row_t empty_matrix[MATRIX_ROWS] = {0};
pin_t pins_row[MATRIX_ROWS] = MATRIX_ROW_PINS;
pin_t pins_col[MATRIX_COLS] = MATRIX_COL_PINS;
-;
__attribute__((weak)) void select_all_cols(void) {
for (uint8_t i = 0; i < MATRIX_COLS; i++) {
@@ -77,44 +77,62 @@ void lpm_timer_stop(void) {
}
static inline bool lpm_any_matrix_action(void) {
-#ifdef OPTICAL_SWITCH
- bool any_key = false;
- for (uint8_t i = 0; i < MATRIX_ROWS; i++)
- if (matrix_get_row(i) != 0) {
- any_key = true;
- }
- return any_key;
-#else
return memcmp(matrix, empty_matrix, sizeof(empty_matrix));
-#endif
+}
+
+__attribute__((weak)) void matrix_enter_low_power(void) {
+ /* Enable key matrix wake up */
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ if (pins_row[x] != NO_PIN) {
+ palEnableLineEvent(pins_row[x], PAL_EVENT_MODE_BOTH_EDGES);
+ }
+ }
+
+ select_all_cols();
+}
+
+__attribute__((weak)) void matrix_exit_low_power(void) {
+ /* Disable all wake up pins */
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ if (pins_row[x] != NO_PIN) {
+ palDisableLineEvent(pins_row[x]);
+ }
+ }
}
/* Implement of entering low power mode and wakeup varies per mcu or platform */
-__attribute__((weak)) void enter_power_mode(pm_t mode) {}
-__attribute__((weak)) bool usb_power_connected(void) {
-#ifdef USB_POWER_SENSE_PIN
- return readPin(USB_POWER_SENSE_PIN) == USB_POWER_CONNECTED_LEVEL;
-#else
- return true;
+__attribute__((weak)) void lpm_pre_enter_low_power(void) {}
+
+__attribute__((weak)) void lpm_enter_low_power_kb(void) {}
+
+__attribute__((weak)) void lpm_enter_low_power(void) {
+ if (get_transport() == TRANSPORT_USB && !usb_power_connected()) {
+#ifdef RGB_MATRIX_ENABLE
+ rgb_matrix_set_color_all(0, 0, 0);
+ rgb_matrix_driver.flush();
+ rgb_matrix_driver_shutdown();
#endif
-}
-
-__attribute__((weak)) bool lpm_is_kb_idle(void) {
- return true;
-}
-
-__attribute__((weak)) bool lpm_set(pm_t mode) {
- return false;
-}
-
-bool pre_enter_low_power_mode(pm_t mode) {
-#if defined(KEEP_USB_CONNECTION_IN_WIRELESS_MODE)
- /* Don't enter low power mode if attached to the host */
- if (mode > PM_SLEEP && usb_power_connected()) return false;
+#ifdef LED_MATRIX_ENABLE
+ led_matrix_set_value_all(0);
+ led_matrix_driver.flush();
+ led_matrix_driver_shutdown();
#endif
-
- if (!lpm_set(mode)) return false;
+#ifdef LED_NUM_LOCK_PIN
+ writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE);
+#endif
+#ifdef LED_CAPS_LOCK_PIN
+ writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE);
+#endif
+#ifdef BAT_LOW_LED_PIN
+ writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
+#endif
+#ifdef BT_INDICATION_LED_PIN_LIST
+ pin_t bt_led_pins[] = BT_INDICATION_LED_PIN_LIST;
+ for (uint8_t i = 0; i < sizeof(bt_led_pins) / sizeof(pin_t); i++)
+ writePin(bt_led_pins[i], !BT_INDICATION_LED_ON_STATE);
+#endif
+ }
#if defined(KEEP_USB_CONNECTION_IN_WIRELESS_MODE)
/* Usb unit is actived and running, stop and disconnect first */
@@ -125,6 +143,13 @@ bool pre_enter_low_power_mode(pm_t mode) {
// PWR->CR2 &= ~PWR_CR2_USV; /*PWR_CR2_USV is available on STM32L4x2xx and STM32L4x3xx devices only. */
#endif
+#if (HAL_USE_SPI == TRUE)
+ spiStop(&SPI_DRIVER);
+ palSetLineMode(SPI_SCK_PIN, PAL_MODE_INPUT_PULLDOWN);
+ palSetLineMode(SPI_MISO_PIN, PAL_MODE_INPUT_PULLDOWN);
+ palSetLineMode(SPI_MOSI_PIN, PAL_MODE_INPUT_PULLDOWN);
+#endif
+
palEnableLineEvent(LKBT51_INT_INPUT_PIN, PAL_EVENT_MODE_FALLING_EDGE);
#ifdef USB_POWER_SENSE_PIN
palEnableLineEvent(USB_POWER_SENSE_PIN, PAL_EVENT_MODE_BOTH_EDGES);
@@ -135,38 +160,7 @@ bool pre_enter_low_power_mode(pm_t mode) {
#ifdef BT_MODE_SELECT_PIN
palEnableLineEvent(BT_MODE_SELECT_PIN, PAL_EVENT_MODE_BOTH_EDGES);
#endif
-
-#ifdef OPTICAL_SWITCH
-
- for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
- if (pins_row[x] != NO_PIN) {
- writePinLow(pins_row[x]);
- }
- }
-
- for (uint8_t x = 0; x < MATRIX_COLS; x++) {
- if (pins_col[x] != NO_PIN) {
- setPinInputLow(pins_col[x]);
- }
- }
-#else
-
- /* Enable key matrix wake up */
- for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
- if (pins_row[x] != NO_PIN) {
- palEnableLineEvent(pins_row[x], PAL_EVENT_MODE_BOTH_EDGES);
- }
- }
-#endif
- select_all_cols();
-
-#if (HAL_USE_SPI == TRUE)
- palSetLineMode(SPI_SCK_PIN, PAL_MODE_INPUT_PULLDOWN);
- palSetLineMode(SPI_MISO_PIN, PAL_MODE_INPUT_PULLDOWN);
- palSetLineMode(SPI_MOSI_PIN, PAL_MODE_INPUT_PULLDOWN);
-#endif
- palSetLineMode(A12, PAL_MODE_INPUT_PULLDOWN);
- palSetLineMode(A11, PAL_MODE_INPUT_PULLDOWN);
+ matrix_enter_low_power();
#if defined(DIP_SWITCH_PINS)
# define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad) / sizeof(pin_t))
@@ -177,19 +171,25 @@ bool pre_enter_low_power_mode(pm_t mode) {
}
#endif
battery_stop();
-
- return true;
+ lpm_enter_low_power_kb();
}
-static inline void lpm_wakeup(void) {
- palSetLineMode(A11, PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
- palSetLineMode(A12, PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
+__attribute__((weak)) void lpm_post_enter_low_power(void) {}
-#if (HAL_USE_SPI == TRUE)
- palSetLineMode(SPI_SCK_PIN, PAL_MODE_ALTERNATE(5));
- palSetLineMode(SPI_MISO_PIN, PAL_MODE_ALTERNATE(5));
- palSetLineMode(SPI_MOSI_PIN, PAL_MODE_ALTERNATE(5));
-#endif
+__attribute__((weak)) void lpm_standby(pm_t mode) {}
+
+__attribute__((weak)) void lpm_early_wakeup(void) {
+ writePinLow(BLUETOOTH_INT_OUTPUT_PIN);
+}
+
+__attribute__((weak)) void lpm_wakeup_init(void) {}
+
+__attribute__((weak)) void lpm_pre_wakeup(void) {
+ writePinHigh(BLUETOOTH_INT_OUTPUT_PIN);
+}
+
+__attribute__((weak)) void lpm_wakeup(void) {
+ matrix_exit_low_power();
halInit();
@@ -200,13 +200,6 @@ static inline void lpm_wakeup(void) {
if (wireless_transport.init) wireless_transport.init(true);
battery_init();
- /* Disable all wake up pins */
- for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
- if (pins_row[x] != NO_PIN) {
- palDisableLineEvent(pins_row[x]);
- }
- }
-
palDisableLineEvent(LKBT51_INT_INPUT_PIN);
#ifdef P2P4_MODE_SELECT_PIN
palDisableLineEvent(P2P4_MODE_SELECT_PIN);
@@ -218,7 +211,11 @@ static inline void lpm_wakeup(void) {
palDisableLineEvent(USB_POWER_SENSE_PIN);
# if defined(KEEP_USB_CONNECTION_IN_WIRELESS_MODE)
- if (usb_power_connected()) {
+ if (usb_power_connected()
+# ifndef BT_MODE_SELECT_PIN
+ && (get_transport() == TRANSPORT_USB)
+# endif
+ ) {
usb_event_queue_init();
init_usb_driver(&USB_DRIVER);
}
@@ -236,8 +233,41 @@ static inline void lpm_wakeup(void) {
debounce_free();
matrix_init();
}
+__attribute__((weak)) void lpm_post_wakeup(void) {}
+
+__attribute__((weak)) bool usb_power_connected(void) {
+#ifdef USB_POWER_SENSE_PIN
+ return readPin(USB_POWER_SENSE_PIN) == USB_POWER_CONNECTED_LEVEL;
+#else
+ return true;
+#endif
+}
+
+__attribute__((weak)) bool lpm_is_kb_idle(void) {
+ return true;
+}
+
+__attribute__((weak)) bool lpm_set(pm_t mode) {
+ return false;
+}
+
+__attribute__((weak)) void lpm_peripheral_enter_low_power(void) {}
+
+__attribute__((weak)) void lpm_peripheral_exit_low_power(void) {}
+
+bool allow_low_power_mode(pm_t mode) {
+#if defined(KEEP_USB_CONNECTION_IN_WIRELESS_MODE)
+ /* Don't enter low power mode if attached to the host */
+ if (mode > PM_SLEEP && usb_power_connected()) return false;
+#endif
+
+ if (!lpm_set(mode)) return false;
+
+ return true;
+}
void lpm_task(void) {
+ bool lpm = false;
if (!lpm_time_up && sync_timer_elapsed32(lpm_timer_buffer) > RUN_MODE_PROCESS_TIME) {
lpm_time_up = true;
lpm_timer_buffer = 0;
@@ -248,30 +278,39 @@ void lpm_task(void) {
init_usb_driver(&USB_DRIVER);
}
- if ((get_transport() == TRANSPORT_BLUETOOTH || get_transport() == TRANSPORT_P2P4) && lpm_time_up && !indicator_is_running() && lpm_is_kb_idle()) {
-#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
+ if ((get_transport() & TRANSPORT_WIRELESS) && lpm_time_up && !indicator_is_running() && lpm_is_kb_idle()) {
if (
-# ifdef LED_MATRIX_ENABLE
- !led_matrix_is_enabled() ||
- (led_matrix_is_enabled() && led_matrix_is_driver_shutdown())
-# endif
-# ifdef RGB_MATRIX_ENABLE
- !rgb_matrix_is_enabled() ||
- (rgb_matrix_is_enabled() && rgb_matrix_is_driver_shutdown())
-# endif
- )
+#ifdef LED_MATRIX_ENABLE
+ !led_matrix_is_enabled() || (led_matrix_is_enabled() && led_matrix_is_driver_shutdown())
+#elif defined(RGB_MATRIX_ENABLE)
+ !rgb_matrix_is_enabled() || (rgb_matrix_is_enabled() && rgb_matrix_is_driver_shutdown())
+#else
+ !bat_level_animiation_actived()
#endif
- {
+ ) {
if (!lpm_any_matrix_action()) {
- if (pre_enter_low_power_mode(LOW_POWER_MODE)) {
- enter_power_mode(LOW_POWER_MODE);
-
- lpm_wakeup();
- lpm_timer_reset();
- report_buffer_init();
- lpm_set(PM_RUN);
+ if (allow_low_power_mode(LOW_POWER_MODE)) {
+ lpm = true;
}
}
}
}
+
+ if (lpm) {
+ lpm_pre_enter_low_power();
+ lpm_enter_low_power();
+ lpm_post_enter_low_power();
+
+ lpm_standby(LOW_POWER_MODE);
+ lpm_early_wakeup();
+ lpm_wakeup_init();
+
+ lpm_pre_wakeup();
+ lpm_wakeup();
+ lpm_post_wakeup();
+
+ lpm_timer_reset();
+ report_buffer_init();
+ lpm_set(PM_RUN);
+ }
}
diff --git a/keyboards/lemokey/common/wireless/lpm.h b/keyboards/lemokey/common/wireless/lpm.h
index ca6fc5d450..bc7055e215 100644
--- a/keyboards/lemokey/common/wireless/lpm.h
+++ b/keyboards/lemokey/common/wireless/lpm.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -30,6 +30,19 @@ typedef enum {
void lpm_init(void);
void lpm_timer_reset(void);
void lpm_timer_stop(void);
+void select_all_cols(void);
+void matrix_enter_low_power(void);
+void matrix_exit_low_power(void);
+void lpm_pre_enter_low_power(void);
+void lpm_enter_low_power(void);
+void lpm_enter_low_power_kb(void);
+void lpm_post_enter_low_power(void) ;
+void lpm_standby(pm_t mode);
+void lpm_early_wakeup(void);
+void lpm_wakeup_init(void);
+void lpm_pre_wakeup(void);
+void lpm_wakeup(void);
+void lpm_post_wakeup(void);
bool usb_power_connected(void);
bool lpm_is_kb_idle(void);
void enter_power_mode(pm_t mode);
diff --git a/keyboards/lemokey/common/wireless/lpm_stm32f401.c b/keyboards/lemokey/common/wireless/lpm_stm32f401.c
index 8b5255879c..f235d344b2 100644
--- a/keyboards/lemokey/common/wireless/lpm_stm32f401.c
+++ b/keyboards/lemokey/common/wireless/lpm_stm32f401.c
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -29,8 +29,29 @@
#include "lpm_stm32f401.h"
#include "config.h"
+#include "hal.h"
+
static pm_t power_mode = PM_RUN;
+void lpm_post_enter_low_power(void) {
+ /* USB D+/D- */
+ palSetLineMode(A12, PAL_MODE_INPUT_PULLDOWN);
+ palSetLineMode(A11, PAL_MODE_INPUT_PULLDOWN);
+}
+
+void lpm_pre_wakeup(void) {
+ /* USB D+/D- */
+ palSetLineMode(A11, PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
+ palSetLineMode(A12, PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
+
+ /* SPI */
+#if (HAL_USE_SPI == TRUE)
+ palSetLineMode(SPI_SCK_PIN, PAL_MODE_ALTERNATE(5));
+ palSetLineMode(SPI_MISO_PIN, PAL_MODE_ALTERNATE(5));
+ palSetLineMode(SPI_MOSI_PIN, PAL_MODE_ALTERNATE(5));
+#endif
+}
+
bool lpm_set(pm_t mode) {
bool ret = true;
@@ -51,20 +72,21 @@ bool lpm_set(pm_t mode) {
else {
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
PWR->CR |=
-#if STOP_MODE_MAIN_REGULATOR_LOW_VOLTAGE
+# if STOP_MODE_MAIN_REGULATOR_LOW_VOLTAGE
PWR_CR_MRLVDS |
-#endif
-#if STOP_MODE_LOW_POWER_REGULATOR_LOW_VOLTAG
+# endif
+# if STOP_MODE_LOW_POWER_REGULATOR_LOW_VOLTAG
PWR_CR_LPLVDS |
-#endif
-#if STOP_MODE_FLASH_POWER_DOWN
+# endif
+# if STOP_MODE_FLASH_POWER_DOWN
PWR_CR_FPDS |
-#endif
-#if STOP_MODE_LOW_POWER_DEEPSLEEP
+# endif
+# if STOP_MODE_LOW_POWER_DEEPSLEEP
PWR_CR_LPDS |
-#endif
+# endif
0;
}
+
break;
case PM_STANDBY:
@@ -83,7 +105,7 @@ bool lpm_set(pm_t mode) {
return ret;
}
-void enter_power_mode(pm_t mode) {
+void lpm_standby(pm_t mode) {
#if STM32_HSE_ENABLED
/* Switch to HSI */
RCC->CFGR = (RCC->CFGR & (~STM32_SW_MASK)) | STM32_SW_HSI;
@@ -103,10 +125,10 @@ void enter_power_mode(pm_t mode) {
__WFI();
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
+}
- writePinLow(BLUETOOTH_INT_OUTPUT_PIN);
+void lpm_wakeup_init(void) {
stm32_clock_init();
- writePinHigh(BLUETOOTH_INT_OUTPUT_PIN);
}
void usb_power_connect(void) {}
diff --git a/keyboards/lemokey/common/wireless/lpm_stm32f401.h b/keyboards/lemokey/common/wireless/lpm_stm32f401.h
index 3b25c3d57c..7c3e74d278 100644
--- a/keyboards/lemokey/common/wireless/lpm_stm32f401.h
+++ b/keyboards/lemokey/common/wireless/lpm_stm32f401.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
diff --git a/keyboards/lemokey/common/wireless/lpm_wb32f3g71.c b/keyboards/lemokey/common/wireless/lpm_wb32f3g71.c
new file mode 100644
index 0000000000..12a8a0485e
--- /dev/null
+++ b/keyboards/lemokey/common/wireless/lpm_wb32f3g71.c
@@ -0,0 +1,135 @@
+
+/* Copyright 2024 @ 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
+ * 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 "quantum.h"
+#include "lpm.h"
+
+bool wakeup_from_lpm;
+static pm_t power_mode = PM_RUN;
+
+static const uint32_t pre_lp_code[] = {553863175u, 554459777u, 1208378049u, 4026624001u, 688390415u, 554227969u, 3204472833u, 1198571264u, 1073807360u, 1073808388u,};
+#define PRE_LP() ((void (*)(void))((unsigned int)(pre_lp_code) | 0x01))()
+
+static const uint32_t post_lp_code[] = {553863177u, 554459777u, 1208509121u, 51443856u, 4026550535u, 1745485839u, 3489677954u, 536895496u, 673389632u, 1198578684u, 1073807360u, 536866816u, 1073808388u,};
+#define POST_LP() ((void (*)(void))((unsigned int)(post_lp_code) | 0x01))()
+
+extern void __early_init(void);
+extern void matrix_init_pins(void);
+
+void stop_mode_entry(void);
+
+void lpm_post_enter_low_power(void) {
+ /* USB D+/D- */
+ palSetLineMode(A12, PAL_MODE_INPUT_PULLUP); // why PAL_MODE_INPUT_PULLUP
+ palSetLineMode(A11, PAL_MODE_INPUT_PULLDOWN);
+
+ palSetLineMode(DP_PULLUP_CONTROL_PIN, PAL_MODE_INPUT_PULLDOWN);
+}
+
+void lpm_pre_wakeup(void) {
+ /* USB D+/D- */
+ palSetLineMode(A11, PAL_WB32_OTYPE_PUSHPULL | PAL_WB32_OSPEED_HIGH | PAL_WB32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
+ palSetLineMode(A12, PAL_WB32_OTYPE_PUSHPULL | PAL_WB32_OSPEED_HIGH | PAL_WB32_PUPDR_FLOATING | PAL_MODE_ALTERNATE(10U));
+
+ /* SPI */
+#if (HAL_USE_SPI == TRUE)
+ palSetLineMode(SPI_SCK_PIN, PAL_MODE_ALTERNATE(5));
+ palSetLineMode(SPI_MISO_PIN, PAL_MODE_ALTERNATE(5));
+ palSetLineMode(SPI_MOSI_PIN, PAL_MODE_ALTERNATE(5));
+#endif
+}
+
+bool lpm_set(pm_t mode) {
+ bool ret = true;
+
+ switch (mode) {
+ case PM_SLEEP:
+ /* Wake source: Any interrupt or event */
+ if (power_mode != PM_RUN)
+ ret = false;
+ else
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
+ break;
+
+ case PM_STOP:
+ if (power_mode != PM_RUN) ret = false;
+ break;
+
+ case PM_STANDBY:
+ if (power_mode != PM_RUN)
+ ret = false;
+ else {
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+ }
+ break;
+
+ default:
+ break;
+ }
+ power_mode = mode;
+
+ return ret;
+}
+
+void lpm_standby(pm_t mode) {
+ chSysDisable();
+ wb32_set_main_clock_to_mhsi();
+
+ rtclp_lld_init();
+ stop_mode_entry();
+ chSysEnable();
+}
+
+void lpm_wakeup_init(void) {
+ wakeup_from_lpm = true;
+ __early_init();
+ wakeup_from_lpm = false;
+}
+
+void stop_mode_entry(void) {
+ EXTI->PR = 0x7FFFF;
+ for (uint8_t i = 0; i < 8; i++) {
+ for (uint8_t j = 0; j < 32; j++) {
+ if (NVIC->ISPR[i] & (0x01UL < j)) {
+ NVIC->ICPR[i] = (0x01UL < j);
+ }
+ }
+ }
+ SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk; // Clear Systick IRQ Pending
+
+ /* Clear all bits except DBP and FCLKSD bit */
+ PWR->CR0 &= 0x09U;
+
+ /* STOP LP4 MODE S32KON */
+ PWR->CR0 |= 0x3B004U;
+ PWR->CFGR = 0x3B3;
+
+ PRE_LP();
+
+ /* Set SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+ /* Request Wait For Interrupt */
+ __WFI();
+
+ POST_LP();
+
+ /* Clear SLEEPDEEP bit of Cortex System Control Register */
+ SCB->SCR &= (~SCB_SCR_SLEEPDEEP_Msk);
+
+ lpm_early_wakeup();
+}
diff --git a/keyboards/lemokey/common/wireless/report_buffer.c b/keyboards/lemokey/common/wireless/report_buffer.c
index 317ba8ce1d..a755aa1b28 100644
--- a/keyboards/lemokey/common/wireless/report_buffer.c
+++ b/keyboards/lemokey/common/wireless/report_buffer.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -95,7 +95,6 @@ bool report_buffer_next_inverval(void) {
}
void report_buffer_set_inverval(uint8_t interval) {
- // OG_TRACE("report_buffer_set_inverval: %d\n\r", interval);
report_interval = interval;
}
diff --git a/keyboards/lemokey/common/wireless/report_buffer.h b/keyboards/lemokey/common/wireless/report_buffer.h
index 714959683a..d5e8d22a01 100644
--- a/keyboards/lemokey/common/wireless/report_buffer.h
+++ b/keyboards/lemokey/common/wireless/report_buffer.h
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
diff --git a/keyboards/lemokey/common/wireless/rtc_timer.c b/keyboards/lemokey/common/wireless/rtc_timer.c
index 9a35b9bddb..ed7c389175 100644
--- a/keyboards/lemokey/common/wireless/rtc_timer.c
+++ b/keyboards/lemokey/common/wireless/rtc_timer.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -17,7 +17,6 @@
#include "hal.h"
#if (HAL_USE_RTC)
-
# include "rtc_timer.h"
void rtc_timer_init(void) {
@@ -39,5 +38,4 @@ uint32_t rtc_timer_read_ms(void) {
uint32_t rtc_timer_elapsed_ms(uint32_t last) {
return TIMER_DIFF_32(rtc_timer_read_ms(), last);
}
-
#endif
diff --git a/keyboards/lemokey/common/wireless/rtc_timer.h b/keyboards/lemokey/common/wireless/rtc_timer.h
index cf6dfb5720..cd7e387d10 100644
--- a/keyboards/lemokey/common/wireless/rtc_timer.h
+++ b/keyboards/lemokey/common/wireless/rtc_timer.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
diff --git a/keyboards/lemokey/common/wireless/transport.c b/keyboards/lemokey/common/wireless/transport.c
index 426cd108a5..a5353e42b2 100644
--- a/keyboards/lemokey/common/wireless/transport.c
+++ b/keyboards/lemokey/common/wireless/transport.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -55,7 +55,7 @@ __attribute__((weak)) void bt_transport_enable(bool enable) {
wireless_disconnect();
uint32_t t = timer_read32();
- while (timer_elapsed32(t) < 50) {
+ while (timer_elapsed32(t) < 100) {
wireless_transport.task();
}
// wireless_connect();
@@ -83,7 +83,7 @@ __attribute__((weak)) void p24g_transport_enable(bool enable) {
wireless_disconnect();
uint32_t t = timer_read32();
- while (timer_elapsed32(t) < 50) {
+ while (timer_elapsed32(t) < 100) {
wireless_transport.task();
}
wireless_connect_ex(P24G_INDEX, 0);
@@ -125,9 +125,10 @@ __attribute__((weak)) void usb_transport_enable(bool enable) {
#endif
}
}
-
void set_transport(transport_t new_transport) {
if (transport != new_transport) {
+ indicator_init();
+
if (transport == TRANSPORT_USB || ((transport != TRANSPORT_USB) && wireless_get_state() == WT_CONNECTED)) clear_keyboard();
transport = new_transport;
@@ -212,10 +213,7 @@ static void reinit_led_drvier(void) {
#endif
void transport_changed(transport_t new_transport) {
- kc_printf("transport_changed %d\n\r", new_transport);
- indicator_init();
-
-#if (REINIT_LED_DRIVER)
+#if (REINIT_LED_DRIVER) && !defined(TRANSPORT_SOFT_SWITCH_ENABLE)
reinit_led_drvier();
#endif
@@ -235,6 +233,10 @@ void transport_changed(transport_t new_transport) {
void usb_remote_wakeup(void) {
if (USB_DRIVER.state == USB_SUSPENDED) {
+#if defined(WB32F3G71xx)
+ wait_ms(300);
+ if (!usb_power_connected()) return;
+#endif
while (USB_DRIVER.state == USB_SUSPENDED) {
wireless_pre_task();
if (get_transport() != TRANSPORT_USB) {
@@ -244,7 +246,11 @@ void usb_remote_wakeup(void) {
/* Do this in the suspended state */
suspend_power_down(); // on AVR this deep sleeps for 15ms
/* Remote wakeup */
- if (suspend_wakeup_condition()) {
+ if (suspend_wakeup_condition()
+#ifdef ENCODER_ENABLE
+ || encoder_read()
+#endif
+ ) {
usbWakeupHost(&USB_DRIVER);
wait_ms(300);
#ifdef MOUSEKEY_ENABLE
diff --git a/keyboards/lemokey/common/wireless/transport.h b/keyboards/lemokey/common/wireless/transport.h
index 2dad9c0cca..475fffc958 100644
--- a/keyboards/lemokey/common/wireless/transport.h
+++ b/keyboards/lemokey/common/wireless/transport.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
diff --git a/keyboards/lemokey/common/wireless/wireless.c b/keyboards/lemokey/common/wireless/wireless.c
index eddc538907..944b64a68c 100644
--- a/keyboards/lemokey/common/wireless/wireless.c
+++ b/keyboards/lemokey/common/wireless/wireless.c
@@ -22,7 +22,7 @@
#include "indicator.h"
#include "transport.h"
#include "rtc_timer.h"
-#include "lemokey_wireless_common.h"
+#include "wireless_common.h"
#include "lemokey_task.h"
extern uint8_t pairing_indication;
@@ -90,6 +90,7 @@ static inline bool wireless_event_dequeue(wireless_event_t *event) {
* Bluetooth init.
*/
void wireless_init(void) {
+ kc_printf("wireless_init\r\n");
wireless_state = WT_INITIALIZED;
wireless_event_queue_init();
@@ -233,51 +234,50 @@ static void wireless_enter_connected(uint8_t host_idx) {
clear_keyboard();
/* Enable NKRO since it may be disabled in pin code entry */
-#if defined(NKRO_ENABLE) && defined(WIRELESS_NKRO_ENABLE)
- keymap_config.nkro = nkro.bluetooth;
-#else
+#if defined(NKRO_ENABLE) && !defined(WIRELESS_NKRO_ENABLE)
keymap_config.nkro = false;
#endif
wireless_enter_connected_kb(host_idx);
-#ifdef BAT_LOW_LED_PIN
if (battery_is_empty()) {
indicator_battery_low_enable(true);
}
-#endif
if (wireless_transport.update_bat_level) wireless_transport.update_bat_level(battery_get_percentage());
+ lpm_timer_reset();
}
/* Enters disconnected state. Upon entering this state we perform the following actions:
* - change state to DISCONNECTED
* - set disconnected indication
*/
-static void wireless_enter_disconnected(uint8_t host_idx) {
- kc_printf("wireless_disconnected %d\n\r", host_idx);
+static void wireless_enter_disconnected(uint8_t host_idx, uint8_t reason) {
+ kc_printf("wireless_disconnected %d, %d\n\r", host_idx, reason);
uint8_t previous_state = wireless_state;
led_state = 0;
- led_update_kb((led_t)led_state);
+ if (get_transport() & TRANSPORT_WIRELESS)
+ led_update_kb((led_t)led_state);
wireless_state = WT_DISCONNECTED;
if (previous_state == WT_CONNECTED) {
lpm_timer_reset();
indicator_set(WT_SUSPEND, host_idx);
- } else
+ } else {
indicator_set(wireless_state, host_idx);
+#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
+ }
#ifndef DISABLE_REPORT_BUFFER
report_buffer_init();
#endif
retry = 0;
- wireless_enter_disconnected_kb(host_idx);
-#ifdef BAT_LOW_LED_PIN
+ wireless_enter_disconnected_kb(host_idx, reason);
+
indicator_battery_low_enable(false);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(false);
-#endif
}
/* Enter pin code entry state. */
@@ -291,8 +291,8 @@ static void wireless_enter_bluetooth_pin_code_entry(void) {
/* Exit pin code entry state. */
static void wireless_exit_bluetooth_pin_code_entry(void) {
-#if defined(NKRO_ENABLE)
- keymap_config.nkro = true;
+#if defined(NKRO_ENABLE) || defined(WIRELESS_NKRO_ENABLE)
+ keymap_config.raw = eeconfig_read_keymap();
#endif
pincodeEntry = false;
wireless_exit_bluetooth_pin_code_entry_kb();
@@ -306,26 +306,24 @@ static void wireless_enter_sleep(void) {
kc_printf("wireless_enter_sleep %d\n\r", wireless_state);
led_state = 0;
- if (wireless_state == WT_PARING) {
- wireless_state = WT_SUSPEND;
+#if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE)
+ if (wireless_state == WT_CONNECTED || wireless_state == WT_PARING)
+#endif
+ {
kc_printf("WT_SUSPEND\n\r");
-
+ lpm_timer_reset();
wireless_enter_sleep_kb();
- indicator_set(wireless_state, 0);
-#ifdef BAT_LOW_LED_PIN
+ indicator_set(WT_SUSPEND, 0);
indicator_battery_low_enable(false);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(false);
-#endif
}
+ wireless_state = WT_SUSPEND;
}
__attribute__((weak)) void wireless_enter_reset_kb(uint8_t reason) {}
__attribute__((weak)) void wireless_enter_discoverable_kb(uint8_t host_idx) {}
__attribute__((weak)) void wireless_enter_reconnecting_kb(uint8_t host_idx) {}
__attribute__((weak)) void wireless_enter_connected_kb(uint8_t host_idx) {}
-__attribute__((weak)) void wireless_enter_disconnected_kb(uint8_t host_idx) {}
+__attribute__((weak)) void wireless_enter_disconnected_kb(uint8_t host_idx, uint8_t reason) {}
__attribute__((weak)) void wireless_enter_bluetooth_pin_code_entry_kb(void) {}
__attribute__((weak)) void wireless_exit_bluetooth_pin_code_entry_kb(void) {}
__attribute__((weak)) void wireless_enter_sleep_kb(void) {}
@@ -436,13 +434,7 @@ void wireless_send_extra(report_extra_t *report) {
}
void wireless_low_battery_shutdown(void) {
-#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(false);
-#endif
-#if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(false);
-#endif
-
report_buffer_init();
clear_keyboard(); //
wait_ms(50); // wait a while for bt module to free buffer by sending report
@@ -485,7 +477,7 @@ void wireless_event_task(void) {
wireless_enter_reconnecting(event.params.hostIndex);
break;
case EVT_DISCONNECTED:
- wireless_enter_disconnected(event.params.hostIndex);
+ wireless_enter_disconnected(event.params.hostIndex, event.data);
break;
case EVT_BT_PINCODE_ENTRY:
wireless_enter_bluetooth_pin_code_entry();
@@ -518,7 +510,7 @@ void wireless_task(void) {
report_buffer_task();
#endif
indicator_task();
- lemokey_wireless_common_task();
+ wireless_common_task();
battery_task();
lpm_task();
}
@@ -540,19 +532,12 @@ bool process_record_wireless(uint16_t keycode, keyrecord_t *record) {
if (get_transport() & TRANSPORT_WIRELESS) {
lpm_timer_reset();
-#if defined(BAT_LOW_LED_PIN) || defined(LOW_BAT_IND_INDEX)
if (battery_is_empty() && wireless_get_state() == WT_CONNECTED && record->event.pressed) {
-# if defined(BAT_LOW_LED_PIN)
indicator_battery_low_enable(true);
-# endif
-# if defined(LOW_BAT_IND_INDEX)
- indicator_battery_low_backlit_enable(true);
-# endif
}
-#endif
}
- if (!process_record_lemokey_wireless(keycode, record)) return false;
+ if (!process_record_wireless_common(keycode, record)) return false;
return true;
}
diff --git a/keyboards/lemokey/common/wireless/wireless.h b/keyboards/lemokey/common/wireless/wireless.h
index adfea6e77a..bc73d7d46b 100644
--- a/keyboards/lemokey/common/wireless/wireless.h
+++ b/keyboards/lemokey/common/wireless/wireless.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -84,7 +84,7 @@ void wireless_enter_reset_kb(uint8_t reason);
void wireless_enter_discoverable_kb(uint8_t host_idx);
void wireless_enter_reconnecting_kb(uint8_t host_idx);
void wireless_enter_connected_kb(uint8_t host_idx);
-void wireless_enter_disconnected_kb(uint8_t host_idx);
+void wireless_enter_disconnected_kb(uint8_t host_idx, uint8_t reason);
void wireless_enter_bluetooth_pin_code_entry_kb(void);
void wireless_exit_bluetooth_pin_code_entry_kb(void);
void wireless_enter_sleep_kb(void);
@@ -98,4 +98,4 @@ wt_state_t wireless_get_state(void);
void wireless_low_battery_shutdown(void);
-bool process_record_wireless(uint16_t keycode, keyrecord_t *record);
+bool process_record_wireless_common(uint16_t keycode, keyrecord_t *record);
diff --git a/keyboards/lemokey/common/wireless/wireless.mk b/keyboards/lemokey/common/wireless/wireless.mk
index 2fe1b53621..98cd1952db 100644
--- a/keyboards/lemokey/common/wireless/wireless.mk
+++ b/keyboards/lemokey/common/wireless/wireless.mk
@@ -11,11 +11,18 @@ SRC += \
$(WIRELESS_DIR)/wireless_main.c \
$(WIRELESS_DIR)/transport.c \
$(WIRELESS_DIR)/lpm.c \
- $(WIRELESS_DIR)/lpm_stm32f401.c \
$(WIRELESS_DIR)/battery.c \
$(WIRELESS_DIR)/bat_level_animation.c \
$(WIRELESS_DIR)/rtc_timer.c \
- $(WIRELESS_DIR)/lemokey_wireless_common.c
+ $(WIRELESS_DIR)/wireless_common.c
+
+ifeq ($(strip $(MCU_SERIES)), STM32F4xx)
+SRC += $(WIRELESS_DIR)/lpm_stm32f401.c
+endif
+
+ifeq ($(strip $(MCU_SERIES)), WB32F3G71xx)
+SRC += $(WIRELESS_DIR)/lpm_wb32f3g71.c
+endif
VPATH += $(TOP_DIR)/keyboards/lemokey/$(WIRELESS_DIR)
diff --git a/keyboards/lemokey/common/wireless/lemokey_wireless_common.c b/keyboards/lemokey/common/wireless/wireless_common.c
similarity index 79%
rename from keyboards/lemokey/common/wireless/lemokey_wireless_common.c
rename to keyboards/lemokey/common/wireless/wireless_common.c
index e24c5e1693..dc5daa2bd8 100644
--- a/keyboards/lemokey/common/wireless/lemokey_wireless_common.c
+++ b/keyboards/lemokey/common/wireless/wireless_common.c
@@ -1,4 +1,4 @@
-/* Copyright 2022 @ Keychron (https://www.keychron.com)
+/* Copyright 2022~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
@@ -15,25 +15,25 @@
*/
#include QMK_KEYBOARD_H
-#ifdef LK_WIRELESS_ENABLE
-# include "lkbt51.h"
-# include "wireless.h"
-# include "indicator.h"
-# include "transport.h"
-# include "battery.h"
-# include "bat_level_animation.h"
-# include "lpm.h"
-# include "lemokey_wireless_common.h"
-# include "lemokey_task.h"
-#endif
+
+#include "lkbt51.h"
+#include "wireless.h"
+#include "indicator.h"
+#include "transport.h"
+#include "battery.h"
+#include "bat_level_animation.h"
+#include "lpm.h"
+#include "wireless_common.h"
+#include "lemokey_task.h"
#include "lemokey_common.h"
+#include "config.h"
bool firstDisconnect = true;
static uint32_t pairing_key_timer;
static uint8_t host_idx = 0;
-bool process_record_lemokey_wireless(uint16_t keycode, keyrecord_t *record) {
+bool process_record_wireless_common(uint16_t keycode, keyrecord_t *record) {
static uint8_t host_idx;
switch (keycode) {
@@ -100,7 +100,7 @@ void wireless_enter_reset_kb(uint8_t reason) {
lkbt51_param_init();
}
-void wireless_enter_disconnected_kb(uint8_t host_idx) {
+void wireless_enter_disconnected_kb(uint8_t host_idx, uint8_t reason) {
/* CKBT51 bluetooth module boot time is slower, it enters disconnected after boot,
so we place initialization here. */
if (firstDisconnect && timer_read32() < 1000) {
@@ -110,7 +110,7 @@ void wireless_enter_disconnected_kb(uint8_t host_idx) {
}
}
-void lemokey_wireless_common_task(void) {
+void wireless_common_task(void) {
if (pairing_key_timer) {
if (timer_elapsed32(pairing_key_timer) > 2000) {
pairing_key_timer = 0;
@@ -120,21 +120,24 @@ void lemokey_wireless_common_task(void) {
}
void wireless_pre_task(void) {
- static uint8_t mode = 0;
- static uint32_t time = 0;
+ static uint8_t dip_switch_state = 0;
+ static uint32_t time = 0;
if (time == 0) {
- if ((readPin(BT_MODE_SELECT_PIN) << 1 | readPin(P2P4_MODE_SELECT_PIN)) != mode) {
- mode = readPin(BT_MODE_SELECT_PIN) << 1 | readPin(P2P4_MODE_SELECT_PIN);
- time = timer_read32();
+ uint8_t pins_state = (readPin(BT_MODE_SELECT_PIN) << 1) | readPin(P2P4_MODE_SELECT_PIN);
+ if (pins_state != dip_switch_state) {
+ dip_switch_state = pins_state;
+ time = timer_read32();
}
}
if ((time && timer_elapsed32(time) > 100) || get_transport() == TRANSPORT_NONE) {
- if ((readPin(BT_MODE_SELECT_PIN) << 1 | readPin(P2P4_MODE_SELECT_PIN)) == mode) {
+ uint8_t pins_state = (readPin(BT_MODE_SELECT_PIN) << 1) | readPin(P2P4_MODE_SELECT_PIN);
+
+ if (pins_state == dip_switch_state) {
time = 0;
- switch (mode) {
+ switch (dip_switch_state) {
case 0x01:
set_transport(TRANSPORT_BLUETOOTH);
break;
@@ -148,8 +151,8 @@ void wireless_pre_task(void) {
break;
}
} else {
- mode = readPin(BT_MODE_SELECT_PIN) << 1 | readPin(P2P4_MODE_SELECT_PIN);
- time = timer_read32();
+ dip_switch_state = pins_state;
+ time = timer_read32();
}
}
}
diff --git a/keyboards/lemokey/common/wireless/lemokey_wireless_common.h b/keyboards/lemokey/common/wireless/wireless_common.h
similarity index 74%
rename from keyboards/lemokey/common/wireless/lemokey_wireless_common.h
rename to keyboards/lemokey/common/wireless/wireless_common.h
index 05b51406f7..f092beedb7 100644
--- a/keyboards/lemokey/common/wireless/lemokey_wireless_common.h
+++ b/keyboards/lemokey/common/wireless/wireless_common.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ Keychron (https://www.lemokey.com)
+/* Copyright 2022~2024 @ Keychron (https://www.lemokey.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
@@ -14,13 +14,11 @@
* along with this program. If not, see .
*/
-#include "stdint.h"
-#ifdef VIA_ENABLE
-# include "via.h"
-#endif
+#pragma once
#include "quantum_keycodes.h"
void lkbt51_param_init(void);
-bool process_record_lemokey_wireless(uint16_t keycode, keyrecord_t *record);
-void lemokey_wireless_common_task(void);
+bool process_record_wireless(uint16_t keycode, keyrecord_t *record);
+void wireless_common_task(void);
+void wireless_pre_task(void);
diff --git a/keyboards/lemokey/common/wireless/wireless_config.h b/keyboards/lemokey/common/wireless/wireless_config.h
index e55ad24290..c3539b7018 100644
--- a/keyboards/lemokey/common/wireless/wireless_config.h
+++ b/keyboards/lemokey/common/wireless/wireless_config.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -18,19 +18,6 @@
#include "config.h"
-//
#ifndef BT_HOST_DEVICES_COUNT
# define BT_HOST_DEVICES_COUNT 3
#endif
-
-#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
-#endif
diff --git a/keyboards/lemokey/common/wireless/wireless_event_type.h b/keyboards/lemokey/common/wireless/wireless_event_type.h
index e40f002ed3..57096c5e89 100644
--- a/keyboards/lemokey/common/wireless/wireless_event_type.h
+++ b/keyboards/lemokey/common/wireless/wireless_event_type.h
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -41,4 +41,5 @@ typedef struct {
uint8_t protocol; /* Parameters to EVT_HID_SET_PROTOCOL event */
uint8_t interval; /* Parameters to EVT_CONECTION_INTERVAL event */
} params;
+ uint8_t data;
} wireless_event_t;
diff --git a/keyboards/lemokey/common/wireless/wireless_main.c b/keyboards/lemokey/common/wireless/wireless_main.c
index 62cc1e5756..dd9fd382ef 100644
--- a/keyboards/lemokey/common/wireless/wireless_main.c
+++ b/keyboards/lemokey/common/wireless/wireless_main.c
@@ -1,4 +1,4 @@
-/* Copyright 2023 @ lokher (https://www.keychron.com)
+/* Copyright 2022~2024 @ 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
@@ -20,6 +20,7 @@
#include "factory_test.h"
#include "lemokey_task.h"
+__attribute__((weak)) bool wireless_pre_task_kb(void) { return true; }
__attribute__((weak)) void wireless_pre_task(void) {}
__attribute__((weak)) void wireless_post_task(void) {}
diff --git a/keyboards/lemokey/l1/ansi/config.h b/keyboards/lemokey/l1/ansi/config.h
index 5d3670f241..00707333c0 100644
--- a/keyboards/lemokey/l1/ansi/config.h
+++ b/keyboards/lemokey/l1/ansi/config.h
@@ -47,7 +47,7 @@
/* Indications */
# define CAPS_LOCK_INDEX 47
-# define LOW_BAT_IND_INDEX \
+# define SPACE_KEY_LOW_BAT_IND \
{ 79 }
# define RGB_MATRIX_KEYPRESSES
diff --git a/keyboards/lemokey/l1/config.h b/keyboards/lemokey/l1/config.h
index 7a9c040e48..0f3044cd3a 100644
--- a/keyboards/lemokey/l1/config.h
+++ b/keyboards/lemokey/l1/config.h
@@ -20,6 +20,8 @@
#define ENCODER_DEFAULT_POS 0x3
#define ENCODER_MAP_KEY_DELAY 2
+# define LED_DRIVER_SHUTDOWN_PIN B7
+
#ifdef LK_WIRELESS_ENABLE
/* Hardware configuration */
# define P2P4_MODE_SELECT_PIN A9
@@ -39,13 +41,10 @@
# if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE)
-# define LED_DRIVER_SHUTDOWN_PIN B7
-
-# define BT_HOST_LED_MATRIX_LIST \
+# define BT_INDICATION_LED_LIST \
{ 16, 17, 18 }
-# define P2P4G_HOST_LED_MATRIX_LIST \
- { 19 }
+# define P24G_INDICATION_LED_INDEX 19
# define BAT_LEVEL_LED_LIST \
{ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }
diff --git a/keyboards/lemokey/l1/l1.c b/keyboards/lemokey/l1/l1.c
index 61b4b701d2..4448aa2acd 100644
--- a/keyboards/lemokey/l1/l1.c
+++ b/keyboards/lemokey/l1/l1.c
@@ -23,7 +23,7 @@
#ifdef LK_WIRELESS_ENABLE
# include "lkbt51.h"
# include "wireless.h"
-# include "lemokey_wireless_common.h"
+# include "wireless_common.h"
# include "battery.h"
# include "transport.h"
#endif
diff --git a/keyboards/lemokey/l1/post_rules.mk b/keyboards/lemokey/l1/post_rules.mk
new file mode 100644
index 0000000000..5deb336ff9
--- /dev/null
+++ b/keyboards/lemokey/l1/post_rules.mk
@@ -0,0 +1,2 @@
+include keyboards/lemokey/common/wireless/wireless.mk
+
diff --git a/keyboards/lemokey/l1/rules.mk b/keyboards/lemokey/l1/rules.mk
index c0d03a3047..95cd29f122 100644
--- a/keyboards/lemokey/l1/rules.mk
+++ b/keyboards/lemokey/l1/rules.mk
@@ -1,4 +1,3 @@
-include keyboards/lemokey/common/wireless/wireless.mk
include keyboards/lemokey/common/lemokey_common.mk
VPATH += $(TOP_DIR)/keyboards/lemokey
diff --git a/keyboards/lemokey/l3/config.h b/keyboards/lemokey/l3/config.h
index 69ff92862d..b734f3ed95 100644
--- a/keyboards/lemokey/l3/config.h
+++ b/keyboards/lemokey/l3/config.h
@@ -54,11 +54,10 @@
# define LED_DRIVER_SHUTDOWN_PIN B7
-# define BT_HOST_LED_MATRIX_LIST \
+# define BT_INDICATION_LED_LIST \
{ 17, 18, 19 }
-# define P2P4G_HOST_LED_MATRIX_LIST \
- { 20 }
+# define P24G_INDICATION_LED_INDEX 20
# define BAT_LEVEL_LED_LIST \
{ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 }
diff --git a/keyboards/lemokey/l3/l3.c b/keyboards/lemokey/l3/l3.c
index 5cb7f95fed..e0ee397aa4 100644
--- a/keyboards/lemokey/l3/l3.c
+++ b/keyboards/lemokey/l3/l3.c
@@ -23,7 +23,7 @@
#ifdef LK_WIRELESS_ENABLE
# include "lkbt51.h"
# include "wireless.h"
-# include "lemokey_wireless_common.h"
+# include "wireless_common.h"
# include "battery.h"
# include "transport.h"
#endif
diff --git a/keyboards/lemokey/l3/post_rules.mk b/keyboards/lemokey/l3/post_rules.mk
new file mode 100644
index 0000000000..5deb336ff9
--- /dev/null
+++ b/keyboards/lemokey/l3/post_rules.mk
@@ -0,0 +1,2 @@
+include keyboards/lemokey/common/wireless/wireless.mk
+
diff --git a/keyboards/lemokey/l3/rules.mk b/keyboards/lemokey/l3/rules.mk
index c0d03a3047..95cd29f122 100644
--- a/keyboards/lemokey/l3/rules.mk
+++ b/keyboards/lemokey/l3/rules.mk
@@ -1,4 +1,3 @@
-include keyboards/lemokey/common/wireless/wireless.mk
include keyboards/lemokey/common/lemokey_common.mk
VPATH += $(TOP_DIR)/keyboards/lemokey
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/ansi_encoder.c b/keyboards/lemokey/p1_pro/ansi_encoder/ansi_encoder.c
new file mode 100644
index 0000000000..744a7f2eb3
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/ansi_encoder.c
@@ -0,0 +1,148 @@
+/* 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/>.
+ */
+
+#include "quantum.h"
+
+// clang-format off
+
+#ifdef RGB_MATRIX_ENABLE
+const snled27351_led_t PROGMEM g_snled27351_leds[RGB_MATRIX_LED_COUNT] = {
+/* Refer to snled27351manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, A_15, C_15, B_15},
+ {0, A_14, C_14, B_14},
+ {0, A_13, C_13, B_13},
+ {0, A_12, C_12, B_12},
+ {0, A_11, C_11, B_11},
+ {0, A_10, C_10, B_10},
+ {0, A_9, C_9, B_9},
+ {0, A_8, C_8, B_8},
+ {0, A_7, C_7, B_7},
+ {0, A_6, C_6, B_6},
+ {0, A_5, C_5, B_5},
+ {0, A_4, C_4, B_4},
+ {0, A_3, C_3, B_3},
+ {0, A_2, C_2, B_2},
+
+ {0, G_15, I_15, H_15},
+ {0, G_14, I_14, H_14},
+ {0, G_13, I_13, H_13},
+ {0, G_12, I_12, H_12},
+ {0, G_11, I_11, H_11},
+ {0, G_10, I_10, H_10},
+ {0, G_9, I_9, H_9},
+ {0, G_8, I_8, H_8},
+ {0, G_7, I_7, H_7},
+ {0, G_6, I_6, H_6},
+ {0, G_5, I_5, H_5},
+ {0, G_4, I_4, H_4},
+ {0, G_3, I_3, H_3},
+ {0, G_2, I_2, H_2},
+ {0, G_1, I_1, H_1},
+
+ {0, D_15, F_15, E_15},
+ {0, D_14, F_14, E_14},
+ {0, D_13, F_13, E_13},
+ {0, D_12, F_12, E_12},
+ {0, D_11, F_11, E_11},
+ {0, D_10, F_10, E_10},
+ {0, D_9, F_9, E_9},
+ {0, D_8, F_8, E_8},
+ {0, D_7, F_7, E_7},
+ {0, D_6, F_6, E_6},
+ {0, D_5, F_5, E_5},
+ {0, D_4, F_4, E_4},
+ {0, D_3, F_3, E_3},
+ {0, D_2, F_2, E_2},
+ {0, D_1, F_1, E_1},
+
+ {1, A_15, C_15, B_15},
+ {1, A_14, C_14, B_14},
+ {1, A_13, C_13, B_13},
+ {1, A_12, C_12, B_12},
+ {1, A_11, C_11, B_11},
+ {1, A_10, C_10, B_10},
+ {1, A_9, C_9, B_9},
+ {1, A_8, C_8, B_8},
+ {1, A_7, C_7, B_7},
+ {1, A_6, C_6, B_6},
+ {1, A_5, C_5, B_5},
+ {1, A_4, C_4, B_4},
+ {1, A_2, C_2, B_2},
+ {1, A_1, C_1, B_1},
+
+ {1, G_15, I_15, H_15},
+ {1, G_13, I_13, H_13},
+ {1, G_12, I_12, H_12},
+ {1, G_11, I_11, H_11},
+ {1, G_10, I_10, H_10},
+ {1, G_9, I_9, H_9},
+ {1, G_8, I_8, H_8},
+ {1, G_7, I_7, H_7},
+ {1, G_6, I_6, H_6},
+ {1, G_5, I_5, H_5},
+ {1, G_4, I_4, H_4},
+ {1, G_3, I_3, H_3},
+ {1, G_2, I_2, H_2},
+
+ {1, D_15, F_15, E_15},
+ {1, D_14, F_14, E_14},
+ {1, D_13, F_13, E_13},
+ {1, D_9, F_9, E_9},
+ {1, D_6, F_6, E_6},
+ {1, D_5, F_5, E_5},
+ {1, D_4, F_4, E_4},
+ {1, D_3, F_3, E_3},
+ {1, D_2, F_2, E_2},
+ {1, D_1, F_1, E_1},
+};
+
+#define __ NO_LED
+
+led_config_t g_led_config = {
+ {
+ // Key Matrix to LED Index
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, __ },
+ { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 },
+ { 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 },
+ { 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, __, 56, 57 },
+ { 58, __, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, __},
+ { 71, 72, 73, __, __, __, 74, __, __, 75, 76, 77, 78, 79, 80 },
+ },
+ {
+ // LED Index to Physical Position
+ {0, 0}, {18, 0}, {33, 0}, {48, 0}, {62, 0}, {81, 0}, {95, 0}, {110, 0}, {125, 0}, {143, 0}, {158, 0}, {172, 0}, {187, 0}, {205, 0},
+ {0,15}, {15,15}, {29,15}, {44,15}, {59,15}, {73,15}, {88,15}, {103,15}, {117,15}, {132,15}, {146,15}, {161,15}, {176,15}, {198,15}, {224,15},
+ {4,26}, {22,26}, {37,26}, {51,26}, {66,26}, {81,26}, {95,26}, {110,26}, {125,26}, {139,26}, {154,26}, {168,26}, {183,26}, {201,26}, {224,26},
+ {6,38}, {26,38}, {40,38}, {55,38}, {70,38}, {84,38}, {99,38}, {114,38}, {128,38}, {143,38}, {158,38}, {172,38}, {196,38}, {224,38},
+ {8,49}, {33,49}, {48,49}, {62,49}, {77,49}, {92,49}, {106,49}, {121,49}, {136,49}, {150,49}, {165,49}, {185,49}, {209,52},
+ {2,61}, {20,61}, {38,61}, {94,61}, {147,61}, {161,61}, {176,61}, {195,64}, {209,64}, {224,64},
+ },
+ {
+ // RGB LED Index to Flag
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ }
+};
+#endif
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/config.h b/keyboards/lemokey/p1_pro/ansi_encoder/config.h
new file mode 100644
index 0000000000..cc1ec118bf
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/config.h
@@ -0,0 +1,57 @@
+/* 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 .
+ */
+
+#pragma once
+
+#ifdef RGB_MATRIX_ENABLE
+/* RGB Matrix driver configuration */
+# define DRIVER_COUNT 2
+# define RGB_MATRIX_LED_COUNT 81
+
+# define SPI_SCK_PIN A5
+# define SPI_MISO_PIN A6
+# define SPI_MOSI_PIN A7
+
+# define DRIVER_CS_PINS \
+ { B15, C6 }
+# define SNLED23751_SPI_DIVISOR 16
+# define SPI_DRIVER SPIDQ
+
+/* Scan phase of led driver set as MSKPHASE_9CHANNEL(defined as 0x03 in CKLED2001.h) */
+# define SNLED27351_PHASE_CHANNEL MSKPHASE_9CHANNEL
+
+/* Set LED driver current */
+# define SNLED27351_CURRENT_TUNE \
+ { 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C }
+
+/* Set to infinit, which is use in USB mode by default */
+# define RGB_MATRIX_TIMEOUT RGB_MATRIX_TIMEOUT_INFINITE
+
+/* Allow shutdown of led driver to save power */
+# define RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE
+/* Turn off backlight on low brightness to save power */
+# define RGB_MATRIX_BRIGHTNESS_TURN_OFF_VAL 32
+
+/* Caps lock indicating led */
+# define CAPS_LOCK_INDEX 44
+# define DIM_CAPS_LOCK
+# define SPACE_KEY_LOW_BAT_IND { 74 }
+# define WINLOCK_LED_LIST { 72 }
+
+# define RGB_MATRIX_KEYPRESSES
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+
+#endif
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/info.json b/keyboards/lemokey/p1_pro/ansi_encoder/info.json
new file mode 100644
index 0000000000..bfb685c1d3
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/info.json
@@ -0,0 +1,99 @@
+{
+ "usb": {
+ "pid": "0x0303",
+ "device_version": "1.0.1"
+ },
+ "layouts": {
+ "LAYOUT_ansi_82": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1.25, "y": 0},
+ {"matrix": [0, 2], "x": 2.25, "y": 0},
+ {"matrix": [0, 3], "x": 3.25, "y": 0},
+ {"matrix": [0, 4], "x": 4.25, "y": 0},
+ {"matrix": [0, 5], "x": 5.5, "y": 0},
+ {"matrix": [0, 6], "x": 6.5, "y": 0},
+ {"matrix": [0, 7], "x": 7.5, "y": 0},
+ {"matrix": [0, 8], "x": 8.5, "y": 0},
+ {"matrix": [0, 9], "x": 9.75, "y": 0},
+ {"matrix": [0, 10], "x": 10.75, "y": 0},
+ {"matrix": [0, 11], "x": 11.75, "y": 0},
+ {"matrix": [0, 12], "x": 12.75, "y": 0},
+ {"matrix": [0, 13], "x": 14, "y": 0},
+ {"matrix": [0, 14], "x": 15.25, "y": 0},
+
+ {"matrix": [1, 0], "x": 0, "y": 1.25},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.25},
+ {"matrix": [1, 3], "x": 3, "y": 1.25},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [1, 5], "x": 5, "y": 1.25},
+ {"matrix": [1, 6], "x": 6, "y": 1.25},
+ {"matrix": [1, 7], "x": 7, "y": 1.25},
+ {"matrix": [1, 8], "x": 8, "y": 1.25},
+ {"matrix": [1, 9], "x": 9, "y": 1.25},
+ {"matrix": [1, 10], "x": 10, "y": 1.25},
+ {"matrix": [1, 11], "x": 11, "y": 1.25},
+ {"matrix": [1, 12], "x": 12, "y": 1.25},
+ {"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
+ {"matrix": [1, 14], "x": 15.25, "y": 1.25},
+
+ {"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
+ {"matrix": [2, 1], "x": 1.5, "y": 2.25},
+ {"matrix": [2, 2], "x": 2.5, "y": 2.25},
+ {"matrix": [2, 3], "x": 3.5, "y": 2.25},
+ {"matrix": [2, 4], "x": 4.5, "y": 2.25},
+ {"matrix": [2, 5], "x": 5.5, "y": 2.25},
+ {"matrix": [2, 6], "x": 6.5, "y": 2.25},
+ {"matrix": [2, 7], "x": 7.5, "y": 2.25},
+ {"matrix": [2, 8], "x": 8.5, "y": 2.25},
+ {"matrix": [2, 9], "x": 9.5, "y": 2.25},
+ {"matrix": [2, 10], "x": 10.5, "y": 2.25},
+ {"matrix": [2, 11], "x": 11.5, "y": 2.25},
+ {"matrix": [2, 12], "x": 12.5, "y": 2.25},
+ {"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
+ {"matrix": [2, 14], "x": 15.25, "y": 2.25},
+
+ {"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
+ {"matrix": [3, 1], "x": 1.75, "y": 3.25},
+ {"matrix": [3, 2], "x": 2.75, "y": 3.25},
+ {"matrix": [3, 3], "x": 3.75, "y": 3.25},
+ {"matrix": [3, 4], "x": 4.75, "y": 3.25},
+ {"matrix": [3, 5], "x": 5.75, "y": 3.25},
+ {"matrix": [3, 6], "x": 6.75, "y": 3.25},
+ {"matrix": [3, 7], "x": 7.75, "y": 3.25},
+ {"matrix": [3, 8], "x": 8.75, "y": 3.25},
+ {"matrix": [3, 9], "x": 9.75, "y": 3.25},
+ {"matrix": [3, 10], "x": 10.75, "y": 3.25},
+ {"matrix": [3, 11], "x": 11.75, "y": 3.25},
+ {"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
+ {"matrix": [3, 14], "x": 15.25, "y": 3.25},
+
+ {"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
+ {"matrix": [4, 2], "x": 2.25, "y": 4.25},
+ {"matrix": [4, 3], "x": 3.25, "y": 4.25},
+ {"matrix": [4, 4], "x": 4.25, "y": 4.25},
+ {"matrix": [4, 5], "x": 5.25, "y": 4.25},
+ {"matrix": [4, 6], "x": 6.25, "y": 4.25},
+ {"matrix": [4, 7], "x": 7.25, "y": 4.25},
+ {"matrix": [4, 8], "x": 8.25, "y": 4.25},
+ {"matrix": [4, 9], "x": 9.25, "y": 4.25},
+ {"matrix": [4, 10], "x": 10.25, "y": 4.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4.25},
+ {"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
+ {"matrix": [4, 13], "x": 14.25, "y": 4.5},
+
+ {"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 6], "x": 3.75, "y": 5.25, "w": 6.25},
+ {"matrix": [5, 9], "x": 10, "y": 5.25},
+ {"matrix": [5, 10], "x": 11, "y": 5.25},
+ {"matrix": [5, 11], "x": 12, "y": 5.25},
+ {"matrix": [5, 12], "x": 13.25, "y": 5.5},
+ {"matrix": [5, 13], "x": 14.25, "y": 5.5},
+ {"matrix": [5, 14], "x": 15.25, "y": 5.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/default/keymap.c b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/default/keymap.c
new file mode 100644
index 0000000000..2973f01c5c
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/default/keymap.c
@@ -0,0 +1,77 @@
+/* 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 .
+ */
+
+#include QMK_KEYBOARD_H
+#include "lemokey_common.h"
+
+// clang-format off
+enum layers {
+ BASE,
+ FN,
+ L2,
+ L3,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_ansi_82(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [FN] = LAYOUT_ansi_82(
+ _______, KC_BRID, KC_BRIU, KC_TASK, KC_FILE, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, RGB_TOG,
+ _______, BT_HST1, BT_HST2, BT_HST3, P2P4G, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
+ RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, BAT_LVL, NK_TOGG, _______, _______, _______, _______, _______, _______,
+ _______, GU_TOGG, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L2] = LAYOUT_ansi_82(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L3] = LAYOUT_ansi_82(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+
+};
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
+ [BASE] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [FN] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
+ [L2] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [L3] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)}
+};
+#endif
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if(!process_record_lemokey_common(keycode, record)) {
+ return false;
+ }
+ return true;
+}
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/keymap.c b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/keymap.c
new file mode 100644
index 0000000000..2973f01c5c
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/keymap.c
@@ -0,0 +1,77 @@
+/* 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 .
+ */
+
+#include QMK_KEYBOARD_H
+#include "lemokey_common.h"
+
+// clang-format off
+enum layers {
+ BASE,
+ FN,
+ L2,
+ L3,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_ansi_82(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [FN] = LAYOUT_ansi_82(
+ _______, KC_BRID, KC_BRIU, KC_TASK, KC_FILE, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, RGB_TOG,
+ _______, BT_HST1, BT_HST2, BT_HST3, P2P4G, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
+ RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, BAT_LVL, NK_TOGG, _______, _______, _______, _______, _______, _______,
+ _______, GU_TOGG, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L2] = LAYOUT_ansi_82(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L3] = LAYOUT_ansi_82(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+
+};
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
+ [BASE] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [FN] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
+ [L2] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [L3] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)}
+};
+#endif
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if(!process_record_lemokey_common(keycode, record)) {
+ return false;
+ }
+ return true;
+}
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/rules.mk b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/lemokey/p1_pro/ansi_encoder/rules.mk b/keyboards/lemokey/p1_pro/ansi_encoder/rules.mk
new file mode 100644
index 0000000000..6e7633bfe0
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/ansi_encoder/rules.mk
@@ -0,0 +1 @@
+# This file intentionally left blank
diff --git a/keyboards/lemokey/p1_pro/config.h b/keyboards/lemokey/p1_pro/config.h
new file mode 100644
index 0000000000..de2baeb507
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/config.h
@@ -0,0 +1,110 @@
+/* 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 .
+ */
+
+#pragma once
+
+/* Encoder Configuration */
+#define ENCODER_DEFAULT_POS 0x3
+#define ENCODER_MAP_KEY_DELAY 2
+
+/* I2C Driver Configuration */
+#define I2C1_SCL_PIN B8
+#define I2C1_SDA_PIN B9
+#define I2C1_CLOCK_SPEED 400000
+#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
+
+/* EEPROM Driver Configuration */
+#define EXTERNAL_EEPROM_BYTE_COUNT 2048
+#define EXTERNAL_EEPROM_PAGE_SIZE 32
+#define EXTERNAL_EEPROM_WRITE_TIME 3
+
+/* User used eeprom */
+#define I2C1_OPMODE OPMODE_I2C
+#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS 0b10100010
+#define KEYCODE_BUFFER_ENABLE
+
+#define LED_DRIVER_SHUTDOWN_PIN B14
+
+/* Hold Fn+Win to lock Win key */
+#define WIN_LOCK_HOLD_TIME 3000
+
+/* Firmware Version for Via */
+#define VIA_FIRMWARE_VERSION 0x00000001
+
+#ifdef LK_WIRELESS_ENABLE
+/* Hardware configuration */
+# define WT_DRIVER SPIDQ
+
+# define P2P4_MODE_SELECT_PIN C11
+# define BT_MODE_SELECT_PIN C13
+
+# define LKBT51_RESET_PIN C4
+# define LKBT51_INT_INPUT_PIN B1
+# define BLUETOOTH_INT_OUTPUT_PIN A4
+
+# define USB_POWER_SENSE_PIN B0
+# define USB_POWER_CONNECTED_LEVEL 0
+
+# define BAT_CHARGING_PIN C10
+# define BAT_CHARGING_LEVEL 0
+
+# define BAT_LOW_LED_PIN C5
+# define BAT_LOW_LED_PIN_ON_STATE 1
+
+# define DP_PULLUP_CONTROL_PIN C6
+
+# define BT_HOST_DEVICES_COUNT 3
+
+# if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE)
+
+# define BT_INDICATION_LED_LIST \
+ { 15, 16, 17 }
+
+# define P24G_INDICATION_LED_INDEX 18
+
+# define BAT_LEVEL_LED_LIST \
+ { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }
+
+/* Backlit disable timeout when keyboard is disconnected(unit: second) */
+# define DISCONNECTED_BACKLIGHT_DISABLE_TIMEOUT 40
+
+/* Backlit disable timeout when keyboard is connected(unit: second) */
+# define CONNECTED_BACKLIGHT_DISABLE_TIMEOUT 600
+
+/* Reinit LED driver on tranport changed */
+# define REINIT_LED_DRIVER 1
+
+# endif
+
+/* Keep USB connection in blueooth mode */
+# define KEEP_USB_CONNECTION_IN_WIRELESS_MODE
+
+/* Enable bluetooth NKRO */
+# define WIRELESS_NKRO_ENABLE
+
+/* Raw hid command for factory test and bluetooth DFU */
+# define RAW_HID_CMD 0xAA ... 0xAB
+#else
+/* Raw hid command for factory test */
+# define RAW_HID_CMD 0xAB
+#endif
+
+/* Factory test keys */
+#define FN_KEY_1 MO(1)
+#define FN_KEY_2 MO(3)
+#define FN_BL_TRIG_KEY KC_END
+
+#define MATRIX_IO_DELAY 10
diff --git a/keyboards/lemokey/p1_pro/halconf.h b/keyboards/lemokey/p1_pro/halconf.h
new file mode 100644
index 0000000000..f8f1a2bfaf
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/halconf.h
@@ -0,0 +1,32 @@
+/* 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 .
+ */
+
+#pragma once
+
+#define _CHIBIOS_HAL_CONF_VER_8_0_
+
+#define HAL_USE_SPI TRUE
+#define HAL_USE_I2C TRUE
+
+#ifdef LK_WIRELESS_ENABLE
+# define HAL_USE_RTC TRUE
+#endif
+
+#if defined(LK_WIRELESS_ENABLE) || defined(ENCODER_ENABLE)
+# define PAL_USE_CALLBACKS TRUE
+#endif
+
+#include_next
diff --git a/keyboards/lemokey/p1_pro/info.json b/keyboards/lemokey/p1_pro/info.json
new file mode 100644
index 0000000000..1b50f4d371
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/info.json
@@ -0,0 +1,73 @@
+{
+ "keyboard_name": "Lemokey P1 Pro",
+ "manufacturer": "Keychron",
+ "url": "https://github.com/Keychron",
+ "maintainer": "Keychron",
+ "processor": "WB32F3G71",
+ "bootloader": "wb32-dfu",
+ "usb": {
+ "vid": "0x362D"
+ },
+ "features": {
+ "bootmagic": true,
+ "extrakey": true,
+ "mousekey": true,
+ "encoder": true,
+ "encoder_map": true,
+ "nkro": true,
+ "rgb_matrix": true,
+ "raw": true,
+ "send_string": true
+ },
+ "matrix_pins": {
+ "cols": ["C14", "C15", "C2", "C3", "A0", "A1", "A2", "A3", "B10", "B12", "B13", "C7", "C8", "C9", "A10"],
+ "rows": ["C12", "D2", "B3", "B4", "B5", "B6"]
+ },
+ "diode_direction": "ROW2COL",
+ "encoder": {
+ "rotary": [
+ {"pin_a": "A8", "pin_b": "A9"}
+ ]
+ },
+ "indicators": {
+ "caps_lock": "C1",
+ "on_state": 1
+ },
+ "rgb_matrix": {
+ "driver": "snled27351_spi",
+ "sleep": true,
+ "animations": {
+ "band_spiral_val": true,
+ "breathing": true,
+ "cycle_all": true,
+ "cycle_left_right": true,
+ "cycle_out_in": true,
+ "cycle_out_in_dual": true,
+ "cycle_pinwheel": true,
+ "cycle_spiral": true,
+ "cycle_up_down": true,
+ "digital_rain": true,
+ "dual_beacon": true,
+ "jellybean_raindrops": true,
+ "pixel_rain": true,
+ "rainbow_beacon": true,
+ "rainbow_moving_chevron": true,
+ "solid_reactive_multinexus": true,
+ "solid_reactive_multiwide": true,
+ "solid_reactive_simple": true,
+ "solid_splash": true,
+ "splash": true,
+ "typing_heatmap": true
+ }
+ },
+ "dynamic_keymap": {
+ "layer_count": 4
+ },
+ "eeprom": {
+ "driver": "i2c"
+ },
+ "build": {
+ "debounce_type": "sym_eager_pk"
+ },
+ "debounce": 20
+}
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/config.h b/keyboards/lemokey/p1_pro/iso_encoder/config.h
new file mode 100644
index 0000000000..60aba266bd
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/config.h
@@ -0,0 +1,57 @@
+/* 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 .
+ */
+
+#pragma once
+
+#ifdef RGB_MATRIX_ENABLE
+/* RGB Matrix driver configuration */
+# define DRIVER_COUNT 2
+# define RGB_MATRIX_LED_COUNT 82
+
+# define SPI_SCK_PIN A5
+# define SPI_MISO_PIN A6
+# define SPI_MOSI_PIN A7
+
+# define DRIVER_CS_PINS \
+ { B15, C6 }
+# define SNLED23751_SPI_DIVISOR 16
+# define SPI_DRIVER SPIDQ
+
+/* Scan phase of led driver set as MSKPHASE_9CHANNEL(defined as 0x03 in CKLED2001.h) */
+# define SNLED27351_PHASE_CHANNEL MSKPHASE_9CHANNEL
+
+/* Set LED driver current */
+# define SNLED27351_CURRENT_TUNE \
+ { 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C }
+
+/* Set to infinit, which is use in USB mode by default */
+# define RGB_MATRIX_TIMEOUT RGB_MATRIX_TIMEOUT_INFINITE
+
+/* Allow shutdown of led driver to save power */
+# define RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE
+/* Turn off backlight on low brightness to save power */
+# define RGB_MATRIX_BRIGHTNESS_TURN_OFF_VAL 32
+
+/* Caps lock indicating led */
+# define CAPS_LOCK_INDEX 44
+# define DIM_CAPS_LOCK
+# define SPACE_KEY_LOW_BAT_IND { 75 }
+# define WINLOCK_LED_LIST { 73 }
+
+# define RGB_MATRIX_KEYPRESSES
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+
+#endif
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/info.json b/keyboards/lemokey/p1_pro/iso_encoder/info.json
new file mode 100644
index 0000000000..414d9f808a
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/info.json
@@ -0,0 +1,100 @@
+{
+ "usb": {
+ "pid": "0x0304",
+ "device_version": "1.0.2"
+ },
+ "layouts": {
+ "LAYOUT_iso_83": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0},
+ {"matrix": [0, 1], "x": 1.25, "y": 0},
+ {"matrix": [0, 2], "x": 2.25, "y": 0},
+ {"matrix": [0, 3], "x": 3.25, "y": 0},
+ {"matrix": [0, 4], "x": 4.25, "y": 0},
+ {"matrix": [0, 5], "x": 5.5, "y": 0},
+ {"matrix": [0, 6], "x": 6.5, "y": 0},
+ {"matrix": [0, 7], "x": 7.5, "y": 0},
+ {"matrix": [0, 8], "x": 8.5, "y": 0},
+ {"matrix": [0, 9], "x": 9.75, "y": 0},
+ {"matrix": [0, 10], "x": 10.75, "y": 0},
+ {"matrix": [0, 11], "x": 11.75, "y": 0},
+ {"matrix": [0, 12], "x": 12.75, "y": 0},
+ {"matrix": [0, 13], "x": 14, "y": 0},
+ {"matrix": [0, 14], "x": 15.25, "y": 0},
+
+ {"matrix": [1, 0], "x": 0, "y": 1.25},
+ {"matrix": [1, 1], "x": 1, "y": 1.25},
+ {"matrix": [1, 2], "x": 2, "y": 1.25},
+ {"matrix": [1, 3], "x": 3, "y": 1.25},
+ {"matrix": [1, 4], "x": 4, "y": 1.25},
+ {"matrix": [1, 5], "x": 5, "y": 1.25},
+ {"matrix": [1, 6], "x": 6, "y": 1.25},
+ {"matrix": [1, 7], "x": 7, "y": 1.25},
+ {"matrix": [1, 8], "x": 8, "y": 1.25},
+ {"matrix": [1, 9], "x": 9, "y": 1.25},
+ {"matrix": [1, 10], "x": 10, "y": 1.25},
+ {"matrix": [1, 11], "x": 11, "y": 1.25},
+ {"matrix": [1, 12], "x": 12, "y": 1.25},
+ {"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2},
+ {"matrix": [1, 14], "x": 15.25, "y": 1.25},
+
+ {"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
+ {"matrix": [2, 1], "x": 1.5, "y": 2.25},
+ {"matrix": [2, 2], "x": 2.5, "y": 2.25},
+ {"matrix": [2, 3], "x": 3.5, "y": 2.25},
+ {"matrix": [2, 4], "x": 4.5, "y": 2.25},
+ {"matrix": [2, 5], "x": 5.5, "y": 2.25},
+ {"matrix": [2, 6], "x": 6.5, "y": 2.25},
+ {"matrix": [2, 7], "x": 7.5, "y": 2.25},
+ {"matrix": [2, 8], "x": 8.5, "y": 2.25},
+ {"matrix": [2, 9], "x": 9.5, "y": 2.25},
+ {"matrix": [2, 10], "x": 10.5, "y": 2.25},
+ {"matrix": [2, 11], "x": 11.5, "y": 2.25},
+ {"matrix": [2, 12], "x": 12.5, "y": 2.25},
+ {"matrix": [2, 14], "x": 15.25, "y": 2.25},
+
+ {"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
+ {"matrix": [3, 1], "x": 1.75, "y": 3.25},
+ {"matrix": [3, 2], "x": 2.75, "y": 3.25},
+ {"matrix": [3, 3], "x": 3.75, "y": 3.25},
+ {"matrix": [3, 4], "x": 4.75, "y": 3.25},
+ {"matrix": [3, 5], "x": 5.75, "y": 3.25},
+ {"matrix": [3, 6], "x": 6.75, "y": 3.25},
+ {"matrix": [3, 7], "x": 7.75, "y": 3.25},
+ {"matrix": [3, 8], "x": 8.75, "y": 3.25},
+ {"matrix": [3, 9], "x": 9.75, "y": 3.25},
+ {"matrix": [3, 10], "x": 10.75, "y": 3.25},
+ {"matrix": [3, 11], "x": 11.75, "y": 3.25},
+ {"matrix": [3, 13], "x": 12.75, "y": 3.25},
+ {"matrix": [2, 13], "x": 13.75, "y": 2.25, "w": 1.25, "h": 2},
+ {"matrix": [3, 14], "x": 15.25, "y": 3.25},
+
+ {"matrix": [4, 0], "x": 0, "y": 4.25, "w": 1.25},
+ {"matrix": [4, 1], "x": 1.25, "y": 4.25},
+ {"matrix": [4, 2], "x": 2.25, "y": 4.25},
+ {"matrix": [4, 3], "x": 3.25, "y": 4.25},
+ {"matrix": [4, 4], "x": 4.25, "y": 4.25},
+ {"matrix": [4, 5], "x": 5.25, "y": 4.25},
+ {"matrix": [4, 6], "x": 6.25, "y": 4.25},
+ {"matrix": [4, 7], "x": 7.25, "y": 4.25},
+ {"matrix": [4, 8], "x": 8.25, "y": 4.25},
+ {"matrix": [4, 9], "x": 9.25, "y": 4.25},
+ {"matrix": [4, 10], "x": 10.25, "y": 4.25},
+ {"matrix": [4, 11], "x": 11.25, "y": 4.25},
+ {"matrix": [4, 12], "x": 12.25, "y": 4.25, "w": 1.75},
+ {"matrix": [4, 13], "x": 14.25, "y": 4.5},
+
+ {"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
+ {"matrix": [5, 6], "x": 3.75, "y": 5.25, "w": 6.25},
+ {"matrix": [5, 9], "x": 10, "y": 5.25},
+ {"matrix": [5, 10], "x": 11, "y": 5.25},
+ {"matrix": [5, 11], "x": 12, "y": 5.25},
+ {"matrix": [5, 12], "x": 13.25, "y": 5.5},
+ {"matrix": [5, 13], "x": 14.25, "y": 5.5},
+ {"matrix": [5, 14], "x": 15.25, "y": 5.5}
+ ]
+ }
+ }
+}
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/iso_encoder.c b/keyboards/lemokey/p1_pro/iso_encoder/iso_encoder.c
new file mode 100644
index 0000000000..0fccce8242
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/iso_encoder.c
@@ -0,0 +1,149 @@
+/* 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/>.
+ */
+
+#include "quantum.h"
+
+// clang-format off
+
+#ifdef RGB_MATRIX_ENABLE
+const snled27351_led_t PROGMEM g_snled27351_leds[RGB_MATRIX_LED_COUNT] = {
+/* Refer to snled27351manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, A_15, C_15, B_15},
+ {0, A_14, C_14, B_14},
+ {0, A_13, C_13, B_13},
+ {0, A_12, C_12, B_12},
+ {0, A_11, C_11, B_11},
+ {0, A_10, C_10, B_10},
+ {0, A_9, C_9, B_9},
+ {0, A_8, C_8, B_8},
+ {0, A_7, C_7, B_7},
+ {0, A_6, C_6, B_6},
+ {0, A_5, C_5, B_5},
+ {0, A_4, C_4, B_4},
+ {0, A_3, C_3, B_3},
+ {0, A_2, C_2, B_2},
+
+ {0, G_15, I_15, H_15},
+ {0, G_14, I_14, H_14},
+ {0, G_13, I_13, H_13},
+ {0, G_12, I_12, H_12},
+ {0, G_11, I_11, H_11},
+ {0, G_10, I_10, H_10},
+ {0, G_9, I_9, H_9},
+ {0, G_8, I_8, H_8},
+ {0, G_7, I_7, H_7},
+ {0, G_6, I_6, H_6},
+ {0, G_5, I_5, H_5},
+ {0, G_4, I_4, H_4},
+ {0, G_3, I_3, H_3},
+ {0, G_2, I_2, H_2},
+ {0, G_1, I_1, H_1},
+
+ {0, D_15, F_15, E_15},
+ {0, D_14, F_14, E_14},
+ {0, D_13, F_13, E_13},
+ {0, D_12, F_12, E_12},
+ {0, D_11, F_11, E_11},
+ {0, D_10, F_10, E_10},
+ {0, D_9, F_9, E_9},
+ {0, D_8, F_8, E_8},
+ {0, D_7, F_7, E_7},
+ {0, D_6, F_6, E_6},
+ {0, D_5, F_5, E_5},
+ {0, D_4, F_4, E_4},
+ {0, D_3, F_3, E_3},
+ {0, D_2, F_2, E_2},
+ {0, D_1, F_1, E_1},
+
+ {1, A_15, C_15, B_15},
+ {1, A_14, C_14, B_14},
+ {1, A_13, C_13, B_13},
+ {1, A_12, C_12, B_12},
+ {1, A_11, C_11, B_11},
+ {1, A_10, C_10, B_10},
+ {1, A_9, C_9, B_9},
+ {1, A_8, C_8, B_8},
+ {1, A_7, C_7, B_7},
+ {1, A_6, C_6, B_6},
+ {1, A_5, C_5, B_5},
+ {1, A_4, C_4, B_4},
+ {1, A_2, C_2, B_2},
+ {1, A_1, C_1, B_1},
+
+ {1, G_15, I_15, H_15},
+ {1, G_14, I_14, H_14},
+ {1, G_13, I_13, H_13},
+ {1, G_12, I_12, H_12},
+ {1, G_11, I_11, H_11},
+ {1, G_10, I_10, H_10},
+ {1, G_9, I_9, H_9},
+ {1, G_8, I_8, H_8},
+ {1, G_7, I_7, H_7},
+ {1, G_6, I_6, H_6},
+ {1, G_5, I_5, H_5},
+ {1, G_4, I_4, H_4},
+ {1, G_3, I_3, H_3},
+ {1, G_2, I_2, H_2},
+
+ {1, D_15, F_15, E_15},
+ {1, D_14, F_14, E_14},
+ {1, D_13, F_13, E_13},
+ {1, D_9, F_9, E_9},
+ {1, D_6, F_6, E_6},
+ {1, D_5, F_5, E_5},
+ {1, D_4, F_4, E_4},
+ {1, D_3, F_3, E_3},
+ {1, D_2, F_2, E_2},
+ {1, D_1, F_1, E_1},
+};
+
+#define __ NO_LED
+
+led_config_t g_led_config = {
+ {
+ // Key Matrix to LED Index
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, __ },
+ { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 },
+ { 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43 },
+ { 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, __, 56, 57 },
+ { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, __ },
+ { 72, 73, 74, __, __, __, 75, __, __, 76, 77, 78, 79, 80, 81 },
+ },
+ {
+ // LED Index to Physical Position
+ {0, 0}, {18, 0}, {33, 0}, {48, 0}, {62, 0}, {81, 0}, {95, 0}, {110, 0}, {125, 0}, {143, 0}, {158, 0}, {172, 0}, {187, 0}, {205, 0},
+ {0,15}, {15,15}, {29,15}, {44,15}, {59,15}, {73,15}, {88,15}, {103,15}, {117,15}, {132,15}, {146,15}, {161,15}, {176,15}, {201,15}, {224,15},
+ {4,26}, {22,26}, {37,26}, {51,26}, {66,26}, {81,26}, {95,26}, {110,26}, {125,26}, {139,26}, {154,26}, {168,26}, {183,26}, {201,30}, {224,26},
+ {6,38}, {26,38}, {40,38}, {55,38}, {70,38}, {84,38}, {99,38}, {114,38}, {128,38}, {143,38}, {158,38}, {172,38}, {190,38}, {224,38},
+ {2,49}, {18,49}, {33,49}, {48,49}, {62,49}, {77,49}, {92,49}, {106,49}, {121,49}, {136,49}, {150,49}, {165,49}, {190,49}, {209,52},
+ {2,61}, {20,61}, {38,61}, {94,61}, {147,61}, {161,61}, {176,61}, {195,64}, {209,64}, {224,64},
+ },
+ {
+ // RGB LED Index to Flag
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ }
+};
+#endif
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/keymaps/default/keymap.c b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/default/keymap.c
new file mode 100644
index 0000000000..1fbbfceaa2
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/default/keymap.c
@@ -0,0 +1,77 @@
+/* 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 .
+ */
+
+#include QMK_KEYBOARD_H
+#include "lemokey_common.h"
+
+// clang-format off
+enum layers {
+ BASE,
+ FN,
+ L2,
+ L3,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_iso_83(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_PGUP,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [FN] = LAYOUT_iso_83(
+ _______, KC_BRID, KC_BRIU, KC_TASK, KC_FILE, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, RGB_TOG,
+ _______, BT_HST1, BT_HST2, BT_HST3, P2P4G, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
+ RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, BAT_LVL, NK_TOGG, _______, _______, _______, _______, _______, _______,
+ _______, GU_TOGG, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L2] = LAYOUT_iso_83(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L3] = LAYOUT_iso_83(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+
+};
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
+ [BASE] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [FN] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
+ [L2] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [L3] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)}
+};
+#endif
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if(!process_record_lemokey_common(keycode, record)) {
+ return false;
+ }
+ return true;
+}
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/keymap.c b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/keymap.c
new file mode 100644
index 0000000000..1fbbfceaa2
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/keymap.c
@@ -0,0 +1,77 @@
+/* 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 .
+ */
+
+#include QMK_KEYBOARD_H
+#include "lemokey_common.h"
+
+// clang-format off
+enum layers {
+ BASE,
+ FN,
+ L2,
+ L3,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [BASE] = LAYOUT_iso_83(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_MUTE,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_PGUP,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ [FN] = LAYOUT_iso_83(
+ _______, KC_BRID, KC_BRIU, KC_TASK, KC_FILE, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, RGB_TOG,
+ _______, BT_HST1, BT_HST2, BT_HST3, P2P4G, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_END,
+ RGB_TOG, RGB_MOD, RGB_VAI, RGB_HUI, RGB_SAI, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, RGB_RMOD, RGB_VAD, RGB_HUD, RGB_SAD, RGB_SPD, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, BAT_LVL, NK_TOGG, _______, _______, _______, _______, _______, _______,
+ _______, GU_TOGG, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L2] = LAYOUT_iso_83(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [L3] = LAYOUT_iso_83(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
+
+};
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
+ [BASE] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [FN] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
+ [L2] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [L3] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)}
+};
+#endif
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ if(!process_record_lemokey_common(keycode, record)) {
+ return false;
+ }
+ return true;
+}
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/rules.mk b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/rules.mk
new file mode 100644
index 0000000000..1e5b99807c
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/lemokey/p1_pro/iso_encoder/rules.mk b/keyboards/lemokey/p1_pro/iso_encoder/rules.mk
new file mode 100644
index 0000000000..6e7633bfe0
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/iso_encoder/rules.mk
@@ -0,0 +1 @@
+# This file intentionally left blank
diff --git a/keyboards/lemokey/p1_pro/mcuconf.h b/keyboards/lemokey/p1_pro/mcuconf.h
new file mode 100644
index 0000000000..50c51bb64b
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/mcuconf.h
@@ -0,0 +1,29 @@
+/* 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 .
+ */
+
+#pragma once
+#include_next
+
+#undef WB32_I2C_USE_I2C1
+#define WB32_I2C_USE_I2C1 TRUE
+
+#undef WB32_SPI_USE_QSPI
+#define WB32_SPI_USE_QSPI TRUE
+
+#undef WB32_LSI_ENABLED
+#define WB32_LSI_ENABLED TRUE
+
+#define WB32_EXTI_REQUIRED
diff --git a/keyboards/lemokey/p1_pro/p1_pro.c b/keyboards/lemokey/p1_pro/p1_pro.c
new file mode 100644
index 0000000000..5282556eac
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/p1_pro.c
@@ -0,0 +1,81 @@
+/* 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 .
+ */
+
+#include "quantum.h"
+#include "lemokey_task.h"
+#ifdef FACTORY_TEST_ENABLE
+# include "factory_test.h"
+# include "lemokey_common.h"
+#endif
+#ifdef LK_WIRELESS_ENABLE
+# include "lkbt51.h"
+# include "wireless.h"
+# include "wireless_common.h"
+# include "battery.h"
+#endif
+
+#define POWER_ON_LED_DURATION 3000
+static uint32_t power_on_indicator_timer_buffer;
+
+void keyboard_post_init_kb(void) {
+#ifdef LK_WIRELESS_ENABLE
+# ifdef BT_MODE_SELECT_PIN
+ palSetLineMode(BT_MODE_SELECT_PIN, PAL_MODE_INPUT);
+# endif
+# ifdef P2P4_MODE_SELECT_PIN
+ palSetLineMode(P2P4_MODE_SELECT_PIN, PAL_MODE_INPUT);
+# endif
+
+ palSetLineMode(B2, PAL_MODE_INPUT);
+ palSetLineMode(C5, PAL_MODE_INPUT);
+
+ writePin(BAT_LOW_LED_PIN, BAT_LOW_LED_PIN_ON_STATE);
+
+ lkbt51_init(false);
+ wireless_init();
+#endif
+
+ power_on_indicator_timer_buffer = timer_read32();
+
+#ifdef ENCODER_ENABLE
+ encoder_cb_init();
+#endif
+ keyboard_post_init_user();
+}
+
+bool lemokey_task_kb(void) {
+ if (power_on_indicator_timer_buffer) {
+ if (timer_elapsed32(power_on_indicator_timer_buffer) > POWER_ON_LED_DURATION) {
+ power_on_indicator_timer_buffer = 0;
+
+#ifdef LK_WIRELESS_ENABLE
+ writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
+#endif
+
+ } else {
+#ifdef LK_WIRELESS_ENABLE
+ writePin(BAT_LOW_LED_PIN, BAT_LOW_LED_PIN_ON_STATE);
+#endif
+ }
+ }
+ return true;
+}
+
+#ifdef LK_WIRELESS_ENABLE
+bool lpm_is_kb_idle(void) {
+ return power_on_indicator_timer_buffer == 0 && !factory_reset_indicating();
+}
+#endif
diff --git a/keyboards/lemokey/p1_pro/post_rules.mk b/keyboards/lemokey/p1_pro/post_rules.mk
new file mode 100644
index 0000000000..5deb336ff9
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/post_rules.mk
@@ -0,0 +1,2 @@
+include keyboards/lemokey/common/wireless/wireless.mk
+
diff --git a/keyboards/lemokey/p1_pro/readme.md b/keyboards/lemokey/p1_pro/readme.md
new file mode 100644
index 0000000000..f4ca2e5877
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/readme.md
@@ -0,0 +1,21 @@
+# Lemokey P1 Pro
+
+![Lemokey P1 Pro]
+
+A customizable 75% keyboard.
+
+* Keyboard Maintainer: [Keychron](https://github.com/keychron)
+* Hardware Supported: Lemokey P1 Pro
+* Hardware Availability: [Lemokey P1 Pro QMK/VIA Wireless Custom Mechanical Keyboard]
+
+Make example for this keyboard (after setting up your build environment):
+
+ make lemokey/p1_pro/ansi_encoder:default
+
+Flashing example for this keyboard:
+
+ make lemokey/p1_pro/ansi_encoder:default:flash
+
+**Reset Key**: Disconnect the USB cable, toggle mode switch to "Cable", hold down the *Esc* key or reset button underneath space bar, then connect the USB cable.
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
diff --git a/keyboards/lemokey/p1_pro/rules.mk b/keyboards/lemokey/p1_pro/rules.mk
new file mode 100644
index 0000000000..acfe7f4add
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/rules.mk
@@ -0,0 +1,4 @@
+
+include keyboards/lemokey/common/lemokey_common.mk
+
+VPATH += $(TOP_DIR)/keyboards/lemokey
diff --git a/keyboards/lemokey/p1_pro/via_json/p1_pro_ansi_encoder_v1.0.json b/keyboards/lemokey/p1_pro/via_json/p1_pro_ansi_encoder_v1.0.json
new file mode 100644
index 0000000000..684676347e
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/via_json/p1_pro_ansi_encoder_v1.0.json
@@ -0,0 +1,287 @@
+{
+ "name": "Lemokey P1 Pro ANSI Knob",
+ "vendorId": "0x362D",
+ "productId": "0x0303",
+ "firmwareVersion": 1,
+ "keycodes": ["qmk_lighting"],
+ "menus": [
+ {
+ "label": "Lighting",
+ "content": [
+ {
+ "label": "Backlight",
+ "content": [
+ {
+ "label": "Brightness",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_brightness", 3, 1]
+ },
+ {
+ "label": "Effect",
+ "type": "dropdown",
+ "content": ["id_qmk_rgb_matrix_effect", 3, 2],
+ "options": [
+ ["None", 0],
+ ["Solid Color", 1],
+ ["Breathing", 2],
+ ["Band Spiral Val", 3],
+ ["Cycle All", 4],
+ ["Cycle Left Right", 5],
+ ["Cycle Up Down", 6],
+ ["Rainbow Moving Chevron", 7],
+ ["Cycle Out In", 8],
+ ["Cycle Out In Dual", 9],
+ ["Cycle Pinwheel", 10],
+ ["Cycle Spiral", 11],
+ ["Dual Beacon", 12],
+ ["Rainbow Beacon", 13],
+ ["Jellybean Raindrops", 14],
+ ["Pixel Rain", 15],
+ ["Typing Heatmap", 16],
+ ["Digital Rain", 17],
+ ["Reactive Simple", 18],
+ ["Reactive Multiwide", 19],
+ ["Reactive Multinexus", 20],
+ ["Splash", 21],
+ ["Solid Splash", 22]
+ ]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} > 1",
+ "label": "Effect Speed",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_effect_speed", 3, 3]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0 && ( {id_qmk_rgb_matrix_effect} < 4 || {id_qmk_rgb_matrix_effect} == 18 || ({id_qmk_rgb_matrix_effect} > 17 && {id_qmk_rgb_matrix_effect} != 21) ) ",
+ "label": "Color",
+ "type": "color",
+ "content": ["id_qmk_rgb_matrix_color", 3, 4]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "customKeycodes": [
+ {"name": "Task View", "title": "Task View in Windows", "shortName": "Task"},
+ {"name": "File Explorer", "title": "File Explorer in Windows", "shortName": "File"},
+ {"name": "Lock Screen", "title": "Lock Screen in Windows", "shortName": "Lock"},
+ {"name": "Misson Control", "title": "Misson Control in Mac", "shortName": "MCtl"},
+ {"name": "Launch Pad", "title": "Lanuch Pad in Windows", "shortName": "LPad"},
+ {"name": "Left Option", "title": "Left Option", "shortName": "LOpt"},
+ {"name": "Right Option", "title": "Right Option", "shortName": "ROpt"},
+ {"name": "Left Cmd", "title": "Left Command", "shortName": "LCmd"},
+ {"name": "Right Cmd", "title": "Right Command", "shortName": "RCmd"},
+ {"name": "Bluetooth Host 1", "title": "Bluetooth Host 1", "shortName": "BTH1"},
+ {"name": "Bluetooth Host 2", "title": "Bluetooth Host 2", "shortName": "BTH2"},
+ {"name": "Bluetooth Host 3", "title": "Bluetooth Host 3", "shortName": "BTH3"},
+ {"name": "2.4G", "title": "2.4G", "shortName": "2.4G"},
+ {"name": "Battery Level", "title": "Show battery level", "shortName": "Batt"}
+ ],
+ "matrix": {"rows": 6, "cols" : 15},
+ "layouts": {
+ "keymap": [
+ [
+ {
+ "c": "#777777"
+ },
+ "0, 0",
+ {
+ "x": 0.25,
+ "c": "#cccccc"
+ },
+ "0, 1",
+ "0, 2",
+ "0, 3",
+ "0, 4",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "0, 5",
+ "0, 6",
+ "0, 7",
+ "0, 8",
+ {
+ "x": 0.25,
+ "c": "#cccccc"
+ },
+ "0, 9",
+ "0, 10",
+ "0, 11",
+ "0, 12",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "0, 13",
+ {
+ "x": 0.25
+ },
+ "0, 14\n\n\n\n\n\n\n\n\ne0"
+ ],
+ [
+ {
+ "y": 0.25,
+ "c": "#aaaaaa"
+ },
+ "1, 0",
+ {
+ "c": "#cccccc"
+ },
+ "1, 1",
+ "1, 2",
+ "1, 3",
+ "1, 4",
+ "1, 5",
+ "1, 6",
+ "1, 7",
+ "1, 8",
+ "1, 9",
+ "1, 10",
+ "1, 11",
+ "1, 12",
+ {
+ "w": 2,
+ "c": "#aaaaaa"
+ },
+ "1, 13",
+ {
+ "x": 0.25
+ },
+ "1, 14"
+ ],
+ [
+ {
+ "w": 1.5,
+ "c": "#aaaaaa"
+ },
+ "2, 0",
+ {
+ "c": "#cccccc"
+ },
+ "2, 1",
+ "2, 2",
+ "2, 3",
+ "2, 4",
+ "2, 5",
+ "2, 6",
+ "2, 7",
+ "2, 8",
+ "2, 9",
+ "2, 10",
+ "2, 11",
+ "2, 12",
+ {
+ "w": 1.5,
+ "c": "#aaaaaa"
+ },
+ "2, 13",
+ {
+ "x": 0.25
+ },
+ "2, 14"
+ ],
+ [
+ {
+ "w": 1.75,
+ "c": "#aaaaaa"
+ },
+ "3, 0",
+ {
+ "c": "#cccccc"
+ },
+ "3, 1",
+ "3, 2",
+ "3, 3",
+ "3, 4",
+ "3, 5",
+ "3, 6",
+ "3, 7",
+ "3, 8",
+ "3, 9",
+ "3, 10",
+ "3, 11",
+ {
+ "w": 2.25,
+ "c": "#777777"
+ },
+ "3, 13",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "3, 14"
+ ],
+ [
+ {
+ "w": 2.25,
+ "c": "#aaaaaa"
+ },
+ "4, 0",
+ {
+ "c": "#cccccc"
+ },
+ "4, 2",
+ "4, 3",
+ "4, 4",
+ "4, 5",
+ "4, 6",
+ "4, 7",
+ "4, 8",
+ "4, 9",
+ "4, 10",
+ "4, 11",
+ {
+ "w": 1.75,
+ "c": "#aaaaaa"
+ },
+ "4, 12",
+ {
+ "x": 0.25,
+ "y": 0.25,
+ "c": "#cccccc"
+ },
+ "4, 13"
+ ],
+ [
+ {
+ "y": -0.25,
+ "w": 1.25,
+ "c": "#aaaaaa"
+ },
+ "5, 0",
+ {
+ "w": 1.25
+ },
+ "5, 1",
+ {
+ "w": 1.25
+ },
+ "5, 2",
+ {
+ "w": 6.25,
+ "c": "#cccccc"
+ },
+ "5, 6",
+ {
+ "c": "#aaaaaa"
+ },
+ "5, 9",
+ "5, 10",
+ "5, 11",
+ {
+ "x": 0.25,
+ "y": 0.25,
+ "c": "#cccccc"
+ },
+ "5, 12",
+ "5, 13",
+ "5, 14"
+ ]
+ ]
+ }
+}
diff --git a/keyboards/lemokey/p1_pro/via_json/p1_pro_iso_encoder_v1.0.json b/keyboards/lemokey/p1_pro/via_json/p1_pro_iso_encoder_v1.0.json
new file mode 100644
index 0000000000..e056b996d2
--- /dev/null
+++ b/keyboards/lemokey/p1_pro/via_json/p1_pro_iso_encoder_v1.0.json
@@ -0,0 +1,290 @@
+{
+ "name": "Lemokey P1 Pro ISO Knob",
+ "vendorId": "0x362D",
+ "productId": "0x0304",
+ "firmwareVersion": 1,
+ "keycodes": ["qmk_lighting"],
+ "menus": [
+ {
+ "label": "Lighting",
+ "content": [
+ {
+ "label": "Backlight",
+ "content": [
+ {
+ "label": "Brightness",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_brightness", 3, 1]
+ },
+ {
+ "label": "Effect",
+ "type": "dropdown",
+ "content": ["id_qmk_rgb_matrix_effect", 3, 2],
+ "options": [
+ ["None", 0],
+ ["Solid Color", 1],
+ ["Breathing", 2],
+ ["Band Spiral Val", 3],
+ ["Cycle All", 4],
+ ["Cycle Left Right", 5],
+ ["Cycle Up Down", 6],
+ ["Rainbow Moving Chevron", 7],
+ ["Cycle Out In", 8],
+ ["Cycle Out In Dual", 9],
+ ["Cycle Pinwheel", 10],
+ ["Cycle Spiral", 11],
+ ["Dual Beacon", 12],
+ ["Rainbow Beacon", 13],
+ ["Jellybean Raindrops", 14],
+ ["Pixel Rain", 15],
+ ["Typing Heatmap", 16],
+ ["Digital Rain", 17],
+ ["Reactive Simple", 18],
+ ["Reactive Multiwide", 19],
+ ["Reactive Multinexus", 20],
+ ["Splash", 21],
+ ["Solid Splash", 22]
+ ]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} > 1",
+ "label": "Effect Speed",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_effect_speed", 3, 3]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0 && ( {id_qmk_rgb_matrix_effect} < 4 || {id_qmk_rgb_matrix_effect} == 18 || ({id_qmk_rgb_matrix_effect} > 17 && {id_qmk_rgb_matrix_effect} != 21) ) ",
+ "label": "Color",
+ "type": "color",
+ "content": ["id_qmk_rgb_matrix_color", 3, 4]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "customKeycodes": [
+ {"name": "Task View", "title": "Task View in Windows", "shortName": "Task"},
+ {"name": "File Explorer", "title": "File Explorer in Windows", "shortName": "File"},
+ {"name": "Lock Screen", "title": "Lock Screen in Windows", "shortName": "Lock"},
+ {"name": "Misson Control", "title": "Misson Control in Mac", "shortName": "MCtl"},
+ {"name": "Launch Pad", "title": "Lanuch Pad in Windows", "shortName": "LPad"},
+ {"name": "Left Option", "title": "Left Option", "shortName": "LOpt"},
+ {"name": "Right Option", "title": "Right Option", "shortName": "ROpt"},
+ {"name": "Left Cmd", "title": "Left Command", "shortName": "LCmd"},
+ {"name": "Right Cmd", "title": "Right Command", "shortName": "RCmd"},
+ {"name": "Bluetooth Host 1", "title": "Bluetooth Host 1", "shortName": "BTH1"},
+ {"name": "Bluetooth Host 2", "title": "Bluetooth Host 2", "shortName": "BTH2"},
+ {"name": "Bluetooth Host 3", "title": "Bluetooth Host 3", "shortName": "BTH3"},
+ {"name": "2.4G", "title": "2.4G", "shortName": "2.4G"},
+ {"name": "Battery Level", "title": "Show battery level", "shortName": "Batt"}
+ ],
+ "matrix": {"rows": 6, "cols" : 15},
+ "layouts": {
+ "keymap": [
+ [
+ {
+ "c": "#777777"
+ },
+ "0, 0",
+ {
+ "x": 0.25,
+ "c": "#cccccc"
+ },
+ "0, 1",
+ "0, 2",
+ "0, 3",
+ "0, 4",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "0, 5",
+ "0, 6",
+ "0, 7",
+ "0, 8",
+ {
+ "x": 0.25,
+ "c": "#cccccc"
+ },
+ "0, 9",
+ "0, 10",
+ "0, 11",
+ "0, 12",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "0, 13",
+ {
+ "x": 0.25
+ },
+ "0, 14\n\n\n\n\n\n\n\n\ne0"
+ ],
+ [
+ {
+ "y": 0.25,
+ "c": "#aaaaaa"
+ },
+ "1, 0",
+ {
+ "c": "#cccccc"
+ },
+ "1, 1",
+ "1, 2",
+ "1, 3",
+ "1, 4",
+ "1, 5",
+ "1, 6",
+ "1, 7",
+ "1, 8",
+ "1, 9",
+ "1, 10",
+ "1, 11",
+ "1, 12",
+ {
+ "w": 2,
+ "c": "#aaaaaa"
+ },
+ "1, 13",
+ {
+ "x": 0.25
+ },
+ "1, 14"
+ ],
+ [
+ {
+ "w": 1.5,
+ "c": "#aaaaaa"
+ },
+ "2, 0",
+ {
+ "c": "#cccccc"
+ },
+ "2, 1",
+ "2, 2",
+ "2, 3",
+ "2, 4",
+ "2, 5",
+ "2, 6",
+ "2, 7",
+ "2, 8",
+ "2, 9",
+ "2, 10",
+ "2, 11",
+ "2, 12",
+ {
+ "x": 0.25,
+ "c": "#777777",
+ "w": 1.25,
+ "h": 2,
+ "w2": 1.5,
+ "h2": 1,
+ "x2": -0.25
+ },
+ "2, 13",
+ {
+ "x": 0.25,
+ "c": "#aaaaaa"
+ },
+ "2, 14"
+ ],
+ [
+ {
+ "w": 1.75,
+ "c": "#aaaaaa"
+ },
+ "3, 0",
+ {
+ "c": "#cccccc"
+ },
+ "3, 1",
+ "3, 2",
+ "3, 3",
+ "3, 4",
+ "3, 5",
+ "3, 6",
+ "3, 7",
+ "3, 8",
+ "3, 9",
+ "3, 10",
+ "3, 11",
+ "3, 13",
+ {
+ "x": 1.5,
+ "c": "#aaaaaa"
+ },
+ "3, 14"
+ ],
+ [
+ {
+ "w": 1.25,
+ "c": "#aaaaaa"
+ },
+ "4, 0",
+ "4, 1",
+ {
+ "c": "#cccccc"
+ },
+ "4, 2",
+ "4, 3",
+ "4, 4",
+ "4, 5",
+ "4, 6",
+ "4, 7",
+ "4, 8",
+ "4, 9",
+ "4, 10",
+ "4, 11",
+ {
+ "w": 1.75,
+ "c": "#aaaaaa"
+ },
+ "4, 12",
+ {
+ "x": 0.25,
+ "y": 0.25,
+ "c": "#cccccc"
+ },
+ "4, 13"
+ ],
+ [
+ {
+ "y": -0.25,
+ "w": 1.25,
+ "c": "#aaaaaa"
+ },
+ "5, 0",
+ {
+ "w": 1.25
+ },
+ "5, 1",
+ {
+ "w": 1.25
+ },
+ "5, 2",
+ {
+ "w": 6.25,
+ "c": "#cccccc"
+ },
+ "5, 6",
+ {
+ "c": "#aaaaaa"
+ },
+ "5, 9",
+ "5, 10",
+ "5, 11",
+ {
+ "x": 0.25,
+ "y": 0.25,
+ "c": "#cccccc"
+ },
+ "5, 12",
+ "5, 13",
+ "5, 14"
+ ]
+ ]
+ }
+}
diff --git a/lib/chibios-contrib b/lib/chibios-contrib
index da78eb3759..5dbc2a078f 160000
--- a/lib/chibios-contrib
+++ b/lib/chibios-contrib
@@ -1 +1 @@
-Subproject commit da78eb3759b8d1779b237657c7667baa4aa95ca1
+Subproject commit 5dbc2a078f5f10a10af053e1255dcc34fda333f8
diff --git a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/mcuconf.h
index 03236292fe..e49fbd4e5b 100644
--- a/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/mcuconf.h
+++ b/platforms/chibios/boards/GENERIC_WB32_F3G71XX/configs/mcuconf.h
@@ -56,6 +56,8 @@
#define WB32_PPRE1 1
#define WB32_PPRE2 1
#define WB32_USBPRE WB32_USBPRE_DIV1P5
+#define WB32_RTCSEL WB32_RTCSEL_HSEDIV
+#define WB32_RTCLP_SEL WB32_RTCSEL_LSI
/*
* EXTI driver system settings.
@@ -84,6 +86,11 @@
#define WB32_GPT_TIM2_IRQ_PRIORITY 7
#define WB32_GPT_TIM3_IRQ_PRIORITY 7
#define WB32_GPT_TIM4_IRQ_PRIORITY 7
+/*
+ * RTC driver system settings.
+ */
+#define WB32_RTCAlarm_IRQ_PRIORITY 14
+#define WB32_RTC_IRQ_PRIORITY 15
/*
* ICU driver system settings.
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index 3c22bbd445..2babd4b1fe 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -101,6 +101,13 @@ _Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_A
# define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY
#endif
+#ifdef KEYCODE_BUFFER_ENABLE
+static uint8_t layer_buffer = 0xFF;
+static uint8_t row_buffer = 0xFF;
+static uint8_t col_buffer = 0xFF;
+static uint16_t keycode_buffer = 0;
+#endif
+
uint8_t dynamic_keymap_get_layer_count(void) {
return DYNAMIC_KEYMAP_LAYER_COUNT;
}
@@ -113,18 +120,33 @@ void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t c
uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return KC_NO;
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
+#ifdef KEYCODE_BUFFER_ENABLE
+ uint16_t keycode = eeprom_read_word(address);
+ keycode=__builtin_bswap16(keycode);
+#else
// Big endian, so we can read/write EEPROM directly from host if we want
uint16_t keycode = eeprom_read_byte(address) << 8;
keycode |= eeprom_read_byte(address + 1);
+#endif
+
return keycode;
}
void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) {
if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return;
+#ifdef KEYCODE_BUFFER_ENABLE
+ if (layer == layer_buffer && row == row_buffer && column == col_buffer)
+ layer_buffer = row_buffer = col_buffer = 0xFF;
+#endif
void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
+#ifdef KEYCODE_BUFFER_ENABLE
+ keycode = __builtin_bswap16(keycode);
+ eeprom_update_word(address, keycode);
+#else
// Big endian, so we can read/write EEPROM directly from host if we want
eeprom_update_byte(address, (uint8_t)(keycode >> 8));
eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF));
+#endif
}
#ifdef ENCODER_MAP_ENABLE
@@ -151,13 +173,26 @@ void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwis
#endif // ENCODER_MAP_ENABLE
void dynamic_keymap_reset(void) {
+#ifdef KEYCODE_BUFFER_ENABLE
+ uint16_t keymap_buffer[MATRIX_ROWS][MATRIX_COLS];
+
+ layer_buffer = row_buffer = col_buffer = 0xFF;
+#endif
// Reset the keymaps in EEPROM to what is in flash.
for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) {
for (int row = 0; row < MATRIX_ROWS; row++) {
for (int column = 0; column < MATRIX_COLS; column++) {
+#ifdef KEYCODE_BUFFER_ENABLE
+ keymap_buffer[row][column] = keycode_at_keymap_location_raw(layer, row, column);
+ keymap_buffer[row][column] = __builtin_bswap16(keymap_buffer[row][column]);
+#else
dynamic_keymap_set_keycode(layer, row, column, keycode_at_keymap_location_raw(layer, row, column));
+#endif
}
}
+#ifdef KEYCODE_BUFFER_ENABLE
+ eeprom_update_block(keymap_buffer, dynamic_keymap_key_to_eeprom_address(layer, 0, 0),sizeof(keymap_buffer));
+#endif
#ifdef ENCODER_MAP_ENABLE
for (int encoder = 0; encoder < NUM_ENCODERS; encoder++) {
dynamic_keymap_set_encoder(layer, encoder, true, keycode_at_encodermap_location_raw(layer, encoder, true));
@@ -197,7 +232,18 @@ void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) {
uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) {
if (layer_num < DYNAMIC_KEYMAP_LAYER_COUNT && row < MATRIX_ROWS && column < MATRIX_COLS) {
+#ifdef KEYCODE_BUFFER_ENABLE
+ if( (layer_num != layer_buffer) || (row != row_buffer) || (column != col_buffer))
+ {
+ layer_buffer = layer_num;
+ row_buffer = row;
+ col_buffer = column;
+ keycode_buffer = dynamic_keymap_get_keycode(layer_num, row, column);
+ }
+ return keycode_buffer;
+#else
return dynamic_keymap_get_keycode(layer_num, row, column);
+#endif
}
return KC_NO;
}