diff --git a/keyboards/bastardkb/scylla/rules.mk b/keyboards/bastardkb/scylla/rules.mk
index 70e6f13e0b66..71af506e28de 100644
--- a/keyboards/bastardkb/scylla/rules.mk
+++ b/keyboards/bastardkb/scylla/rules.mk
@@ -23,3 +23,4 @@ RGB_MATRIX_DRIVER = WS2812 # RGB matrix driver support
BLUETOOTH_ENABLE = no # Enable Bluetooth
AUDIO_ENABLE = no # Audio output
SPLIT_KEYBOARD = yes
+
diff --git a/keyboards/kmac/rules.mk b/keyboards/kmac/rules.mk
index 2a35f70cdf87..31390b356a23 100644
--- a/keyboards/kmac/rules.mk
+++ b/keyboards/kmac/rules.mk
@@ -39,3 +39,11 @@ SRC += matrix.c
# Supported layouts
LAYOUTS = tkl_ansi
+
+
+
+
+
+
+
+
diff --git a/keyboards/yandrstudio/Eureka75/Eureka75.c b/keyboards/yandrstudio/Eureka75/Eureka75.c
new file mode 100644
index 000000000000..2afbf88112cf
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/Eureka75.c
@@ -0,0 +1,52 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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
+
+
+#ifdef RGB_MATRIX_ENABLE
+led_config_t g_led_config = {
+ {
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED},
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED},
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED},
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED},
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED},
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED}
+ },
+ {
+ // LED Index to Physical Position
+ {0,0}
+ },
+ {
+ // LED Index to Flag
+ 4
+ }
+};
+
+
+#endif
+
+#ifdef RGB_DISABLE_WHEN_USB_SUSPENDED
+void suspend_power_down_kb(void) {
+ rgb_matrix_set_suspend_state(true);
+ suspend_power_down_user();
+}
+
+void suspend_wakeup_init_kb(void) {
+ rgb_matrix_set_suspend_state(false);
+ suspend_wakeup_init_user();
+}
+#endif
diff --git a/keyboards/yandrstudio/Eureka75/Eureka75.h b/keyboards/yandrstudio/Eureka75/Eureka75.h
new file mode 100644
index 000000000000..96c0faa472f0
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/Eureka75.h
@@ -0,0 +1,34 @@
+/* Copyright 2020 zvecr
+ *
+ * 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"
+
+#define LAYOUT( \
+ K000, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014, \
+ K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114, \
+ K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214, \
+ K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, K313, K314, \
+ K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, K412, K413, \
+ K500, K501, K502, K503, K504, K505, K509, K510, K511, K512, K513, K514 \
+) { \
+ { K000, KC_NO, K002, K003, K004, K005, K006, K007, K008, K009, K010, K011, K012, K013, K014 }, \
+ { K100, K101, K102, K103, K104, K105, K106, K107, K108, K109, K110, K111, K112, K113, K114 }, \
+ { K200, K201, K202, K203, K204, K205, K206, K207, K208, K209, K210, K211, K212, K213, K214 }, \
+ { K300, K301, K302, K303, K304, K305, K306, K307, K308, K309, K310, K311, KC_NO, K313, K314 }, \
+ { K400, K401, K402, K403, K404, K405, K406, K407, K408, K409, K410, KC_NO, K412, K413, KC_NO }, \
+ { K500, K501, K502, K503, K504, K505, KC_NO, KC_NO, KC_NO, K509, K510, K511, K512, K513, K514 } \
+}
diff --git a/keyboards/yandrstudio/Eureka75/config.h b/keyboards/yandrstudio/Eureka75/config.h
new file mode 100644
index 000000000000..d18d8e536bb7
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/config.h
@@ -0,0 +1,44 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xAA96
+#define PRODUCT_ID 0xAAAA
+#define DEVICE_VER 0x0001
+#define MANUFACTURER JasonRen biu
+#define PRODUCT Eureka75
+
+// enable the nkro when using the VIA.
+#define FORCE_NKRO
+
+// fix VIA RGB_light
+#define VIA_HAS_BROKEN_KEYCODES
+
+/* define if matrix has ghost */
+//#define MATRIX_HAS_GHOST
+
+/* Set 0 if debouncing isn't needed */
+#define DEBOUNCE 5
+
+// #define DEBUG_MATRIX_SCAN_RATE
+
+#define USB_POLLING_INTERVAL_MS 1
+#define QMK_KEYS_PER_SCAN 4
+
+#define TAP_CODE_DELAY 15
diff --git a/keyboards/yandrstudio/Eureka75/f401/board.h b/keyboards/yandrstudio/Eureka75/f401/board.h
new file mode 100644
index 000000000000..1a46a8194575
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/board.h
@@ -0,0 +1,25 @@
+/* Copyright 2020 Nick Brassel (tzarc)
+ *
+ * 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 3 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 "board.h"
+
+
+#undef STM32_HSECLK
+#define STM32_HSECLK 16000000
+
+
+#define BOARD_YANDR_BIU_F401
diff --git a/keyboards/yandrstudio/Eureka75/f401/chconf.h b/keyboards/yandrstudio/Eureka75/f401/chconf.h
new file mode 100644
index 000000000000..b69c1fca78bf
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/chconf.h
@@ -0,0 +1,36 @@
+/* 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 CH_CFG_ST_FREQUENCY 10000
+
+#define CH_CFG_ST_RESOLUTION 16
+
+#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
+
+#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
+
+#define CH_CFG_FACTORY_SEMAPHORES TRUE
+
+#define CH_CFG_FACTORY_MAILBOXES TRUE
+
+#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
+
+#define CH_CFG_FACTORY_PIPES TRUE
+
+#include_next
+
diff --git a/keyboards/yandrstudio/Eureka75/f401/config.h b/keyboards/yandrstudio/Eureka75/f401/config.h
new file mode 100644
index 000000000000..9d509d5fde9b
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/config.h
@@ -0,0 +1,89 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "config_common.h"
+
+/* key matrix size */
+#define MATRIX_ROWS 6
+#define MATRIX_COLS 15
+
+// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+#define MATRIX_COL_PINS { A13, A14, A15, A0, A1, A2, A3, B12, B13, B14, B15, B4, A8, A9, A10}
+#define MATRIX_ROW_PINS { A5, A6, A7, B0, B4, B1}
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION ROW2COL
+
+
+/* RGN Matrix */
+#ifdef RGB_MATRIX_ENABLE
+
+# define RGB_DI_PIN B5
+# define RGBLED_NUM 1
+# define DRIVER_LED_TOTAL RGBLED_NUM
+
+
+#define WS2812_PWM_DRIVER PWMD3 // default: PWMD2
+#define WS2812_PWM_CHANNEL 2 // default: 2
+#define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2
+#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
+#define WS2812_DMA_CHANNEL 5 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
+
+
+# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150
+# define RGBLIGHT_VAL_STEP 15
+# define RGB_DISABLE_WHEN_USB_SUSPENDED true
+# define RGB_MATRIX_CENTER { 32, 96 }
+# define RGB_MATRIX_KEYPRESSES
+# define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+# define RGBLIGHT_ANIMATIONS
+
+// # define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_RGB
+
+#endif
+
+
+#ifdef RGBLIGHT_ENABLE
+
+# define RGB_DI_PIN B5
+# define RGBLED_NUM 1
+# define DRIVER_LED_TOTAL RGBLED_NUM
+# define RGBLIGHT_LIMIT_VAL 150
+# define RGBLIGHT_SLEEP
+
+#define WS2812_PWM_DRIVER PWMD3 // default: PWMD2
+#define WS2812_PWM_CHANNEL 2 // default: 2
+#define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2
+#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
+#define WS2812_DMA_CHANNEL 5 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU.
+
+
+
+// # define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_RGB
+
+#endif
+
+
+
+#ifdef ENCODER_ENABLE
+
+#define ENCODERS_PAD_A { B7 }
+#define ENCODERS_PAD_B { B6 }
+
+#define ENCODER_RESOLUTIONS { 4 }
+
+#endif
diff --git a/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32.c b/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32.c
new file mode 100644
index 000000000000..12071a21291e
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32.c
@@ -0,0 +1,217 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
+ * Artur F.
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ * update for STM32F4 support and the the flashing algorithm by yulei
+ * Adjust the file structure to custom EEPROM_DRIVER by jiaxin96 for support stm32f401cc
+ */
+
+#include
+#include
+#include "eeprom_stm32_custom.h"
+#include "eeprom_driver.h"
+/*****************************************************************************
+ * Allows to use the internal flash to store non volatile data. To initialize
+ * the functionality use the EEPROM_Init() function. Be sure that by reprogramming
+ * of the controller just affected pages will be deleted. In other case the non
+ * volatile data will be lost.
+ ******************************************************************************/
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Functions -----------------------------------------------------------------*/
+
+#define IS_VALID_ADDRESS(x) ((x) < FEE_MAX_BYTES)
+
+uint8_t DataBuf[FEE_MAX_BYTES];
+static void EEPROM_Backup(void);
+static FLASH_Status EEPROM_Restore(void);
+static uint32_t EEPROM_FindValidAddress(void);
+static void EEPROM_Clear(void);
+
+/*****************************************************************************
+ * Unlock the FLASH programming and initialized the DataBuf
+ ******************************************************************************/
+uint16_t EEPROM_Init(void) {
+ // unlock flash
+ FLASH_Unlock();
+
+ // initialize DataBuf
+ EEPROM_Backup();
+
+ // Clear Flags
+ // FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR);
+
+ return FEE_DENSITY_BYTES;
+}
+void eeprom_driver_init(void) {
+ EEPROM_Init();
+}
+
+/*****************************************************************************
+ * Erase the whole reserved Flash Space used for user Data
+ ******************************************************************************/
+void EEPROM_Erase(void) {
+ // erase all flash pages
+ EEPROM_Clear();
+
+ // reset the content of the buffer
+ memset(&DataBuf[0], FEE_EMPTY_BYTE, sizeof(DataBuf));
+}
+void eeprom_driver_erase(void) {
+ EEPROM_Erase();
+}
+/*****************************************************************************
+ * Write data with its eeprom address to flash if there has empty words,
+ * otherwise backup the current valid data, erase all flash pages,
+ * and finally restore the valid data.
+ *******************************************************************************/
+uint16_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) {
+ FLASH_Status FlashStatus = FLASH_COMPLETE;
+
+ uint32_t addr;
+ // exit if not a valid address
+ if (!IS_VALID_ADDRESS(Address)) {
+ return 0;
+ }
+
+// we are sure the address will not be out of bound
+#pragma GCC diagnostic ignored "-Warray-bounds"
+ // same value, do not need program
+ if (DataBuf[Address] == DataByte) {
+ return FlashStatus;
+ }
+
+ // find the address can be written
+ addr = EEPROM_FindValidAddress();
+ DataBuf[Address] = DataByte;
+#pragma GCC diagnostic pop
+ if (addr == FEE_EMPTY_VALUE) {
+ // EEPROM is full, need to erase and reprogramming
+ EEPROM_Clear();
+ EEPROM_Restore();
+ } else {
+ FLASH_ProgramHalfWord(FEE_ADDR_ADDRESS(addr), Address);
+ FLASH_ProgramHalfWord(FEE_DATA_ADDRESS(addr), DataByte);
+ }
+
+ return FlashStatus;
+}
+/*****************************************************************************
+ * Read once data byte from a specified address.
+ *******************************************************************************/
+uint8_t EEPROM_ReadDataByte(uint16_t Address) {
+ if (!IS_VALID_ADDRESS(Address)) {
+ return FEE_EMPTY_BYTE;
+ }
+
+ // Get Byte from caches
+ return DataBuf[Address];
+}
+
+/*****************************************************************************
+ * helper functions
+ *******************************************************************************/
+// backup the current data
+void EEPROM_Backup(void)
+{
+ uint32_t begin = FEE_PAGE_BASE_ADDRESS;
+ uint32_t end = FEE_PAGE_END_ADDRESS;
+ memset(&DataBuf[0], FEE_EMPTY_BYTE, sizeof(DataBuf));
+ while( begin < end) {
+ uint16_t addr = *(__IO uint16_t*)(FEE_ADDR_ADDRESS(begin));
+ if (IS_VALID_ADDRESS(addr)) {
+ DataBuf[addr] = *(__IO uint16_t*)(FEE_DATA_ADDRESS(begin));
+ } else if( addr == FEE_EMPTY_WORD) {
+ uint16_t data = *(__IO uint16_t*)(FEE_DATA_ADDRESS(begin));
+ if (data == FEE_EMPTY_WORD) {
+ // we reached the end of valid data
+ break;
+ }
+ }
+ begin += 4;
+ }
+}
+// restore data from DataBuf
+FLASH_Status EEPROM_Restore(void) {
+ uint32_t cur = FEE_PAGE_BASE_ADDRESS;
+ for (uint8_t i = 0; i < FEE_MAX_BYTES; i++) {
+ if (DataBuf[i] != FEE_EMPTY_BYTE) {
+ FLASH_ProgramHalfWord(FEE_ADDR_ADDRESS(cur), i);
+ FLASH_ProgramHalfWord(FEE_DATA_ADDRESS(cur), DataBuf[i]);
+ cur += 4;
+ }
+ }
+ return FLASH_COMPLETE;
+}
+// find an empty place for programming
+uint32_t EEPROM_FindValidAddress(void) {
+ uint32_t begin = FEE_PAGE_BASE_ADDRESS;
+ uint32_t end = FEE_PAGE_END_ADDRESS;
+ while( begin < end) {
+ uint32_t data = *(__IO uint32_t*)(begin);
+ if (data == FEE_EMPTY_VALUE) {
+ return begin;
+ }
+ begin += 4;
+ }
+ return FEE_EMPTY_VALUE;
+}
+
+void EEPROM_Clear(void)
+{
+#if defined(EEPROM_EMU_STM32F401xC)
+ FLASH_ErasePage(FEE_SECTOR_ID);
+#else
+ int page_num = 0;
+
+ // delete all pages from specified start page to the last page
+ do {
+ FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE));
+ page_num++;
+ } while (page_num < FEE_DENSITY_PAGES);
+#endif
+}
+/*****************************************************************************
+ * Wrap library in AVR style functions.
+ *******************************************************************************/
+uint8_t eeprom_read_byte_f4(const uint8_t *Address) {
+ const uint16_t p = (const uint32_t)Address;
+ return EEPROM_ReadDataByte(p);
+}
+
+void eeprom_write_byte_f4(uint8_t *Address, uint8_t Value) {
+ uint16_t p = (uint32_t)Address;
+ EEPROM_WriteDataByte(p, Value);
+}
+
+
+void eeprom_read_block(void *buf, const void *addr, size_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t * dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte_f4(p++);
+ }
+}
+
+void eeprom_write_block(const void *buf, void *addr, size_t len) {
+ uint8_t * p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte_f4(p++, *src++);
+ }
+}
+
+
diff --git a/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32_custom.h b/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32_custom.h
new file mode 100644
index 000000000000..70beda433bbc
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/eep/eeprom_stm32_custom.h
@@ -0,0 +1,106 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
+ * Artur F.
+ *
+ *
+ * This library assumes 8-bit data locations. To add a new MCU, please provide the flash
+ * page size and the total flash size in Kb. The number of available pages must be a multiple
+ * of 2. Only half of the pages account for the total EEPROM size.
+ * This library also assumes that the pages are not used by the firmware.
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ * update for STM32F4 support and the the flashing algorithm by yulei
+ * Adjust the file structure to custom EEPROM_DRIVER by jiaxin96 for support stm32f401cc
+ */
+
+#pragma once
+
+#include
+#include
+#include "flash_stm32.h"
+
+// HACK ALERT. This definition may not match your processor
+// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
+#if defined(EEPROM_EMU_STM32F303xC)
+# define MCU_STM32F303CC
+#elif defined(EEPROM_EMU_STM32F103xB)
+# define MCU_STM32F103RB
+#elif defined(EEPROM_EMU_STM32F072xB)
+# define MCU_STM32F072CB
+#elif defined(EEPROM_EMU_STM32F042x6)
+# define MCU_STM32F042K6
+#elif defined(EEPROM_EMU_STM32F401xC)
+# define MCU_STM32F401xC
+#else
+# error "not implemented."
+#endif
+
+
+
+
+
+#ifndef EEPROM_PAGE_SIZE
+# if defined(MCU_STM32F103RB) || defined(MCU_STM32F042K6)
+# define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
+# define FEE_DENSITY_PAGES 4 // How many pages are used
+# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB)
+# define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
+# define FEE_DENSITY_PAGES 4 // How many pages are used
+# elif defined(MCU_STM32F401xC)
+# define FEE_PAGE_SIZE (uint32_t)0x20000 // Page size = 128KByte
+# define FEE_DENSITY_PAGES 1 // How many pages are used
+# define FEE_SECTOR_ID 5 // sector id of the flash
+# else
+# error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
+# endif
+#endif
+
+#ifndef EEPROM_START_ADDRESS
+# if defined(MCU_STM32F103RB) || defined(MCU_STM32F072CB)
+# define FEE_MCU_FLASH_SIZE 128 // Size in Kb
+# elif defined(MCU_STM32F042K6)
+# define FEE_MCU_FLASH_SIZE 32 // Size in Kb
+# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE)
+# define FEE_MCU_FLASH_SIZE 512 // Size in Kb
+# elif defined(MCU_STM32F103RD)
+# define FEE_MCU_FLASH_SIZE 384 // Size in Kb
+# elif defined(MCU_STM32F303CC)
+# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
+# elif defined(MCU_STM32F401xC)
+# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
+# else
+# error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
+# endif
+#endif
+
+// DONT CHANGE
+// Choose location for the first EEPROM Page address on the top of flash
+// #define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
+// #define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1)
+// #define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
+// #define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
+// #define FEE_ADDR_OFFSET(Address) (Address * 2) // 1Byte per Word will be saved to preserve Flash
+
+#define FEE_PAGE_END_ADDRESS ((uint32_t)(0x08000000 + FEE_MCU_FLASH_SIZE * 1024))
+#define FEE_PAGE_BASE_ADDRESS ((uint32_t)((FEE_PAGE_END_ADDRESS) - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
+#define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 4) * FEE_DENSITY_PAGES - 1) // 4 Bytes for address, value pair
+//#define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
+#define FEE_EMPTY_BYTE ((uint8_t)0xFF)
+#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
+#define FEE_EMPTY_VALUE ((uint32_t)0xFFFFFFFF)
+//#define FEE_ADDR_OFFSET(Address) (Address * 2) // 1 Byte per Word will be saved to preserve Flash
+#define FEE_DATA_ADDRESS(Address) ((Address)+2) // flash address of the eeprom data
+#define FEE_ADDR_ADDRESS(Address) (Address) // flash address of the eeprom address
+#define FEE_MAX_BYTES ((FEE_DENSITY_BYTES+1) > 1024 ? 1024 : (FEE_DENSITY_BYTES+1)) // eeprom size
+
diff --git a/keyboards/yandrstudio/Eureka75/f401/eep/flash_stm32.c b/keyboards/yandrstudio/Eureka75/f401/eep/flash_stm32.c
new file mode 100644
index 000000000000..c3f1937c5258
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/eep/flash_stm32.c
@@ -0,0 +1,223 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ * Adjust the file structure to custom EEPROM_DRIVER by jiaxin96 for support stm32f401cc
+ */
+
+#if defined(EEPROM_EMU_STM32F303xC)
+# define STM32F303xC
+# include "stm32f3xx.h"
+#elif defined(EEPROM_EMU_STM32F103xB)
+# define STM32F103xB
+# include "stm32f1xx.h"
+#elif defined(EEPROM_EMU_STM32F072xB)
+# define STM32F072xB
+# include "stm32f0xx.h"
+#elif defined(EEPROM_EMU_STM32F042x6)
+# define STM32F042x6
+# include "stm32f0xx.h"
+#elif defined(EEPROM_EMU_STM32F401xC)
+# define STM32F401xC
+# include "stm32f4xx.h"
+#else
+# error "not implemented."
+#endif
+
+
+#include "flash_stm32.h"
+
+#if defined(EEPROM_EMU_STM32F103xB)
+# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
+#endif
+
+#if defined(EEPROM_EMU_STM32F401xC)
+# define FLASH_PSIZE_HFWORD FLASH_CR_PSIZE_0
+# define FLASH_PSIZE_WORD FLASH_CR_PSIZE_1
+# define FLASH_CR_SNB_POS 3
+/* the flash key was not defined in the CMSIS used by current chibios */
+#define FLASH_KEY1 0x45670123U
+#define FLASH_KEY2 0xCDEF89ABU
+# define FLASH_SR_FLAGS (FLASH_SR_PGAERR|FLASH_SR_PGPERR|FLASH_SR_PGSERR|FLASH_SR_WRPERR)
+#else
+# define FLASH_SR_FLAGS (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR)
+#endif
+
+/* Delay definition */
+#define EraseTimeout ((uint32_t)0x00000FFF)
+#define ProgramTimeout ((uint32_t)0x0000001F)
+
+#define ASSERT(exp) (void)((0))
+
+/**
+ * @brief Inserts a time delay.
+ * @param None
+ * @retval None
+ */
+static void delay(void) {
+ __IO uint32_t i = 0;
+ for (i = 0xFF; i != 0; i--) {
+ }
+}
+
+/**
+ * @brief Returns the FLASH Status.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP or FLASH_COMPLETE
+ */
+FLASH_Status FLASH_GetStatus(void) {
+ if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) return FLASH_BUSY;
+
+#if defined(EEPROM_EMU_STM32F401xC)
+ if ((FLASH->SR & (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR))) return FLASH_ERROR_PG;
+ if ((FLASH->SR & FLASH_SR_WRPERR)) return FLASH_ERROR_WRP;
+#else
+ if ((FLASH->SR & FLASH_SR_PGERR) != 0) return FLASH_ERROR_PG;
+ if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
+ if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
+#endif
+
+ return FLASH_COMPLETE;
+}
+
+/**
+ * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
+ * @param Timeout: FLASH progamming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) {
+ FLASH_Status status;
+
+ /* Check for the Flash Status */
+ status = FLASH_GetStatus();
+ /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+ while ((status == FLASH_BUSY) && (Timeout != 0x00)) {
+ delay();
+ status = FLASH_GetStatus();
+ Timeout--;
+ }
+ if (Timeout == 0) status = FLASH_TIMEOUT;
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @brief Erases a specified FLASH page.
+ * @param Page_Address: The page address or sector to be erased.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ErasePage(uint32_t Page) {
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ //ASSERT(IS_FLASH_ADDRESS(Page_Address));
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ if (status == FLASH_COMPLETE) {
+ /* if the previous operation is completed, proceed to erase the page */
+#if defined(EEPROM_EMU_STM32F401xC)
+ FLASH->CR &= ~FLASH_CR_SNB;
+ FLASH->CR |= FLASH_CR_SER | (Page << FLASH_CR_SNB_POS);
+#else
+ FLASH->CR |= FLASH_CR_PER;
+ FLASH->AR = Page;
+#endif
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ /* clear the SER or PER Bit */
+#if defined(EEPROM_EMU_STM32F401xC)
+ FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB);
+#else
+ FLASH->CR &= ~FLASH_CR_PER;
+#endif
+ FLASH_ClearFlag(FLASH_SR_FLAGS);
+ }
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified address.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
+ FLASH_Status status = FLASH_BAD_ADDRESS;
+ if ((Address % sizeof(uint16_t) != 0 ) || !IS_FLASH_ADDRESS(Address)) {
+ return status;
+ }
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if (status == FLASH_COMPLETE) {
+ /* if the previous operation is completed, proceed to program the new data */
+#if defined(EEPROM_EMU_STM32F401xC)
+ FLASH->CR &= ~FLASH_CR_PSIZE;
+ FLASH->CR |= FLASH_PSIZE_HFWORD;
+#endif
+ FLASH->CR |= FLASH_CR_PG;
+ *(__IO uint16_t*)Address = Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if (status != FLASH_TIMEOUT) {
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= ~FLASH_CR_PG;
+ }
+ FLASH_ClearFlag(FLASH_SR_FLAGS);
+ }
+ return status;
+}
+
+/**
+ * @brief Unlocks the FLASH Program Erase Controller.
+ * @param None
+ * @retval None
+ */
+void FLASH_Unlock(void) {
+ /* Authorize the FPEC Access */
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+}
+
+/**
+ * @brief Locks the FLASH Program Erase Controller.
+ * @param None
+ * @retval None
+ */
+void FLASH_Lock(void) {
+ /* Set the Lock Bit to lock the FPEC and the FCR */
+ FLASH->CR |= FLASH_CR_LOCK;
+}
+
+/**
+ * @brief Clears the FLASH's pending flags.
+ * @param FLASH_FLAG: specifies the FLASH flags to clear.
+ * This parameter can be any combination of the following values:
+ * @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
+ * @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
+ * @arg FLASH_FLAG_EOP: FLASH End of Programming flag
+ * @retval None
+ */
+void FLASH_ClearFlag(uint32_t FLASH_FLAG) {
+ /* Clear the flags */
+ FLASH->SR |= FLASH_FLAG;
+}
diff --git a/keyboards/yandrstudio/Eureka75/f401/halconf.h b/keyboards/yandrstudio/Eureka75/f401/halconf.h
new file mode 100644
index 000000000000..c03bc49506d1
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/halconf.h
@@ -0,0 +1,35 @@
+/* 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
+
+#undef HAL_USE_PWM
+#define HAL_USE_PWM TRUE
+
+#undef SERIAL_USB_BUFFERS_SIZE
+#define SERIAL_USB_BUFFERS_SIZE 256
+
+#undef SERIAL_BUFFERS_SIZE
+#define SERIAL_BUFFERS_SIZE 128
+
+#undef SPI_USE_WAIT
+#define SPI_USE_WAIT TRUE
+
+#undef SPI_SELECT_MODE
+#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
+
diff --git a/keyboards/yandrstudio/Eureka75/f401/matrix.c b/keyboards/yandrstudio/Eureka75/f401/matrix.c
new file mode 100644
index 000000000000..d7040e338fbe
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/matrix.c
@@ -0,0 +1,236 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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
+#include
+#include "util.h"
+#include "matrix.h"
+#include "debounce.h"
+#include "quantum.h"
+
+#ifdef DIRECT_PINS
+static pin_t direct_pins[MATRIX_ROWS][MATRIX_COLS] = DIRECT_PINS;
+#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW)
+static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
+static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
+#endif
+
+/* matrix state(1:on, 0:off) */
+extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
+extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
+
+static inline void setPinOutput_writeLow(pin_t pin) {
+ ATOMIC_BLOCK_FORCEON {
+ setPinOutput(pin);
+ writePinLow(pin);
+ }
+}
+
+static inline void setPinInputHigh_atomic(pin_t pin) {
+ ATOMIC_BLOCK_FORCEON { setPinInputHigh(pin); }
+}
+
+// matrix code
+
+#ifdef DIRECT_PINS
+
+static void init_pins(void) {
+ for (int row = 0; row < MATRIX_ROWS; row++) {
+ for (int col = 0; col < MATRIX_COLS; col++) {
+ pin_t pin = direct_pins[row][col];
+ if (pin != NO_PIN) {
+ setPinInputHigh(pin);
+ }
+ }
+ }
+}
+
+static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
+ // Start with a clear matrix row
+ matrix_row_t current_row_value = 0;
+
+ for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
+ pin_t pin = direct_pins[current_row][col_index];
+ if (pin != NO_PIN) {
+ current_row_value |= readPin(pin) ? 0 : (MATRIX_ROW_SHIFTER << col_index);
+ }
+ }
+
+ // If the row has changed, store the row and return the changed flag.
+ if (current_matrix[current_row] != current_row_value) {
+ current_matrix[current_row] = current_row_value;
+ return true;
+ }
+ return false;
+}
+
+#elif defined(DIODE_DIRECTION)
+# if (DIODE_DIRECTION == COL2ROW)
+
+static void select_col(uint8_t col) { palSetLine(col_pins[col]); }
+
+static void unselect_col(uint8_t col) { palClearLine(col_pins[col]); }
+
+static void unselect_rows(void) {
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ palSetLineMode(row_pins[x], PAL_MODE_INPUT_PULLDOWN);
+ }
+}
+
+static void init_pins(void) {
+ unselect_rows();
+ for (uint8_t x = 0; x < MATRIX_COLS; x++) {
+ palSetLineMode(col_pins[x], PAL_MODE_OUTPUT_PUSHPULL);
+ }
+ for (uint8_t x = 0; x < MATRIX_COLS; x++) {
+ palClearLine(col_pins[x]);
+ }
+}
+
+static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
+ bool matrix_changed = false;
+
+ // Select col
+ select_col(current_col);
+ matrix_output_select_delay();
+
+ // For each row...
+ for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
+ // Store last value of row prior to reading
+ matrix_row_t last_row_value = current_matrix[row_index];
+ matrix_row_t current_row_value = last_row_value;
+
+ // Check row pin state
+ if (readPin(row_pins[row_index]) == 1) {
+ // Pin HI, set col bit
+ current_row_value |= (MATRIX_ROW_SHIFTER << current_col);
+ } else {
+ // Pin LO, clear col bit
+ current_row_value &= ~(MATRIX_ROW_SHIFTER << current_col);
+ }
+
+ // Determine if the matrix changed state
+ if ((last_row_value != current_row_value)) {
+ matrix_changed |= true;
+ current_matrix[row_index] = current_row_value;
+ }
+ }
+
+ // Unselect col
+ unselect_col(current_col);
+ if (current_col + 1 < MATRIX_COLS) {
+ matrix_output_unselect_delay(); // wait for col signal to go HIGH
+ }
+
+ return matrix_changed;
+}
+
+# elif (DIODE_DIRECTION == ROW2COL)
+
+static void select_row(uint8_t row) { palSetLine(row_pins[row]); }
+
+static void unselect_row(uint8_t row) { palClearLine(row_pins[row]); }
+
+static void unselect_cols(void) {
+ for (uint8_t x = 0; x < MATRIX_COLS; x++) {
+ palSetLineMode(col_pins[x], PAL_MODE_INPUT_PULLDOWN);
+ }
+}
+
+static void init_pins(void) {
+ unselect_cols();
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ palSetLineMode(row_pins[x], PAL_MODE_OUTPUT_PUSHPULL);
+ }
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ palClearLine(row_pins[x]);
+ }
+}
+
+
+static bool read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) {
+ // Start with a clear matrix row
+ matrix_row_t current_row_value = 0;
+
+ // Select row
+ select_row(current_row);
+ matrix_output_select_delay();
+
+ // For each col...
+ for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
+ // Select the col pin to read (active low)
+ uint8_t pin_state = readPin(col_pins[col_index]);
+
+ // Populate the matrix row with the state of the col pin
+ current_row_value |= pin_state ? (MATRIX_ROW_SHIFTER << col_index) : 0;
+ }
+
+ // Unselect row
+ unselect_row(current_row);
+ if (current_row + 1 < MATRIX_ROWS) {
+ matrix_output_unselect_delay(); // wait for row signal to go HIGH
+ }
+
+ // If the row has changed, store the row and return the changed flag.
+ if (current_matrix[current_row] != current_row_value) {
+ current_matrix[current_row] = current_row_value;
+ return true;
+ }
+ return false;
+}
+
+# else
+# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL!
+# endif
+#else
+# error DIODE_DIRECTION is not defined!
+#endif
+
+void matrix_init(void) {
+ // initialize key pins
+ init_pins();
+
+ // initialize matrix state: all keys off
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ raw_matrix[i] = 0;
+ matrix[i] = 0;
+ }
+
+ debounce_init(MATRIX_ROWS);
+
+ matrix_init_quantum();
+}
+
+uint8_t matrix_scan(void) {
+ bool changed = false;
+
+#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW)
+ // Set col, read rows
+ for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
+ changed |= read_rows_on_col(raw_matrix, current_col);
+ }
+#elif (DIODE_DIRECTION == ROW2COL)
+ // Set row, read cols
+ for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
+ changed |= read_cols_on_row(raw_matrix, current_row);
+ }
+#endif
+
+ debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
+
+ matrix_scan_quantum();
+ return (uint8_t)changed;
+}
diff --git a/keyboards/yandrstudio/Eureka75/f401/mcuconf.h b/keyboards/yandrstudio/Eureka75/f401/mcuconf.h
new file mode 100644
index 000000000000..404ac6ddda6a
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/mcuconf.h
@@ -0,0 +1,86 @@
+/* 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
+
+#undef STM32_PWM_USE_TIM3
+#define STM32_PWM_USE_TIM3 TRUE
+
+#undef STM32_ST_USE_TIMER
+#define STM32_ST_USE_TIMER 2
+
+#undef STM32_NO_INIT
+#undef STM32_HSI_ENABLED
+#undef STM32_LSI_ENABLED
+#undef STM32_HSE_ENABLED
+#undef STM32_LSE_ENABLED
+#undef STM32_CLOCK48_REQUIRED
+#undef STM32_SW
+#undef STM32_PLLSRC
+#undef STM32_PLLM_VALUE
+#undef STM32_PLLN_VALUE
+#undef STM32_PLLP_VALUE
+#undef STM32_PLLQ_VALUE
+#undef STM32_HPRE
+#undef STM32_PPRE1
+#undef STM32_PPRE2
+#undef STM32_RTCSEL
+#undef STM32_RTCPRE_VALUE
+#undef STM32_MCO1SEL
+#undef STM32_MCO1PRE
+#undef STM32_MCO2SEL
+#undef STM32_MCO2PRE
+#undef STM32_I2SSRC
+#undef STM32_PLLI2SN_VALUE
+#undef STM32_PLLI2SR_VALUE
+#undef STM32_PVD_ENABLE
+#undef STM32_PLS
+#undef STM32_BKPRAM_ENABLE
+
+#define STM32_NO_INIT FALSE
+#define STM32_HSI_ENABLED TRUE
+#define STM32_LSI_ENABLED TRUE
+#define STM32_HSE_ENABLED TRUE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_CLOCK48_REQUIRED TRUE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSE
+#define STM32_PLLM_VALUE 16
+#define STM32_PLLN_VALUE 192
+#define STM32_PLLP_VALUE 4
+#define STM32_PLLQ_VALUE 4
+// AHB prescaler value.
+#define STM32_HPRE STM32_HPRE_DIV1
+//APB1 prescaler value.
+#define STM32_PPRE1 STM32_PPRE1_DIV4
+//APB2 prescaler value.
+#define STM32_PPRE2 STM32_PPRE2_DIV2
+#define STM32_RTCSEL STM32_RTCSEL_LSI
+#define STM32_RTCPRE_VALUE 8
+#define STM32_MCO1SEL STM32_MCO1SEL_HSI
+#define STM32_MCO1PRE STM32_MCO1PRE_DIV1
+#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK
+#define STM32_MCO2PRE STM32_MCO2PRE_DIV5
+#define STM32_I2SSRC STM32_I2SSRC_CKIN
+#define STM32_PLLI2SN_VALUE 192
+#define STM32_PLLI2SR_VALUE 5
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+#define STM32_BKPRAM_ENABLE FALSE
+
+
diff --git a/keyboards/yandrstudio/Eureka75/f401/rules.mk b/keyboards/yandrstudio/Eureka75/f401/rules.mk
new file mode 100644
index 000000000000..a91f83c8e9b1
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/f401/rules.mk
@@ -0,0 +1,30 @@
+# MCU name
+MCU = STM32F401
+
+# Address of the bootloader in system memory
+STM32_BOOTLOADER_ADDRESS = 0x1FFF0000
+
+# Bootloader selection
+BOOTLOADER = stm32-dfu
+
+# # project specific file
+CUSTOM_MATRIX = lite # for using the A9 pin as matrix io
+QUANTUM_SRC += matrix.c
+
+# RGB_MATRIX_ENABLE = yes
+# RGB_MATRIX_DRIVER = WS2812
+RGBLIGHT_ENABLE = yes
+RGBLIGHT_DRIVER = WS2812
+WS2812_DRIVER = pwm
+
+ENCODER_ENABLE = yes
+
+# EEPROM_DRIVER = spi
+EEPROM_DRIVER = custom
+SRC += eep/eeprom_stm32.c
+SRC += eep/flash_stm32.c
+OPT_DEFS += -DEEPROM_EMU_STM32F401xC
+COMMON_VPATH += patsubst$(%/, %, dir $(mkfile_patch))/eep
+
+# Enter lower-power sleep mode when on the ChibiOS idle thread
+OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
diff --git a/keyboards/yandrstudio/Eureka75/info-via.json b/keyboards/yandrstudio/Eureka75/info-via.json
new file mode 100644
index 000000000000..0fdf57947f90
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/info-via.json
@@ -0,0 +1,198 @@
+{
+ "name": "Eureka75_Y&R",
+ "vendorId": "0xAA96",
+ "productId": "0xAAAA",
+ "lighting": {
+ "extends": "none",
+ "keycodes": "qmk"
+ },
+ "matrix": {
+ "rows": 6,
+ "cols": 15
+ },
+ "layouts": {
+ "keymap":
+ [
+ [
+ {
+ "y": 0.25,
+ "x": 16.5
+ },
+ "5,3"
+ ],
+ [
+ {
+ "y": -0.5
+ },
+ "0,0",
+ {
+ "x": 0.5
+ },
+ "0,2",
+ "0,3",
+ "0,4",
+ "0,5",
+ {
+ "x": 0.25
+ },
+ "0,6",
+ "0,7",
+ "0,8",
+ "0,9",
+ {
+ "x": 0.25
+ },
+ "0,10",
+ "0,11",
+ "0,12",
+ "0,13",
+ {
+ "x": 1.5
+ },
+ "0,14"
+ ],
+ [
+ {
+ "y": -0.5,
+ "x": 16.5
+ },
+ "5,4"
+ ],
+ [
+ {
+ "y": -0.25
+ },
+ "1,0",
+ "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
+ },
+ "1,13",
+ {
+ "x": 0.25
+ },
+ "1,14"
+ ],
+ [
+ {
+ "w": 1.5
+ },
+ "2,0",
+ "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
+ },
+ "2,13",
+ {
+ "x": 0.25
+ },
+ "2,14"
+ ],
+ [
+ {
+ "w": 1.75
+ },
+ "3,0",
+ "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
+ },
+ "3,13",
+ {
+ "x": 0.25
+ },
+ "3,14"
+ ],
+ [
+ {
+ "w": 2.25
+ },
+ "4,0",
+ "4,1",
+ "4,2",
+ "4,3",
+ "4,4",
+ "4,5",
+ "4,6",
+ "4,7",
+ "4,8",
+ "4,9",
+ "4,10",
+ {
+ "w": 1.75
+ },
+ "4,12"
+ ],
+ [
+ {
+ "y": -0.75,
+ "x": 14.25
+ },
+ "4,13"
+ ],
+ [
+ {
+ "y": -0.25,
+ "w": 1.25
+ },
+ "5,0",
+ "5,1",
+ {
+ "w": 1.25
+ },
+ "5,2",
+ {
+ "w": 6.25
+ },
+ "5,5",
+ "5,9",
+ "5,10",
+ {
+ "w": 1.25
+ },
+ "5,11"
+ ],
+ [
+ {
+ "y": -0.75,
+ "x": 13.25
+ },
+ "5,12",
+ "5,13",
+ "5,14"
+ ]
+ ]
+ }
+}
diff --git a/keyboards/yandrstudio/Eureka75/keymaps/default/keymap.c b/keyboards/yandrstudio/Eureka75/keymaps/default/keymap.c
new file mode 100644
index 000000000000..d40f0bfa1c3a
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/keymaps/default/keymap.c
@@ -0,0 +1,91 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ LAYOUT(
+ 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_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_INS,
+ 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_DEL,
+ 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_END,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_PGDN,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_VOLU, KC_VOLD, KC_SPC, KC_LALT, KC_LGUI, KC_MENU, KC_LEFT, KC_DOWN, KC_RGHT),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
+
+};
+
+
+#ifdef ENCODER_ENABLE
+
+
+bool encoder_update_user(uint8_t index, bool clockwise) {
+
+ if (clockwise) {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 5, 3);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ } else {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 5, 4);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ }
+
+ return false;
+}
+
+
+#endif
+
+
+void keyboard_post_init_user(void) {
+ // eeconfig_init();
+ // Customise these values to desired behaviour
+ // debug_enable=true;
+ // debug_matrix=false;
+ // debug_keyboard=true;
+ //debug_mouse=true;
+}
diff --git a/keyboards/yandrstudio/Eureka75/keymaps/via/keymap.c b/keyboards/yandrstudio/Eureka75/keymaps/via/keymap.c
new file mode 100644
index 000000000000..c1ccdd8f2737
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/keymaps/via/keymap.c
@@ -0,0 +1,91 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ LAYOUT(
+ 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_SPC,
+ 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_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_DEL,
+ 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_END,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_NO,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_LALT, KC_LGUI, KC_MENU, KC_NO, KC_NO, KC_NO),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
+
+
+#ifdef ENCODER_ENABLE
+
+
+bool encoder_update_user(uint8_t index, bool clockwise) {
+
+ if (clockwise) {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 5, 3);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ } else {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 5, 4);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ }
+
+ return false;
+}
+
+
+#endif
+
+
+void keyboard_post_init_user(void) {
+ // eeconfig_init();
+ // Customise these values to desired behaviour
+ // debug_enable=true;
+ // debug_matrix=false;
+ // debug_keyboard=true;
+ //debug_mouse=true;
+}
diff --git a/keyboards/yandrstudio/Eureka75/keymaps/via/rules.mk b/keyboards/yandrstudio/Eureka75/keymaps/via/rules.mk
new file mode 100644
index 000000000000..1e5b99807cb7
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/keymaps/via/rules.mk
@@ -0,0 +1 @@
+VIA_ENABLE = yes
diff --git a/keyboards/yandrstudio/Eureka75/readme.md b/keyboards/yandrstudio/Eureka75/readme.md
new file mode 100644
index 000000000000..f872060adef4
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/readme.md
@@ -0,0 +1,16 @@
+Eureka75 version 1.0
+===
+
+A 75% keys keyboard with rgb (keys).
+This keyboard use 8mhz HSE and STM32F401 as MCU.
+
+Keyboard Maintainer: https://github.com/jiaxin96
+Hardware Supported: Eureka75
+Hardware Availability: https://github.com/Oh-My-Mechanical-Keyboard
+
+Make example for this keyboard (after setting up your build environment):
+
+ make yandrstudio/Eureka75/f401:via
+
+See [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) then the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information.
+
diff --git a/keyboards/yandrstudio/Eureka75/rules.mk b/keyboards/yandrstudio/Eureka75/rules.mk
new file mode 100644
index 000000000000..24fe138d7d7b
--- /dev/null
+++ b/keyboards/yandrstudio/Eureka75/rules.mk
@@ -0,0 +1,14 @@
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = lite # Virtual DIP switch configuration
+KEYBOARD_SHARED_EP = yes # Free up some extra endpoints - needed if console+mouse+extra
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = yes # Console for debug
+# COMMAND_ENABLE = yes # Commands for debug and configuration
+# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+NKRO_ENABLE = yes # USB Nkey Rollover
+NO_USB_STARTUP_CHECK = no # Disable initialization only when usb is plugged in
+
+
diff --git a/keyboards/yandrstudio/hotdox76_V2/config.h b/keyboards/yandrstudio/hotdox76_V2/config.h
index db494ff73c64..99fd38fe3990 100644
--- a/keyboards/yandrstudio/hotdox76_V2/config.h
+++ b/keyboards/yandrstudio/hotdox76_V2/config.h
@@ -61,11 +61,11 @@
/* RGN Matrix */
#ifdef RGB_MATRIX_ENABLE
-# define RGB_MATRIX_SPLIT {38, 38}
+# define RGB_MATRIX_SPLIT {43, 43}
# define SPLIT_TRANSPORT_MIRROR
# define RGB_DI_PIN D3
-# define RGBLED_NUM (38*2)
+# define RGBLED_NUM (43*2)
# define DRIVER_LED_TOTAL RGBLED_NUM
# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 150
@@ -85,10 +85,10 @@
#ifdef RGBLIGHT_ENABLE
# define RGBLIGHT_SPLIT
-# define RGBLED_SPLIT {38, 38}
+# define RGBLED_SPLIT {43, 43}
# define RGB_DI_PIN D3
-# define RGBLED_NUM (38*2)
+# define RGBLED_NUM (43*2)
# define DRIVER_LED_TOTAL RGBLED_NUM
# define RGBLIGHT_LIMIT_VAL 150
# define RGBLIGHT_SLEEP
@@ -110,6 +110,15 @@
#endif
+
+#ifdef OLED_DRIVER_ENABLE
+
+# define OLED_BRIGHTNESS 200
+# define OLED_TIMEOUT 120000
+
+#endif
+
+
/*
* Feature disable options
* These options are also useful to firmware size reduction.
diff --git a/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.c b/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.c
index e6e4f2cdb94c..9aef87eaa97f 100644
--- a/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.c
+++ b/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.c
@@ -1,4 +1,7 @@
#include QMK_KEYBOARD_H
+#include
+#include "oled_font_lib/logo.h"
+#include "oled_font_lib/ext_font.h"
#ifdef RGB_MATRIX_ENABLE
led_config_t g_led_config = {
@@ -25,32 +28,47 @@ led_config_t g_led_config = {
{103,38}, {86,38}, {69,38}, {52,38}, {34,38}, {17,38}, {0,38}, \
{0,51}, {17,51}, {34,51}, {52,51}, {69,51}, \
{86,64}, {69,64}, {52,64}, {34,64}, {17,64}, {0,64}, \
+ {69,64}, {52,64}, {34,64}, {17,64}, {0,64}, \
+
\
{224,0}, {207,0}, {190,0}, {172,0}, {155,0}, {138,0}, {121,0}, \
{121,13}, {138,13}, {155,13}, {172,13}, {190,13}, {207,13}, {224,13}, \
{224,26}, {207,26}, {190,26}, {172,26}, {155,26}, {138,26}, \
{121,38}, {138,38}, {155,38}, {172,38}, {190,38}, {207,38}, {224,38}, \
{224,51}, {207,51}, {190,51}, {172,51}, {155,51}, \
- {138,64}, {155,64}, {172,64}, {190,64}, {207,64}, {224,64}\
+ {138,64}, {155,64}, {172,64}, {190,64}, {207,64}, {224,64}, \
+ {155,64}, {172,64}, {190,64}, {207,64}, {224,64}\
+
},
{
// LED Index to Flag
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
+ 2,2,2,2,2,\
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,\
+ 2,2,2,2,2
}
};
#endif
+// #define I_AM_LEFT
+
#ifdef OLED_DRIVER_ENABLE
-char wpm_str[10]; // limit WPM string length.
+
+# define UNC (94+0x21)
+volatile char current_alp[7];
+volatile uint8_t cur_alp_index;
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
- // oled_scroll_set_area(0,2);
- // oled_scroll_set_speed(4);
- // oled_scroll_right();
+ strcpy((char *)(current_alp), "[ ]");
+ current_alp[1] = UNC;
+ current_alp[2] = UNC;
+ current_alp[3] = UNC;
+ current_alp[4] = UNC;
+
+ cur_alp_index = 1;
# ifdef I_AM_LEFT
return OLED_ROTATION_0;
# else
@@ -58,44 +76,143 @@ oled_rotation_t oled_init_user(oled_rotation_t rotation) {
# endif
}
+
void render_logo(void) {
+ uint8_t i = 0, j = 0;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 32; ++j) {
+# ifdef I_AM_LEFT
+ oled_write_raw_byte(logo_idobao[i*32+j], i*128+j);
+# else
+ oled_write_raw_byte(logo_idobao[i*32+j], i*128+j+96);
+# endif
+ }
+ }
+}
+
+
+void render_layer_helper_fun(uint8_t start_line, const char * data, uint8_t gap_w) {
+ uint8_t j = 0, k = 0, l = strlen(data);
+ for (j = 0; j < l; ++j) { // font index
+ for (k = 0; k < 12; ++k) { // font byte index
+ // base + logo_w(32) + gap_w(12) +l*font_w(12)+current_byte_index
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k], start_line*2*128 + 32 + gap_w + j*12+k);
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k+12], start_line*2*128+128 + 32 + gap_w + j*12+k);
+ }
+ }
+ for (j = 0; j < gap_w; ++j) {
+ oled_write_raw_byte(blank_block, start_line*2*128 + 32 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128 + 32 + gap_w + l*12 + j);
+
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + 32 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + 32 + gap_w + l*12 + j);
+ }
+}
+void render_layer(uint8_t layer) {
+ render_layer_helper_fun(0, PSTR("LAYER:"), 12);
+ switch (layer)
+ {
+ case 0:
+ render_layer_helper_fun(1, PSTR("1:HOME"), 12);
+ break;
+ case 1:
+ render_layer_helper_fun(1, PSTR("2:CODE"), 12);
+ break;
+ case 2:
+ render_layer_helper_fun(1, PSTR("3:OFFICE"), 0);
+ break;
+ case 3:
+ default:
+ render_layer_helper_fun(1, PSTR("4:OTHERS"), 0);
+ break;
+ }
}
-void oled_task_user(void) {
+void render_cur_input_helper_fun(uint8_t start_line, const char * data, uint8_t gap_w) {
+ uint8_t j = 0, k = 0, l = strlen(data);
+ for (j = 0; j < l; ++j) { // font index
+ for (k = 0; k < 12; ++k) { // font byte index
+ // base + logo_w(0) + gap_w(12) +l*font_w(12)+current_byte_index
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k], start_line*2*128 + gap_w + j*12+k);
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][12+k], start_line*2*128+128 + gap_w + j*12+k);
+ }
+ }
+ for (j = 0; j < gap_w; ++j) {
+ oled_write_raw_byte(blank_block, start_line*2*128 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128 + gap_w + l*12 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + gap_w + l*12 + j);
+ }
+}
+
+void render_cur_input(void) {
+ render_cur_input_helper_fun(0, PSTR("INPUTS:"), 6);
+ render_cur_input_helper_fun(1, (const char *)(current_alp), 12);
+ return;
+}
+
+
+void oled_task_user(void) {
+ render_logo();
# ifdef I_AM_LEFT
+ render_layer(biton32(layer_state));
+# else
+ render_cur_input();
+# endif
+}
+
+static const char PROGMEM code_to_name[0xFF] = {
+// 0 1 2 3 4 5 6 7 8 9 A B c D E F
+ UNC, UNC, UNC, UNC, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
+ '3', '4', '5', '6', '7', '8', '9', '0', UNC, UNC, UNC, UNC, UNC, '-', '=', '[', // 2x
+ ']', '\\', '#', ';', '\'', '`', ',', '.', '/', UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 3x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 4x
+ UNC, UNC, UNC, UNC, '/', '*', '-', '+', UNC, '1', '2', '3', '4', '5', '6', '7', // 5x
+ '8', '9', '0', '.', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 6x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 7x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 8x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 9x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ax
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Bx
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Cx
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Dx
+ UNC, UNC, 'A', 'W', UNC, 'S', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ex
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC // Fx
+};
- switch (biton32(layer_state)) {
- case 0:
- oled_write_ln("Layer: Base", false);
- break;
- case 1:
- oled_write_ln("Layer: Function", false);
- break;
- case 2:
- oled_write_ln("Layer: System", false);
- break;
- case 3:
- oled_write_ln("Layer: User", false);
- break;
- default:
- oled_write_ln("Layer: Undefine", false);
+void get_cur_alp_hook(uint16_t keycode) {
+ if (keycode >= 0xF0) {
+ keycode = 0xF0;
+ }
+ if (cur_alp_index < 4) {
+ current_alp[cur_alp_index] = code_to_name[keycode];
+ cur_alp_index++;
+ } else {
+ for (uint8_t i = 2; i <= 4; ++i) {
+ current_alp[i-1] = current_alp[i];
+ }
+ current_alp[cur_alp_index] = code_to_name[keycode];
}
- oled_write_P((get_mods() & MOD_MASK_SHIFT) ? "SF>* " : "SF>x ", false);
- oled_write_P((get_mods() & MOD_MASK_CTRL) ? "CT>* " : "CT>x ", false);
- oled_write_P((get_mods() & MOD_MASK_ALT) ? "AL>* " : "AL>x ", false);
- oled_write_ln((get_mods() & MOD_MASK_GUI) ? "GU>*" : "GU>x", false);
+}
-# else
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ get_cur_alp_hook(keycode);
+ return true;
+}
-# endif
+void matrix_scan_user(void) {
+ if(!is_oled_on()) {
+ cur_alp_index = 1;
+ }
}
-#endif
+#endif
bool is_keyboard_left(void) {
@@ -106,3 +223,4 @@ bool is_keyboard_left(void) {
#endif
}
+
diff --git a/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.h b/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.h
index c0cdec85fa89..a47f8acc9d18 100644
--- a/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.h
+++ b/keyboards/yandrstudio/hotdox76_V2/hotdox76_V2.h
@@ -31,7 +31,7 @@
R106, R105, R104, R103, R102, R101, R100, \
R905, R904, R903, R902, R901, R900, \
R806, R805, R804, R803, R802, R801, R800, \
- R705, R704, R703, R701, R700, \
+ R704, R703, R702, R701, R700, \
R606, R605, \
R604, \
R601, R602, R603 \
@@ -44,7 +44,7 @@
{ L500, L501, L502, L503, L504, L505, L506 }, \
\
{ KC_NO, R601, R602, R603, R604, R605, R606 }, \
- { R700, R701, R703, R704, R705, KC_NO, KC_NO }, \
+ { R700, R701, R702, R703, R704, KC_NO, KC_NO }, \
{ R800, R801, R802, R803, R804, R805, R806 }, \
{ R900, R901, R902, R903, R904, R905, KC_NO }, \
{ R100, R101, R102, R103, R104, R105, R106 }, \
diff --git a/keyboards/yandrstudio/hotdox76_V2/info-via.json b/keyboards/yandrstudio/hotdox76_V2/info-via.json
index 5172a4954847..72b7b6fe2c41 100644
--- a/keyboards/yandrstudio/hotdox76_V2/info-via.json
+++ b/keyboards/yandrstudio/hotdox76_V2/info-via.json
@@ -13,176 +13,353 @@
"layouts": {
"keymap": [
[
- "0,0",
+ {
+ "x": 3.5
+ },
+ "5,3",
+ {
+ "x": 10.5
+ },
+ "11,3"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 2.5
+ },
+ "5,2",
{
"x": 1
},
- "0,2",
- "0,3",
- "0,4",
- "0,5",
+ "5,4",
{
- "x": 0.5
+ "x": 8.5
},
- "0,7",
- "0,8",
- "0,9",
- "0,10",
+ "11,4",
{
- "x": 0.5
+ "x": 1
+ },
+ "11,2"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 5.5
},
- "0,11",
- "0,12",
- "0,13",
- "0,14",
+ "5,5",
+ "5,6",
{
- "x": 0.25
+ "x": 4.5
},
- "0,15",
- "0,16",
- "0,17"
+ "11,6",
+ "11,5"
],
[
{
- "y": 0.5
+ "y": -0.875,
+ "w": 1.5
},
- "1,0",
- "1,1",
- "1,2",
- "1,3",
- "1,4",
- "1,5",
- "1,6",
- "1,7",
- "1,8",
- "1,9",
- "1,10",
- "1,11",
- "1,12",
- "1,13",
- "1,14",
+ "5,0",
+ "5,1",
+ {
+ "x": 14.5
+ },
+ "11,1",
+ {
+ "w": 1.5
+ },
+ "11,0"
+ ],
+ [
+ {
+ "y": -0.375,
+ "x": 3.5
+ },
+ "4,3",
+ {
+ "x": 10.5
+ },
+ "10,3"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 2.5
+ },
+ "4,2",
+ {
+ "x": 1
+ },
+ "4,4",
+ {
+ "x": 8.5
+ },
+ "10,4",
{
- "x": 0.25
+ "x": 1
},
- "1,15",
- "1,16",
- "1,17"
+ "10,2"
],
[
{
+ "y": -0.875,
+ "x": 5.5
+ },
+ "4,5",
+ {
+ "h": 1.5
+ },
+ "4,6",
+ {
+ "x": 4.5,
+ "h": 1.5
+ },
+ "10,6",
+ "10,5"
+ ],
+ [
+ {
+ "y": -0.875,
"w": 1.5
},
- "2,0",
- "2,1",
- "2,2",
- "2,3",
- "2,4",
- "2,5",
- "2,6",
- "2,7",
- "2,8",
- "2,9",
- "2,10",
- "2,11",
- "2,12",
+ "4,0",
+ "4,1",
+ {
+ "x": 14.5
+ },
+ "10,1",
{
"w": 1.5
},
- "2,14",
+ "10,0"
+ ],
+ [
+ {
+ "y": -0.375,
+ "x": 3.5
+ },
+ "3,3",
{
- "x": 0.25
+ "x": 10.5
},
- "2,15",
- "2,16",
- "2,17"
+ "9,3"
],
[
{
- "w": 1.75
+ "y": -0.875,
+ "x": 2.5
},
- "3,0",
- "3,1",
"3,2",
- "3,3",
+ {
+ "x": 1
+ },
"3,4",
+ {
+ "x": 8.5
+ },
+ "9,4",
+ {
+ "x": 1
+ },
+ "9,2"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 5.5
+ },
"3,5",
- "3,6",
- "3,7",
- "3,8",
- "3,9",
- "3,10",
- "3,11",
- "3,12",
{
- "w": 1.25
+ "x": 6.5
},
- "3,14"
+ "9,5"
],
[
{
- "w": 1.25
+ "y": -0.875,
+ "w": 1.5
},
- "4,0",
- "4,1",
- "4,2",
- "4,3",
- "4,4",
- "4,5",
- "4,6",
- "4,7",
- "4,8",
- "4,9",
- "4,10",
- "4,11",
+ "3,0",
+ "3,1",
{
- "w": 1.75
+ "x": 14.5
},
- "4,12",
- "4,14",
+ "9,1",
{
- "x": 1.25
+ "w": 1.5
},
- "4,16"
+ "9,0"
],
[
{
- "w": 1.25
+ "y": -0.625,
+ "x": 6.5,
+ "h": 1.5
},
- "5,0",
+ "2,6",
{
- "w": 1.25
+ "x": 4.5,
+ "h": 1.5
},
- "5,1",
+ "8,6"
+ ],
+ [
{
- "w": 1.25
+ "y": -0.75,
+ "x": 3.5
},
- "5,2",
+ "2,3",
{
- "w": 6.25
+ "x": 10.5
},
- "5,6",
+ "8,3"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 2.5
+ },
+ "2,2",
+ {
+ "x": 1
+ },
+ "2,4",
+ {
+ "x": 8.5
+ },
+ "8,4",
+ {
+ "x": 1
+ },
+ "8,2"
+ ],
+ [
{
- "w": 1.25
+ "y": -0.875,
+ "x": 5.5
},
- "5,10",
+ "2,5",
{
- "w": 1.25
+ "x": 6.5
},
- "5,11",
+ "8,5"
+ ],
+ [
{
- "w": 1.25
+ "y": -0.875,
+ "w": 1.5
},
- "5,12",
+ "2,0",
+ "2,1",
+ {
+ "x": 14.5
+ },
+ "8,1",
{
- "w": 1.25
+ "w": 1.5
},
- "5,14",
+ "8,0"
+ ],
+ [
+ {
+ "y": -0.375,
+ "x": 3.5
+ },
+ "1,3",
+ {
+ "x": 10.5
+ },
+ "7,3"
+ ],
+ [
+ {
+ "y": -0.875,
+ "x": 2.5
+ },
+ "1,2",
+ {
+ "x": 1
+ },
+ "1,4",
+ {
+ "x": 8.5
+ },
+ "7,4",
+ {
+ "x": 1
+ },
+ "7,2"
+ ],
+ [
+ {
+ "y": -0.75,
+ "x": 0.5
+ },
+ "1,0",
+ "1,1",
+ {
+ "x": 14.5
+ },
+ "7,1",
+ "7,0"
+ ],
+ [
+ {
+ "r": 30,
+ "rx": 6.5,
+ "ry": 4.25,
+ "y": -1,
+ "x": 1
+ },
+ "0,5",
+ "0,6"
+ ],
+ [
+ {
+ "h": 2
+ },
+ "0,3",
+ {
+ "h": 2
+ },
+ "0,2",
+ "0,4"
+ ],
+ [
+ {
+ "x": 2
+ },
+ "0,1"
+ ],
+ [
+ {
+ "r": -30,
+ "rx": 13,
+ "y": -1,
+ "x": -3
+ },
+ "6,6",
+ "6,5"
+ ],
+ [
+ {
+ "x": -3
+ },
+ "6,4",
+ {
+ "h": 2
+ },
+ "6,2",
+ {
+ "h": 2
+ },
+ "6,3"
+ ],
+ [
{
- "x": 0.25
+ "x": -3
},
- "5,15",
- "5,16",
- "5,17"
+ "6,1"
]
]
}
diff --git a/keyboards/yandrstudio/hotdox76_V2/keymaps/default/config.h b/keyboards/yandrstudio/hotdox76_V2/keymaps/default/config.h
index a0aedf8b8574..463aa7cec2a9 100644
--- a/keyboards/yandrstudio/hotdox76_V2/keymaps/default/config.h
+++ b/keyboards/yandrstudio/hotdox76_V2/keymaps/default/config.h
@@ -22,6 +22,9 @@
#define DISABLE_RGB_MATRIX_BAND_SAT
#define DISABLE_RGB_MATRIX_BAND_VAL
#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+#define DISABLE_RGB_MATRIX_CYCLE_ALL
+
#define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
#define DISABLE_RGB_MATRIX_SOLID_REACTIVE
@@ -29,6 +32,7 @@
#define DISABLE_RGB_MATRIX_DIGITAL_RAIN
#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
+#define DISABLE_RGB_MATRIX_CYCLE_SPIRAL
#define DISABLE_RGB_MATRIX_SPLASH
#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#define DISABLE_RGB_MATRIX_SOLID_SPLASH
diff --git a/keyboards/yandrstudio/hotdox76_V2/keymaps/default/keymap.c b/keyboards/yandrstudio/hotdox76_V2/keymaps/default/keymap.c
index 46fa7c2c5d2f..defa52b5726f 100644
--- a/keyboards/yandrstudio/hotdox76_V2/keymaps/default/keymap.c
+++ b/keyboards/yandrstudio/hotdox76_V2/keymaps/default/keymap.c
@@ -1,5 +1,11 @@
#include QMK_KEYBOARD_H
+enum Layer_name {
+ HOME,
+ CODE,
+ OFFICE,
+ OTHER
+};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
@@ -23,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | |ace | End | | PgDn | | |
* `--------------------' `----------------------'
*/
- LAYOUT(
+ [HOME] = LAYOUT(
// left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
KC_DEL, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(1),
@@ -64,7 +70,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [CODE] = LAYOUT(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_TRNS,
@@ -105,7 +111,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [OFFICE] = LAYOUT(
// left hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
@@ -146,7 +152,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [OTHER] = LAYOUT(
// left hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
diff --git a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/config.h b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/config.h
index a0aedf8b8574..463aa7cec2a9 100644
--- a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/config.h
+++ b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/config.h
@@ -22,6 +22,9 @@
#define DISABLE_RGB_MATRIX_BAND_SAT
#define DISABLE_RGB_MATRIX_BAND_VAL
#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+#define DISABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+#define DISABLE_RGB_MATRIX_CYCLE_ALL
+
#define DISABLE_RGB_MATRIX_BAND_SPIRAL_VAL
#define DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
#define DISABLE_RGB_MATRIX_SOLID_REACTIVE
@@ -29,6 +32,7 @@
#define DISABLE_RGB_MATRIX_DIGITAL_RAIN
#define DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#define DISABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
+#define DISABLE_RGB_MATRIX_CYCLE_SPIRAL
#define DISABLE_RGB_MATRIX_SPLASH
#define DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#define DISABLE_RGB_MATRIX_SOLID_SPLASH
diff --git a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/keymap.c b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/keymap.c
index 46fa7c2c5d2f..defa52b5726f 100644
--- a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/keymap.c
+++ b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/keymap.c
@@ -1,5 +1,11 @@
#include QMK_KEYBOARD_H
+enum Layer_name {
+ HOME,
+ CODE,
+ OFFICE,
+ OTHER
+};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap 0: Basic layer
@@ -23,7 +29,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | |ace | End | | PgDn | | |
* `--------------------' `----------------------'
*/
- LAYOUT(
+ [HOME] = LAYOUT(
// left hand
KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
KC_DEL, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(1),
@@ -64,7 +70,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [CODE] = LAYOUT(
// left hand
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
KC_TRNS, KC_EXLM, KC_AT, KC_LCBR, KC_RCBR, KC_PIPE, KC_TRNS,
@@ -105,7 +111,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [OFFICE] = LAYOUT(
// left hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
@@ -146,7 +152,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
* | | | | | | | |
* `--------------------' `--------------------'
*/
- LAYOUT(
+ [OTHER] = LAYOUT(
// left hand
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
diff --git a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/rules.mk b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/rules.mk
index 3379c3570270..6db1bde5ebb2 100644
--- a/keyboards/yandrstudio/hotdox76_V2/keymaps/via/rules.mk
+++ b/keyboards/yandrstudio/hotdox76_V2/keymaps/via/rules.mk
@@ -1,5 +1,5 @@
VIA_ENABLE = yes
-# RGBLIGHT_ENABLE = yes
-# RGBLIGHT_DRIVER = WS2812
-RGB_MATRIX_ENABLE = yes
-RGB_MATRIX_DRIVER = WS2812
+RGBLIGHT_ENABLE = yes
+RGBLIGHT_DRIVER = WS2812
+# RGB_MATRIX_ENABLE = yes
+# RGB_MATRIX_DRIVER = WS2812
diff --git a/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/ext_font.h b/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/ext_font.h
new file mode 100644
index 000000000000..e7295a67af73
--- /dev/null
+++ b/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/ext_font.h
@@ -0,0 +1,132 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "progmem.h"
+/*
+ !(0) "(1) #(2) $(3) %(4) &(5) '(6) ((7)
+ )(8) *(9) +(10) ,(11) -(12) .(13) /(14) 0(15)
+ 1(16) 2(17) 3(18) 4(19) 5(20) 6(21) 7(22) 8(23)
+ 9(24) :(25) ;(26) <(27) =(28) >(29) ?(30) @(31)
+ A(32) B(33) C(34) D(35) E(36) F(37) G(38) H(39)
+ I(40) J(41) K(42) L(43) M(44) N(45) O(46) P(47)
+ Q(48) R(49) S(50) T(51) U(52) V(53) W(54) X(55)
+ Y(56) Z(57) [(58) \(59) ](60) ^(61) _(62) `(63)
+ a(64) b(65) c(66) d(67) e(68) f(69) g(70) h(71)
+ i(72) j(73) k(74) l(75) m(76) n(77) o(78) p(79)
+ q(80) r(81) s(82) t(83) u(84) v(85) w(86) x(87)
+ y(88) z(89) {(90) |(91) }(92) ~(93)
+ */
+static const unsigned char ext_big_font[][24] PROGMEM = {
+{0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00},/*"!",0*/
+{0x00,0x00,0x00,0x18,0xF8,0x18,0x00,0x18,0xF8,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",1*/
+{0x00,0x00,0x60,0x60,0xFE,0xFE,0x60,0xFE,0xFE,0x60,0x00,0x00,0x00,0x00,0x06,0x7F,0x7F,0x06,0x7F,0x7F,0x06,0x06,0x00,0x00},/*"#",2*/
+{0x00,0x00,0x00,0xF0,0xF8,0x9E,0x9E,0xB8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0xF9,0xF9,0x1F,0x0F,0x00,0x00,0x00},/*"$",3*/
+{0x00,0x00,0x38,0x44,0xC4,0xC4,0xB8,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x0E,0x11,0x11,0x11,0x0E,0x00,0x00,0x00},/*"%",4*/
+{0x00,0x00,0x60,0xE0,0xB0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x0E,0x0F,0x19,0x19,0x1B,0x1E,0x0E,0x0F,0x1B,0x00,0x00},/*"&",5*/
+{0x00,0x00,0x00,0x00,0x00,0x18,0xF8,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",6*/
+{0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x3C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x78,0x60,0x00,0x00,0x00},/*"(",7*/
+{0x00,0x00,0x0C,0x3C,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x78,0x1F,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*")",8*/
+{0x00,0x00,0x30,0xB0,0xF0,0xFC,0xFC,0xF0,0xB0,0x30,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x00},/*"*",9*/
+{0x00,0x80,0x80,0x80,0x80,0xF8,0xF8,0x80,0x80,0x80,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x1F,0x1F,0x01,0x01,0x01,0x01,0x00},/*"+",10*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x38,0x08,0x00,0x00,0x00,0x00,0x00},/*",",11*/
+{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00},/*"-",12*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00},/*".",13*/
+{0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x78,0x1E,0x06,0x00,0x00,0x00,0x00,0x60,0x78,0x1E,0x07,0x01,0x00,0x00,0x00,0x00,0x00},/*"/",14*/
+{0x00,0x00,0xF0,0xF8,0x1C,0x0C,0x1C,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00},/*"0",15*/
+{0x00,0x00,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"1",16*/
+{0x00,0x00,0x30,0x38,0x0C,0x0C,0x8C,0xF8,0x70,0x00,0x00,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x19,0x18,0x18,0x00,0x00,0x00},/*"2",17*/
+{0x00,0x00,0x18,0x1C,0xCC,0xCC,0xCC,0xFC,0x38,0x00,0x00,0x00,0x00,0x0C,0x1C,0x18,0x18,0x18,0x19,0x0F,0x07,0x00,0x00,0x00},/*"3",18*/
+{0x00,0x00,0xC0,0xE0,0x78,0x1C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x1B,0x1B,0x1F,0x1F,0x1B,0x00,0x00,0x00},/*"4",19*/
+{0x00,0x00,0xFC,0xFC,0xCC,0xCC,0xCC,0x8C,0x00,0x00,0x00,0x00,0x00,0x0C,0x1C,0x18,0x18,0x18,0x18,0x0F,0x07,0x00,0x00,0x00},/*"5",20*/
+{0x00,0x00,0xE0,0xF0,0xB8,0xDC,0xCC,0xCC,0x8C,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x19,0x18,0x18,0x1F,0x0F,0x00,0x00,0x00},/*"6",21*/
+{0x00,0x00,0x1C,0x1C,0x0C,0x0C,0xCC,0xFC,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1F,0x03,0x00,0x00,0x00,0x00},/*"7",22*/
+{0x00,0x00,0x38,0xFC,0xCC,0xCC,0xCC,0xFC,0x38,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x1F,0x0F,0x00,0x00,0x00},/*"8",23*/
+{0x00,0x00,0xF8,0xFC,0x8C,0x8C,0xCC,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x18,0x19,0x19,0x1D,0x0E,0x07,0x03,0x00,0x00,0x00},/*"9",24*/
+{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00},/*":",25*/
+{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x08,0x00,0x00,0x00,0x00,0x00},/*";",26*/
+{0x00,0x00,0x00,0x80,0x80,0xC0,0x60,0x60,0x30,0x30,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x06,0x0C,0x0C,0x18,0x18,0x00,0x00},/*"<",27*/
+{0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00},/*"=",28*/
+{0x00,0x30,0x30,0x60,0x60,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0C,0x0C,0x06,0x03,0x03,0x01,0x01,0x00,0x00},/*">",29*/
+{0x00,0x00,0x70,0x78,0x18,0x18,0x98,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x1B,0x01,0x01,0x00,0x00,0x00,0x00},/*"?",30*/
+{0x00,0x00,0xF0,0x08,0xC4,0x24,0x24,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x21,0x22,0x22,0x13,0x00,0x00,0x00,0x00},/*"@",31*/
+{0x00,0x00,0x18,0x98,0xF8,0x38,0x38,0xF0,0x80,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x1B,0x03,0x03,0x1B,0x1F,0x1C,0x18,0x00},/*"A",32*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0x70,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x19,0x19,0x19,0x1F,0x0E,0x00,0x00},/*"B",33*/
+{0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x10,0x78,0x78,0x00,0x00,0x00,0x07,0x0F,0x0C,0x18,0x18,0x18,0x18,0x0C,0x0C,0x00,0x00},/*"C",34*/
+{0x00,0x18,0xF8,0xF8,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"D",35*/
+{0x00,0x18,0xF8,0xF8,0x98,0xD8,0xD8,0x18,0x78,0x78,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x1B,0x18,0x1E,0x1E,0x00,0x00},/*"E",36*/
+{0x00,0x18,0xF8,0xF8,0x98,0xD8,0xD8,0x18,0x78,0x78,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00},/*"F",37*/
+{0x00,0xE0,0xF0,0x38,0x18,0x18,0x10,0x38,0x38,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x1B,0x1B,0x1F,0x0F,0x03,0x00,0x00},/*"G",38*/
+{0x00,0x18,0xF8,0xF8,0x98,0x80,0x98,0xF8,0xF8,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x01,0x19,0x1F,0x1F,0x18,0x00,0x00},/*"H",39*/
+{0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"I",40*/
+{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x00,0x00,0x00,0x0F,0x0F,0x18,0x18,0x18,0x0F,0x0F,0x00,0x00,0x00},/*"J",41*/
+{0x00,0x18,0xF8,0xF8,0x98,0xC0,0x78,0x38,0x18,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x01,0x07,0x1E,0x18,0x18,0x00,0x00},/*"K",42*/
+{0x00,0x18,0x18,0xF8,0xF8,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x1F,0x1F,0x00,0x00},/*"L",43*/
+{0x18,0xF8,0xF8,0x38,0xE0,0x00,0xE0,0x38,0xF8,0xF8,0x18,0x00,0x18,0x1F,0x1F,0x18,0x19,0x03,0x19,0x18,0x1F,0x1F,0x18,0x00},/*"M",44*/
+{0x00,0x18,0xF8,0xF8,0xF8,0xE0,0x18,0xF8,0xF8,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x03,0x1F,0x1F,0x1F,0x00,0x00,0x00},/*"N",45*/
+{0x00,0xC0,0xF0,0x30,0x18,0x18,0x18,0x30,0xF0,0xC0,0x00,0x00,0x00,0x03,0x0F,0x0C,0x18,0x18,0x18,0x0C,0x0F,0x03,0x00,0x00},/*"O",46*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0xF0,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x19,0x19,0x01,0x00,0x00,0x00,0x00},/*"P",47*/
+{0x00,0xC0,0xF0,0x30,0x18,0x18,0x18,0x30,0xF0,0xC0,0x00,0x00,0x00,0x03,0x0F,0xCC,0xF8,0x78,0x78,0xCC,0xEF,0x63,0x00,0x00},/*"Q",48*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0x70,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x07,0x0E,0x1C,0x18,0x00,0x00},/*"R",49*/
+{0x00,0x00,0x70,0xF8,0x98,0x98,0x90,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x09,0x19,0x19,0x1F,0x0E,0x00,0x00,0x00},/*"S",50*/
+{0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x00,0x00,0x00},/*"T",51*/
+{0x00,0x18,0xF8,0xF8,0x18,0x00,0x18,0xF8,0xF8,0x18,0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x18,0x18,0x0F,0x07,0x00,0x00,0x00},/*"U",52*/
+{0x00,0x18,0x78,0xF8,0x98,0x00,0x98,0xF8,0x78,0x18,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x18,0x1F,0x03,0x00,0x00,0x00,0x00},/*"V",53*/
+{0x18,0xF8,0xF8,0x18,0xD8,0xC0,0xD8,0x18,0xF8,0xF8,0x18,0x00,0x00,0x01,0x1F,0x1C,0x1F,0x01,0x1F,0x1C,0x1F,0x01,0x00,0x00},/*"W",54*/
+{0x00,0x18,0x38,0x78,0xD8,0x80,0xD8,0x78,0x38,0x18,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x01,0x1B,0x1E,0x1C,0x18,0x00,0x00},/*"X",55*/
+{0x00,0x18,0x38,0x78,0xD8,0x80,0x80,0xD8,0x78,0x38,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x00,0x00,0x00},/*"Y",56*/
+{0x00,0x00,0x78,0x78,0x18,0x98,0xD8,0x78,0x38,0x00,0x00,0x00,0x00,0x00,0x1C,0x1E,0x1B,0x19,0x18,0x1E,0x1E,0x00,0x00,0x00},/*"Z",57*/
+{0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x60,0x60,0x00,0x00,0x00},/*"[",58*/
+{0x00,0x00,0x06,0x1E,0x78,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x1E,0x78,0x60,0x00,0x00},/*"\",59*/
+{0x00,0x00,0x00,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00},/*"]",60*/
+{0x00,0x00,0x00,0x60,0x70,0x18,0x0C,0x18,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",61*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"_",62*/
+{0x00,0x00,0x00,0x00,0x02,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",63*/
+{0x00,0x00,0x00,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x0E,0x1F,0x1B,0x1B,0x0B,0x1F,0x1F,0x18,0x00,0x00},/*"a",64*/
+{0x00,0x0C,0xFC,0xFC,0xC0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x18,0x1F,0x1F,0x0C,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"b",65*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xC0,0xE0,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x0C,0x00,0x00},/*"c",66*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xCC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x0C,0x1F,0x1F,0x18,0x00},/*"d",67*/
+{0x00,0x00,0x80,0xC0,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x07,0x0F,0x1B,0x1B,0x1B,0x1B,0x1B,0x0B,0x00,0x00},/*"e",68*/
+{0x00,0x00,0x60,0x60,0xF8,0xFC,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00,0x00},/*"f",69*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xC0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x07,0x0F,0xDC,0xD8,0xD8,0xCC,0xFF,0x7F,0x00,0x00},/*"g",70*/
+{0x00,0x0C,0xFC,0xFC,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00},/*"h",71*/
+{0x00,0x00,0x00,0x60,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"i",72*/
+{0x00,0x00,0x60,0x60,0x60,0x6C,0x6C,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00},/*"j",73*/
+{0x00,0x00,0x0C,0xFC,0xFC,0x80,0xE0,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x03,0x06,0x1C,0x18,0x18,0x00,0x00},/*"k",74*/
+{0x00,0x00,0x00,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"l",75*/
+{0x00,0x60,0xE0,0xE0,0x60,0xE0,0xC0,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x00,0x1F,0x1F,0x00,0x1F,0x1F,0x18,0x00},/*"m",76*/
+{0x00,0x60,0xE0,0xE0,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00},/*"n",77*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"o",78*/
+{0x00,0x60,0xE0,0xE0,0xC0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xCC,0xD8,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"p",79*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xC0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0xD8,0xCC,0xFF,0xFF,0xC0,0x00},/*"q",80*/
+{0x00,0x00,0x60,0x60,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00,0x00},/*"r",81*/
+{0x00,0x00,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x1D,0x1D,0x1B,0x1B,0x1B,0x1E,0x0E,0x00,0x00,0x00},/*"s",82*/
+{0x00,0x00,0x60,0x60,0xFC,0xFC,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x0C,0x00,0x00},/*"t",83*/
+{0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x0C,0x1F,0x1F,0x18,0x00},/*"u",84*/
+{0x00,0x60,0xE0,0xE0,0x60,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x18,0x1F,0x07,0x00,0x00,0x00,0x00},/*"v",85*/
+{0x60,0xE0,0xE0,0x60,0x00,0x80,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x01,0x1F,0x1E,0x07,0x03,0x07,0x1E,0x1F,0x01,0x00,0x00},/*"w",86*/
+{0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x03,0x03,0x1F,0x1C,0x18,0x00,0x00},/*"x",87*/
+{0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0xC0,0xC0,0xC1,0xE7,0xFE,0xDC,0xC7,0x03,0x00,0x00,0x00},/*"y",88*/
+{0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x1B,0x19,0x1C,0x1C,0x00,0x00},/*"z",89*/
+{0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3F,0x7E,0x60,0x00,0x00,0x00,0x00},/*"{",90*/
+{0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00},/*"|",91*/
+{0x00,0x00,0x00,0x00,0x0C,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x7E,0x3F,0x01,0x00,0x00,0x00,0x00},/*"}",92*/
+{0x00,0x00,0x80,0xC0,0xC0,0xC0,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00},/*"~",93*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",94*/
+};
+
+
+
+static const unsigned char blank_block PROGMEM = 0x00;
diff --git a/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/logo.h b/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/logo.h
new file mode 100644
index 000000000000..230044bd1e79
--- /dev/null
+++ b/keyboards/yandrstudio/hotdox76_V2/oled_font_lib/logo.h
@@ -0,0 +1,42 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "progmem.h"
+
+static const unsigned char logo_idobao[] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xE0,
+ 0xF0, 0xF0, 0x70, 0x60, 0x04, 0x0E, 0x0E, 0x1E,
+ 0x8E, 0x8E, 0xC4, 0xC0, 0xE0, 0xF0, 0xF0, 0xF0,
+ 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
+
+
+ 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x01,
+ 0xF0, 0xF8, 0xFC, 0xFC, 0x1E, 0x1E, 0x0F, 0x0F,
+ 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x01,
+ 0x01, 0x03, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
+
+
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xC0, 0xE0, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
+
+
+ 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x0F, 0x0F, 0x1F, 0x1F, 0x3E, 0x3C, 0x7C, 0x7C,
+ 0x7C, 0x7C, 0x3C, 0x3E, 0x1E, 0x1F, 0x0F, 0x0F,
+ 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00
+};
diff --git a/keyboards/yandrstudio/hotdox76_V2/rules.mk b/keyboards/yandrstudio/hotdox76_V2/rules.mk
index e52102301c67..0cf6961ae71f 100644
--- a/keyboards/yandrstudio/hotdox76_V2/rules.mk
+++ b/keyboards/yandrstudio/hotdox76_V2/rules.mk
@@ -20,7 +20,6 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = no # Commands for debug and configuration
NKRO_ENABLE = yes # USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
-# WPM_ENABLE = yes
OLED_DRIVER_ENABLE = yes # Enable Support for SSD1306 or SH1106 OLED Displays; Communicating over I2C
SPLIT_KEYBOARD = yes
diff --git a/keyboards/yandrstudio/rainbow65/keymaps/test_font/config.h b/keyboards/yandrstudio/rainbow65/keymaps/test_font/config.h
new file mode 100644
index 000000000000..52998fe547e3
--- /dev/null
+++ b/keyboards/yandrstudio/rainbow65/keymaps/test_font/config.h
@@ -0,0 +1,23 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 .
+ */
+
+/* OLED */
+#ifdef OLED_DRIVER_ENABLE
+
+# define OLED_BRIGHTNESS 250
+# define OLED_TIMEOUT 300000
+
+#endif
diff --git a/keyboards/yandrstudio/rainbow65/keymaps/test_font/keymap.c b/keyboards/yandrstudio/rainbow65/keymaps/test_font/keymap.c
new file mode 100644
index 000000000000..d11a405f70b2
--- /dev/null
+++ b/keyboards/yandrstudio/rainbow65/keymaps/test_font/keymap.c
@@ -0,0 +1,246 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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
+#include
+#include "dynamic_keymap.h"
+#include "oled_font_lib/logo.h"
+#include "oled_font_lib/ext_font.h"
+
+enum layer_names { _BASE, _FN, _SYS, _USER };
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_BASE] = LAYOUT(
+ KC_ESC, RESET, 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_MUTE,
+ 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_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_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_VOLD, KC_VOLU, KC_SPC, KC_RALT, MO(1), MO(2), MO(3), KC_DOWN, KC_RGHT),
+
+ [_FN] = LAYOUT(
+ KC_GRV, 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, TO(_BASE),
+ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_CAPS,
+ KC_TRNS, RGB_TOG, RGB_MOD, RGB_MODE_REVERSE, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, RGB_MODE_PLAIN, RGB_MODE_BREATHE, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ [_SYS] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+ [_USER] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)
+};
+
+
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_user(uint8_t index, bool clockwise) {
+ if (clockwise) {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 4, 3);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ } else {
+ uint16_t keycode = dynamic_keymap_get_keycode(biton32(layer_state), 4, 4);
+ if (keycode >= MACRO00 && keycode <= MACRO15) {
+ dynamic_keymap_macro_send(keycode - MACRO00);
+ } else {
+ tap_code16(keycode);
+ }
+ }
+ return false;
+}
+#endif
+
+
+
+// #define I_AM_LEFT
+
+#ifdef OLED_DRIVER_ENABLE
+
+# define UNC (94+0x21)
+volatile char current_alp[7];
+volatile uint8_t cur_alp_index;
+
+oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+ strcpy((char *)(current_alp), "[ ]");
+ current_alp[1] = UNC;
+ current_alp[2] = UNC;
+ current_alp[3] = UNC;
+ current_alp[4] = UNC;
+
+ cur_alp_index = 1;
+# ifdef I_AM_LEFT
+ return OLED_ROTATION_0;
+# else
+ return OLED_ROTATION_180;
+# endif
+}
+
+
+void render_logo(void) {
+ uint8_t i = 0, j = 0;
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 32; ++j) {
+# ifdef I_AM_LEFT
+ oled_write_raw_byte(logo_idobao[i*32+j], i*128+j);
+# else
+ oled_write_raw_byte(logo_idobao[i*32+j], i*128+j+96);
+# endif
+ }
+ }
+}
+
+
+void render_layer_helper_fun(uint8_t start_line, const char * data, uint8_t gap_w) {
+ uint8_t j = 0, k = 0, l = strlen(data);
+ for (j = 0; j < l; ++j) { // font index
+ for (k = 0; k < 12; ++k) { // font byte index
+ // base + logo_w(32) + gap_w(12) +l*font_w(12)+current_byte_index
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k], start_line*2*128 + 32 + gap_w + j*12+k);
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k+12], start_line*2*128+128 + 32 + gap_w + j*12+k);
+ }
+ }
+ for (j = 0; j < gap_w; ++j) {
+ oled_write_raw_byte(blank_block, start_line*2*128 + 32 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128 + 32 + gap_w + l*12 + j);
+
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + 32 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + 32 + gap_w + l*12 + j);
+
+ }
+}
+void render_layer(uint8_t layer) {
+ render_layer_helper_fun(0, PSTR("LAYER:"), 12);
+ switch (layer)
+ {
+ case 0:
+ render_layer_helper_fun(1, PSTR("1:HOME"), 12);
+ break;
+ case 1:
+ render_layer_helper_fun(1, PSTR("2:CODE"), 12);
+ break;
+ case 2:
+ render_layer_helper_fun(1, PSTR("3:OFFICE"), 0);
+ break;
+ case 3:
+ default:
+ render_layer_helper_fun(1, PSTR("OTHER"), 18);
+ break;
+ }
+}
+
+void render_cur_input_helper_fun(uint8_t start_line, const char * data, uint8_t gap_w) {
+ uint8_t j = 0, k = 0, l = strlen(data);
+ for (j = 0; j < l; ++j) { // font index
+ for (k = 0; k < 12; ++k) { // font byte index
+ // base + logo_w(0) + gap_w(12) +l*font_w(12)+current_byte_index
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][k], start_line*2*128 + gap_w + j*12+k);
+ oled_write_raw_byte(ext_big_font[data[j]-0x21][12+k], start_line*2*128+128 + gap_w + j*12+k);
+ }
+ }
+ for (j = 0; j < gap_w; ++j) {
+ oled_write_raw_byte(blank_block, start_line*2*128 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128 + gap_w + l*12 + j);
+
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + j);
+ oled_write_raw_byte(blank_block, start_line*2*128+128 + gap_w + l*12 + j);
+ }
+}
+
+void render_cur_input(void) {
+ render_cur_input_helper_fun(0, PSTR("INPUTS:"), 6);
+ render_cur_input_helper_fun(1, (const char *)(current_alp), 12);
+ return;
+}
+
+
+void oled_task_user(void) {
+ render_logo();
+# ifdef I_AM_LEFT
+ render_layer(biton32(layer_state));
+# else
+ render_cur_input();
+# endif
+}
+
+
+
+static const char PROGMEM code_to_name[0xFF] = {
+// 0 1 2 3 4 5 6 7 8 9 A B c D E F
+ UNC, UNC, UNC, UNC, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
+ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
+ '3', '4', '5', '6', '7', '8', '9', '0', UNC, UNC, UNC, UNC, UNC, '-', '=', '[', // 2x
+ ']', '\\', '#', ';', '\'', '`', ',', '.', '/', UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 3x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 4x
+ UNC, UNC, UNC, UNC, '/', '*', '-', '+', UNC, '1', '2', '3', '4', '5', '6', '7', // 5x
+ '8', '9', '0', '.', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 6x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 7x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 8x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // 9x
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ax
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Bx
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Cx
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Dx
+ UNC, UNC, 'A', 'W', UNC, 'S', UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, // Ex
+ UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC, UNC // Fx
+};
+
+
+
+
+void get_cur_alp_hook(uint16_t keycode) {
+ if (keycode >= 0xF0) {
+ keycode = 0xF0;
+ }
+ if (cur_alp_index < 4) {
+ current_alp[cur_alp_index] = code_to_name[keycode];
+ cur_alp_index++;
+ } else {
+ for (uint8_t i = 2; i <= 4; ++i) {
+ current_alp[i-1] = current_alp[i];
+ }
+ current_alp[cur_alp_index] = code_to_name[keycode];
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+
+ get_cur_alp_hook(keycode);
+ return true;
+
+}
+
+
+void matrix_scan_user(void) {
+ if(!is_oled_on()) {
+ cur_alp_index = 1;
+ }
+}
+
+
+#endif
diff --git a/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/ext_font.h b/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/ext_font.h
new file mode 100644
index 000000000000..e7295a67af73
--- /dev/null
+++ b/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/ext_font.h
@@ -0,0 +1,132 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "progmem.h"
+/*
+ !(0) "(1) #(2) $(3) %(4) &(5) '(6) ((7)
+ )(8) *(9) +(10) ,(11) -(12) .(13) /(14) 0(15)
+ 1(16) 2(17) 3(18) 4(19) 5(20) 6(21) 7(22) 8(23)
+ 9(24) :(25) ;(26) <(27) =(28) >(29) ?(30) @(31)
+ A(32) B(33) C(34) D(35) E(36) F(37) G(38) H(39)
+ I(40) J(41) K(42) L(43) M(44) N(45) O(46) P(47)
+ Q(48) R(49) S(50) T(51) U(52) V(53) W(54) X(55)
+ Y(56) Z(57) [(58) \(59) ](60) ^(61) _(62) `(63)
+ a(64) b(65) c(66) d(67) e(68) f(69) g(70) h(71)
+ i(72) j(73) k(74) l(75) m(76) n(77) o(78) p(79)
+ q(80) r(81) s(82) t(83) u(84) v(85) w(86) x(87)
+ y(88) z(89) {(90) |(91) }(92) ~(93)
+ */
+static const unsigned char ext_big_font[][24] PROGMEM = {
+{0x00,0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00},/*"!",0*/
+{0x00,0x00,0x00,0x18,0xF8,0x18,0x00,0x18,0xF8,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",1*/
+{0x00,0x00,0x60,0x60,0xFE,0xFE,0x60,0xFE,0xFE,0x60,0x00,0x00,0x00,0x00,0x06,0x7F,0x7F,0x06,0x7F,0x7F,0x06,0x06,0x00,0x00},/*"#",2*/
+{0x00,0x00,0x00,0xF0,0xF8,0x9E,0x9E,0xB8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0xF9,0xF9,0x1F,0x0F,0x00,0x00,0x00},/*"$",3*/
+{0x00,0x00,0x38,0x44,0xC4,0xC4,0xB8,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x0E,0x11,0x11,0x11,0x0E,0x00,0x00,0x00},/*"%",4*/
+{0x00,0x00,0x60,0xE0,0xB0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x0E,0x0F,0x19,0x19,0x1B,0x1E,0x0E,0x0F,0x1B,0x00,0x00},/*"&",5*/
+{0x00,0x00,0x00,0x00,0x00,0x18,0xF8,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",6*/
+{0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0x3C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x78,0x60,0x00,0x00,0x00},/*"(",7*/
+{0x00,0x00,0x0C,0x3C,0xF0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x78,0x1F,0x07,0x00,0x00,0x00,0x00,0x00,0x00},/*")",8*/
+{0x00,0x00,0x30,0xB0,0xF0,0xFC,0xFC,0xF0,0xB0,0x30,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x00,0x00,0x00},/*"*",9*/
+{0x00,0x80,0x80,0x80,0x80,0xF8,0xF8,0x80,0x80,0x80,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x1F,0x1F,0x01,0x01,0x01,0x01,0x00},/*"+",10*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x38,0x08,0x00,0x00,0x00,0x00,0x00},/*",",11*/
+{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00},/*"-",12*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00},/*".",13*/
+{0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x78,0x1E,0x06,0x00,0x00,0x00,0x00,0x60,0x78,0x1E,0x07,0x01,0x00,0x00,0x00,0x00,0x00},/*"/",14*/
+{0x00,0x00,0xF0,0xF8,0x1C,0x0C,0x1C,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x1C,0x0F,0x07,0x00,0x00,0x00},/*"0",15*/
+{0x00,0x00,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"1",16*/
+{0x00,0x00,0x30,0x38,0x0C,0x0C,0x8C,0xF8,0x70,0x00,0x00,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x19,0x18,0x18,0x00,0x00,0x00},/*"2",17*/
+{0x00,0x00,0x18,0x1C,0xCC,0xCC,0xCC,0xFC,0x38,0x00,0x00,0x00,0x00,0x0C,0x1C,0x18,0x18,0x18,0x19,0x0F,0x07,0x00,0x00,0x00},/*"3",18*/
+{0x00,0x00,0xC0,0xE0,0x78,0x1C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x1B,0x1B,0x1F,0x1F,0x1B,0x00,0x00,0x00},/*"4",19*/
+{0x00,0x00,0xFC,0xFC,0xCC,0xCC,0xCC,0x8C,0x00,0x00,0x00,0x00,0x00,0x0C,0x1C,0x18,0x18,0x18,0x18,0x0F,0x07,0x00,0x00,0x00},/*"5",20*/
+{0x00,0x00,0xE0,0xF0,0xB8,0xDC,0xCC,0xCC,0x8C,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x19,0x18,0x18,0x1F,0x0F,0x00,0x00,0x00},/*"6",21*/
+{0x00,0x00,0x1C,0x1C,0x0C,0x0C,0xCC,0xFC,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1F,0x03,0x00,0x00,0x00,0x00},/*"7",22*/
+{0x00,0x00,0x38,0xFC,0xCC,0xCC,0xCC,0xFC,0x38,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x1F,0x0F,0x00,0x00,0x00},/*"8",23*/
+{0x00,0x00,0xF8,0xFC,0x8C,0x8C,0xCC,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x18,0x19,0x19,0x1D,0x0E,0x07,0x03,0x00,0x00,0x00},/*"9",24*/
+{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x00,0x00,0x00,0x00},/*":",25*/
+{0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x18,0x08,0x00,0x00,0x00,0x00,0x00},/*";",26*/
+{0x00,0x00,0x00,0x80,0x80,0xC0,0x60,0x60,0x30,0x30,0x00,0x00,0x00,0x01,0x01,0x03,0x03,0x06,0x0C,0x0C,0x18,0x18,0x00,0x00},/*"<",27*/
+{0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x00,0x00},/*"=",28*/
+{0x00,0x30,0x30,0x60,0x60,0xC0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0C,0x0C,0x06,0x03,0x03,0x01,0x01,0x00,0x00},/*">",29*/
+{0x00,0x00,0x70,0x78,0x18,0x18,0x98,0xF8,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1B,0x1B,0x01,0x01,0x00,0x00,0x00,0x00},/*"?",30*/
+{0x00,0x00,0xF0,0x08,0xC4,0x24,0x24,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x21,0x22,0x22,0x13,0x00,0x00,0x00,0x00},/*"@",31*/
+{0x00,0x00,0x18,0x98,0xF8,0x38,0x38,0xF0,0x80,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x1B,0x03,0x03,0x1B,0x1F,0x1C,0x18,0x00},/*"A",32*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0x70,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x19,0x19,0x19,0x1F,0x0E,0x00,0x00},/*"B",33*/
+{0x00,0xE0,0xF0,0x38,0x18,0x18,0x18,0x10,0x78,0x78,0x00,0x00,0x00,0x07,0x0F,0x0C,0x18,0x18,0x18,0x18,0x0C,0x0C,0x00,0x00},/*"C",34*/
+{0x00,0x18,0xF8,0xF8,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"D",35*/
+{0x00,0x18,0xF8,0xF8,0x98,0xD8,0xD8,0x18,0x78,0x78,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x1B,0x18,0x1E,0x1E,0x00,0x00},/*"E",36*/
+{0x00,0x18,0xF8,0xF8,0x98,0xD8,0xD8,0x18,0x78,0x78,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x1B,0x00,0x00,0x00,0x00,0x00},/*"F",37*/
+{0x00,0xE0,0xF0,0x38,0x18,0x18,0x10,0x38,0x38,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x1B,0x1B,0x1F,0x0F,0x03,0x00,0x00},/*"G",38*/
+{0x00,0x18,0xF8,0xF8,0x98,0x80,0x98,0xF8,0xF8,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x01,0x19,0x1F,0x1F,0x18,0x00,0x00},/*"H",39*/
+{0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"I",40*/
+{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xF8,0xF8,0x18,0x18,0x00,0x00,0x00,0x0F,0x0F,0x18,0x18,0x18,0x0F,0x0F,0x00,0x00,0x00},/*"J",41*/
+{0x00,0x18,0xF8,0xF8,0x98,0xC0,0x78,0x38,0x18,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x01,0x07,0x1E,0x18,0x18,0x00,0x00},/*"K",42*/
+{0x00,0x18,0x18,0xF8,0xF8,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x1F,0x1F,0x00,0x00},/*"L",43*/
+{0x18,0xF8,0xF8,0x38,0xE0,0x00,0xE0,0x38,0xF8,0xF8,0x18,0x00,0x18,0x1F,0x1F,0x18,0x19,0x03,0x19,0x18,0x1F,0x1F,0x18,0x00},/*"M",44*/
+{0x00,0x18,0xF8,0xF8,0xF8,0xE0,0x18,0xF8,0xF8,0x18,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x03,0x1F,0x1F,0x1F,0x00,0x00,0x00},/*"N",45*/
+{0x00,0xC0,0xF0,0x30,0x18,0x18,0x18,0x30,0xF0,0xC0,0x00,0x00,0x00,0x03,0x0F,0x0C,0x18,0x18,0x18,0x0C,0x0F,0x03,0x00,0x00},/*"O",46*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0xF0,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x19,0x19,0x01,0x00,0x00,0x00,0x00},/*"P",47*/
+{0x00,0xC0,0xF0,0x30,0x18,0x18,0x18,0x30,0xF0,0xC0,0x00,0x00,0x00,0x03,0x0F,0xCC,0xF8,0x78,0x78,0xCC,0xEF,0x63,0x00,0x00},/*"Q",48*/
+{0x00,0x18,0xF8,0xF8,0x98,0x98,0x98,0xF8,0x70,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x19,0x1B,0x07,0x0E,0x1C,0x18,0x00,0x00},/*"R",49*/
+{0x00,0x00,0x70,0xF8,0x98,0x98,0x90,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x09,0x19,0x19,0x1F,0x0E,0x00,0x00,0x00},/*"S",50*/
+{0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x00,0x00,0x00},/*"T",51*/
+{0x00,0x18,0xF8,0xF8,0x18,0x00,0x18,0xF8,0xF8,0x18,0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x18,0x18,0x0F,0x07,0x00,0x00,0x00},/*"U",52*/
+{0x00,0x18,0x78,0xF8,0x98,0x00,0x98,0xF8,0x78,0x18,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x18,0x1F,0x03,0x00,0x00,0x00,0x00},/*"V",53*/
+{0x18,0xF8,0xF8,0x18,0xD8,0xC0,0xD8,0x18,0xF8,0xF8,0x18,0x00,0x00,0x01,0x1F,0x1C,0x1F,0x01,0x1F,0x1C,0x1F,0x01,0x00,0x00},/*"W",54*/
+{0x00,0x18,0x38,0x78,0xD8,0x80,0xD8,0x78,0x38,0x18,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x01,0x1B,0x1E,0x1C,0x18,0x00,0x00},/*"X",55*/
+{0x00,0x18,0x38,0x78,0xD8,0x80,0x80,0xD8,0x78,0x38,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x00,0x00,0x00},/*"Y",56*/
+{0x00,0x00,0x78,0x78,0x18,0x98,0xD8,0x78,0x38,0x00,0x00,0x00,0x00,0x00,0x1C,0x1E,0x1B,0x19,0x18,0x1E,0x1E,0x00,0x00,0x00},/*"Z",57*/
+{0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x0C,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x60,0x60,0x00,0x00,0x00},/*"[",58*/
+{0x00,0x00,0x06,0x1E,0x78,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x1E,0x78,0x60,0x00,0x00},/*"\",59*/
+{0x00,0x00,0x00,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00},/*"]",60*/
+{0x00,0x00,0x00,0x60,0x70,0x18,0x0C,0x18,0x70,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",61*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"_",62*/
+{0x00,0x00,0x00,0x00,0x02,0x04,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",63*/
+{0x00,0x00,0x00,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x0E,0x1F,0x1B,0x1B,0x0B,0x1F,0x1F,0x18,0x00,0x00},/*"a",64*/
+{0x00,0x0C,0xFC,0xFC,0xC0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x18,0x1F,0x1F,0x0C,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"b",65*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xC0,0xE0,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x18,0x18,0x0C,0x00,0x00},/*"c",66*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xCC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x0C,0x1F,0x1F,0x18,0x00},/*"d",67*/
+{0x00,0x00,0x80,0xC0,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,0x07,0x0F,0x1B,0x1B,0x1B,0x1B,0x1B,0x0B,0x00,0x00},/*"e",68*/
+{0x00,0x00,0x60,0x60,0xF8,0xFC,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00,0x00},/*"f",69*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xC0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x07,0x0F,0xDC,0xD8,0xD8,0xCC,0xFF,0x7F,0x00,0x00},/*"g",70*/
+{0x00,0x0C,0xFC,0xFC,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00},/*"h",71*/
+{0x00,0x00,0x00,0x60,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"i",72*/
+{0x00,0x00,0x60,0x60,0x60,0x6C,0x6C,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0x7F,0x00,0x00,0x00},/*"j",73*/
+{0x00,0x00,0x0C,0xFC,0xFC,0x80,0xE0,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x18,0x1F,0x1F,0x03,0x06,0x1C,0x18,0x18,0x00,0x00},/*"k",74*/
+{0x00,0x00,0x00,0x0C,0x0C,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00},/*"l",75*/
+{0x00,0x60,0xE0,0xE0,0x60,0xE0,0xC0,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x00,0x1F,0x1F,0x00,0x1F,0x1F,0x18,0x00},/*"m",76*/
+{0x00,0x60,0xE0,0xE0,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00,0x00,0x18,0x1F,0x1F,0x18,0x00},/*"n",77*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"o",78*/
+{0x00,0x60,0xE0,0xE0,0xC0,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0xC0,0xFF,0xFF,0xCC,0xD8,0x18,0x1C,0x0F,0x07,0x00,0x00},/*"p",79*/
+{0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0xC0,0xE0,0xE0,0x60,0x00,0x00,0x00,0x07,0x0F,0x1C,0x18,0xD8,0xCC,0xFF,0xFF,0xC0,0x00},/*"q",80*/
+{0x00,0x00,0x60,0x60,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x18,0x18,0x1F,0x1F,0x18,0x18,0x18,0x00,0x00,0x00},/*"r",81*/
+{0x00,0x00,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x1D,0x1D,0x1B,0x1B,0x1B,0x1E,0x0E,0x00,0x00,0x00},/*"s",82*/
+{0x00,0x00,0x60,0x60,0xFC,0xFC,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x0C,0x00,0x00},/*"t",83*/
+{0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x0F,0x1F,0x18,0x18,0x18,0x0C,0x1F,0x1F,0x18,0x00},/*"u",84*/
+{0x00,0x60,0xE0,0xE0,0x60,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x18,0x1F,0x07,0x00,0x00,0x00,0x00},/*"v",85*/
+{0x60,0xE0,0xE0,0x60,0x00,0x80,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x01,0x1F,0x1E,0x07,0x03,0x07,0x1E,0x1F,0x01,0x00,0x00},/*"w",86*/
+{0x00,0x00,0x60,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x18,0x1C,0x1F,0x03,0x03,0x1F,0x1C,0x18,0x00,0x00},/*"x",87*/
+{0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0x60,0xE0,0xE0,0x60,0x00,0x00,0xC0,0xC0,0xC1,0xE7,0xFE,0xDC,0xC7,0x03,0x00,0x00,0x00},/*"y",88*/
+{0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x60,0x00,0x00,0x00,0x00,0x18,0x1C,0x1E,0x1B,0x1B,0x19,0x1C,0x1C,0x00,0x00},/*"z",89*/
+{0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3F,0x7E,0x60,0x00,0x00,0x00,0x00},/*"{",90*/
+{0x00,0x00,0x00,0x00,0x00,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00},/*"|",91*/
+{0x00,0x00,0x00,0x00,0x0C,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x7E,0x3F,0x01,0x00,0x00,0x00,0x00},/*"}",92*/
+{0x00,0x00,0x80,0xC0,0xC0,0xC0,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x03,0x03,0x03,0x01,0x00,0x00},/*"~",93*/
+{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",94*/
+};
+
+
+
+static const unsigned char blank_block PROGMEM = 0x00;
diff --git a/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/logo.h b/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/logo.h
new file mode 100644
index 000000000000..f2a3cee42c87
--- /dev/null
+++ b/keyboards/yandrstudio/rainbow65/keymaps/test_font/oled_font_lib/logo.h
@@ -0,0 +1,47 @@
+/* Copyright 2021 JasonRen(biu)
+ *
+ * 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 "progmem.h"
+
+static const unsigned char logo_idobao[] PROGMEM = {
+ 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xE0, 0xE0,
+ 0xF0, 0xF0, 0x70, 0x60, 0x04, 0x0E, 0x0E, 0x1E,
+ 0x8E, 0x8E, 0xC4, 0xC0, 0xE0, 0xF0, 0xF0, 0xF0,
+ 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
+
+
+ 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0x03, 0x01,
+ 0xF0, 0xF8, 0xFC, 0xFC, 0x1E, 0x1E, 0x0F, 0x0F,
+ 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x01,
+ 0x01, 0x03, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
+
+
+ 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0xC0, 0xE0, 0xF8, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
+
+
+ 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
+ 0x0F, 0x0F, 0x1F, 0x1F, 0x3E, 0x3C, 0x7C, 0x7C,
+ 0x7C, 0x7C, 0x3C, 0x3E, 0x1E, 0x1F, 0x0F, 0x0F,
+ 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00
+};
+
+// {0x00,0x00,0x80,0xC0,0xC0,0xE0,0xE0,0xF0,0xF8,0xF0,0xF0,0xE4,0x6E,0x4E,0x1E,0x9F,0x9F,0xCE,0xCE,0xE6,0xF4,0xF0,0xF8,0xF8,0xF0,0xE0,0xE0,0xC0,0xC0,0x80,0x00,0x00},
+// {0x00,0xFF,0xFF,0xFF,0xFF,0x07,0x03,0xFB,0xF9,0xFD,0xFC,0xFE,0x3E,0x1F,0x1F,0x0F,0x0F,0x07,0x07,0x03,0x03,0x01,0x01,0x01,0x03,0x07,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC},
+// {0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0xC0,0xC0,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F},
+// {0x00,0x00,0x01,0x03,0x03,0x00,0x00,0x0F,0x0F,0x1F,0x1F,0x3F,0x3E,0x7E,0x7E,0x7C,0x7C,0x7E,0x7E,0x7E,0x3F,0x1F,0x1F,0x0F,0x0F,0x07,0x07,0x03,0x03,0x01,0x00,0x00},
diff --git a/keyboards/yandrstudio/rainbow65/keymaps/test_font/rules.mk b/keyboards/yandrstudio/rainbow65/keymaps/test_font/rules.mk
new file mode 100644
index 000000000000..70767b0f26e9
--- /dev/null
+++ b/keyboards/yandrstudio/rainbow65/keymaps/test_font/rules.mk
@@ -0,0 +1,4 @@
+VIA_ENABLE = yes
+OPT_ENABLE = yes
+WPM_ENABLE = yes
+OLED_DRIVER_ENABLE = yes
diff --git a/keyboards/yandrstudio/zhou75/keymaps/via/keymap.c b/keyboards/yandrstudio/zhou75/keymaps/via/keymap.c
index 40adf0bb2c34..332fe6cfcc41 100644
--- a/keyboards/yandrstudio/zhou75/keymaps/via/keymap.c
+++ b/keyboards/yandrstudio/zhou75/keymaps/via/keymap.c
@@ -15,7 +15,6 @@
*/
#include QMK_KEYBOARD_H
-
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
LAYOUT(
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,