forked from mirrors/qmk_userspace
		
	Added Lemokey P1 Pro
This commit is contained in:
		
					parent
					
						
							
								b71b83f882
							
						
					
				
			
			
				commit
				
					
						62030ee6bb
					
				
			
		
					 72 changed files with 2876 additions and 507 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<NUM_ENCODERS; i++)
 | 
			
		||||
    {
 | 
			
		||||
        palEnableLineEvent(encoders_pad_a[i], PAL_EVENT_MODE_BOTH_EDGES);
 | 
			
		||||
        palEnableLineEvent(encoders_pad_b[i], PAL_EVENT_MODE_BOTH_EDGES);
 | 
			
		||||
        palSetLineCallback(encoders_pad_a[i], encoder_pad_cb, (void*)i);
 | 
			
		||||
        palSetLineCallback(encoders_pad_b[i], encoder_pad_cb, (void*)i);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
__attribute__((weak)) void suspend_power_down_lemokey(void) {}
 | 
			
		||||
__attribute__((weak)) void suspend_wakeup_init_lemokey(void) {}
 | 
			
		||||
 | 
			
		||||
void suspend_power_down_kb(void) {
 | 
			
		||||
#ifdef WIN_LOCK_LED_PIN
 | 
			
		||||
    writePin(WIN_LOCK_LED_PIN, !WIN_LOCK_LED_ON_LEVEL);
 | 
			
		||||
#endif
 | 
			
		||||
    suspend_power_down_lemokey();
 | 
			
		||||
    suspend_power_down_user();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void suspend_wakeup_init_kb(void) {
 | 
			
		||||
#ifdef WIN_LOCK_LED_PIN
 | 
			
		||||
    if (keymap_config.no_gui) writePin(WIN_LOCK_LED_PIN, !WIN_LOCK_LED_ON_LEVEL);
 | 
			
		||||
#endif
 | 
			
		||||
    suspend_wakeup_init_lemokey();
 | 
			
		||||
    suspend_wakeup_init_user();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ enum {
 | 
			
		|||
    KC_FILE_EXPLORER,
 | 
			
		||||
    KC_LOCK_SCREEN,        // Lock screen
 | 
			
		||||
    KC_MCTRL,
 | 
			
		||||
    KC_LANCH,
 | 
			
		||||
    KC_LNPAD,
 | 
			
		||||
    KC_LOPTN,
 | 
			
		||||
    KC_ROPTN,
 | 
			
		||||
    KC_LCMMD,
 | 
			
		||||
| 
						 | 
				
			
			@ -35,15 +35,16 @@ enum {
 | 
			
		|||
    BT_HST3,
 | 
			
		||||
    P2P4G,
 | 
			
		||||
    BAT_LVL,
 | 
			
		||||
    __LK_WIRELESS_ENABLE_END = BAT_LVL,
 | 
			
		||||
#else
 | 
			
		||||
    BT_HST1 = _______,
 | 
			
		||||
    BT_HST2 = _______,
 | 
			
		||||
    BT_HST3 = _______,
 | 
			
		||||
    P2P4G   = _______,
 | 
			
		||||
    BAT_LVL = _______,
 | 
			
		||||
    __LK_WIRELESS_ENABLE_END = KC_LOCK_SCREEN,
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	NEW_SAFE_RANGE,
 | 
			
		||||
	NEW_SAFE_RANGE = __LK_WIRELESS_ENABLE_END + 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define KC_TASK KC_TASK_VIEW
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,11 @@
 | 
			
		|||
OPT_DEFS += -DFACTORY_TEST_ENABLE
 | 
			
		||||
OPT_DEFS += -DFACTORY_TEST_ENABLE -DAPDAPTIVE_NKRO_ENABLE
 | 
			
		||||
 | 
			
		||||
LEMOKEY_COMMON_DIR = common
 | 
			
		||||
SRC += \
 | 
			
		||||
	$(LEMOKEY_COMMON_DIR)/lemokey_task.c \
 | 
			
		||||
     $(LEMOKEY_COMMON_DIR)/lemokey_common.c \
 | 
			
		||||
     $(LEMOKEY_COMMON_DIR)/factory_test.c
 | 
			
		||||
    $(LEMOKEY_COMMON_DIR)/lemokey_task.c \
 | 
			
		||||
    $(LEMOKEY_COMMON_DIR)/lemokey_common.c \
 | 
			
		||||
    $(LEMOKEY_COMMON_DIR)/lemokey_raw_hid.c \
 | 
			
		||||
    $(LEMOKEY_COMMON_DIR)/factory_test.c
 | 
			
		||||
 | 
			
		||||
VPATH += $(TOP_DIR)/keyboards/lemokey/$(LEMOKEY_COMMON_DIR)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										120
									
								
								keyboards/lemokey/common/lemokey_raw_hid.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								keyboards/lemokey/common/lemokey_raw_hid.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
/* 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 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
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										135
									
								
								keyboards/lemokey/common/wireless/lpm_wb32f3g71.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								keyboards/lemokey/common/wireless/lpm_wb32f3g71.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								keyboards/lemokey/l1/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								keyboards/lemokey/l1/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
include keyboards/lemokey/common/wireless/wireless.mk
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
include keyboards/lemokey/common/wireless/wireless.mk
 | 
			
		||||
include keyboards/lemokey/common/lemokey_common.mk
 | 
			
		||||
 | 
			
		||||
VPATH += $(TOP_DIR)/keyboards/lemokey
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								keyboards/lemokey/l3/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								keyboards/lemokey/l3/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
include keyboards/lemokey/common/wireless/wireless.mk
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
include keyboards/lemokey/common/wireless/wireless.mk
 | 
			
		||||
include keyboards/lemokey/common/lemokey_common.mk
 | 
			
		||||
 | 
			
		||||
VPATH += $(TOP_DIR)/keyboards/lemokey
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										148
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/ansi_encoder.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/ansi_encoder.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										57
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										99
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/info.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/info.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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}
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/keymaps/via/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
VIA_ENABLE = yes
 | 
			
		||||
							
								
								
									
										1
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								keyboards/lemokey/p1_pro/ansi_encoder/rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
# This file intentionally left blank
 | 
			
		||||
							
								
								
									
										110
									
								
								keyboards/lemokey/p1_pro/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								keyboards/lemokey/p1_pro/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										32
									
								
								keyboards/lemokey/p1_pro/halconf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								keyboards/lemokey/p1_pro/halconf.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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 <halconf.h>
 | 
			
		||||
							
								
								
									
										73
									
								
								keyboards/lemokey/p1_pro/info.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								keyboards/lemokey/p1_pro/info.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								keyboards/lemokey/p1_pro/iso_encoder/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								keyboards/lemokey/p1_pro/iso_encoder/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										100
									
								
								keyboards/lemokey/p1_pro/iso_encoder/info.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								keyboards/lemokey/p1_pro/iso_encoder/info.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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}
 | 
			
		||||
            ]
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										149
									
								
								keyboards/lemokey/p1_pro/iso_encoder/iso_encoder.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								keyboards/lemokey/p1_pro/iso_encoder/iso_encoder.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								keyboards/lemokey/p1_pro/iso_encoder/keymaps/via/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
VIA_ENABLE = yes
 | 
			
		||||
							
								
								
									
										1
									
								
								keyboards/lemokey/p1_pro/iso_encoder/rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								keyboards/lemokey/p1_pro/iso_encoder/rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
# This file intentionally left blank
 | 
			
		||||
							
								
								
									
										29
									
								
								keyboards/lemokey/p1_pro/mcuconf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								keyboards/lemokey/p1_pro/mcuconf.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include_next <mcuconf.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										81
									
								
								keyboards/lemokey/p1_pro/p1_pro.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								keyboards/lemokey/p1_pro/p1_pro.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
							
								
								
									
										2
									
								
								keyboards/lemokey/p1_pro/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								keyboards/lemokey/p1_pro/post_rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
include keyboards/lemokey/common/wireless/wireless.mk
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								keyboards/lemokey/p1_pro/readme.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								keyboards/lemokey/p1_pro/readme.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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).
 | 
			
		||||
							
								
								
									
										4
									
								
								keyboards/lemokey/p1_pro/rules.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								keyboards/lemokey/p1_pro/rules.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
 | 
			
		||||
include keyboards/lemokey/common/lemokey_common.mk
 | 
			
		||||
 | 
			
		||||
VPATH += $(TOP_DIR)/keyboards/lemokey
 | 
			
		||||
							
								
								
									
										287
									
								
								keyboards/lemokey/p1_pro/via_json/p1_pro_ansi_encoder_v1.0.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								keyboards/lemokey/p1_pro/via_json/p1_pro_ansi_encoder_v1.0.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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"
 | 
			
		||||
      ]
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										290
									
								
								keyboards/lemokey/p1_pro/via_json/p1_pro_iso_encoder_v1.0.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								keyboards/lemokey/p1_pro/via_json/p1_pro_iso_encoder_v1.0.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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"
 | 
			
		||||
      ]
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit da78eb3759b8d1779b237657c7667baa4aa95ca1
 | 
			
		||||
Subproject commit 5dbc2a078f5f10a10af053e1255dcc34fda333f8
 | 
			
		||||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue