From 2ec82dd56b67685791422ae8f949b153536335cf Mon Sep 17 00:00:00 2001
From: lalalademaxiya1 <2831039915@qq.com>
Date: Thu, 20 Jan 2022 11:42:00 +0800
Subject: [PATCH] Update v4.
---
keyboards/keychron/v4/chconf.h | 30 +++++
keyboards/keychron/v4/config.h | 119 ++++++++++++++++++
keyboards/keychron/v4/halconf.h | 27 ++++
keyboards/keychron/v4/mcuconf.h | 30 +++++
keyboards/keychron/v4/readme.md | 19 +++
keyboards/keychron/v4/test.c | 210 ++++++++++++++++++++++++++++++++
keyboards/keychron/v4/v4.c | 34 ++++++
keyboards/keychron/v4/v4.h | 23 ++++
8 files changed, 492 insertions(+)
create mode 100644 keyboards/keychron/v4/chconf.h
create mode 100644 keyboards/keychron/v4/config.h
create mode 100644 keyboards/keychron/v4/halconf.h
create mode 100644 keyboards/keychron/v4/mcuconf.h
create mode 100644 keyboards/keychron/v4/readme.md
create mode 100644 keyboards/keychron/v4/test.c
create mode 100644 keyboards/keychron/v4/v4.c
create mode 100644 keyboards/keychron/v4/v4.h
diff --git a/keyboards/keychron/v4/chconf.h b/keyboards/keychron/v4/chconf.h
new file mode 100644
index 0000000000..a331fdef37
--- /dev/null
+++ b/keyboards/keychron/v4/chconf.h
@@ -0,0 +1,30 @@
+/* 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 .
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/acheron/arctic/chconf.h -r platforms/chibios/common/configs/chconf.h`
+ */
+
+#pragma once
+
+#define CH_CFG_ST_FREQUENCY 10000
+
+#define CH_CFG_OPTIMIZE_SPEED FALSE
+
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+
+#include_next
\ No newline at end of file
diff --git a/keyboards/keychron/v4/config.h b/keyboards/keychron/v4/config.h
new file mode 100644
index 0000000000..9b0aa14899
--- /dev/null
+++ b/keyboards/keychron/v4/config.h
@@ -0,0 +1,119 @@
+/* Copyright 2021 @ 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
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x3434
+#define MANUFACTURER Keychron
+#define PRODUCT Keychron V4
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+
+/* key matrix pins */
+#define MATRIX_ROW_PINS { B4, B3, A15, A14, A13 }
+#define MATRIX_COL_PINS { C14, C15, A0, A1, A2, A3, A4, A5, A6, A7, B0, B1, A8, A9 }
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION ROW2COL
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 5
+
+/* Disable DIP switch in matrix data */
+#define MATRIX_MASKED
+
+/* NKRO */
+#define FORCE_NKRO
+
+/* turn off effects when suspended */
+#define RGB_DISABLE_WHEN_USB_SUSPENDED
+
+/* RGB Matrix Driver Configuration */
+#define DRIVER_COUNT 2
+#define DRIVER_ADDR_1 0b1110111
+#define DRIVER_ADDR_2 0b1110100
+
+/* DIP switch */
+#define DIP_SWITCH_MATRIX_GRID \
+ { \
+ { 4, 4 } \
+ }
+
+/* Scan phase of led driver set as MSKPHASE_9CHANNEL(defined as 0x03 in CKLED2001.h) */
+#define PHASE_CHANNEL MSKPHASE_9CHANNEL
+
+/* We have 2KB EEPROM size on STM32L432 */
+#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 2047
+
+/* Set 5 dynamic keymap layers */
+#define DYNAMIC_KEYMAP_LAYER_COUNT 5
+
+// 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
+
+/* Allow VIA to edit lighting */
+#ifdef VIA_ENABLE
+# define VIA_QMK_RGBLIGHT_ENABLE
+#endif
diff --git a/keyboards/keychron/v4/halconf.h b/keyboards/keychron/v4/halconf.h
new file mode 100644
index 0000000000..5614639e79
--- /dev/null
+++ b/keyboards/keychron/v4/halconf.h
@@ -0,0 +1,27 @@
+/* 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 .
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/nk65/halconf.h -r platforms/chibios/QMK_PROTON_C/configs/halconf.h`
+ */
+
+#pragma once
+
+#define HAL_USE_I2C TRUE
+#define HAL_USE_GPT TRUE
+
+#include_next
\ No newline at end of file
diff --git a/keyboards/keychron/v4/mcuconf.h b/keyboards/keychron/v4/mcuconf.h
new file mode 100644
index 0000000000..b272140692
--- /dev/null
+++ b/keyboards/keychron/v4/mcuconf.h
@@ -0,0 +1,30 @@
+/* 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 .
+ */
+
+/*
+ * This file was auto-generated by:
+ * `qmk chibios-confmigrate -i keyboards/acheron/arctic/mcuconf.h -r platforms/chibios/GENERIC_STM32_F072XB/configs/mcuconf.h`
+ */
+
+#pragma once
+
+#include_next
+
+#undef STM32_I2C_USE_I2C1
+#define STM32_I2C_USE_I2C1 TRUE
+
+#undef STM32_GPT_USE_TIM1
+#define STM32_GPT_USE_TIM1 TRUE
\ No newline at end of file
diff --git a/keyboards/keychron/v4/readme.md b/keyboards/keychron/v4/readme.md
new file mode 100644
index 0000000000..df4eab16d0
--- /dev/null
+++ b/keyboards/keychron/v4/readme.md
@@ -0,0 +1,19 @@
+# Keychron V4
+
+A customizable 60% keyboard.
+
+* Keyboard Maintainer: [Keychron](https://github.com/keychron)
+* Hardware Supported: Keychron V4
+* Hardware Availability: [Keychron](https://www.keychron.com)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make keychron/v4/v4_ansi_stm32l432:default
+
+Flashing example for this keyboard ([after setting up the bootloadHID flashing environment](https://docs.qmk.fm/#/flashing_bootloadhid))
+
+ make keychron/q4/v4_ansi_stm32l432:default:flash
+
+**Reset Key**: Hold down the key located at *K00*, commonly programmed as *Esc* while plugging in the keyboard.
+
+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/v4/test.c b/keyboards/keychron/v4/test.c
new file mode 100644
index 0000000000..658c0aa29b
--- /dev/null
+++ b/keyboards/keychron/v4/test.c
@@ -0,0 +1,210 @@
+#include "eeconfig.h"
+
+#define _FN1 2
+#define _FN2 3
+
+enum colors { WHITE, RED, GREEN, BLUE };
+
+enum colors led_color_status = WHITE;
+
+enum mode { NONE, TEST_OR_CLEAR, LED_BLINK };
+
+enum mode test_clear_blink = NONE;
+static uint8_t key_press = 0;
+static uint32_t key_count = 0;
+static bool key_count_flag = false;
+static uint16_t current_time = 0;
+static uint16_t passed_time = 0;
+static bool entry_led_test_flag = false;
+static uint8_t led_state = 0;
+static uint32_t led_time_buffer = 0;
+static uint8_t time_200ms = 0;
+
+HSV hsv;
+
+void led_test(uint8_t color);
+void clear_eeprom(void);
+
+bool process_record_kb(uint16_t keycode, keyrecord_t* record) {
+ switch (keycode) {
+ case MO(_FN1):
+ case MO(_FN2):
+ if (record->event.pressed) {
+ key_press += 1;
+ key_count += 1;
+ key_count_flag = true;
+ } else {
+ key_press = 0;
+ key_count = 0;
+ key_count_flag = false;
+ }
+
+ return true;
+
+ case KC_J:
+ case KC_Z:
+ if (key_count_flag && record->event.pressed) {
+ key_count += 1;
+
+ if (key_count == 3) {
+ key_count_flag = false;
+ test_clear_blink = TEST_OR_CLEAR;
+ current_time = timer_read();
+ }
+ } else {
+ key_count = 0;
+ }
+
+ return true;
+
+ case KC_RGHT:
+ if (record->event.pressed) {
+ if (key_count_flag) {
+ key_press += 1;
+
+ if (key_press == 3) {
+ key_count_flag = false;
+ led_state = rgb_matrix_get_mode();
+ hsv = rgb_matrix_get_hsv();
+ test_clear_blink = TEST_OR_CLEAR;
+ current_time = timer_read();
+ }
+ }
+
+ if (entry_led_test_flag) {
+ led_color_status += 1;
+
+ if (led_color_status > 3) {
+ led_color_status = WHITE;
+ }
+
+ led_test(led_color_status);
+ }
+ } else {
+ key_press = 0;
+ }
+
+ return true;
+
+ case KC_HOME:
+ if (record->event.pressed) {
+ if (key_count_flag) {
+ key_press += 1;
+
+ if (key_press == 3) {
+ key_count_flag = false;
+ led_state = rgb_matrix_get_mode();
+ hsv = rgb_matrix_get_hsv();
+ test_clear_blink = TEST_OR_CLEAR;
+ current_time = timer_read();
+ }
+ }
+
+ if (entry_led_test_flag) {
+ entry_led_test_flag = false;
+ rgb_matrix_sethsv_noeeprom(hsv.h, hsv.s, hsv.v);
+ rgb_matrix_mode_noeeprom(led_state);
+ }
+ } else {
+ key_press = 0;
+ }
+
+ return true;
+
+ default:
+ // return true;
+ return process_record_user(keycode, record);
+ }
+}
+
+void matrix_scan_kb(void) {
+ switch (test_clear_blink) {
+ case TEST_OR_CLEAR:
+ passed_time = timer_elapsed(current_time);
+
+ if (passed_time >= 3000) {
+ test_clear_blink = NONE;
+
+ if (key_press == 3) {
+ led_test(led_color_status);
+ } else if (key_count == 3) {
+ clear_eeprom();
+ }
+ }
+
+ break;
+
+ case LED_BLINK:
+ if ((timer_elapsed(led_time_buffer)) >= 300) {
+ led_time_buffer = timer_read();
+
+ if (time_200ms++ % 2 == 0) {
+ rgb_matrix_sethsv_noeeprom(HSV_RED);
+ } else {
+ rgb_matrix_sethsv_noeeprom(HSV_OFF);
+ }
+
+ if (time_200ms >= 7) {
+ time_200ms = 0;
+ test_clear_blink = NONE;
+ entry_led_test_flag = false;
+ rgb_matrix_init();
+ }
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ matrix_scan_user();
+}
+
+void led_test(uint8_t color) {
+ rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
+ entry_led_test_flag = true;
+
+ switch (color) {
+ case WHITE:
+ rgb_matrix_sethsv_noeeprom(HSV_WHITE);
+ break;
+
+ case RED:
+ rgb_matrix_sethsv_noeeprom(HSV_RED);
+ break;
+
+ case GREEN:
+ rgb_matrix_sethsv_noeeprom(HSV_GREEN);
+ break;
+
+ case BLUE:
+ rgb_matrix_sethsv_noeeprom(HSV_BLUE);
+ break;
+ }
+}
+
+void clear_eeprom(void) {
+ layer_state_t default_layer_tmp = default_layer_state;
+ eeconfig_init();
+ default_layer_set(default_layer_tmp);
+
+#ifdef VIA_ENABLE
+ // This resets the layout options
+ via_set_layout_options(VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT);
+
+ // This resets the keymaps in EEPROM to what is in flash.
+ dynamic_keymap_reset();
+
+ // This resets the macros in EEPROM to nothing.
+ dynamic_keymap_macro_reset();
+#endif
+ rgb_matrix_enable_noeeprom();
+ led_time_buffer = timer_read();
+ test_clear_blink = LED_BLINK;
+ rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
+ rgb_matrix_sethsv_noeeprom(HSV_OFF);
+}
+
+void restart_usb_driver(USBDriver *usbp) {
+ // Do nothing here.
+}
diff --git a/keyboards/keychron/v4/v4.c b/keyboards/keychron/v4/v4.c
new file mode 100644
index 0000000000..f8f74c6ade
--- /dev/null
+++ b/keyboards/keychron/v4/v4.c
@@ -0,0 +1,34 @@
+/* Copyright 2021 @ 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 "v4.h"
+#include "test.c"
+
+const matrix_row_t matrix_mask[] = {
+ 0b1111111111111111,
+ 0b1111111111111111,
+ 0b1111111111111111,
+ 0b1111111111111111,
+ 0b1111111111101111,
+};
+
+bool dip_switch_update_kb(uint8_t index, bool active) {
+ if (!dip_switch_update_user(index, active)) { return false;}
+ if (index == 0) {
+ default_layer_set(1UL << (active ? 1 : 0));
+ }
+ return true;
+}
diff --git a/keyboards/keychron/v4/v4.h b/keyboards/keychron/v4/v4.h
new file mode 100644
index 0000000000..ab01c3eb7f
--- /dev/null
+++ b/keyboards/keychron/v4/v4.h
@@ -0,0 +1,23 @@
+/* Copyright 2021 @ 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"
+
+#if defined(KEYBOARD_keychron_v4_v4_ansi_stm32l432)
+# include "v4_ansi_stm32l432.h"
+#endif