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