From fb6e59d76e673db0532caf4ac2b93a9d54f7ea5d Mon Sep 17 00:00:00 2001 From: richud Date: Wed, 1 Jan 2025 14:46:10 +0000 Subject: [PATCH] Add support for K1 Pro ISO RGB --- keyboards/keychron/k1_pro/config.h | 98 ++++++ .../firmware/keychron_k1_pro_iso_rgb_vial.bin | Bin 0 -> 64972 bytes keyboards/keychron/k1_pro/halconf.h | 29 ++ keyboards/keychron/k1_pro/info.json | 225 ++++++++++++ keyboards/keychron/k1_pro/iso/rgb/config.h | 106 ++++++ keyboards/keychron/k1_pro/iso/rgb/info.json | 130 +++++++ .../k1_pro/iso/rgb/keymaps/default/keymap.c | 59 ++++ .../k1_pro/iso/rgb/keymaps/via/keymap.c | 59 ++++ .../k1_pro/iso/rgb/keymaps/via/rules.mk | 1 + .../k1_pro/iso/rgb/keymaps/vial/config.h | 6 + .../k1_pro/iso/rgb/keymaps/vial/keymap.c | 59 ++++ .../k1_pro/iso/rgb/keymaps/vial/rules.mk | 5 + .../k1_pro/iso/rgb/keymaps/vial/vial.json | 304 ++++++++++++++++ keyboards/keychron/k1_pro/iso/rgb/rgb.c | 122 +++++++ keyboards/keychron/k1_pro/iso/rgb/rules.mk | 1 + keyboards/keychron/k1_pro/k1_pro.c | 325 ++++++++++++++++++ keyboards/keychron/k1_pro/k1_pro.h | 57 +++ keyboards/keychron/k1_pro/matrix.c | 190 ++++++++++ keyboards/keychron/k1_pro/mcuconf.h | 39 +++ keyboards/keychron/k1_pro/readme.md | 31 ++ keyboards/keychron/k1_pro/rules.mk | 17 + 21 files changed, 1863 insertions(+) create mode 100644 keyboards/keychron/k1_pro/config.h create mode 100755 keyboards/keychron/k1_pro/firmware/keychron_k1_pro_iso_rgb_vial.bin create mode 100644 keyboards/keychron/k1_pro/halconf.h create mode 100644 keyboards/keychron/k1_pro/info.json create mode 100755 keyboards/keychron/k1_pro/iso/rgb/config.h create mode 100755 keyboards/keychron/k1_pro/iso/rgb/info.json create mode 100755 keyboards/keychron/k1_pro/iso/rgb/keymaps/default/keymap.c create mode 100755 keyboards/keychron/k1_pro/iso/rgb/keymaps/via/keymap.c create mode 100755 keyboards/keychron/k1_pro/iso/rgb/keymaps/via/rules.mk create mode 100644 keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/config.h create mode 100755 keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/keymap.c create mode 100755 keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/rules.mk create mode 100644 keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/vial.json create mode 100755 keyboards/keychron/k1_pro/iso/rgb/rgb.c create mode 100755 keyboards/keychron/k1_pro/iso/rgb/rules.mk create mode 100644 keyboards/keychron/k1_pro/k1_pro.c create mode 100644 keyboards/keychron/k1_pro/k1_pro.h create mode 100644 keyboards/keychron/k1_pro/matrix.c create mode 100644 keyboards/keychron/k1_pro/mcuconf.h create mode 100644 keyboards/keychron/k1_pro/readme.md create mode 100644 keyboards/keychron/k1_pro/rules.mk diff --git a/keyboards/keychron/k1_pro/config.h b/keyboards/keychron/k1_pro/config.h new file mode 100644 index 00000000000..21eb5c74936 --- /dev/null +++ b/keyboards/keychron/k1_pro/config.h @@ -0,0 +1,98 @@ +/* Copyright 2023 @ 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 + +/* turn off effects when suspended */ +#define RGB_DISABLE_WHEN_USB_SUSPENDED +#define LED_DISABLE_WHEN_USB_SUSPENDED + +/* DIP switch */ +#define DIP_SWITCH_PINS \ + { A8 } + +/* Caps lock LED */ +#define LED_CAPS_LOCK_PIN A0 +#define LED_PIN_ON_STATE 1 + +/* Increase I2C speed to 1000 KHz */ +#define I2C1_TIMINGR_PRESC 0U +#define I2C1_TIMINGR_SCLDEL 3U +#define I2C1_TIMINGR_SDADEL 0U +#define I2C1_TIMINGR_SCLH 15U +#define I2C1_TIMINGR_SCLL 51U + +#ifdef KC_BLUETOOTH_ENABLE +/* Hardware configuration */ +# define USB_BT_MODE_SELECT_PIN A10 + +# define CKBT51_RESET_PIN A9 +# define CKBT51_INT_INPUT_PIN A5 +# define BLUETOOTH_INT_INPUT_PIN A6 + +# define USB_POWER_SENSE_PIN B1 +# define USB_POWER_CONNECTED_LEVEL 0 + +# define BAT_LOW_LED_PIN A4 +# define BAT_LOW_LED_PIN_ON_STATE 1 + +# define HOST_DEVICES_COUNT 3 + +# define HOST_LED_PIN_LIST \ + { H3, H3, H3 } +# define HOST_LED_PIN_ON_STATE 1 + +# if defined(RGB_MATRIX_ENABLE) || defined(LED_MATRIX_ENABLE) + +# define LED_DRIVER_SHUTDOWN_PIN C14 + +# define HOST_LED_MATRIX_LIST \ + { 17, 18, 19 } + +# define BAT_LEVEL_LED_LIST \ + { 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 } + +/* 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 +# endif + +/* Keep USB connection in blueooth mode */ +# define KEEP_USB_CONNECTION_IN_BLUETOOTH_MODE + +/* Enable bluetooth NKRO */ +# define BLUETOOTH_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 // KC_BLUETOOTH_ENABLE + +/* Emulated EEPROM configuration */ +#define WEAR_LEVELING_LOGICAL_SIZE 2048 +#define WEAR_LEVELING_BACKING_SIZE (WEAR_LEVELING_LOGICAL_SIZE * 2) + +/* Emulated EEPROM configuration */ +#define FEE_DENSITY_BYTES FEE_PAGE_SIZE +#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047 + +/* Factory test keys */ +#define FN_KEY1 MO(1) +#define FN_KEY2 MO(3) diff --git a/keyboards/keychron/k1_pro/firmware/keychron_k1_pro_iso_rgb_vial.bin b/keyboards/keychron/k1_pro/firmware/keychron_k1_pro_iso_rgb_vial.bin new file mode 100755 index 0000000000000000000000000000000000000000..75805db70c9f5ab7f1b3afae1e88b98070c8908f GIT binary patch literal 64972 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 literal 0 HcmV?d00001 diff --git a/keyboards/keychron/k1_pro/halconf.h b/keyboards/keychron/k1_pro/halconf.h new file mode 100644 index 00000000000..306f917783d --- /dev/null +++ b/keyboards/keychron/k1_pro/halconf.h @@ -0,0 +1,29 @@ +/* Copyright 2020 QMK + * + * 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_I2C TRUE + +#ifdef KC_BLUETOOTH_ENABLE +# define PAL_USE_CALLBACKS TRUE +# define HAL_USE_SERIAL TRUE +# define HAL_USE_RTC TRUE +#endif + +#include_next diff --git a/keyboards/keychron/k1_pro/info.json b/keyboards/keychron/k1_pro/info.json new file mode 100644 index 00000000000..f3de2017762 --- /dev/null +++ b/keyboards/keychron/k1_pro/info.json @@ -0,0 +1,225 @@ +{ + "keyboard_name": "Keychron K1 Pro", + "manufacturer": "Keychron", + "url": "https://github.com/Keychron", + "maintainer": "lalalademaxiya1", + "processor": "STM32L432", + "bootloader": "stm32-dfu", + "usb": { + "vid": "0x3434" + }, + "features": { + "bootmagic": true, + "mousekey": true, + "extrakey": true, + "nkro": true, + "dip_switch": true, + "raw": true + }, + "diode_direction": "ROW2COL", + "matrix_size": { + "rows": 6, + "cols": 17 + }, + "matrix_pins": { + "rows": ["B5", "B4", "B3", "A15", "A14", "A13"], + "cols": ["C15", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null], + "custom": true, + "custom_lite": true + }, + "layouts": { + "LAYOUT_tkl_ansi": { + "layout": [ + {"matrix":[0,0], "x":0, "y":0}, + {"matrix":[0,1], "x":2, "y":0}, + {"matrix":[0,2], "x":3, "y":0}, + {"matrix":[0,3], "x":4, "y":0}, + {"matrix":[0,4], "x":5, "y":0}, + {"matrix":[0,5], "x":6.5, "y":0}, + {"matrix":[0,6], "x":7.5, "y":0}, + {"matrix":[0,7], "x":8.5, "y":0}, + {"matrix":[0,8], "x":9.5, "y":0}, + {"matrix":[0,9], "x":11, "y":0}, + {"matrix":[0,10], "x":12, "y":0}, + {"matrix":[0,11], "x":13, "y":0}, + {"matrix":[0,12], "x":14, "y":0}, + {"matrix":[0,14], "x":15.25, "y":0}, + {"matrix":[0,15], "x":16.25, "y":0}, + {"matrix":[0,16], "x":17.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":[1,15], "x":16.25, "y":1.25}, + {"matrix":[1,16], "x":17.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":[2,15], "x":16.25, "y":2.25}, + {"matrix":[2,16], "x":17.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":[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,13], "x":12.25, "y":4.25, "w":2.75}, + {"matrix":[4,15], "x":16.25, "y":4.25}, + + {"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,10], "x":10, "y":5.25, "w":1.25}, + {"matrix":[5,11], "x":11.25, "y":5.25, "w":1.25}, + {"matrix":[5,12], "x":12.5, "y":5.25, "w":1.25}, + {"matrix":[5,13], "x":13.75, "y":5.25, "w":1.25}, + {"matrix":[5,14], "x":15.25, "y":5.25}, + {"matrix":[5,15], "x":16.25, "y":5.25}, + {"matrix":[5,16], "x":17.25, "y":5.25} + ] + }, + "LAYOUT_tkl_iso": { + "layout": [ + {"matrix":[0,0], "x":0, "y":0}, + {"matrix":[0,1], "x":2, "y":0}, + {"matrix":[0,2], "x":3, "y":0}, + {"matrix":[0,3], "x":4, "y":0}, + {"matrix":[0,4], "x":5, "y":0}, + {"matrix":[0,5], "x":6.5, "y":0}, + {"matrix":[0,6], "x":7.5, "y":0}, + {"matrix":[0,7], "x":8.5, "y":0}, + {"matrix":[0,8], "x":9.5, "y":0}, + {"matrix":[0,9], "x":11, "y":0}, + {"matrix":[0,10], "x":12, "y":0}, + {"matrix":[0,11], "x":13, "y":0}, + {"matrix":[0,12], "x":14, "y":0}, + {"matrix":[0,14], "x":15.25, "y":0}, + {"matrix":[0,15], "x":16.25, "y":0}, + {"matrix":[0,16], "x":17.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":[1,15], "x":16.25, "y":1.25}, + {"matrix":[1,16], "x":17.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":[2,15], "x":16.25, "y":2.25}, + {"matrix":[2,16], "x":17.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":[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,13], "x":12.25, "y":4.25, "w":2.75}, + {"matrix":[4,15], "x":16.25, "y":4.25}, + + {"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,10], "x":10, "y":5.25, "w":1.25}, + {"matrix":[5,11], "x":11.25, "y":5.25, "w":1.25}, + {"matrix":[5,12], "x":12.5, "y":5.25, "w":1.25}, + {"matrix":[5,13], "x":13.75, "y":5.25, "w":1.25}, + {"matrix":[5,14], "x":15.25, "y":5.25}, + {"matrix":[5,15], "x":16.25, "y":5.25}, + {"matrix":[5,16], "x":17.25, "y":5.25} + ] + } + } +} diff --git a/keyboards/keychron/k1_pro/iso/rgb/config.h b/keyboards/keychron/k1_pro/iso/rgb/config.h new file mode 100755 index 00000000000..4d92ac5e9f2 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/config.h @@ -0,0 +1,106 @@ +/* Copyright 2023 @ 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 DRIVER_ADDR_1 0b1110111 +# define DRIVER_ADDR_2 0b1110100 + +/* RGB Matrix Configuration */ +# define DRIVER_1_LED_TOTAL 47 +# define DRIVER_2_LED_TOTAL 41 +# define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) +# define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) + +/* Set to infinit, which is use in USB mode by default */ +# define RGB_MATRIX_TIMEOUT RGB_MATRIX_TIMEOUT_INFINITE +# define RGB_DISABLE_TIMEOUT RGB_MATRIX_TIMEOUT_INFINITE + +/* Allow to shutdown driver to save power */ +# define RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE + +/* Turn off backllit if brightness value is low */ +# define RGB_MATRIX_BRIGHTNESS_TURN_OFF_VAL 48 + +/* Indication led */ +# define LOW_BAT_IND_INDEX 80 + +# define RGB_MATRIX_KEYPRESSES +# define RGB_MATRIX_FRAMEBUFFER_EFFECTS + +/* RGB Matrix Animation modes. Explicitly enabled + * For full list of effects, see: + * https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects + */ + +// # define ENABLE_RGB_MATRIX_ALPHAS_MODS +// # define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +// # define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_BREATHING +// # define ENABLE_RGB_MATRIX_BAND_SAT +// # define ENABLE_RGB_MATRIX_BAND_VAL +// # define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT +// # define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL +// # define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT +# define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL +# define ENABLE_RGB_MATRIX_CYCLE_ALL +# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN +# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL +# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL +# define ENABLE_RGB_MATRIX_DUAL_BEACON +# define ENABLE_RGB_MATRIX_RAINBOW_BEACON +// # define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +//# define ENABLE_RGB_MATRIX_RAINDROPS +# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +//# define ENABLE_RGB_MATRIX_HUE_BREATHING +//# define ENABLE_RGB_MATRIX_HUE_PENDULUM +//# define ENABLE_RGB_MATRIX_HUE_WAVE +# define ENABLE_RGB_MATRIX_PIXEL_RAIN +//# define ENABLE_RGB_MATRIX_PIXEL_FLOW +//# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL + +/* enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined */ +# define ENABLE_RGB_MATRIX_TYPING_HEATMAP +# define ENABLE_RGB_MATRIX_DIGITAL_RAIN + +/* enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined*/ +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE +//# define ENABLE_RGB_MATRIX_SOLID_REACTIVE +//# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE +//# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS +//# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS +//# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS +# define ENABLE_RGB_MATRIX_SPLASH +//# define ENABLE_RGB_MATRIX_MULTISPLASH +# define ENABLE_RGB_MATRIX_SOLID_SPLASH +//# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH + +/* Use first 9 channels of LED driver */ +# define PHASE_CHANNEL MSKPHASE_9CHANNEL + +/* Set LED driver current */ +# define CKLED2001_CURRENT_TUNE \ + { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } +#endif diff --git a/keyboards/keychron/k1_pro/iso/rgb/info.json b/keyboards/keychron/k1_pro/iso/rgb/info.json new file mode 100755 index 00000000000..528089dc746 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/info.json @@ -0,0 +1,130 @@ +{ + "usb": { + "pid": "0x0211", + "device_version": "1.0.2" + }, + "features": { + "rgb_matrix": true + }, + "rgb_matrix": { + "driver": "CKLED2001", + "animations": { + "breathing": true, + "band_spiral_val": true, + "cycle_all": true, + "cycle_left_right": true, + "cycle_up_down": true, + "rainbow_moving_chevron": true, + "cycle_out_in": true, + "cycle_out_in_dual": true, + "cycle_pinwheel": true, + "cycle_spiral": true, + "dual_beacon": true, + "rainbow_beacon": true, + "jellybean_raindrops": true, + "pixel_rain": true, + "typing_heatmap": true, + "digital_rain": true, + "solid_reactive_simple": true, + "solid_reactive_multiwide": true, + "solid_reactive_multinexus": true, + "splash": true, + "solid_splash": true + }, + "layout": [ + {"matrix":[0, 0], "flags":1, "x":0, "y":0}, + {"matrix":[0, 1], "flags":1, "x":26, "y":0}, + {"matrix":[0, 2], "flags":1, "x":39, "y":0}, + {"matrix":[0, 3], "flags":1, "x":52, "y":0}, + {"matrix":[0, 4], "flags":1, "x":65, "y":0}, + {"matrix":[0, 5], "flags":1, "x":85, "y":0}, + {"matrix":[0, 6], "flags":1, "x":98, "y":0}, + {"matrix":[0, 7], "flags":1, "x":111, "y":0}, + {"matrix":[0, 8], "flags":1, "x":124, "y":0}, + {"matrix":[0, 9], "flags":1, "x":144, "y":0}, + {"matrix":[0, 10], "flags":1, "x":157, "y":0}, + {"matrix":[0, 11], "flags":1, "x":170, "y":0}, + {"matrix":[0, 12], "flags":1, "x":183, "y":0}, + {"matrix":[0, 14], "flags":1, "x":197, "y":0}, + {"matrix":[0, 15], "flags":1, "x":210, "y":0}, + {"matrix":[0, 16], "flags":1, "x":224, "y":0}, + + {"matrix":[1, 0], "flags":1, "x":0, "y":13}, + {"matrix":[1, 1], "flags":8, "x":13, "y":13}, + {"matrix":[1, 2], "flags":8, "x":26, "y":13}, + {"matrix":[1, 3], "flags":8, "x":39, "y":13}, + {"matrix":[1, 4], "flags":4, "x":52, "y":13}, + {"matrix":[1, 5], "flags":4, "x":65, "y":13}, + {"matrix":[1, 6], "flags":4, "x":78, "y":13}, + {"matrix":[1, 7], "flags":4, "x":91, "y":13}, + {"matrix":[1, 8], "flags":4, "x":104, "y":13}, + {"matrix":[1, 9], "flags":4, "x":117, "y":13}, + {"matrix":[1, 10], "flags":4, "x":130, "y":13}, + {"matrix":[1, 11], "flags":4, "x":144, "y":13}, + {"matrix":[1, 12], "flags":4, "x":157, "y":13}, + {"matrix":[1, 13], "flags":1, "x":176, "y":13}, + {"matrix":[1, 14], "flags":1, "x":197, "y":13}, + {"matrix":[1, 15], "flags":1, "x":210, "y":13}, + {"matrix":[1, 16], "flags":1, "x":224, "y":13}, + + {"matrix":[2, 0], "flags":1, "x":3, "y":26}, + {"matrix":[2, 1], "flags":4, "x":19, "y":26}, + {"matrix":[2, 2], "flags":4, "x":32, "y":26}, + {"matrix":[2, 3], "flags":4, "x":45, "y":26}, + {"matrix":[2, 4], "flags":4, "x":58, "y":26}, + {"matrix":[2, 5], "flags":4, "x":72, "y":26}, + {"matrix":[2, 6], "flags":4, "x":85, "y":26}, + {"matrix":[2, 7], "flags":4, "x":98, "y":26}, + {"matrix":[2, 8], "flags":4, "x":111, "y":26}, + {"matrix":[2, 9], "flags":4, "x":124, "y":26}, + {"matrix":[2, 10], "flags":4, "x":137, "y":26}, + {"matrix":[2, 11], "flags":4, "x":150, "y":26}, + {"matrix":[2, 12], "flags":1, "x":163, "y":26}, + {"matrix":[2, 14], "flags":1, "x":197, "y":26}, + {"matrix":[2, 15], "flags":1, "x":210, "y":26}, + {"matrix":[2, 16], "flags":1, "x":224, "y":26}, + + {"matrix":[3, 0], "flags":8, "x":4, "y":38}, + {"matrix":[3, 1], "flags":4, "x":22, "y":38}, + {"matrix":[3, 2], "flags":4, "x":36, "y":38}, + {"matrix":[3, 3], "flags":4, "x":49, "y":38}, + {"matrix":[3, 4], "flags":4, "x":62, "y":38}, + {"matrix":[3, 5], "flags":4, "x":75, "y":38}, + {"matrix":[3, 6], "flags":4, "x":88, "y":38}, + {"matrix":[3, 7], "flags":4, "x":101, "y":38}, + {"matrix":[3, 8], "flags":4, "x":114, "y":38}, + {"matrix":[3, 9], "flags":4, "x":127, "y":38}, + {"matrix":[3, 10], "flags":4, "x":140, "y":38}, + {"matrix":[3, 11], "flags":4, "x":153, "y":38}, + {"matrix":[3, 13], "flags":1, "x":167, "y":38}, + {"matrix":[2, 13], "flags":1, "x":182, "y":33}, + + {"matrix":[4, 0], "flags":1, "x":8, "y":51}, + {"matrix":[4, 1], "flags":1, "x":16, "y":51}, + {"matrix":[4, 2], "flags":4, "x":29, "y":51}, + {"matrix":[4, 3], "flags":4, "x":42, "y":51}, + {"matrix":[4, 4], "flags":4, "x":55, "y":51}, + {"matrix":[4, 5], "flags":4, "x":68, "y":51}, + {"matrix":[4, 6], "flags":4, "x":81, "y":51}, + {"matrix":[4, 7], "flags":4, "x":94, "y":51}, + {"matrix":[4, 8], "flags":4, "x":108, "y":51}, + {"matrix":[4, 9], "flags":4, "x":121, "y":51}, + {"matrix":[4, 10], "flags":4, "x":134, "y":51}, + {"matrix":[4, 11], "flags":4, "x":147, "y":51}, + {"matrix":[4, 13], "flags":1, "x":171, "y":51}, + {"matrix":[4, 15], "flags":1, "x":210, "y":51}, + + {"matrix":[5, 0], "flags":1, "x":1, "y":64}, + {"matrix":[5, 1], "flags":1, "x":18, "y":64}, + {"matrix":[5, 2], "flags":1, "x":34, "y":64}, + {"matrix":[5, 6], "flags":4, "x":83, "y":64}, + {"matrix":[5, 10], "flags":1, "x":132, "y":64}, + {"matrix":[5, 11], "flags":1, "x":148, "y":64}, + {"matrix":[5, 12], "flags":1, "x":165, "y":64}, + {"matrix":[5, 13], "flags":1, "x":181, "y":64}, + {"matrix":[5, 14], "flags":1, "x":197, "y":64}, + {"matrix":[5, 15], "flags":1, "x":210, "y":64}, + {"matrix":[5, 16], "flags":1, "x":224, "y":64} + ] + } +} diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/default/keymap.c b/keyboards/keychron/k1_pro/iso/rgb/keymaps/default/keymap.c new file mode 100755 index 00000000000..68c9e9144f2 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/default/keymap.c @@ -0,0 +1,59 @@ +/* Copyright 2023 @ 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 + +enum layers{ + MAC_BASE, + MAC_FN, + WIN_BASE, + WIN_FN, +}; + +// clang-format off +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [MAC_BASE] = LAYOUT_tkl_iso( + KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_SNAP, KC_SIRI, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LOPTN, KC_LCMMD, KC_SPC, KC_RCMMD, KC_ROPTN, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [MAC_FN] = LAYOUT_tkl_iso( + _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, RGB_TOG, + _______, BT_HST1, BT_HST2, BT_HST3, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), + + [WIN_BASE] = LAYOUT_tkl_iso( + 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_PSCR, KC_CTANA, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LWIN, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [WIN_FN] = LAYOUT_tkl_iso( + _______, 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, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______) +}; diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/keymap.c b/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/keymap.c new file mode 100755 index 00000000000..68c9e9144f2 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/keymap.c @@ -0,0 +1,59 @@ +/* Copyright 2023 @ 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 + +enum layers{ + MAC_BASE, + MAC_FN, + WIN_BASE, + WIN_FN, +}; + +// clang-format off +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [MAC_BASE] = LAYOUT_tkl_iso( + KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_SNAP, KC_SIRI, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LOPTN, KC_LCMMD, KC_SPC, KC_RCMMD, KC_ROPTN, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [MAC_FN] = LAYOUT_tkl_iso( + _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, RGB_TOG, + _______, BT_HST1, BT_HST2, BT_HST3, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), + + [WIN_BASE] = LAYOUT_tkl_iso( + 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_PSCR, KC_CTANA, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LWIN, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [WIN_FN] = LAYOUT_tkl_iso( + _______, 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, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______) +}; diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/rules.mk b/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/rules.mk new file mode 100755 index 00000000000..45fa68954c1 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/config.h b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/config.h new file mode 100644 index 00000000000..bf43bab82ac --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/config.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#define VIAL_KEYBOARD_UID {0x4A, 0x55, 0x4E, 0x11, 0x2D, 0xCB, 0x3E, 0x05} + diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/keymap.c b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/keymap.c new file mode 100755 index 00000000000..68c9e9144f2 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/keymap.c @@ -0,0 +1,59 @@ +/* Copyright 2023 @ 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 + +enum layers{ + MAC_BASE, + MAC_FN, + WIN_BASE, + WIN_FN, +}; + +// clang-format off +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [MAC_BASE] = LAYOUT_tkl_iso( + KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_SNAP, KC_SIRI, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LOPTN, KC_LCMMD, KC_SPC, KC_RCMMD, KC_ROPTN, MO(MAC_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [MAC_FN] = LAYOUT_tkl_iso( + _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, RGB_TOG, + _______, BT_HST1, BT_HST2, BT_HST3, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), + + [WIN_BASE] = LAYOUT_tkl_iso( + 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_PSCR, KC_CTANA, RGB_MOD, + 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_INS, KC_HOME, KC_PGUP, + 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_DEL, KC_END, KC_PGDN, + 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_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_LWIN, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(WIN_FN),KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + + [WIN_FN] = LAYOUT_tkl_iso( + _______, 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, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + 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, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______) +}; diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/rules.mk b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/rules.mk new file mode 100755 index 00000000000..df35dded1c3 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/rules.mk @@ -0,0 +1,5 @@ +VIA_ENABLE = yes +VIAL_ENABLE = yes +VIAL_INSECURE = yes +VIALRGB_ENABLE = yes +LTO_ENABLE = yes diff --git a/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/vial.json b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/vial.json new file mode 100644 index 00000000000..f333eddd820 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/keymaps/vial/vial.json @@ -0,0 +1,304 @@ +{ + "name": "Keychron K1 Pro", + "vendorId": "0x3434", + "productId": "0x0211", + "lighting": "vialrgb", + "matrix": { + "rows": 6, + "cols": 17 + }, + "customKeycodes": [ + { + "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": "Misson Control", + "title": "Misson Control, availabe in macOS", + "shortName": "MCtrl" + }, + { + "name": "Launch pad", + "title": "Launch pad, availabe in macOS", + "shortName": "LPad" + }, + { + "name": "Task View", + "title": "Task View in Windows", + "shortName": "Task" + }, + { + "name": "File Explorer", + "title": "File Explorer in Windows", + "shortName": "File" + }, + { + "name": "Screen shot", + "title": "Screenshot in macOS", + "shortName": "SShot" + }, + { + "name": "Cortana", + "title": "Cortana in Windows", + "shortName": "Cortana" + }, + { + "name": "Siri", + "title": "Siri in macOS", + "shortName": "Siri" + }, + { + "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": "Battery Level", + "title": "Show battery level", + "shortName": "Batt" + } + ], + "layouts": { + "keymap": [ + [ + { + "c": "#777777" + }, + "0,0", + { + "x": 1, + "c": "#cccccc" + }, + "0,1", + "0,2", + "0,3", + "0,4", + { + "x": 0.5, + "c": "#aaaaaa" + }, + "0,5", + "0,6", + "0,7", + "0,8", + { + "x": 0.5, + "c": "#cccccc" + }, + "0,9", + "0,10", + "0,11", + "0,12", + { + "x": 0.25, + "c": "#aaaaaa" + }, + "0,14", + "0,15", + "0,16" + ], + [ + { + "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", + "1,15", + "1,16" + ], + [ + { + "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, + "w": 1.25, + "h": 2, + "x2": -0.25, + "w2": 1.5, + "h2": 1, + "c": "#777777" + }, + "2,13", + { + "c": "#aaaaaa" + }, + { + "x": 0.25 + }, + "2,14", + "2,15", + "2,16" + ], + [ + { + "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", + { + "c": "#aaaaaa" + }, + "3,13" + ], + [ + { + "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": 2.75, + "c": "#aaaaaa" + }, + "4,13", + { + "x": 1.25, + "c": "#cccccc" + }, + "4,15" + ], + [ + { + "w": 1.25, + "c": "#aaaaaa" + }, + "5,0", + { + "w": 1.25 + }, + "5,1", + { + "w": 1.25 + }, + "5,2", + { + "w": 6.25, + "c": "#cccccc" + }, + "5,6", + { + "w": 1.25, + "c": "#aaaaaa" + }, + "5,10", + { + "w": 1.25 + }, + "5,11", + { + "w": 1.25 + }, + "5,12", + { + "w": 1.25, + "c": "#aaaaaa" + }, + "5,13", + { + "x": 0.25, + "c": "#cccccc" + }, + "5,14", + "5,15", + "5,16" + ] + ] + } +} + diff --git a/keyboards/keychron/k1_pro/iso/rgb/rgb.c b/keyboards/keychron/k1_pro/iso/rgb/rgb.c new file mode 100755 index 00000000000..b2bd1fd09bd --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/rgb.c @@ -0,0 +1,122 @@ +/* Copyright 2023 @ 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" + +// clang-format off +#ifdef RGB_MATRIX_ENABLE +const ckled2001_led g_ckled2001_leds[RGB_MATRIX_LED_COUNT] = { +/* Refer to CKLED2001 manual for these locations + * driver + * | R location + * | | G location + * | | | B location + * | | | | */ + {0, I_1, G_1, H_1}, + {0, I_2, G_2, H_2}, + {0, I_3, G_3, H_3}, + {0, I_4, G_4, H_4}, + {0, I_5, G_5, H_5}, + {0, I_6, G_6, H_6}, + {0, I_7, G_7, H_7}, + {0, I_8, G_8, H_8}, + {0, I_9, G_9, H_9}, + {0, I_10, G_10, H_10}, + {0, I_11, G_11, H_11}, + {0, I_12, G_12, H_12}, + {0, I_13, G_13, H_13}, + {0, I_15, G_15, H_15}, + {0, I_16, G_16, H_16}, + {1, F_8, D_8, E_8}, + + {0, F_1, D_1, E_1}, + {0, F_2, D_2, E_2}, + {0, F_3, D_3, E_3}, + {0, F_4, D_4, E_4}, + {0, F_5, D_5, E_5}, + {0, F_6, D_6, E_6}, + {0, F_7, D_7, E_7}, + {0, F_8, D_8, E_8}, + {0, F_9, D_9, E_9}, + {0, F_10, D_10, E_10}, + {0, F_11, D_11, E_11}, + {0, F_12, D_12, E_12}, + {0, F_13, D_13, E_13}, + {0, F_14, D_14, E_14}, + {0, F_15, D_15, E_15}, + {0, F_16, D_16, E_16}, + {1, F_9, D_9, E_9}, + + {0, A_1, C_1, B_1}, + {0, A_2, C_2, B_2}, + {0, A_3, C_3, B_3}, + {0, A_4, C_4, B_4}, + {0, A_5, C_5, B_5}, + {0, A_6, C_6, B_6}, + {0, A_7, C_7, B_7}, + {0, A_8, C_8, B_8}, + {0, A_9, C_9, B_9}, + {0, A_10, C_10, B_10}, + {0, A_11, C_11, B_11}, + {0, A_12, C_12, B_12}, + {0, A_13, C_13, B_13}, + {0, A_15, C_15, B_15}, + {0, A_16, C_16, B_16}, + {1, F_6, D_6, E_6}, + + {1, I_1, G_1, H_1}, + {1, I_2, G_2, H_2}, + {1, I_3, G_3, H_3}, + {1, I_4, G_4, H_4}, + {1, I_5, G_5, H_5}, + {1, I_6, G_6, H_6}, + {1, I_7, G_7, H_7}, + {1, I_8, G_8, H_8}, + {1, I_9, G_9, H_9}, + {1, I_10, G_10, H_10}, + {1, I_11, G_11, H_11}, + {1, I_12, G_12, H_12}, + {1, I_14, G_14, H_14}, + {0, A_14, C_14, B_14}, + + {1, C_1, A_1, B_1}, + {1, C_2, A_2, B_2}, + {1, C_3, A_3, B_3}, + {1, C_4, A_4, B_4}, + {1, C_5, A_5, B_5}, + {1, C_6, A_6, B_6}, + {1, C_7, A_7, B_7}, + {1, C_8, A_8, B_8}, + {1, C_9, A_9, B_9}, + {1, C_10, A_10, B_10}, + {1, C_11, A_11, B_11}, + {1, C_12, A_12, B_12}, + {1, C_14, A_14, B_14}, + {1, C_16, A_16, B_16}, + + {1, F_1, D_1, E_1}, + {1, F_2, D_2, E_2}, + {1, F_3, D_3, E_3}, + {1, F_7, D_7, E_7}, + {1, F_11, D_11, E_11}, + {1, F_12, D_12, E_12}, + {1, F_13, D_13, E_13}, + {1, F_14, D_14, E_14}, + {1, F_15, D_15, E_15}, + {1, F_16, D_16, E_16}, + {1, C_15, A_15, B_15} +}; +#endif diff --git a/keyboards/keychron/k1_pro/iso/rgb/rules.mk b/keyboards/keychron/k1_pro/iso/rgb/rules.mk new file mode 100755 index 00000000000..6e7633bfe01 --- /dev/null +++ b/keyboards/keychron/k1_pro/iso/rgb/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/keychron/k1_pro/k1_pro.c b/keyboards/keychron/k1_pro/k1_pro.c new file mode 100644 index 00000000000..ebf1b9119c5 --- /dev/null +++ b/keyboards/keychron/k1_pro/k1_pro.c @@ -0,0 +1,325 @@ +/* Copyright 2023 @ 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 "k1_pro.h" +#ifdef KC_BLUETOOTH_ENABLE +# include "ckbt51.h" +# include "bluetooth.h" +# include "indicator.h" +# include "transport.h" +# include "battery.h" +# include "bat_level_animation.h" +# include "lpm.h" +#endif + +#ifdef ENABLE_FACTORY_TEST +# include "factory_test.h" +#endif + +#define POWER_ON_LED_DURATION 3000 + +typedef struct PACKED { + uint8_t len; + uint8_t keycode[3]; +} key_combination_t; + +static uint32_t factory_timer_buffer = 0; +static uint32_t power_on_indicator_timer_buffer = 0; +static uint32_t siri_timer_buffer = 0; +static uint8_t mac_keycode[4] = {KC_LOPT, KC_ROPT, KC_LCMD, KC_RCMD}; + +key_combination_t key_comb_list[4] = { + {2, {KC_LWIN, KC_TAB}}, // Task (win) + {2, {KC_LWIN, KC_E}}, // Files (win) + {3, {KC_LSFT, KC_LGUI, KC_4}}, // Snapshot (mac) + {2, {KC_LWIN, KC_C}} // Cortana (win) +}; + +#ifdef KC_BLUETOOTH_ENABLE +bool firstDisconnect = true; +bool bt_factory_reset = false; +static virtual_timer_t pairing_key_timer; +extern uint8_t g_pwm_buffer[DRIVER_COUNT][192]; + +static void pairing_key_timer_cb(void *arg) { + bluetooth_pairing_ex(*(uint8_t *)arg, NULL); +} +#endif + +bool dip_switch_update_kb(uint8_t index, bool active) { + if (index == 0) { +#ifdef INVERT_OS_SWITCH_STATTE + default_layer_set(1UL << (!active ? 0 : 2)); +#else + default_layer_set(1UL << (active ? 0 : 2)); +#endif + } + dip_switch_update_user(index, active); + + return true; +} + +#ifdef KC_BLUETOOTH_ENABLE +bool process_record_kb_bt(uint16_t keycode, keyrecord_t *record) { +#else +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { +#endif + static uint8_t host_idx = 0; + + switch (keycode) { + case KC_LOPTN: + case KC_ROPTN: + case KC_LCMMD: + case KC_RCMMD: + if (record->event.pressed) { + register_code(mac_keycode[keycode - KC_LOPTN]); + } else { + unregister_code(mac_keycode[keycode - KC_LOPTN]); + } + return false; // Skip all further processing of this key) + case KC_TASK: + case KC_FILE: + case KC_SNAP: + case KC_CTANA: + if (record->event.pressed) { + for (uint8_t i = 0; i < key_comb_list[keycode - KC_TASK].len; i++) + register_code(key_comb_list[keycode - KC_TASK].keycode[i]); + } else { + for (uint8_t i = 0; i < key_comb_list[keycode - KC_TASK].len; i++) + unregister_code(key_comb_list[keycode - KC_TASK].keycode[i]); + } + return false; // Skip all further processing of this key + case KC_SIRI: + if (record->event.pressed && siri_timer_buffer == 0) { + register_code(KC_LGUI); + register_code(KC_SPACE); + siri_timer_buffer = sync_timer_read32() | 1; + } + return false; // Skip all further processing of this key +#ifdef KC_BLUETOOTH_ENABLE + case BT_HST1 ... BT_HST3: + if (get_transport() == TRANSPORT_BLUETOOTH) { + if (record->event.pressed) { + host_idx = keycode - BT_HST1 + 1; + chVTSet(&pairing_key_timer, TIME_MS2I(2000), (vtfunc_t)pairing_key_timer_cb, &host_idx); + bluetooth_connect_ex(host_idx, 0); + } else { + host_idx = 0; + chVTReset(&pairing_key_timer); + } + } + break; + case BAT_LVL: + if (get_transport() == TRANSPORT_BLUETOOTH && !usb_power_connected()) { + bat_level_animiation_start(battery_get_percentage()); + } + break; +#endif + default: +#ifdef FACTORY_RESET_CHECK + FACTORY_RESET_CHECK(keycode, record); +#endif + break; + } + return true; +} + +void keyboard_post_init_kb(void) { + dip_switch_read(true); + +#ifdef KC_BLUETOOTH_ENABLE + /* Currently we don't use this reset pin */ + palSetLineMode(CKBT51_RESET_PIN, PAL_MODE_OUTPUT_PUSHPULL); + palWriteLine(CKBT51_RESET_PIN, PAL_HIGH); + + /* IMPORTANT: DO NOT enable internal pull-up resistor + * as there is an external pull-down resistor. + */ + palSetLineMode(USB_BT_MODE_SELECT_PIN, PAL_MODE_INPUT); + + ckbt51_init(false); + bluetooth_init(); +#endif + + power_on_indicator_timer_buffer = sync_timer_read32() | 1; +#ifdef KC_BLUETOOTH_ENABLE + writePin(H3, HOST_LED_PIN_ON_STATE); +#endif + writePin(BAT_LOW_LED_PIN, BAT_LOW_LED_PIN_ON_STATE); + writePin(LED_CAPS_LOCK_PIN, LED_PIN_ON_STATE); + + keyboard_post_init_user(); +} + +void matrix_scan_kb(void) { + if (factory_timer_buffer && timer_elapsed32(factory_timer_buffer) > 2000) { + factory_timer_buffer = 0; + if (bt_factory_reset) { + bt_factory_reset = false; + palWriteLine(CKBT51_RESET_PIN, PAL_LOW); + wait_ms(5); + palWriteLine(CKBT51_RESET_PIN, PAL_HIGH); + } + } + + if (power_on_indicator_timer_buffer) { + if (sync_timer_elapsed32(power_on_indicator_timer_buffer) > POWER_ON_LED_DURATION) { + power_on_indicator_timer_buffer = 0; + writePin(H3, !HOST_LED_PIN_ON_STATE); + writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE); + if (!host_keyboard_led_state().caps_lock) writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE); + } else { + writePin(H3, HOST_LED_PIN_ON_STATE); + writePin(BAT_LOW_LED_PIN, BAT_LOW_LED_PIN_ON_STATE); + writePin(LED_CAPS_LOCK_PIN, LED_PIN_ON_STATE); + } + } + + if (siri_timer_buffer && sync_timer_elapsed32(siri_timer_buffer) > 500) { + siri_timer_buffer = 0; + unregister_code(KC_LGUI); + unregister_code(KC_SPACE); + } + +#ifdef FACTORY_RESET_TASK + FACTORY_RESET_TASK(); +#endif + matrix_scan_user(); +} + +#ifdef KC_BLUETOOTH_ENABLE +static void ckbt51_param_init(void) { + /* Set bluetooth device name */ + ckbt51_set_local_name(STR(PRODUCT)); + wait_ms(10); + /* Set bluetooth parameters */ + module_param_t param = {.event_mode = 0x02, + .connected_idle_timeout = 7200, + .pairing_timeout = 180, + .pairing_mode = 0, + .reconnect_timeout = 5, + .report_rate = 90, + .vendor_id_source = 1, + .verndor_id = 0, // Must be 0x3434 + .product_id = PRODUCT_ID}; + ckbt51_set_param(¶m); + wait_ms(10); +} + +void bluetooth_enter_disconnected_kb(uint8_t host_idx) { + if (bt_factory_reset) { + ckbt51_param_init(); + factory_timer_buffer = timer_read32(); + } + /* CKBT51 bluetooth module boot time is slower, it enters disconnected after boot, + so we place initialization here. */ + if (firstDisconnect && sync_timer_read32() < 1000 && get_transport() == TRANSPORT_BLUETOOTH) { + ckbt51_param_init(); + bluetooth_connect(); + firstDisconnect = false; + } +} + +void ckbt51_default_ack_handler(uint8_t *data, uint8_t len) { + if (data[1] == 0x45) { + module_param_t param = {.event_mode = 0x02, + .connected_idle_timeout = 7200, + .pairing_timeout = 180, + .pairing_mode = 0, + .reconnect_timeout = 5, + .report_rate = 90, + .vendor_id_source = 1, + .verndor_id = 0, // Must be 0x3434 + .product_id = PRODUCT_ID}; + ckbt51_set_param(¶m); + } +} + +void bluetooth_pre_task(void) { + static uint8_t mode = 1; + + if (readPin(USB_BT_MODE_SELECT_PIN) != mode) { + if (readPin(USB_BT_MODE_SELECT_PIN) != mode) { + mode = readPin(USB_BT_MODE_SELECT_PIN); + set_transport(mode == 0 ? TRANSPORT_BLUETOOTH : TRANSPORT_USB); + } + } +} +#endif + +void battery_calculte_voltage(uint16_t value) { + uint16_t voltage = ((uint32_t)value) * 2246 / 1000; + +#ifdef LED_MATRIX_ENABLE + if (led_matrix_is_enabled()) { + uint32_t totalBuf = 0; + + for (uint8_t i = 0; i < DRIVER_COUNT; i++) + for (uint8_t j = 0; j < 192; j++) + totalBuf += g_pwm_buffer[i][j]; + /* We assumpt it is linear relationship*/ + voltage += (30 * totalBuf / LED_MATRIX_LED_COUNT / 255); + } +#endif +#ifdef RGB_MATRIX_ENABLE + if (rgb_matrix_is_enabled()) { + uint32_t totalBuf = 0; + + for (uint8_t i = 0; i < DRIVER_COUNT; i++) + for (uint8_t j = 0; j < 192; j++) + totalBuf += g_pwm_buffer[i][j]; + /* We assumpt it is linear relationship*/ + uint32_t compensation = 60 * totalBuf / RGB_MATRIX_LED_COUNT / 255 / 3; + voltage += compensation; + } +#endif + battery_set_voltage(voltage); +} + +bool via_command_kb(uint8_t *data, uint8_t length) { + switch (data[0]) { +#ifdef KC_BLUETOOTH_ENABLE + case 0xAA: + ckbt51_dfu_rx(data, length); + break; +#endif +#ifdef ENABLE_FACTORY_TEST + 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; + } +} +#endif + +void suspend_wakeup_init_kb(void) { + // code will run on keyboard wakeup + clear_keyboard(); + send_keyboard_report(); +} diff --git a/keyboards/keychron/k1_pro/k1_pro.h b/keyboards/keychron/k1_pro/k1_pro.h new file mode 100644 index 00000000000..bc1b1c5090c --- /dev/null +++ b/keyboards/keychron/k1_pro/k1_pro.h @@ -0,0 +1,57 @@ +/* Copyright 2023 @ 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 "quantum.h" +#ifdef VIA_ENABLE +# include "via.h" +#endif + +#define ___ KC_NO + +#ifdef VIA_ENABLE +# define USER_START USER00 +#else +# define USER_START SAFE_RANGE +#endif + +// clang-format off +enum { + KC_LOPTN = USER_START, + KC_ROPTN, + KC_LCMMD, + KC_RCMMD, + KC_MCTL, + KC_LPAD, + KC_TASK, + KC_FILE, + KC_SNAP, + KC_CTANA, + KC_SIRI, +#ifdef KC_BLUETOOTH_ENABLE + BT_HST1, + BT_HST2, + BT_HST3, + BAT_LVL, +#else + BT_HST1 = KC_TRNS, + BT_HST2 = KC_TRNS, + BT_HST3 = KC_TRNS, + BAT_LVL = KC_TRNS, +#endif + NEW_SAFE_RANGE +}; diff --git a/keyboards/keychron/k1_pro/matrix.c b/keyboards/keychron/k1_pro/matrix.c new file mode 100644 index 00000000000..1ef3f960503 --- /dev/null +++ b/keyboards/keychron/k1_pro/matrix.c @@ -0,0 +1,190 @@ +/* Copyright 2023 @ 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" + +#define HC595_STCP B0 +#define HC595_SHCP A1 +#define HC595_DS A7 + +#define DIRECT_COL_NUM 1 + +pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; + +static inline uint8_t readMatrixPin(pin_t pin) { + if (pin != NO_PIN) { + return readPin(pin); + } else { + return 1; + } +} + +static inline void setPinOutput_writeLow(pin_t pin) { + setPinOutput(pin); + writePinLow(pin); +} + +static inline void setPinOutput_writeHigh(pin_t pin) { + setPinOutput(pin); + writePinHigh(pin); +} + +static inline void HC595_delay(uint16_t n) { + while (n-- > 0) { + asm volatile("nop" ::: "memory"); + } +} + +static void HC595_output(uint16_t data) { + uint8_t n = 1; + uint8_t i; + + for (i = 0; i < (MATRIX_COLS - DIRECT_COL_NUM); i++) { + writePinLow(HC595_SHCP); + if (data & 0x1) { + writePinHigh(HC595_DS); + } else { + writePinLow(HC595_DS); + } + HC595_delay(n); + writePinHigh(HC595_SHCP); + HC595_delay(n); + + data = data >> 1; + } + writePinLow(HC595_STCP); + HC595_delay(n); + writePinHigh(HC595_STCP); +} + +static void HC595_output_bit(uint16_t data) { + uint8_t n = 1; + + writePinLow(HC595_SHCP); + if (data & 0x1) { + writePinHigh(HC595_DS); + } else { + writePinLow(HC595_DS); + } + HC595_delay(n); + + writePinHigh(HC595_SHCP); + HC595_delay(n); + + writePinLow(HC595_STCP); + HC595_delay(n); + writePinHigh(HC595_STCP); +} + +static void select_col(uint8_t col) { + if (col < DIRECT_COL_NUM) { + setPinOutput_writeLow(col_pins[col]); + } else { + if (col == DIRECT_COL_NUM) { + HC595_output_bit(0x00); + } + } +} + +static void unselect_col(uint8_t col) { + if (col < DIRECT_COL_NUM) { +#ifdef MATRIX_UNSELECT_DRIVE_HIGH + setPinOutput_writeHigh(col_pins[col]); +#else + setPinInputHigh(col_pins[col]); +#endif + } else { + HC595_output_bit(0x01); + } +} + +static void unselect_cols(void) { + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + if (x < DIRECT_COL_NUM) { +#ifdef MATRIX_UNSELECT_DRIVE_HIGH + setPinOutput_writeHigh(col_pins[x]); +#else + setPinInputHigh(col_pins[x]); +#endif + } else { + if (x == DIRECT_COL_NUM) HC595_output(0xFFFF); + break; + } + } +} + +void select_all_cols(void) { + for (uint8_t x = 0; x < MATRIX_COLS; x++) { + if (x < DIRECT_COL_NUM) { + setPinOutput_writeLow(col_pins[x]); + } else { + if (x == DIRECT_COL_NUM) HC595_output(0x0000); + break; + } + } +} + +static void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) { + // Select col + select_col(current_col); + HC595_delay(200); + + // For each row... + for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) { + // Check row pin state + if (readMatrixPin(row_pins[row_index]) == 0) { + // Pin LO, set col bit + current_matrix[row_index] |= row_shifter; + } else { + // Pin HI, clear col bit + current_matrix[row_index] &= ~row_shifter; + } + } + + // Unselect col + unselect_col(current_col); + HC595_delay(200); // wait for all Row signals to go HIGH +} + +void matrix_init_custom(void) { + setPinOutput(HC595_DS); + setPinOutput(HC595_STCP); + setPinOutput(HC595_SHCP); + + for (uint8_t x = 0; x < MATRIX_ROWS; x++) { + if (row_pins[x] != NO_PIN) { + setPinInputHigh(row_pins[x]); + } + } + + unselect_cols(); +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + matrix_row_t curr_matrix[MATRIX_ROWS] = {0}; + + // Set col, read rows + matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; + for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++, row_shifter <<= 1) { + matrix_read_rows_on_col(curr_matrix, current_col, row_shifter); + } + + bool changed = memcmp(current_matrix, curr_matrix, sizeof(curr_matrix)) != 0; + if (changed) memcpy(current_matrix, curr_matrix, sizeof(curr_matrix)); + + return changed; +} diff --git a/keyboards/keychron/k1_pro/mcuconf.h b/keyboards/keychron/k1_pro/mcuconf.h new file mode 100644 index 00000000000..30b6109616f --- /dev/null +++ b/keyboards/keychron/k1_pro/mcuconf.h @@ -0,0 +1,39 @@ +/* Copyright 2020 QMK + * + * 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 + +/* Set HCLK to 48 MHz as tradeoff of USB lowest clockand and + * lower power comsumption for bluetooth. Will use dynamic + * clock when STM32L4 is supported in ChibiOS */ +#undef STM32_PLLM_VALUE +#define STM32_PLLM_VALUE 2 + +#undef STM32_PLLN_VALUE +#define STM32_PLLN_VALUE 12 + +#undef STM32_I2C_USE_I2C1 +#define STM32_I2C_USE_I2C1 TRUE + +#ifdef KC_BLUETOOTH_ENABLE +# undef STM32_SERIAL_USE_USART2 +# define STM32_SERIAL_USE_USART2 TRUE +#endif + + + diff --git a/keyboards/keychron/k1_pro/readme.md b/keyboards/keychron/k1_pro/readme.md new file mode 100644 index 00000000000..cf906787b3f --- /dev/null +++ b/keyboards/keychron/k1_pro/readme.md @@ -0,0 +1,31 @@ +# Keychron K1 Pro + +![Keychron K1 Pro](https://github.com/Keychron/ProductImage/blob/main/K_Pro/k1_pro.jpg?raw=true) + +A customizable 80% TKL keyboard. + +* Keyboard Maintainer: [Keychron](https://github.com/keychron) +* Hardware Supported: Keychron K1 Pro +* Hardware Availability: [Keychron K1 Pro QMK/VIA Wireless Custom Mechanical Keyboard](https://www.keychron.com/products/keychron-k1-pro-qmk-via-wireless-custom-mechanical-keyboard) + +Initial build environment setup (brief) + cd ~ + pipx install qmk + git clone https://github.com/Keychron/vial-qmk/ + cd vial-qmk/ + #qmk setup //run once to setup deps etc. need sudo. + git checkout bluetooth_playground + make git-submodule + +Make VIAL for this keyboard (after setting up your build environment): + + make keychron/k1_pro/iso/rgb:vial + + +Make VIAL for this keyboard and flash for this keyboard: + + make keychron/k1_pro/iso/rgb:vial:flash + +**Reset Key**: Connect the USB cable, toggle mode switch to "Off", hold down the *Esc* key or reset button underneath space bar, then toggle then switch to "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/keychron/k1_pro/rules.mk b/keyboards/keychron/k1_pro/rules.mk new file mode 100644 index 00000000000..e5ecee33533 --- /dev/null +++ b/keyboards/keychron/k1_pro/rules.mk @@ -0,0 +1,17 @@ +# Build Options +# change yes to no to disable +# +BLUETOOTH_ENABLE = no # Enable Bluetooth with +BLUETOOTH_DRIVER = custom + +EEPROM_DRIVER = wear_leveling +WEAR_LEVELING_DRIVER = embedded_flash + +# Enter lower-power sleep mode when on the ChibiOS idle thread +OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE +OPT_DEFS += -DNO_USB_STARTUP_CHECK -DENABLE_FACTORY_TEST +OPT_DEFS += -DKC_BLUETOOTH_ENABLE + +SRC += matrix.c + +include keyboards/keychron/bluetooth/bluetooth.mk