Compare commits

...

4 Commits

Author SHA1 Message Date
LiWen
6d2a5093c6
Merge 54b4dc4ed1 into 9bea332a21 2024-11-21 14:24:15 +08:00
Ryan
9bea332a21
qmk via2json: Improve macro parsing (#24345) 2024-11-21 17:20:05 +11:00
Ryan
8cbcdcac62
qmk new-keymap: validate keymap name (#23420) 2024-11-21 17:18:51 +11:00
LiuLiuQMK
54b4dc4ed1 sk75 2024-11-14 14:19:09 +08:00
26 changed files with 5396 additions and 9 deletions

View File

@ -0,0 +1,485 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
Keyboard_Info_t Keyboard_Info = {
.Key_Mode = INIT_WORK_MODE,
.Ble_Channel = INIT_BLE_CHANNEL,
.Batt_Number = INIT_BATT_NUMBER,
.Nkro = INIT_ALL_SIX_KEY,
.Mac_Win_Mode = INIT_WIN_MAC_MODE,
.Win_Lock = INIT_WIN_LOCK_NLOCK,
};
Keyboard_Status_t Keyboard_Status = {
.System_Work_Status = 0x00,
.System_Work_Mode = 0x00,
.System_Work_Channel = 0x00,
.System_Connect_Status = 0x00,
.System_Led_Status = 0x00,
.System_Sleep_Mode = 0x00
};
const uint32_t g_es_dma_ch2pri_cfg = ((MD_DMA_CHANNEL_CFG_MODE_PERIPHERAL_PRIMARY) | \
((MD_DMA_CHANNEL_CFG_RPOWER_SIZE_4) << 14) | \
((MD_DMA_CHANNEL_CFG_SRCDATA_SIZE_WORD) << 24) | \
((MD_DMA_CHANNEL_CFG_SRCINC_WORD) << 26) | \
((MD_DMA_CHANNEL_CFG_DSTDATA_SIZE_WORD) << 28) | \
((MD_DMA_CHANNEL_CFG_DSTINC_WORD) << 30));
const uint32_t g_es_dma_ch2alt_cfg = ((MD_DMA_CHANNEL_CFG_MODE_PERIPHERAL_ALTERNATE) | \
((MD_DMA_CHANNEL_CFG_RPOWER_SIZE_1) << 14) | \
((MD_DMA_CHANNEL_CFG_SRCDATA_SIZE_BYTE) << 24) | \
((MD_DMA_CHANNEL_CFG_SRCINC_BYTE) << 26) | \
((MD_DMA_CHANNEL_CFG_DSTDATA_SIZE_BYTE) << 28) | \
((MD_DMA_CHANNEL_CFG_DSTINC_NO_INC) << 30));
bool Led_Rf_Pair_Flg = false;
bool Key_2p4g_Status = false;
bool Key_Ble_1_Status = false;
bool Key_Ble_2_Status = false;
bool Key_Ble_3_Status = false;
bool Key_Reset_Status = false;
bool Keyboard_Reset = false;
bool Init_Eeprom_Flg = false;
bool Led_Off_Start = false;
bool Led_Power_Up = false;
bool Usb_If_Ok_Led = false;
uint16_t Led_Power_Up_Delay = 0;
uint8_t Temp_System_Led_Status = 0xff;
uint8_t Systick_6ms_Count = 0U;
uint8_t Systick_10ms_Count = 0x00;
uint16_t Systick_Interval_Count = 0x00;
uint8_t Systick_Led_Count = 0x00;
uint8_t Batt_Led_Count = 0x00;
uint16_t Time_3s_Count = 0;
uint16_t Func_Time_3s_Count = 0;
//WAKEUP_IRQHandler
OSAL_IRQ_HANDLER(Vector4C) {
md_syscfg_clear_flag_wakeup(SYSCFG);
md_exti_clear_it_wakeup(EXTI); //Clear Wakeup Flag
}
//EXTI_0to1_IRQHandler
OSAL_IRQ_HANDLER(Vector54) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = EXTI->IFM;
EXTI->ICR = irq_ifm;
OSAL_IRQ_EPILOGUE();
}
//EXTI_2to3_IRQHandler
OSAL_IRQ_HANDLER(Vector58) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = EXTI->IFM;
EXTI->ICR = irq_ifm;
OSAL_IRQ_EPILOGUE();
}
//GP32C4T1_IRQHandler
OSAL_IRQ_HANDLER(Vector7C) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = GP32C4T1->IFM;
GP32C4T1->ICR = irq_ifm;
OSAL_IRQ_EPILOGUE();
}
//GP16C4T1_IRQHandler
OSAL_IRQ_HANDLER(Vector80) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = GP16C4T1->IFM;
GP16C4T1->ICR = irq_ifm;
OSAL_IRQ_EPILOGUE();
}
//GP16C4T2_IRQHandler
OSAL_IRQ_HANDLER(Vector84) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = GP16C4T2->IFM;
GP16C4T2->ICR = irq_ifm;
OSAL_IRQ_EPILOGUE();
}
//DMA1_CH12_IRQHandler
OSAL_IRQ_HANDLER(Vector68) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = DMA1->IFM;
DMA1->ICR = irq_ifm;
if(irq_ifm & (1U << 1)){
/*DMA 收发完成*/
}
OSAL_IRQ_EPILOGUE();
}
//EXTI_4to15_IRQHandler
OSAL_IRQ_HANDLER(Vector5C) {
uint32_t irq_ifm;
OSAL_IRQ_PROLOGUE();
irq_ifm = EXTI->IFM;
EXTI->ICR = irq_ifm;
if (!Init_Spi_Power_Up) {
if(irq_ifm & (1U << 4)) {
if (Spi_Send_Recv_Flg) {
if (Send_Key_Type == SPI_NACK) {
if (!gpio_read_pin(ES_SPI_ACK_IO)) {
Spi_Send_Recv_Flg = 0;
}
} else {
if (gpio_read_pin(ES_SPI_ACK_IO)) {
if (Spi_Send_Recv_Flg == 1) {
Spi_Send_Recv_Flg = 2;
memset((void *)g_es_spi_rx_buf, 0x00, USER_KEYBOARD_LENGTH);
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, (void*)(0x1000));
}
} else {
if (Spi_Send_Recv_Flg == 2) {
if (Emi_Test_Start && ((USER_EMI_COMMAND == g_es_spi_rx_buf[0]) || ((USER_EMI_COMMAND & 0X7F) == g_es_spi_rx_buf[0]))) {
Get_Spi_Return_Data(g_es_spi_rx_buf);
Spi_Send_Recv_Flg = 0;
} else if (USER_KEYBOARD_COMMAND == g_es_spi_rx_buf[0]) {
Get_Spi_Return_Data(g_es_spi_rx_buf);
Spi_Send_Recv_Flg = 0;
} else {
Repet_Send_Count++;
if (Repet_Send_Count >= 3) {
Repet_Send_Count = 0;
Spi_Send_Recv_Flg = 0;
} else {
Spi_Send_Recv_Flg = 1;
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, g_es_spi_tx_buf);
}
}
}
}
}
}
}
}
OSAL_IRQ_EPILOGUE();
}
//BS16T1_IRQHandler 2ms
OSAL_IRQ_HANDLER(Vector78) {
OSAL_IRQ_PROLOGUE();
BS16T1->ICR = BS16T1->IFM;
if (Init_Spi_Power_Up) {
Init_Spi_100ms_Delay++;
if (Init_Spi_100ms_Delay >= 10) {
Init_Spi_100ms_Delay = 0;
if (!gpio_read_pin(ES_SPI_ACK_IO)) {
Init_Spi_Power_Up = false;
} else {
Init_Spi_100ms_Delay = 5;
}
}
}
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
if (Keyboard_Status.System_Work_Status && (!Keyboard_Status.System_Sleep_Mode)) {
Spi_Ack_Send_Commad(USER_KEYBOARD_SLEEP);
} else {
Spi_Main_Loop();
}
}
if (User_Batt_Power_Up_Delay) {
User_Batt_Power_Up_Delay_100ms_Count++;
if (User_Batt_Power_Up_Delay_100ms_Count >= 50) {
User_Batt_Power_Up_Delay_100ms_Count = 0;
User_Batt_Power_Up_Delay = false;
}
} else {
if (User_Batt_Power_Up) {
User_Batt_10ms_Count++;
if (User_Batt_10ms_Count >= 4) {
User_Batt_10ms_Count = 0;
if((md_adc_is_active_flag_normal_status(ADC)) == 0) {
User_Adc_Batt[User_Adc_Batt_Count] = md_adc_get_normal_data(ADC);
md_adc_set_start_normal(ADC, MD_ADC_CON_NSTART_START_REGULAR);
User_Adc_Batt_Count++;
if (User_Adc_Batt_Count >= USER_BATT_POWER_SCAN_COUNT) {
User_Adc_Batt_Count = 0;
for(uint8_t i = 0; i < USER_BATT_POWER_SCAN_COUNT; i++) {
User_Scan_Batt[i] = User_Adc_Batt[i];
}
User_Adc_Batt_Power_Up_Init();
}
}
}
} else {
User_Batt_10ms_Count++;
if (User_Batt_10ms_Count >= 20) {
User_Batt_10ms_Count = 0;
if((md_adc_is_active_flag_normal_status(ADC)) == 0) {
User_Adc_Batt[User_Adc_Batt_Count] = md_adc_get_normal_data(ADC);
md_adc_set_start_normal(ADC, MD_ADC_CON_NSTART_START_REGULAR);
User_Adc_Batt_Count++;
if (User_Adc_Batt_Count >= USER_BATT_SCAN_COUNT) {
User_Adc_Batt_Count = 0;
for(uint8_t i = 0; i < USER_BATT_SCAN_COUNT; i++) {
User_Scan_Batt[i] = User_Adc_Batt[i];
}
User_Adc_Batt_Number();
}
}
User_Batt_Time_15S_Count++;
}
}
}
Systick_6ms_Count++;
if (Systick_6ms_Count >= 3) {
Systick_6ms_Count = 0;
host_driver_t * temp_driver;
temp_driver = host_get_driver();
if((temp_driver != (&es_user_driver))&&(temp_driver)) {
es_qmk_driver = host_get_driver();
host_set_driver((host_driver_t *)(&es_user_driver));
}
}
Systick_10ms_Count++;
if (Systick_10ms_Count >= 5) {
Systick_10ms_Count = 0;
if (Mode_Synchronization_Signal) {
Mode_Synchronization_Signal = false;
Mode_Synchronization();
}
if (Ble_Name_Spi_Send) {
Ble_Name_Synchronization();
}
Systick_Led_Count++;
if (Systick_Led_Count >= 255) {
Systick_Led_Count = 0;
}
Batt_Led_Count++;
if (Batt_Led_Count >= 255) {
Batt_Led_Count = 0;
}
if (Led_Power_Up == false) {
Led_Power_Up_Delay++;
if (Led_Power_Up_Delay >= 50) {
Led_Power_Up_Delay = 0;
Led_Power_Up = true;
if (Keyboard_Info.Key_Mode == QMK_BLE_MODE) {
User_Batt_Send_Spi = true;
}
}
}
Usb_Change_Mode_Delay++;
if (Usb_Change_Mode_Delay >= USER_TIME_3S_TIME) {
Usb_Change_Mode_Delay = 0;
Usb_Change_Mode_Wakeup = true;
}
if (Save_Flash) {
Save_Flash_3S_Count++;
if (Save_Flash_3S_Count >= USER_TIME_3S_TIME) {
if (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO)) || (!Led_Flash_Busy)) {
Save_Flash_3S_Count = (USER_TIME_3S_TIME - 10);
} else {
Reset_Save_Flash = true;
eeprom_write_block_user((void *)&Keyboard_Info.Key_Mode, 0, sizeof(Keyboard_Info_t));
Reset_Save_Flash = false;
Save_Flash = false;
Save_Flash_3S_Count = 0;
}
}
} else {
Save_Flash_3S_Count = 0;
}
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
if (User_Batt_Send_Spi) {
User_Batt_Send_Spi = false;
Spi_Send_Commad(USER_BATTERY_DATA);
}
Usb_If_Ok_Led = false;
} else {
g_usb_sof_frame_id = ((USB->FRAME1) | (USB->FRAME2 << 8));
Usb_Dis_Connect = true;
}
if (gpio_read_pin(ES_USB_POWER_IO)) {
if (gpio_read_pin(ES_BATT_STDBY_IO)) {
es_stdby_pin_state = 1;
} else {
es_stdby_pin_state = 2;
}
} else {
es_stdby_pin_state = 0;
}
Time_3s_Count++;
if (Time_3s_Count >= USER_TIME_3S_TIME) {
Time_3s_Count = 0;
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
if (Key_2p4g_Status || Key_Ble_1_Status || Key_Ble_2_Status || Key_Ble_3_Status) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: {
if (Key_2p4g_Status){
Key_2p4g_Status = 0;
Spi_Send_Commad(USER_SWITCH_2P4G_PAIR);
Led_Rf_Pair_Flg = true;
}
break;
}
case QMK_BLE_MODE: {
if ((Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_1) && Key_Ble_1_Status){
Key_Ble_1_Status = 0;
Spi_Send_Commad(USER_SWITCH_BLE_1_PAIR);
Led_Rf_Pair_Flg = true;
} else if ((Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_2) && Key_Ble_2_Status){
Key_Ble_2_Status = 0;
Spi_Send_Commad(USER_SWITCH_BLE_2_PAIR);
Led_Rf_Pair_Flg = true;
} else if ((Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_3) && Key_Ble_3_Status){
Key_Ble_3_Status = 0;
Spi_Send_Commad(USER_SWITCH_BLE_3_PAIR);
Led_Rf_Pair_Flg = true;
}
break;
}
default: {
break;
}
}
}
}
}
Func_Time_3s_Count++;
if (Func_Time_3s_Count >= USER_TIME_3S_TIME) {
Func_Time_3s_Count = 0;
if (Key_Reset_Status) {
Key_Reset_Status = false;
Keyboard_Reset = true;
}
}
}
Systick_Interval_Count++;
if (Systick_Interval_Count >= Spi_Interval) {
Systick_Interval_Count = 0;
if (!Keyboard_Status.System_Work_Status) {
if(Spi_Ack_Send_Commad(USER_GET_RF_STATUS) == SPI_BUSY) {
Systick_Interval_Count = (Spi_Interval - 10);
}
}
}
OSAL_IRQ_EPILOGUE();
}
void Init_Keyboard_Infomation(void) {
eeprom_read_block_user((void *)&Keyboard_Info.Key_Mode, 0, sizeof(Keyboard_Info_t));
if ((Keyboard_Info.Key_Mode == 0XFF) && (Keyboard_Info.Ble_Channel == 0XFF) && (Keyboard_Info.Batt_Number == 0XFF) && (Keyboard_Info.Nkro == 0XFF) && (Keyboard_Info.Mac_Win_Mode == 0XFF) && (Keyboard_Info.Win_Lock == 0XFF)) {
Keyboard_Info.Key_Mode = INIT_WORK_MODE;
Keyboard_Info.Ble_Channel = INIT_BLE_CHANNEL;
Keyboard_Info.Batt_Number = INIT_BATT_NUMBER;
Keyboard_Info.Nkro = INIT_ALL_KEY;
Keyboard_Info.Mac_Win_Mode = INIT_WIN_MODE;
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
} else if ((Keyboard_Info.Key_Mode == 0) && (Keyboard_Info.Ble_Channel == 0) && (Keyboard_Info.Batt_Number == 0) && (Keyboard_Info.Nkro == 0) && (Keyboard_Info.Mac_Win_Mode == 0) && (Keyboard_Info.Win_Lock == 0)) {
Keyboard_Info.Key_Mode = INIT_WORK_MODE;
Keyboard_Info.Ble_Channel = INIT_BLE_CHANNEL;
Keyboard_Info.Batt_Number = INIT_BATT_NUMBER;
Keyboard_Info.Nkro = INIT_ALL_KEY;
Keyboard_Info.Mac_Win_Mode = INIT_WIN_MODE;
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
} else {
if (Keyboard_Info.Key_Mode > QMK_USB_MODE) {
Keyboard_Info.Key_Mode = QMK_USB_MODE;
}
if (Keyboard_Info.Ble_Channel > QMK_BLE_CHANNEL_3) {
Keyboard_Info.Ble_Channel = QMK_BLE_CHANNEL_3;
}
if (Keyboard_Info.Batt_Number > 100) {
Keyboard_Info.Batt_Number = 100;
}
if (Keyboard_Info.Nkro > INIT_ALL_KEY) {
Keyboard_Info.Nkro = INIT_ALL_KEY;
}
if (Keyboard_Info.Mac_Win_Mode > INIT_MAC_MODE) {
Keyboard_Info.Mac_Win_Mode = INIT_WIN_MODE;
}
if (Keyboard_Info.Win_Lock > INIT_WIN_LOCK) {
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
}
}
}
void es_change_qmk_nkro_mode_enable(void) {
if(!keymap_config.nkro) {
clear_keyboard(); // clear first buffer to prevent stuck keys
keymap_config.nkro = true;
Keyboard_Info.Nkro = keymap_config.nkro;
Save_Flash_Set();
}
}
void es_change_qmk_nkro_mode_disable(void) {
if(keymap_config.nkro) {
clear_keyboard(); // clear first buffer to prevent stuck keys
keymap_config.nkro = false;
Keyboard_Info.Nkro = keymap_config.nkro;
Save_Flash_Set();
}
}

View File

@ -0,0 +1,198 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include "quantum.h"
#include "quantum_keycodes.h"
#include "dynamic_keymap.h"
#include "md_adc.h"
#include "usb_main.h"
#include "raw_hid.h"
#include "usb_descriptor.h"
#include "three_mode.h"
#include "user_battery.h"
#include "user_eeprom.h"
#include "user_emi.h"
#include "user_led_custom.h"
#include "user_spi.h"
#include "user_system.h"
#define ES_BATT_ADC_IO (C4)
#define ES_BATT_STDBY_IO (A13)
#define ES_USB_POWER_IO (C5)
#define ES_SPI_ACK_IO (A4)
#define ES_PWM_DMA_IO (A2)
#define ES_WUKEUP_IO (D1)
#define ES_SDB_POWER_IO (A3)
#define ES_LED_POWER_IO (D0)
#define PAL_ES32_PUPDR_PULLDOWN PAL_ES32_PUD_PULLDOWN
#define USER_KEY_BYTE_LENGTH 0X08
#define USER_KEY_BIT_LENGTH 0X0F
#define USER_MOUSE_LENGTH 0X08
#define USER_CONSUMER_LENGTH 0X03
#define USER_SYSTEM_LENGTH 0X03
#define USER_BATTERY_LENGTH 0X02
#define KB_REPORT_ID 0x06 // Extend keyboard report ID.
#define SYS_REPORT_ID 0x03 // Extend System report ID.
#define CON_REPORT_ID 0x04 // Extend Consumer report ID.
#define MOUSE_REPORT_ID 0x02 // Extend mouse report ID.
#define USER_DEFINE_KEY (QK_KB)
enum Custom_Keycodes {
QMK_KB_MODE_2P4G = USER_DEFINE_KEY,
QMK_KB_MODE_BLE1,
QMK_KB_MODE_BLE2,
QMK_KB_MODE_BLE3,
QMK_KB_MODE_USB,
QMK_BATT_NUM,
QMK_WIN_LOCK,
QMK_KB_SIX_N_CH,
QMK_TEST_COLOUR,
QMK_KB_2P4G_PAIR,
QMK_KB_BLE1_PAIR,
QMK_KB_BLE2_PAIR,
QMK_KB_BLE3_PAIR
};
enum Custom_KeyModes {
QMK_BLE_MODE = 0,
QMK_2P4G_MODE,
QMK_USB_MODE
};
enum Custom_BleChannels {
QMK_BLE_CHANNEL_1 = 1,
QMK_BLE_CHANNEL_2,
QMK_BLE_CHANNEL_3
};
enum Custom_Ble_24G_Status_S {
BLE_24G_NONE,
BLE_24G_PIAR,
BLE_24G_RETURN
};
typedef struct {
uint8_t Key_Mode;
uint8_t Ble_Channel;
uint8_t Batt_Number;
uint8_t Nkro;
uint8_t Mac_Win_Mode;
uint8_t Win_Lock;
} Keyboard_Info_t;
typedef struct {
uint8_t System_Work_Status;
uint8_t System_Work_Mode;
uint8_t System_Work_Channel;
uint8_t System_Connect_Status;
uint8_t System_Led_Status;
uint8_t System_Sleep_Mode;
} Keyboard_Status_t;
typedef enum {
KB_MODE_CONNECT_OK,
KB_MODE_CONNECT_PAIR,
KB_MODE_CONNECT_RETURN,
} keyboard_System_state_e;
typedef enum {
USER_SLEEP_PASS,
USER_SLEEP_FIAL,
} keyboard_System_Sleep_Status_s;
#define INIT_WORK_MODE (QMK_USB_MODE)
#define INIT_BLE_CHANNEL (QMK_BLE_CHANNEL_1)
#define INIT_BATT_NUMBER (50)
#define INIT_SIX_KEY (0)
#define INIT_ALL_KEY (1)
#define INIT_ALL_SIX_KEY (INIT_ALL_KEY)
#define INIT_WIN_MODE (0)
#define INIT_MAC_MODE (1)
#define INIT_WIN_MAC_MODE (INIT_WIN_MODE)
#define INIT_WIN_NLOCK (0)
#define INIT_WIN_LOCK (1)
#define INIT_WIN_LOCK_NLOCK (INIT_WIN_NLOCK)
#define U_PWM (RGB_MATRIX_MAXIMUM_BRIGHTNESS)
#define USER_BATT_DELAY_TIME (100 * 25) //25S
#define USER_TIME_3S_TIME (100 * 3) //3S
#define KC_K29 KC_BACKSLASH
#define KC_K42 KC_NONUS_HASH
#define KC_K45 KC_NONUS_BACKSLASH
#define KC_K56 KC_INTERNATIONAL_1
#define KC_K14 KC_INTERNATIONAL_3
#define KC_K132 KC_INTERNATIONAL_4
#define KC_K131 KC_INTERNATIONAL_5
#define KC_K133 KC_INTERNATIONAL_2
#define KC_K151 KC_LANGUAGE_1
#define KC_K150 KC_LANGUAGE_2
#define MD_24G QMK_KB_MODE_2P4G
#define MD_BLE1 QMK_KB_MODE_BLE1
#define MD_BLE2 QMK_KB_MODE_BLE2
#define MD_BLE3 QMK_KB_MODE_BLE3
#define MD_USB QMK_KB_MODE_USB
#define QK_BAT QMK_BATT_NUM
#define QK_WLO QMK_WIN_LOCK
#define SIX_N QMK_KB_SIX_N_CH
#define TEST_CL QMK_TEST_COLOUR
extern Keyboard_Info_t Keyboard_Info;
extern Keyboard_Status_t Keyboard_Status;
extern const uint32_t g_es_dma_ch2pri_cfg;
extern const uint32_t g_es_dma_ch2alt_cfg;
extern bool Led_Rf_Pair_Flg;
extern bool Key_2p4g_Status;
extern bool Key_Ble_1_Status;
extern bool Key_Ble_2_Status;
extern bool Key_Ble_3_Status;
extern bool Key_Reset_Status;
extern bool Keyboard_Reset;
extern bool Init_Eeprom_Flg;
extern bool Led_Off_Start;
extern bool Led_Power_Up;
extern bool Usb_If_Ok_Led;
extern uint16_t Led_Power_Up_Delay;
extern uint8_t Temp_System_Led_Status;
extern uint8_t Systick_6ms_Count;
extern uint8_t Systick_10ms_Count;
extern uint16_t Systick_Interval_Count;
extern uint8_t Systick_Led_Count;
extern uint8_t Batt_Led_Count;
extern uint16_t Time_3s_Count;
extern uint16_t Func_Time_3s_Count;
extern void Init_Keyboard_Infomation(void);
extern void es_change_qmk_nkro_mode_enable(void);
void es_change_qmk_nkro_mode_disable(void);

View File

@ -0,0 +1,209 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
uint16_t Usb_Suspend_Delay = 0;
uint16_t Usb_Change_Mode_Delay = 0;
bool Usb_Change_Mode_Wakeup = false;
bool Mode_Synchronization_Signal = false;
uint16_t g_usb_sof_frame_id = 0;
uint16_t g_usb_sof_frame_id_last = 0;
bool Usb_Dis_Connect = false;
void Mode_Synchronization(void) {
switch(Keyboard_Info.Key_Mode) {
case QMK_BLE_MODE: {
switch (Keyboard_Info.Ble_Channel) {
case QMK_BLE_CHANNEL_1: Spi_Send_Commad(USER_SWITCH_BLE_1_MODE); break;
case QMK_BLE_CHANNEL_2: Spi_Send_Commad(USER_SWITCH_BLE_2_MODE); break;
case QMK_BLE_CHANNEL_3: Spi_Send_Commad(USER_SWITCH_BLE_3_MODE); break;
default: break;
}
break;
}
case QMK_2P4G_MODE: Spi_Send_Commad(USER_SWITCH_2P4G_MODE); break;
case QMK_USB_MODE: Spi_Send_Commad(USER_SWITCH_USB_MODE); break;
default: break;
}
}
void Ble_Name_Synchronization(void) {
switch(Ble_Name_Spi_Count) {
case QMK_BLE_CHANNEL_1: Spi_Send_Commad(USER_BLE1_WRITE_NAME); Ble_Name_Spi_Count++; break;
case QMK_BLE_CHANNEL_2: Spi_Send_Commad(USER_BLE2_WRITE_NAME); Ble_Name_Spi_Count++; break;
case QMK_BLE_CHANNEL_3: Spi_Send_Commad(USER_BLE3_WRITE_NAME); Ble_Name_Spi_Count++; break;
default: break;
}
if(Ble_Name_Spi_Count > QMK_BLE_CHANNEL_3) {
Ble_Name_Spi_Count = QMK_BLE_CHANNEL_1;
Ble_Name_Spi_Send = false;
}
}
uint8_t es_keyboard_leds(void) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: break;
case QMK_BLE_MODE: break;
case QMK_USB_MODE: break;
default: break;
}
if(es_qmk_driver) {
return((*es_qmk_driver->keyboard_leds)());
}
return 0;
}
void es_send_keyboard(report_keyboard_t *report) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_keyboard_t)); break;
case QMK_BLE_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_keyboard_t)); break;
case QMK_USB_MODE: break;
default: break;
}
if(es_qmk_driver) {
(*es_qmk_driver->send_keyboard)(report);
}
}
void es_send_nkro(report_nkro_t *report) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_nkro_t)); break;
case QMK_BLE_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_nkro_t)); break;
case QMK_USB_MODE: break;
default: break;
}
if(es_qmk_driver) {
(*es_qmk_driver->send_nkro)(report);
}
}
void es_send_mouse(report_mouse_t *report) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_mouse_t)); break;
case QMK_BLE_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_mouse_t)); break;
case QMK_USB_MODE: break;
default: break;
}
if(es_qmk_driver) {
(*es_qmk_driver->send_mouse)(report);
}
}
void es_send_extra(report_extra_t *report) {
switch (Keyboard_Info.Key_Mode) {
case QMK_2P4G_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_extra_t)); break;
case QMK_BLE_MODE: User_bluetooth_send_keyboard((uint8_t *)report,sizeof(report_extra_t)); break;
case QMK_USB_MODE: break;
default: break;
}
if(es_qmk_driver) {
(*es_qmk_driver->send_extra)(report);
}
}
volatile host_driver_t * es_qmk_driver = NULL;
const host_driver_t es_user_driver = {es_keyboard_leds, es_send_keyboard, es_send_nkro, es_send_mouse, es_send_extra};
void User_bluetooth_send_keyboard(uint8_t *report, uint32_t len) {
if(app_2g4_buffer_full()) {
return;
}
if (len > USER_KEYBOARD_LENGTH - 3) {
len = USER_KEYBOARD_LENGTH - 3;
}
uint8_t Temp_Tx_Buf[USER_KEYBOARD_LENGTH] = {0};
Temp_Tx_Buf[0] = USER_KEYBOARD_COMMAND;
Temp_Tx_Buf[1] = USER_KEYBOARD_LENGTH;
if (len == sizeof(report_keyboard_t)) { //六键
memcpy((void *)&Temp_Tx_Buf[3], report, len);
Temp_Tx_Buf[2] = USER_KEY_BYTE_DATA;
} else {
switch (report[0]) {
case KB_REPORT_ID: { //全键
memcpy((void *)&Temp_Tx_Buf[3], report, len);
Temp_Tx_Buf[2] = USER_KEY_BIT_DATA;
break;
}
case SYS_REPORT_ID: { //系统键
memcpy((void *)&Temp_Tx_Buf[3], report, len);
Temp_Tx_Buf[2] = USER_SYSTEM_DATA;
break;
}
case CON_REPORT_ID: { //多媒体键
memcpy((void *)&Temp_Tx_Buf[3], report, len);
Temp_Tx_Buf[2] = USER_CONSUMER_DATA;
break;
}
case MOUSE_REPORT_ID: { //鼠标
memcpy((void *)&Temp_Tx_Buf[3], report, len);
Temp_Tx_Buf[2] = USER_MOUSE_DATA;
break;
}
default: {
break;
}
}
}
memcpy(app_2g4_data[app_2g4_data_rev], Temp_Tx_Buf, USER_KEYBOARD_LENGTH);
app_2g4_buffer_rev_add();
}
void User_Usb_Init(void) {
/*Using USB_SOF to calibrate the internal clock*/
md_rcu_enable_csu(RCU);
CSU->CON |= CSU_CON_AUTOEN_MSK;
CSU->CON |= CSU_CON_CNTEN_MSK;
}
void es_restart_usb_driver(void) {
md_rcu_enable_usb(RCU);
ald_usb_device_components_init();
USB->TXIER = 0x7F;
USB->RXIER = 0x7E;
USB->IER = 0x2F;
usb_lld_connect_bus(0);
ald_usb_int_register();
}
void Usb_Disconnect(void) {
ald_usb_int_unregister();
usb_lld_disconnect_bus(0);
md_rcu_enable_usb_reset(RCU);
md_rcu_disable_usb_reset(RCU);
md_rcu_disable_usb(RCU);
}
void User_Usb_Deinit(void) {
md_rcu_enable_csu_reset(RCU);
md_rcu_disable_csu_reset(RCU);
md_rcu_disable_csu(RCU);
}

View File

@ -0,0 +1,45 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
extern uint16_t Usb_Suspend_Delay;
extern uint16_t Usb_Change_Mode_Delay;
extern bool Usb_Change_Mode_Wakeup;
extern bool Mode_Synchronization_Signal;
extern uint16_t g_usb_sof_frame_id;
extern uint16_t g_usb_sof_frame_id_last;
extern bool Usb_Dis_Connect;
extern void Mode_Synchronization(void);
extern void Ble_Name_Synchronization(void);
extern uint8_t es_keyboard_leds(void);
extern void es_send_keyboard(report_keyboard_t *report);
extern void es_send_nkro(report_nkro_t *report);
extern void es_send_mouse(report_mouse_t *report);
extern void es_send_extra(report_extra_t *report);
extern void User_bluetooth_send_keyboard(uint8_t *report, uint32_t len);
extern volatile host_driver_t * es_qmk_driver;
extern const host_driver_t es_user_driver;
extern void User_Usb_Init(void);
extern void es_restart_usb_driver(void);
extern void Usb_Disconnect(void);
extern void User_Usb_Deinit(void);

View File

@ -0,0 +1,418 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
uint16_t User_Adc_Batt[USER_BATT_SCAN_COUNT] = {0};
uint16_t User_Scan_Batt[USER_BATT_SCAN_COUNT] = {0};
uint8_t User_Adc_Batt_Count = 0U;
uint8_t User_Batt_BaiFen = 0U;
uint8_t User_Batt_Old_BaiFen = 0U;
uint8_t User_Batt_10ms_Count = 0x00;
uint16_t User_Batt_Time_15S_Count = 0U;
bool User_Batt_Power_Up = false;
bool User_Batt_Send_Spi = false;
uint16_t User_Batt_Power_Up_Delay_100ms_Count = 0U;
bool User_Batt_Power_Up_Delay = false;
bool User_Power_Low = false;
uint8_t User_Power_Low_Count = 0U;
uint8_t es_stdby_pin_state = 0U;
const md_adc_initial adc_initStruct = /**< ADC init structure */
{
MD_ADC_CFG_ALIGN_RIGHT, //Data alignment
MD_ADC_CFG_RSEL_12BIT, //Data resolution
MD_ADC_MODE_NCHS, //Regular or Injected
MD_ADC_CFG_CM_SINGLE, //Single mode
MD_ADC_NCHS1_NSL_1CON, //sample count
MD_ADC_SMPT1_CKDIV_DIV6, //ADC prescale
};
ErrorStatus rdmctmzt_adc_software_calibration(ADC_TypeDef *ADCx, md_adc_initial *ADC_InitStruct) {
//ADC input APB clock 12MHz
uint8_t clkdiv = 8;
uint16_t adc_data_1 = 0;
uint16_t adc_data_15 = 0;
int16_t adc_offset = 0;
uint16_t adc_gain = 0;
float temp_adc_offset = 0.0f;
md_syscfg_set_vref_source(SYSCFG, MD_SYSCFG_PWR_VDDA); // VRES choose VDDA
md_syscfg_enable_vref(SYSCFG);
//ADC Setting
md_adc_set_convsersion_mode(ADC, MD_ADC_CFG_CM_SINGLE); // 1:Continuous
md_adc_set_resolution_selection(ADC, MD_ADC_CFG_RSEL_12BIT); // 12-bit resolution
md_adc_set_normal_sequence_selection_1th(ADC, MD_ADC_NCHS1_NS1_CH18); // channel number(16:Temperature)
md_adc_set_adc_clock_predivider(ADC, ADC_InitStruct->CKDIV);
if (ADC_InitStruct->CKDIV == MD_ADC_SMPT1_CKDIV_DIV1) {
clkdiv = 1;
} else if (ADC_InitStruct->CKDIV == MD_ADC_SMPT1_CKDIV_DIV2){
clkdiv = 2;
} else if (ADC_InitStruct->CKDIV == MD_ADC_SMPT1_CKDIV_DIV4){
clkdiv = 4;
} else if (ADC_InitStruct->CKDIV == MD_ADC_SMPT1_CKDIV_DIV6){
clkdiv = 6;
} else if (ADC_InitStruct->CKDIV == MD_ADC_SMPT1_CKDIV_DIV8){
clkdiv = 8;
}
if ((SystemFrequency_APBClk / clkdiv) <= 12000000) {
md_adc_set_sampletime_channel_18(ADCx, 0x40); //Sample Time Cycle
} else {
md_adc_set_sampletime_channel_18(ADCx, 0x80); //Sample Time Cycle
}
//CLEAR CALCR
md_adc_set_gain_factor(ADCx, 1024);
md_adc_set_offset_factor(ADCx, 0);
//ADC ENABLE
md_adc_enable_adcpower(ADCx);
while (!md_adc_is_active_flag_adc_ready(ADCx));
// --------------------------------------------------------
// 1/16 Sample
md_adc_set_vref_level(ADCx, MD_ADC_CCR_REFINTS_1DIV16);
md_adc_set_start_normal(ADCx, MD_ADC_CON_NSTART_START_REGULAR);
while (md_adc_is_active_flag_normal_status(ADCx));
adc_data_1 = md_adc_get_normal_data(ADCx);
// --------------------------------------------------------
// 15/16 Sample
md_adc_set_vref_level(ADCx, MD_ADC_CCR_REFINTS_15DIV16);
md_adc_set_start_normal(ADCx, MD_ADC_CON_NSTART_START_REGULAR);
while (md_adc_is_active_flag_normal_status(ADCx));
adc_data_15 = md_adc_get_normal_data(ADCx);
// --------------------------------------------------------
temp_adc_offset = (float)((15 * adc_data_1) - adc_data_15) / 14;
if (temp_adc_offset > 0) {
adc_offset = (int16_t)(temp_adc_offset + 0.5);
} else {
adc_offset = (int16_t)(temp_adc_offset - 0.5);
}
adc_gain = (uint16_t)((3584 * 1024) / (float)(adc_data_15 - adc_data_1) + 0.5);
md_adc_set_gain_factor(ADCx, adc_gain);
md_adc_set_offset_factor(ADCx, adc_offset);
// --------------------------------------------------------
md_adc_set_convsersion_mode(ADCx, 0);
md_adc_set_resolution_selection(ADCx, MD_ADC_CFG_RSEL_6BIT);
md_adc_set_normal_sequence_selection_1th(ADCx, MD_ADC_NCHS1_NS1_CH0);
md_adc_set_adc_clock_predivider(ADCx, MD_ADC_SMPT1_CKDIV_DIV1);
md_adc_set_sampletime_channel_18(ADCx, 0);
md_adc_set_icr(ADCx, 0xFFFE);
return SUCCESS;
}
ErrorStatus md_adc_optionbyte_calibration(ADC_TypeDef *ADCx, md_adc_initial *ADC_InitStruct) {
int8_t adc_offset = 0;
uint32_t adc_gain = 1024;
uint32_t cal_value = 0;
md_fc_read_info(ADC_CALIBRATION_ADDR, &cal_value);
adc_gain = (cal_value & 0xFFF);
adc_offset = (cal_value >> 16) & 0xFF;
//ADC ENABLE
md_adc_enable_adcpower(ADCx);
md_adc_set_gain_factor(ADCx, adc_gain);
md_adc_set_offset_factor(ADCx, adc_offset);
return SUCCESS;
}
ErrorStatus rdmctmzt_adc_calibration(ADC_TypeDef *ADCx, md_adc_initial *ADC_InitStruct) {
uint32_t cal_value = 0;
md_fc_read_info(ADC_CALIBRATION_ADDR, &cal_value);
if (cal_value == 0xFFFFFFFF) {
return rdmctmzt_adc_software_calibration(ADCx, ADC_InitStruct);
} else {
return md_adc_optionbyte_calibration(ADCx, ADC_InitStruct);
}
}
void md_adc_init(ADC_TypeDef *ADCx, md_adc_initial *ADC_InitStruct) {
while (md_adc_is_enabled_calibration(ADCx));
md_adc_set_adc_clock_predivider(ADC, ADC_InitStruct->CKDIV);
md_adc_enable_adcpower(ADCx);
while (!md_adc_is_active_flag_adc_ready(ADCx));
while ((md_adc_get_start_inj(ADCx) == MD_ADC_CON_ISTART_START_INJECTED));
while ((md_adc_get_start_normal(ADCx) == MD_ADC_CON_NSTART_START_REGULAR));
md_adc_set_data_alignment(ADCx, ADC_InitStruct->ALIGN);
md_adc_set_resolution_selection(ADCx, ADC_InitStruct->RSEL);
md_adc_set_convsersion_mode(ADCx, ADC_InitStruct->Regular_CM);
#ifdef ADC_DMA
md_adc_enable_dma_access(ADCx);
#else
md_adc_disable_dma_access(ADCx);
#endif
}
void User_Adc_Init(void) { //ES_BATT_ADC_IO
md_gpio_inittypedef gpiox;
gpiox.OutputType = MD_GPIO_OUTPUT_PUSHPULL;
gpiox.Pull = MD_GPIO_PULL_FLOATING;
gpiox.OutDrive = MD_GPIO_DRIVING_8MA;
gpiox.Function = MD_GPIO_AF0;
gpiox.Mode = MD_GPIO_MODE_ANALOG;
gpiox.Pin = MD_GPIO_PIN_4;
md_gpio_init(GPIOC, &gpiox);
md_rcu_enable_adc(RCU);
rdmctmzt_adc_calibration(ADC, (md_adc_initial *)(&adc_initStruct));
md_adc_set_sampletime_channel_14(ADC, 0x40);
md_adc_init(ADC, (md_adc_initial *)(&adc_initStruct));
while ((ADC->RIF & 0x1) == 0);
md_adc_set_normal_sequence_length(ADC, adc_initStruct.Cnt);
md_adc_set_normal_sequence_selection_1th(ADC, MD_ADC_NCHS1_NS1_CH14);
md_adc_set_start_normal(ADC, MD_ADC_CON_NSTART_START_REGULAR);
}
void User_Adc_Deinit(void) {
md_rcu_enable_adc_reset(RCU);
md_rcu_disable_adc_reset(RCU);
md_rcu_disable_adc(RCU);
}
void U16_Buff_Clear(uint16_t *Buff, uint8_t Len) {
for(uint8_t i = 0; i < Len; i++) {
Buff[i] = 0;
}
}
void Init_Batt_Infomation(void) {
if (gpio_read_pin(ES_USB_POWER_IO)) {
User_Batt_BaiFen = Keyboard_Info.Batt_Number;
User_Batt_Old_BaiFen = User_Batt_BaiFen;
User_Batt_Power_Up = false;
} else {
User_Batt_Power_Up = true;
}
User_Batt_10ms_Count = 0;
User_Adc_Batt_Count = 0;
User_Batt_Time_15S_Count = 0;
User_Power_Low = false;
User_Power_Low_Count = 0;
U16_Buff_Clear(User_Adc_Batt, USER_BATT_SCAN_COUNT);
U16_Buff_Clear(User_Scan_Batt, USER_BATT_SCAN_COUNT);
User_Batt_Power_Up_Delay_100ms_Count = 0;
User_Batt_Power_Up_Delay = true;
}
void User_Adc_Batt_Power_Up_Init(void) {
uint8_t Min_Batt = 0, Max_Batt = 0;
for (uint8_t i = 0; i < USER_BATT_POWER_SCAN_COUNT; i++) {
if (User_Scan_Batt[Min_Batt] < User_Scan_Batt[i]) {
Min_Batt = i;
}
if (User_Scan_Batt[Max_Batt] > User_Scan_Batt[i]) {
Max_Batt = i;
}
}
uint16_t Temp_Batt_Sub = 0;
if (Min_Batt == Max_Batt) {
for (uint8_t i = 0; i < (USER_BATT_POWER_SCAN_COUNT - 2); i++) {
Temp_Batt_Sub += User_Scan_Batt[i];
}
} else {
for (uint8_t i = 0; i < USER_BATT_POWER_SCAN_COUNT; i++) {
if ((Min_Batt == i) || (Max_Batt == i)) {
continue;
}
Temp_Batt_Sub += User_Scan_Batt[i];
}
}
uint16_t Temp_Average = (Temp_Batt_Sub / (USER_BATT_POWER_SCAN_COUNT - 2));
uint8_t Temp_Batt_Number = 0;
if (Temp_Average >= USER_BATT_HIGH_POWER) {
Temp_Batt_Number = 100;
} else if (Temp_Average <= USER_BATT_STDOWN_POWER) {
Temp_Batt_Number = 0;
} else {
Temp_Batt_Number = (((Temp_Average - USER_BATT_STDOWN_POWER) * 100) / (USER_BATT_HIGH_POWER - USER_BATT_STDOWN_POWER));
}
if (Temp_Average <= USER_BATT_STDOWN_POWER) {
User_Power_Low_Count++;
if (User_Power_Low_Count >= 4) {
User_Power_Low_Count = 0;
User_Power_Low = true;
}
} else if (Temp_Average <= USER_BATT_LOW_POWER) {
User_Power_Low_Count++;
if (User_Power_Low_Count >= 10) {
User_Power_Low_Count = 0;
User_Power_Low = true;
}
} else {
User_Power_Low_Count = 0;
}
User_Batt_BaiFen = Temp_Batt_Number;
User_Batt_Old_BaiFen = User_Batt_BaiFen;
if (User_Batt_BaiFen != Keyboard_Info.Batt_Number) {
Keyboard_Info.Batt_Number = User_Batt_BaiFen;
Save_Flash_Set();
}
User_Adc_Batt_Count = 0;
User_Batt_10ms_Count = 0;
User_Batt_Time_15S_Count = 0;
User_Batt_Power_Up = false;
}
void User_Adc_Batt_Number(void) {
if (es_stdby_pin_state == 2) {
User_Batt_BaiFen = 100;
User_Batt_Old_BaiFen = 100;
if (Keyboard_Info.Batt_Number != User_Batt_BaiFen) {
Keyboard_Info.Batt_Number = User_Batt_BaiFen;
User_Batt_Send_Spi = true;
Save_Flash_Set();
}
User_Power_Low = false;
User_Power_Low_Count = 0;
return;
}
uint8_t Min_Batt = 0, Max_Batt = 0;
for (uint8_t i = 0; i < USER_BATT_SCAN_COUNT; i++) {
if (User_Scan_Batt[Min_Batt] < User_Scan_Batt[i]) {
Min_Batt = i;
}
if (User_Scan_Batt[Max_Batt] > User_Scan_Batt[i]) {
Max_Batt = i;
}
}
uint16_t Temp_Batt_Sub = 0;
if (Min_Batt == Max_Batt) {
for (uint8_t i = 0; i < (USER_BATT_SCAN_COUNT - 2); i++) {
Temp_Batt_Sub += User_Scan_Batt[i];
}
} else {
for (uint8_t i = 0; i < USER_BATT_SCAN_COUNT; i++) {
if ((Min_Batt == i) || (Max_Batt == i)) {
continue;
}
Temp_Batt_Sub += User_Scan_Batt[i];
}
}
uint16_t Temp_Average = (Temp_Batt_Sub / (USER_BATT_SCAN_COUNT - 2));
uint8_t Temp_Batt_Number = 0;
if (Temp_Average >= USER_BATT_HIGH_POWER) {
Temp_Batt_Number = 100;
} else if (Temp_Average <= USER_BATT_STDOWN_POWER) {
Temp_Batt_Number = 0;
} else {
Temp_Batt_Number = (((Temp_Average - USER_BATT_STDOWN_POWER) * 100) / (USER_BATT_HIGH_POWER - USER_BATT_STDOWN_POWER));
}
if (es_stdby_pin_state == 1) {
if (Temp_Batt_Number >= 100) {
Temp_Batt_Number = 99;
} else if (Temp_Batt_Number <= 0) {
Temp_Batt_Number = 1;
}
} else {
if (Temp_Average <= USER_BATT_STDOWN_POWER) {
User_Power_Low_Count++;
if (User_Power_Low_Count >= 5) {
User_Power_Low_Count = 0;
User_Power_Low = true;
}
} else if (Temp_Average <= USER_BATT_LOW_POWER) {
User_Power_Low_Count++;
if (User_Power_Low_Count >= 10) {
User_Power_Low_Count = 0;
User_Power_Low = true;
}
} else {
User_Power_Low_Count = 0;
}
}
if (es_stdby_pin_state) {
if (Temp_Batt_Number > User_Batt_Old_BaiFen) {
if (User_Batt_Time_15S_Count >= USER_BATT_DELAY_TIME) {
User_Batt_Time_15S_Count = 0;
if (User_Batt_BaiFen <= 98) {
User_Batt_BaiFen++;
}
User_Batt_Old_BaiFen = User_Batt_BaiFen;
}
} else {
User_Batt_Time_15S_Count = 0;
}
User_Power_Low = false;
User_Power_Low_Count = 0;
} else {
if (Temp_Batt_Number < User_Batt_Old_BaiFen) {
if (User_Batt_Time_15S_Count >= USER_BATT_DELAY_TIME) {
User_Batt_Time_15S_Count = 0;
if (User_Batt_BaiFen) {
User_Batt_BaiFen--;
}
User_Batt_Old_BaiFen = User_Batt_BaiFen;
}
} else {
User_Batt_Time_15S_Count = 0;
}
}
if (Keyboard_Info.Batt_Number != User_Batt_BaiFen) {
Keyboard_Info.Batt_Number = User_Batt_BaiFen;
User_Batt_Send_Spi = true;
Save_Flash_Set();
}
}

View File

@ -0,0 +1,51 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define USER_BATT_HIGH_POWER (2555)
#define USER_BATT_LOW_POWER (2065)
#define USER_BATT_STDOWN_POWER (1865)
#define USER_BATT_POWER_SCAN_COUNT (10)
#define USER_BATT_SCAN_COUNT (10)
extern uint16_t User_Adc_Batt[USER_BATT_SCAN_COUNT];
extern uint16_t User_Scan_Batt[USER_BATT_SCAN_COUNT];
extern uint8_t User_Adc_Batt_Count;
extern uint8_t User_Batt_BaiFen;
extern uint8_t User_Batt_Old_BaiFen;
extern uint8_t User_Batt_10ms_Count;
extern uint16_t User_Batt_Time_15S_Count;
extern bool User_Batt_Power_Up;
extern bool User_Batt_Send_Spi;
extern uint16_t User_Batt_Power_Up_Delay_100ms_Count;
extern bool User_Batt_Power_Up_Delay;
extern bool User_Power_Low;
extern uint8_t User_Power_Low_Count;
extern uint8_t es_stdby_pin_state;
extern const md_adc_initial adc_initStruct;
extern void User_Adc_Init(void);
extern void User_Adc_Deinit(void);
extern void U16_Buff_Clear(uint16_t *Buff, uint8_t Len);
extern void Init_Batt_Infomation(void);
extern void User_Adc_Batt_Power_Up_Init(void);
extern void User_Adc_Batt_Number(void);

View File

@ -0,0 +1,630 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
#if defined(EEPROM_CUSTOM)
/* Exported Constants --------------------------------------------------------*/
/* Define the size of the sectors to be used */
#define MCU_PAGE_SIZE (uint32_t)0x200 /* MCU page size = 0.5kB */
#define PAGE_SIZE (uint32_t)0x2000 /* Page size = 8kB */
#define MCU_PAGE_NUM PAGE_SIZE / MCU_PAGE_SIZE
/* EEPROM start address in Flash */
#define EEPROM_START_ADDRESS ((uint32_t)0x1C000)
/* Pages 0 and 1 base and end addresses */
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS))
#define PAGE0_END_ADDRESS ((uint32_t)(PAGE0_BASE_ADDRESS + (PAGE_SIZE - 1)))
#define PAGE1_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + PAGE_SIZE))
#define PAGE1_END_ADDRESS ((uint32_t)(PAGE1_BASE_ADDRESS + (PAGE_SIZE - 1)))
/* Used Flash pages for EEPROM emulation */
#define PAGE0 ((uint32_t)0x00000000)
#define PAGE1 ((uint32_t)0x00000001)
/* No valid page define */
#define NO_VALID_PAGE ((uint32_t)0x000000AB)
/* Page status definitions */
#define ERASED ((uint32_t)0xFFFFFFFF) /* Page is empty */
#define RECEIVE_DATA ((uint32_t)0xEEEEEEEE) /* Page is marked to receive data */
#define VALID_PAGE ((uint32_t)0x00000000) /* Page containing valid data */
/* Valid pages in read and write defines */
#define READ_FROM_VALID_PAGE ((uint8_t)0x00)
#define WRITE_IN_VALID_PAGE ((uint8_t)0x01)
/* Page full define */
#define PAGE_FULL ((uint8_t)0x80)
/* Variables' number */
#define NB_OF_VAR (EEPROM_SIZE)
#define NB_OF_PRIVATE_VAR (64)
#define ES_MCU_MEM_REMAP_OFFSET ((((SYSCFG->REMAP)&SYSCFG_REMAP_REALBASE_MSK) >> SYSCFG_REMAP_REALBASE_POSS) << 12)
//__attribute__((aligned(4))) static uint8_t g_es_flash_eeprom_table[EEPROM_SIZE + 2];
__attribute__((aligned(4))) static uint8_t g_es_flash_eeprom_table[EEPROM_SIZE + NB_OF_PRIVATE_VAR + 2];
volatile uint32_t g_tst_remap_offset;
static uint32_t ee_format(void);
static uint32_t ee_find_valid_page(uint8_t operation);
static uint32_t ee_verify_pagefull_write_variable(uint32_t virt_address, uint32_t data);
static uint32_t ee_page_transfer(uint32_t virt_address, uint32_t data);
static uint32_t IAPROM_PAGE_ERASE(uint32_t addr)
{
md_fc_ControlTypeDef SErasePara;
if ((addr & 0x1ff) != 0)
{
return !SET;
}
__disable_irq();
md_fc_unlock();
SErasePara.SAddr = addr;
SErasePara.SAddrC = ~(addr);
md_fc_page_erase(&SErasePara);
md_fc_lock();
__enable_irq();
return SET;
}
static uint32_t IAPROM_WORD_PROGRAM(uint32_t addr,uint32_t data)
{
md_fc_ControlTypeDef ProgramPara;
if ((addr & 0x3) != 0)
{
return !SET;
}
if ((((uint32_t)(&data)) & 0x3) != 0)
{
return !SET;
}
__disable_irq();
md_fc_unlock();
ProgramPara.BCnt = 4;
ProgramPara.pU32Buf = &data;
ProgramPara.SAddr = addr;
ProgramPara.SAddrC = ~(addr);
md_fc_program(&ProgramPara);
md_fc_lock();
__enable_irq();
return SET;
}
static uint32_t ee_init(void)
{
uint32_t page_status0 = 6U, page_status1 = 6U;
uint32_t var_idx = 0U;
uint32_t eeprom_status = 0U;
uint32_t flash_status;
uint8_t addr_index;
uint32_t rom_read_end;
/* Get Page0 status */
page_status0 = (*(__IO uint32_t *)(PAGE0_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET));
/* Get Page1 status */
page_status1 = (*(__IO uint32_t *)(PAGE1_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET));
if(page_status0 == VALID_PAGE)
{
rom_read_end = PAGE0_END_ADDRESS - ES_MCU_MEM_REMAP_OFFSET;
for(var_idx = PAGE0_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET + 4;var_idx < rom_read_end;var_idx += 4)
{
if(((*(__IO uint32_t *)var_idx) >> 16) < NB_OF_VAR)
{
*(((uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + ((*(__IO uint32_t *)var_idx) >> 16)) = (*(__IO uint32_t *)var_idx) & 0xFFFF;
}
else
{
break;
}
}
}
if(page_status1 == VALID_PAGE)
{
rom_read_end = PAGE1_END_ADDRESS - ES_MCU_MEM_REMAP_OFFSET;
for(var_idx = PAGE1_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET + 4;var_idx < rom_read_end;var_idx += 4)
{
if(((*(__IO uint32_t *)var_idx) >> 16) < NB_OF_VAR)
{
*(((uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + ((*(__IO uint32_t *)var_idx) >> 16)) = (*(__IO uint32_t *)var_idx) & 0xFFFF;
}
else
{
break;
}
}
}
/* Check for invalid header states and repair if necessary */
switch (page_status0)
{
case ERASED:
if (page_status1 == VALID_PAGE) /* Page0 erased, Page1 valid */
{
/* Erase Page0 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE0_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
}
else if (page_status1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
{
/* Erase Page0 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE0_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
IAPROM_WORD_PROGRAM(PAGE1_BASE_ADDRESS, VALID_PAGE);
}
else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
{
/* Erase both Page0 and Page1 and set Page0 as valid page */
flash_status = ee_format();
if (flash_status != SET)
return flash_status;
}
break;
case RECEIVE_DATA:
if (page_status1 == VALID_PAGE) /* Page0 receive, Page1 valid */
{
/* Transfer data from Page1 to Page0 */
for (var_idx = 0; var_idx < (NB_OF_VAR / 2 + 1); var_idx++)
{
if((*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)) != 0)
{
/* Transfer the variable to the Page0 */
eeprom_status = ee_verify_pagefull_write_variable(var_idx, (*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)));
/* If program operation was failed, a Flash error code is returned */
if (eeprom_status != SET)
return eeprom_status;
}
}
IAPROM_WORD_PROGRAM(PAGE0_BASE_ADDRESS, VALID_PAGE);
/* Erase Page1 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE1_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
}
else if (page_status1 == ERASED) /* Page0 receive, Page1 erased */
{
/* Erase Page1 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE1_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
IAPROM_WORD_PROGRAM(PAGE0_BASE_ADDRESS, VALID_PAGE);
}
else /* Invalid state -> format eeprom */
{
flash_status = ee_format();
if (flash_status != SET)
return flash_status;
}
break;
case VALID_PAGE:
if (page_status1 == VALID_PAGE) /* Invalid state -> format eeprom */
{
flash_status = ee_format();
if (flash_status != SET)
return flash_status;
}
else if (page_status1 == ERASED) /* Page0 valid, Page1 erased */
{
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE1_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
}
else /* Page0 valid, Page1 receive */
{
/* Transfer data from Page0 to Page1 */
for (var_idx = 0; var_idx < (NB_OF_VAR / 2 + 1); var_idx++)
{
if((*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)) != 0)
{
/* Transfer the variable to the Page0 */
eeprom_status = ee_verify_pagefull_write_variable(var_idx, (*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)));
/* If program operation was failed, a Flash error code is returned */
if (eeprom_status != SET)
return eeprom_status;
}
}
IAPROM_WORD_PROGRAM(PAGE1_BASE_ADDRESS, VALID_PAGE);
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE0_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
}
break;
default: /* Any other state -> format eeprom */
flash_status = ee_format();
if (flash_status != SET)
return flash_status;
break;
}
return SET;
}
static uint32_t ee_write_variable(uint32_t virt_address)
{
uint32_t status = 0U;
uint16_t data;
if(virt_address >= NB_OF_VAR)
{
return !SET;
}
virt_address = virt_address / 2;
data = *(((uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + virt_address);
/* Write the variable virtual address and value in the EEPROM */
status = ee_verify_pagefull_write_variable(virt_address, data);
/* In case the EEPROM active page is full */
if (status == PAGE_FULL)
status = ee_page_transfer(virt_address, data); /* Perform Page transfer */
/* Return last operation status */
return status;
}
static uint32_t ee_format(void)
{
uint32_t flash_status = SET;
uint8_t addr_index;
/* Erase Page0 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE0_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
/* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
IAPROM_WORD_PROGRAM(PAGE0_BASE_ADDRESS, VALID_PAGE);
/* Erase Page1 */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(PAGE1_BASE_ADDRESS + addr_index * MCU_PAGE_SIZE);
}
/* Return Page1 erase operation status */
return flash_status;
}
static uint32_t ee_find_valid_page(uint8_t operation)
{
uint32_t page_status0 = 6U, page_status1 = 6U;
/* Get Page0 status */
page_status0 = (*(__IO uint32_t *)(PAGE0_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET));
/* Get Page1 status */
page_status1 = (*(__IO uint32_t *)(PAGE1_BASE_ADDRESS - ES_MCU_MEM_REMAP_OFFSET));
/* Write or read operation */
switch (operation)
{
case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
if (page_status1 == VALID_PAGE)
{
/* Page0 receiving data */
if (page_status0 == RECEIVE_DATA)
return PAGE0; /* Page0 valid */
else
return PAGE1; /* Page1 valid */
}
else if (page_status0 == VALID_PAGE)
{
/* Page1 receiving data */
if (page_status1 == RECEIVE_DATA)
return PAGE1; /* Page1 valid */
else
return PAGE0; /* Page0 valid */
}
else
{
return NO_VALID_PAGE; /* No valid Page */
}
case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
if (page_status0 == VALID_PAGE)
return PAGE0; /* Page0 valid */
else if (page_status1 == VALID_PAGE)
return PAGE1; /* Page1 valid */
else
return NO_VALID_PAGE ; /* No valid Page */
default:
return PAGE0; /* Page0 valid */
}
}
static uint32_t ee_verify_pagefull_write_variable(uint32_t virt_address, uint32_t data)
{
uint32_t flash_status = SET;
uint32_t valid_page = PAGE0;
uint32_t address = EEPROM_START_ADDRESS;
uint32_t page_endaddress = EEPROM_START_ADDRESS + PAGE_SIZE;
/* Get valid Page for write operation */
valid_page = ee_find_valid_page(WRITE_IN_VALID_PAGE);
/* Check if there is no valid page */
if (valid_page == NO_VALID_PAGE)
return NO_VALID_PAGE;
/* Get the valid Page start address */
address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(valid_page * PAGE_SIZE)) - ES_MCU_MEM_REMAP_OFFSET;
/* Get the valid Page end address */
page_endaddress = (uint32_t)((EEPROM_START_ADDRESS - 4) + (uint32_t)((1 + valid_page) * PAGE_SIZE)) - ES_MCU_MEM_REMAP_OFFSET;
/* Check each active page address starting from begining */
while (address <= page_endaddress)
{
/* Verify if address and address+4 contents are 0xFFFFFFFF */
if ((*(__IO uint32_t *)address) == 0xFFFFFFFF)
{
/* Set variable virtual address and data */
flash_status = IAPROM_WORD_PROGRAM(address + ES_MCU_MEM_REMAP_OFFSET, (virt_address << 16) | data);
/* Return program operation status */
return flash_status;
}
else
{
/* Next address location */
address = address + 4;
}
}
/* Return PAGE_FULL in case the valid page is full */
return PAGE_FULL;
}
static uint32_t ee_page_transfer(uint32_t virt_address, uint32_t data)
{
uint32_t flash_status = SET;
uint32_t new_pageaddress = EEPROM_START_ADDRESS;
uint32_t old_pageaddress;
uint32_t valid_page = PAGE0, var_idx = 0U;
uint32_t eeprom_status = 0U;
uint8_t addr_index;
/* Get active Page for read operation */
valid_page = ee_find_valid_page(READ_FROM_VALID_PAGE);
if (valid_page == PAGE1) /* Page1 valid */
{
/* New page address where variable will be moved to */
new_pageaddress = PAGE0_BASE_ADDRESS;
/* Old page ID where variable will be taken from */
old_pageaddress = PAGE1_BASE_ADDRESS;
}
else if (valid_page == PAGE0) /* Page0 valid */
{
/* New page address where variable will be moved to */
new_pageaddress = PAGE1_BASE_ADDRESS;
/* Old page ID where variable will be taken from */
old_pageaddress = PAGE0_BASE_ADDRESS;
}
else
{
return NO_VALID_PAGE; /* No valid Page */
}
/* Erase the new Page*/
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(new_pageaddress + addr_index * MCU_PAGE_SIZE);
}
/* Set the new Page status to RECEIVE_DATA status */
IAPROM_WORD_PROGRAM(new_pageaddress, RECEIVE_DATA);
/* Write the variable passed as parameter in the new active page */
eeprom_status = ee_verify_pagefull_write_variable(virt_address, data);
/* If program operation was failed, a Flash error code is returned */
if (eeprom_status != SET)
return eeprom_status;
/* Transfer process: transfer variables from old to the new active page */
//for (var_idx = 0; var_idx < NB_OF_VAR; var_idx++)
{
/* Transfer data from Page1 to Page0 */
for (var_idx = 0; var_idx < (NB_OF_VAR / 2 + 1); var_idx++)
{
if((*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)) != 0)
{
/* Transfer the variable to the Page0 */
eeprom_status = ee_verify_pagefull_write_variable(var_idx, (*(((__IO uint16_t*)((uint32_t)g_es_flash_eeprom_table)) + var_idx)));
/* If program operation was failed, a Flash error code is returned */
if (eeprom_status != SET)
return eeprom_status;
}
}
}
/* Erase the old Page: Set old Page status to ERASED status */
for (addr_index = 0; addr_index < MCU_PAGE_NUM; addr_index++)
{
IAPROM_PAGE_ERASE(old_pageaddress + addr_index * MCU_PAGE_SIZE);
}
/* Set new Page status to VALID_PAGE status */
IAPROM_WORD_PROGRAM(new_pageaddress, VALID_PAGE);
/* Return last operation flash status */
return flash_status;
}
size_t clamp_length(intptr_t offset, size_t len) {
if (offset + len > EEPROM_SIZE) {
len = EEPROM_SIZE - offset;
}
return len;
}
size_t clamp_length_user(intptr_t offset, size_t len) {
if (offset + len > NB_OF_PRIVATE_VAR) {
len = NB_OF_PRIVATE_VAR - offset;
}
return len;
}
void eeprom_driver_erase(void) {
ee_format();
memset(g_es_flash_eeprom_table, 0x00, sizeof(g_es_flash_eeprom_table));
}
#define USER_EEPROM_START_ADDRESS1 (EEPROM_START_ADDRESS - (MCU_PAGE_SIZE))
volatile uint8_t es_eeprom_init_flag = 0U;
void eeprom_driver_init(void) {
if(es_eeprom_init_flag)
return;
g_tst_remap_offset = ES_MCU_MEM_REMAP_OFFSET;
(void)g_tst_remap_offset;
memset(g_es_flash_eeprom_table, 0x00, sizeof(g_es_flash_eeprom_table));
ee_init();
memcpy(g_es_flash_eeprom_table, (uint8_t*)(USER_EEPROM_START_ADDRESS1 - ES_MCU_MEM_REMAP_OFFSET), NB_OF_PRIVATE_VAR);
es_eeprom_init_flag = 1;
}
void eeprom_read_block(void *buf, const void *addr, size_t len) {
intptr_t offset = (intptr_t)addr;
memset(buf, 0x00, len);
len = clamp_length(offset, len);
if (len > 0) {
memcpy(buf, &g_es_flash_eeprom_table[NB_OF_PRIVATE_VAR + offset], len);
}
}
void eeprom_write_block(const void *buf, void *addr, size_t len) {
uint16_t i;
intptr_t offset = (intptr_t)addr;
len = clamp_length(offset, len);
if (len > 0) {
for(i = 0;i < len;i++)
{
if(g_es_flash_eeprom_table[i + offset + NB_OF_PRIVATE_VAR] != (*((uint8_t*)((uint32_t)buf) + i)))
{
g_es_flash_eeprom_table[i + offset + NB_OF_PRIVATE_VAR] = (*((uint8_t*)((uint32_t)buf) + i));
ee_write_variable(i + offset + NB_OF_PRIVATE_VAR);
}
}
memcpy(&g_es_flash_eeprom_table[offset + NB_OF_PRIVATE_VAR], buf, len);
}
}
void eeprom_read_block_user(void *buf, const void *addr, size_t len) {
intptr_t offset = (intptr_t)addr;
memset(buf, 0x00, len);
len = clamp_length_user(offset, len);
if (len > 0) {
memcpy(buf, (uint8_t*)(USER_EEPROM_START_ADDRESS1 - ES_MCU_MEM_REMAP_OFFSET) + offset, len);
}
}
void eeprom_write_block_user(const void *buf, void *addr, size_t len) {
md_fc_ControlTypeDef ProgramPara;
intptr_t offset = (intptr_t)addr;
len = clamp_length_user(offset, len);
if (len > 0) {
__disable_irq();
if(memcmp(buf,(uint8_t*)(USER_EEPROM_START_ADDRESS1 - ES_MCU_MEM_REMAP_OFFSET) + offset,len))
{
memcpy(&g_es_flash_eeprom_table[offset], buf, len);
md_fc_unlock();
ProgramPara.SAddr = USER_EEPROM_START_ADDRESS1;
ProgramPara.SAddrC = ~(USER_EEPROM_START_ADDRESS1);
md_fc_page_erase(&ProgramPara);
md_fc_lock();
md_fc_unlock();
ProgramPara.BCnt = NB_OF_PRIVATE_VAR;
ProgramPara.pU32Buf = (uint32_t*)(&g_es_flash_eeprom_table);
ProgramPara.SAddr = USER_EEPROM_START_ADDRESS1;
ProgramPara.SAddrC = ~(USER_EEPROM_START_ADDRESS1);
md_fc_program(&ProgramPara);
md_fc_lock();
}
__enable_irq();
}
}
#endif
bool Save_Flash = false;
bool Reset_Save_Flash = false;
uint16_t Save_Flash_3S_Count = 0;
bool Led_Flash_Busy = false;
void Save_Flash_Set(void) {
Save_Flash = true;
Save_Flash_3S_Count = 0;
}

View File

@ -0,0 +1,31 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if defined(EEPROM_CUSTOM)
extern void eeprom_driver_init(void);
extern void eeprom_write_block_user(const void *buf, void *addr, size_t len);
extern void eeprom_read_block_user(void *buf, const void *addr, size_t len);
#endif
extern bool Save_Flash;
extern bool Reset_Save_Flash;
extern uint16_t Save_Flash_3S_Count;
extern bool Led_Flash_Busy;
extern void Save_Flash_Set(void);

View File

@ -0,0 +1,64 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
bool Emi_Test_Start = false;
void Emi_Init(void) {
Spi_Interval = SPI_DELAY_USB_TIME;
Keyboard_Status.System_Work_Status = 0;
Keyboard_Status.System_Sleep_Mode = 0;
Mode_Synchronization_Signal = false;
Led_Rf_Pair_Flg = false;
Ble_Name_Spi_Send = false;
}
void Emi_Read_Data(uint8_t *User_Data, uint8_t User_Length) {
if (Emi_Test_Start == false) {
return;
}
if (Init_Spi_Power_Up) {
return;
}
if (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO))) {
return;
}
Spi_Send_Recv_Flg = 1;
Send_Key_Type = SPI_ACK;
Repet_Send_Count = 0;
/*将需要发送的指令发送到680*/
for (uint8_t i = 0; i < User_Length; i++) {
g_es_spi_tx_buf[i] = User_Data[i];
}
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, g_es_spi_tx_buf);
return;
}
void Emi_Write_Data(uint8_t *User_Data, uint8_t User_Length) {
if (Emi_Test_Start == false) {
return;
}
if (User_Data[0] == USER_KEYBOARD_COMMAND) {
return;
}
User_Data[0] = USER_EMI_COMMAND;
}

View File

@ -0,0 +1,24 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
extern bool Emi_Test_Start;
extern void Emi_Init(void);
extern void Emi_Read_Data(uint8_t *User_Data, uint8_t User_Length);
extern void Emi_Write_Data(uint8_t *User_Data, uint8_t User_Length);

View File

@ -0,0 +1,256 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
uint8_t Led_Colour_Tab[9][3] = {
{255, 0, 0 },
{255, 128, 0 },
{255, 255, 0 },
{0, 255, 0 },
{0, 255, 255 },
{0, 0, 255 },
{128, 0, 255 },
{255, 255, 255 }
};
uint8_t Led_Wave_Pwm_Tab[128] = {
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 44, 48, 52, 56, 60,
64, 68, 72, 76, 80, 84, 88, 92,
96, 100, 104, 108, 112, 116, 120, 124,
128, 132, 136, 140, 144, 148, 152, 156,
160, 164, 168, 172, 176, 180, 184, 188,
192, 196, 200, 204, 208, 212, 216, 220,
224, 228, 232, 236, 240, 244, 248, 255,
255, 248, 244, 240, 236, 232, 228, 224,
220, 216, 212, 208, 204, 200, 196, 192,
188, 184, 180, 176, 172, 168, 164, 160,
156, 152, 148, 144, 140, 136, 132, 128,
124, 120, 116, 112, 108, 104, 100, 96,
92, 88, 84, 80, 76, 72, 68, 64,
60, 56, 52, 48, 44, 40, 36, 32,
28, 24, 20, 16, 12, 8, 4, 0,
};
#define ES_PWM_LED_SIZE (42)
#define ES_PWM_LED_BYTE (24)
#define ES_PWM_DMA_SIZE (ES_PWM_LED_SIZE * ES_PWM_LED_BYTE)
#define ES_PWM_WS2812_H_VALUE (43)
#define ES_PWM_WS2812_L_VALUE (17)
rgb_led_t rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT];
uint8_t g_es_pwm_rgb_matrix_array_dma_buf[(RGB_MATRIX_LED_COUNT * ES_PWM_LED_BYTE) + 2] = {0};
md_dma_channel_config_typedef DMA_list[5] = {0};
void rgb_matrix_driver_init(void) {
md_rcu_enable_dma1(RCU);
md_dma_set_configuration(DMA1, ENABLE);
md_rcu_enable_gp16c2t1(RCU);
md_timer_set_auto_reload_value_arrv(GP16C2T1, 60);
md_timer_set_output_compare1_mode_ch1mod(GP16C2T1, MD_TIMER_OUTPUTMODE_PWMMODE1);
md_timer_set_capture_compare1_value_ccrv1(GP16C2T1, 0);
md_timer_enable_cc1_output_cc1en(GP16C2T1);
md_timer_enable_main_output_goen(GP16C2T1);
md_timer_enable_output_compare1_preload_ch1pen(GP16C2T1);
md_timer_enable_dma_upd(GP16C2T1);
md_timer_enable_counter_cnten(GP16C2T1);
gpio_set_pin_output(ES_PWM_DMA_IO);
GPIOA->AFL &= 0xFFFFF0FF;
GPIOA->AFL |= 0x00000500;
GPIOA->MOD &= 0xFFFFFFCF;
GPIOA->MOD |= 0x00000020;
md_dma_set_request_peripherals(DMA1, MD_DMA_CHANNEL2, MD_DMA_PRS_GP16C2T1_UP);
if (rgb_matrix_get_val() <= 0) {
memset((void *)g_es_pwm_rgb_matrix_array_dma_buf, ES_PWM_WS2812_L_VALUE, (RGB_MATRIX_LED_COUNT * ES_PWM_LED_BYTE) + 2);
}
}
void User_Pwm_Deinit(void) {
md_rcu_enable_gp16c2t1_reset(RCU);
md_rcu_disable_gp16c2t1_reset(RCU);
md_rcu_disable_gp16c2t1(RCU);
md_rcu_enable_dma1_reset(RCU);
md_rcu_disable_dma1_reset(RCU);
md_rcu_disable_dma1(RCU);
gpio_set_pin_output(ES_PWM_DMA_IO);
gpio_write_pin_low(ES_PWM_DMA_IO);
}
void rgb_matrix_driver_flush_pwm_dma_start(void) {
while ((DMA1->CHENSET) & 0x4);
if (Keyboard_Status.System_Sleep_Mode || ((Keyboard_Info.Key_Mode != QMK_USB_MODE) && Usb_Change_Mode_Wakeup && Keyboard_Status.System_Work_Status) || (!Led_Power_Up)) {
Led_Off_Start = true;
gpio_write_pin_low(ES_LED_POWER_IO);
return;
}
if (rgblight_is_enabled()) {
gpio_write_pin_high(ES_LED_POWER_IO);
if (Led_Off_Start) {
Led_Off_Start = false;
wait_ms(3);
}
} else {
Led_Off_Start = true;
gpio_write_pin_low(ES_LED_POWER_IO);
}
md_timer_disable_dma_upd(GP16C2T1);
g_es_pwm_rgb_matrix_array_dma_buf[(RGB_MATRIX_LED_COUNT * ES_PWM_LED_BYTE)] = 0;
g_es_pwm_rgb_matrix_array_dma_buf[(RGB_MATRIX_LED_COUNT * ES_PWM_LED_BYTE) + 1] = 0;
#if (RGB_MATRIX_LED_COUNT <= 42)
uint16_t Data_Size = ((RGB_MATRIX_LED_COUNT * ES_PWM_LED_BYTE) + 2);
DMA_list[0].control.word = ((Data_Size - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[0].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + (Data_Size - 1));
DMA_list[0].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA1->PRI_CH02_SRC_DATA_END_PTR = ((uint32_t)(DMA_list)) + ((16 - 4));
DMA1->PRI_CH02_CHANNEL_CFG = ((4 - 1) << 4) | g_es_dma_ch2pri_cfg;
#elif (RGB_MATRIX_LED_COUNT <= 84)
DMA_list[0].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[0].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + (ES_PWM_DMA_SIZE - 1));
DMA_list[0].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
uint16_t Data_Size = (((RGB_MATRIX_LED_COUNT - ES_PWM_LED_SIZE) * ES_PWM_LED_BYTE) + 2);
DMA_list[1].control.word = ((Data_Size - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[1].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + (ES_PWM_DMA_SIZE + Data_Size - 1));
DMA_list[1].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA1->PRI_CH02_SRC_DATA_END_PTR = ((uint32_t)(DMA_list)) + ((32 - 4));
DMA1->PRI_CH02_CHANNEL_CFG = ((8 - 1) << 4) | g_es_dma_ch2pri_cfg;
#elif (RGB_MATRIX_LED_COUNT <= 126)
DMA_list[0].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[0].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + (ES_PWM_DMA_SIZE - 1));
DMA_list[0].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA_list[1].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[1].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + ((ES_PWM_DMA_SIZE * 2) - 1));
DMA_list[1].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
uint16_t Data_Size = (((RGB_MATRIX_LED_COUNT - (ES_PWM_LED_SIZE * 2)) * ES_PWM_LED_BYTE) + 2);
DMA_list[2].control.word = ((Data_Size - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[2].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + ((ES_PWM_DMA_SIZE * 2) + Data_Size - 1));
DMA_list[2].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA1->PRI_CH02_SRC_DATA_END_PTR = ((uint32_t)(DMA_list)) + ((48 - 4));
DMA1->PRI_CH02_CHANNEL_CFG = ((12 - 1) << 4) | g_es_dma_ch2pri_cfg;
#elif (RGB_MATRIX_LED_COUNT <= 168)
DMA_list[0].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[0].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + (ES_PWM_DMA_SIZE - 1));
DMA_list[0].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA_list[1].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[1].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + ((ES_PWM_DMA_SIZE * 2) - 1));
DMA_list[1].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA_list[2].control.word = ((ES_PWM_DMA_SIZE - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[2].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + ((ES_PWM_DMA_SIZE * 3) - 1));
DMA_list[2].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
uint16_t Data_Size = (((RGB_MATRIX_LED_COUNT - (ES_PWM_LED_SIZE * 3)) * ES_PWM_LED_BYTE) + 2);
DMA_list[3].control.word = ((Data_Size - 1) << 4) | g_es_dma_ch2alt_cfg;
DMA_list[3].source_data_end_address = (uint32_t)(g_es_pwm_rgb_matrix_array_dma_buf + ((ES_PWM_DMA_SIZE * 3) + Data_Size - 1));
DMA_list[3].destination_data_end_address = (uint32_t)(&(GP16C2T1->CCVAL1));
DMA1->PRI_CH02_SRC_DATA_END_PTR = ((uint32_t)(DMA_list)) + ((64 - 4));
DMA1->PRI_CH02_CHANNEL_CFG = ((16 - 1) << 4) | g_es_dma_ch2pri_cfg;
#endif
DMA1->PRI_CH02_DST_DATA_END_PTR = ((uint32_t)(&(DMA1->ALT_CH02_SRC_DATA_END_PTR))) + 16 - 4;
DMA1->CHENSET = 0x4;
md_timer_enable_dma_upd(GP16C2T1);
}
void rgb_matrix_driver_flush(void) {
Led_Flash_Busy = false;
if((GP16C2T1->AR) != 60) {
rgb_matrix_driver_init();
}
rgb_matrix_driver_flush_pwm_dma_start();
}
void rgb_matrix_driver_set_color(int index, uint8_t r, uint8_t g, uint8_t b) {
uint8_t * buf;
if (index == (RGB_MATRIX_LED_COUNT - 1)) {
Led_Flash_Busy = false;
} else if(index == 0) {
Led_Flash_Busy = true;
}
if (rgb_matrix_ws2812_array[index].r == r && rgb_matrix_ws2812_array[index].g == g && rgb_matrix_ws2812_array[index].b == b) {
return;
}
rgb_matrix_ws2812_array[index].r = r;
rgb_matrix_ws2812_array[index].g = g;
rgb_matrix_ws2812_array[index].b = b;
buf = g_es_pwm_rgb_matrix_array_dma_buf + (index * 24);
for (unsigned char bit = 0; bit < 8; bit++) {
bool is_one = g & (1 << (7 - bit));
// using something like wait_ns(is_one ? T1L : T0L) here throws off timings
*buf = (is_one)? ES_PWM_WS2812_H_VALUE : ES_PWM_WS2812_L_VALUE;
buf++;
}
for (unsigned char bit = 0; bit < 8; bit++) {
bool is_one = r & (1 << (7 - bit));
// using something like wait_ns(is_one ? T1L : T0L) here throws off timings
*buf = (is_one)? ES_PWM_WS2812_H_VALUE : ES_PWM_WS2812_L_VALUE;
buf++;
}
for (unsigned char bit = 0; bit < 8; bit++) {
bool is_one = b & (1 << (7 - bit));
// using something like wait_ns(is_one ? T1L : T0L) here throws off timings
*buf = (is_one)? ES_PWM_WS2812_H_VALUE : ES_PWM_WS2812_L_VALUE;
buf++;
}
}
void rgb_matrix_driver_set_color_all(uint8_t r, uint8_t g, uint8_t b) {
for(uint32_t i = 0;i < RGB_MATRIX_LED_COUNT;i++) {
rgb_matrix_driver_set_color(i,r,g,b);
}
}
// clang-format off
const rgb_matrix_driver_t rgb_matrix_driver = {
.init = rgb_matrix_driver_init,
.flush = rgb_matrix_driver_flush,
.set_color = rgb_matrix_driver_set_color,
.set_color_all = rgb_matrix_driver_set_color_all,
};

View File

@ -0,0 +1,28 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
extern uint8_t Led_Colour_Tab[9][3];
extern uint8_t Led_Wave_Pwm_Tab[128];
extern void rgb_matrix_driver_init(void);
extern void User_Pwm_Deinit(void);
extern void rgb_matrix_driver_flush_pwm_dma_start(void);
extern void rgb_matrix_driver_flush(void);
extern void rgb_matrix_driver_set_color(int index, uint8_t r, uint8_t g, uint8_t b);
extern void rgb_matrix_driver_set_color_all(uint8_t r, uint8_t g, uint8_t b);
extern const rgb_matrix_driver_t rgb_matrix_driver;

View File

@ -0,0 +1,322 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
volatile uint8_t Spi_Send_Recv_Flg = 0U;
uint8_t g_es_spi_rx_buf[64] = {0};
uint8_t g_es_spi_tx_buf[64] = {0};
uint8_t Repet_Send_Count = 0x00;
uint8_t Send_Key_Type = SPI_NACK;
bool Init_Spi_Power_Up = true;
uint8_t Init_Spi_100ms_Delay = 0;
uint16_t Spi_Interval = SPI_DELAY_RF_TIME;
bool Ble_Name_Spi_Send = false;
uint8_t Ble_Name_Spi_Count = QMK_BLE_CHANNEL_1;
uint8_t app_2g4_data[APP_2G4_BUF_CNT][APP_2G4_BUF_SIZE];
volatile uint8_t app_2g4_data_send = 0;
volatile uint8_t app_2g4_data_rev = 0;
const md_spi_inittypedef SPI2_InitStruct = /**< SPI init structure */
{
MD_SPI_MODE_MASTER,
MD_SPI_PHASE_2EDGE,
MD_SPI_POLARITY_HIGH,
MD_SPI_BAUDRATEPRESCALER_DIV8,
MD_SPI_MSB_FIRST,
MD_SPI_FULL_DUPLEX,
MD_SPI_FRAME_FORMAT_8BIT,
MD_SPI_NSS_HARD,
};
uint8_t app_2g4_buffer_full(void) {
uint8_t tmp_rev = app_2g4_data_rev + 1;
if(tmp_rev == APP_2G4_BUF_CNT)
{
tmp_rev = 0;
}
return (tmp_rev == app_2g4_data_send);
}
uint8_t app_2g4_buffer_empty(void) {
return (app_2g4_data_rev == app_2g4_data_send);
}
void app_2g4_buffer_rev_add(void) {
app_2g4_data_rev++;
if(app_2g4_data_rev >= APP_2G4_BUF_CNT)
app_2g4_data_rev = 0;
}
void app_2g4_buffer_send_add(void) {
app_2g4_data_send++;
if(app_2g4_data_send >= APP_2G4_BUF_CNT)
app_2g4_data_send = 0;
}
void Spi_Main_Loop(void) {
if (Init_Spi_Power_Up || Keyboard_Status.System_Work_Status) {
return;
}
if ((!app_2g4_buffer_empty()) && (!Spi_Send_Recv_Flg) && (!gpio_read_pin(ES_SPI_ACK_IO))) {
Spi_Send_Recv_Flg = 1;
Send_Key_Type = SPI_NACK;
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, app_2g4_data[app_2g4_data_send]);
app_2g4_buffer_send_add();
}
}
void es_ble_spi_init(void) {
md_gpio_inittypedef gpiox;
md_rcu_enable_spi2(RCU);
gpiox.Pin = MD_GPIO_PIN_0;
gpiox.Mode = MD_GPIO_MODE_FUNCTION;
gpiox.OutputType = MD_GPIO_OUTPUT_PUSHPULL;
gpiox.Pull = MD_GPIO_PULL_UP;
gpiox.OutDrive = MD_GPIO_DRIVING_8MA;
gpiox.Function = MD_GPIO_AF0;
md_gpio_init(GPIOC, &gpiox);
gpiox.Pin = MD_GPIO_PIN_1;
md_gpio_init(GPIOC, &gpiox);
gpiox.Pin = MD_GPIO_PIN_2;
md_gpio_init(GPIOC, &gpiox);
gpiox.Pin = MD_GPIO_PIN_3;
md_gpio_init(GPIOC, &gpiox);
md_spi_init(SPI2, (md_spi_inittypedef *)(&SPI2_InitStruct));
}
void es_ble_spi_deinit(void) {
md_rcu_enable_spi2_reset(RCU);
md_rcu_disable_spi2_reset(RCU);
md_rcu_disable_spi2(RCU);
GPIOC->MOD |= 0x000000FF;
GPIOC->PUD &= 0xFFFFFF00;
GPIOC->OT &= 0xFFFFFF00;
GPIOC->DS &= 0xFFFFFF00;
GPIOC->IST &= 0xFFFFFF00;
}
void es_spi_send_recv_by_dma(uint32_t num, uint8_t *rx_buf, uint8_t *tx_buf) {
uint32_t tx_index = 0;
uint32_t rx_index = 0;
__disable_irq();
if(((uint32_t)tx_buf) >= 0x20000000) {
if(num & 0x1) {
SPI2->DATA = tx_buf[tx_index++];
}
while(tx_index < num) {
if(md_spi_get_txfifo_value(SPI2) <= 2) {
SPI2->DATA = tx_buf[tx_index++];
SPI2->DATA = tx_buf[tx_index++];
}
if(md_spi_get_rxfifo_value(SPI2)) {
rx_buf[rx_index++] = SPI2->DATA;
}
}
while(rx_index < num) {
if(md_spi_get_rxfifo_value(SPI2)) {
rx_buf[rx_index++] = SPI2->DATA;
}
}
} else {
if(num & 0x1) {
SPI2->DATA = 0X00;
}
while(tx_index < num) {
if(md_spi_get_txfifo_value(SPI2) <= 2) {
SPI2->DATA = 0X00;
SPI2->DATA = 0X00;
tx_index += 2;
}
if(md_spi_get_rxfifo_value(SPI2)) {
rx_buf[rx_index++] = SPI2->DATA;
}
}
while(rx_index < num) {
if(md_spi_get_rxfifo_value(SPI2)) {
rx_buf[rx_index++] = SPI2->DATA;
}
}
}
__enable_irq();
}
void Spi_Send_Commad(uint8_t Commad) {
if (Init_Spi_Power_Up || Keyboard_Status.System_Work_Status) {
return;
}
uint16_t Time_Delay = 0;
while (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO))){
Time_Delay++;
if (Time_Delay >= 2000) {
Time_Delay = 0;
return;
}
}
Spi_Send_Recv_Flg = 1;
Send_Key_Type = SPI_NACK;
Spi_Interval = SPI_DELAY_RF_TIME;
g_es_spi_tx_buf[0] = USER_KEYBOARD_COMMAND;
g_es_spi_tx_buf[1] = USER_KEYBOARD_LENGTH;
g_es_spi_tx_buf[2] = Commad;
if (Commad == USER_BATTERY_DATA) {
g_es_spi_tx_buf[3] = Keyboard_Info.Batt_Number;
} else if (Commad == USER_BLE1_WRITE_NAME) {
g_es_spi_tx_buf[3] = ((USER_BlE_ID >> 8) & 0XFF);
g_es_spi_tx_buf[4] = (USER_BlE_ID & 0X00FF);
g_es_spi_tx_buf[5] = strlen(USER_BlE1_NAME);
for (uint8_t len = 0; len < strlen(USER_BlE1_NAME); len++) {
g_es_spi_tx_buf[6 + len] = USER_BlE1_NAME[len];
}
} else if (Commad == USER_BLE2_WRITE_NAME) {
g_es_spi_tx_buf[3] = ((USER_BlE_ID >> 8) & 0XFF);
g_es_spi_tx_buf[4] = (USER_BlE_ID & 0X00FF);
g_es_spi_tx_buf[5] = strlen(USER_BlE2_NAME);
for (uint8_t len = 0; len < strlen(USER_BlE2_NAME); len++) {
g_es_spi_tx_buf[6 + len] = USER_BlE2_NAME[len];
}
} else if (Commad == USER_BLE3_WRITE_NAME) {
g_es_spi_tx_buf[3] = ((USER_BlE_ID >> 8) & 0XFF);
g_es_spi_tx_buf[4] = (USER_BlE_ID & 0X00FF);
g_es_spi_tx_buf[5] = strlen(USER_BlE3_NAME);
for (uint8_t len = 0; len < strlen(USER_BlE3_NAME); len++) {
g_es_spi_tx_buf[6 + len] = USER_BlE3_NAME[len];
}
}
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, g_es_spi_tx_buf);
}
uint8_t Spi_Ack_Send_Commad(uint8_t Commad) {
if (Init_Spi_Power_Up) {
return SPI_BUSY;
}
if (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO))) {
return SPI_BUSY;
}
Spi_Send_Recv_Flg = 1;
Send_Key_Type = SPI_ACK;
Repet_Send_Count = 0;
g_es_spi_tx_buf[0] = USER_KEYBOARD_COMMAND;
g_es_spi_tx_buf[1] = USER_KEYBOARD_LENGTH;
g_es_spi_tx_buf[2] = Commad;
es_spi_send_recv_by_dma(USER_KEYBOARD_LENGTH, g_es_spi_rx_buf, g_es_spi_tx_buf);
return SPI_IDLE;
}
void Get_Spi_Return_Data(uint8_t *Data) {
if (Emi_Test_Start) {
Emi_Write_Data(Data, USER_KEYBOARD_LENGTH);
} else {
if (Data[2] == USER_GET_RF_STATUS) {
Keyboard_Status.System_Work_Status = Data[3];
if (Keyboard_Status.System_Work_Status) {
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
if (Usb_Change_Mode_Wakeup) {
User_Sleep();
} else {
Keyboard_Status.System_Work_Status = 0;
}
} else {
Keyboard_Status.System_Work_Status = 0;
Spi_Interval = SPI_DELAY_USB_TIME;
}
}
Keyboard_Status.System_Work_Mode = Data[4];
if (Keyboard_Info.Key_Mode != Keyboard_Status.System_Work_Mode) {
Mode_Synchronization_Signal = true;
if (Keyboard_Status.System_Work_Status) {
Keyboard_Status.System_Work_Status = 0;
}
} else {
if (Keyboard_Info.Key_Mode == QMK_USB_MODE) {
Spi_Interval = SPI_DELAY_USB_TIME;
}
}
Keyboard_Status.System_Work_Channel = Data[5];
if ((Keyboard_Info.Ble_Channel != Keyboard_Status.System_Work_Channel) && (Keyboard_Info.Key_Mode == QMK_BLE_MODE)) {
Mode_Synchronization_Signal = true;
if (Keyboard_Status.System_Work_Status) {
Keyboard_Status.System_Work_Status = 0;
}
}
Keyboard_Status.System_Connect_Status = Data[6];
if (Temp_System_Led_Status != Keyboard_Status.System_Connect_Status) {
Temp_System_Led_Status = Keyboard_Status.System_Connect_Status;
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
Led_Rf_Pair_Flg = true;
} else {
Led_Rf_Pair_Flg = false;
}
}
Keyboard_Status.System_Led_Status = Data[7];
uint16_t Ble_ID = ((Data[8] << 8) | (Data[9]));
if (Ble_ID != USER_BlE_ID) {
if (Ble_Name_Spi_Send == false) {
Ble_Name_Spi_Send = true;
Ble_Name_Spi_Count = QMK_BLE_CHANNEL_1;
}
}
} else if (Data[2] == USER_KEYBOARD_SLEEP) {
if (Keyboard_Status.System_Work_Status && (Data[3] == USER_SLEEP_PASS)) {
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
Keyboard_Status.System_Sleep_Mode = 1;
} else {
Keyboard_Status.System_Sleep_Mode = 0;
}
} else if (Data[3] == USER_SLEEP_FIAL) {
Keyboard_Status.System_Work_Status = 0;
Keyboard_Status.System_Sleep_Mode = 0;
}
}
if (0XBB == Data[10]) {
Emi_Test_Start = true;
Emi_Init();
}
}
}

View File

@ -0,0 +1,96 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define USER_EMI_COMMAND 0XBB
#define USER_KEYBOARD_COMMAND 0X0A
#define USER_KEYBOARD_LENGTH (64)
#define USER_SWITCH_2P4G_MODE 0X00
#define USER_SWITCH_BLE_1_MODE 0X01
#define USER_SWITCH_BLE_2_MODE 0X02
#define USER_SWITCH_BLE_3_MODE 0X03
#define USER_SWITCH_2P4G_PAIR 0X04
#define USER_SWITCH_BLE_1_PAIR 0X05
#define USER_SWITCH_BLE_2_PAIR 0X06
#define USER_SWITCH_BLE_3_PAIR 0X07
#define USER_SWITCH_USB_MODE 0X08
#define USER_KEYBOARD_SLEEP 0X09
#define USER_KEYBOARD_WAKEUP 0X0A
#define USER_KEY_BYTE_DATA 0X0B
#define USER_KEY_BIT_DATA 0X0C
#define USER_MOUSE_DATA 0X0D
#define USER_CONSUMER_DATA 0X0E
#define USER_SYSTEM_DATA 0X0F
#define USER_BATTERY_DATA 0X10
#define USER_GET_RF_STATUS 0X11
#define USER_BLE1_WRITE_NAME 0X12
#define USER_BLE2_WRITE_NAME 0X13
#define USER_BLE3_WRITE_NAME 0X14
#define APP_2G4_BUF_SIZE (USER_KEYBOARD_LENGTH)
#define APP_2G4_BUF_CNT (20)
#define SPI_DELAY_RF_TIME (60)
#define SPI_DELAY_USB_TIME (500 * 3)
enum Custom_Spi_Ack_S {
SPI_NACK,
SPI_ACK
};
enum Custom_Spi_Busy_S {
SPI_BUSY,
SPI_IDLE
};
extern volatile uint8_t Spi_Send_Recv_Flg;
extern uint8_t g_es_spi_rx_buf[64];
extern uint8_t g_es_spi_tx_buf[64];
extern uint8_t Repet_Send_Count;
extern uint8_t Send_Key_Type;
extern bool Init_Spi_Power_Up;
extern uint8_t Init_Spi_100ms_Delay;
extern uint16_t Spi_Interval;
extern bool Ble_Name_Spi_Send;
extern uint8_t Ble_Name_Spi_Count;
extern uint8_t app_2g4_data[APP_2G4_BUF_CNT][APP_2G4_BUF_SIZE];
extern volatile uint8_t app_2g4_data_send;
extern volatile uint8_t app_2g4_data_rev;
extern const md_spi_inittypedef SPI2_InitStruct;
extern uint8_t app_2g4_buffer_full(void);
extern uint8_t app_2g4_buffer_empty(void);
extern void app_2g4_buffer_rev_add(void);
extern void app_2g4_buffer_send_add(void);
extern void Spi_Main_Loop(void);
extern void es_ble_spi_init(void);
extern void es_ble_spi_deinit(void);
extern void es_spi_send_recv_by_dma(uint32_t num, uint8_t *rx_buf, uint8_t *tx_buf);
extern void Spi_Send_Commad(uint8_t Commad);
extern uint8_t Spi_Ack_Send_Commad(uint8_t Commad);
extern void Get_Spi_Return_Data(uint8_t *Data);

View File

@ -0,0 +1,438 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
void es_mcu_reset(void) {
uint16_t Time_Delay = 0;
while (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO)) || Reset_Save_Flash) {
Time_Delay++;
if (Time_Delay >= 36000) {
Time_Delay = 0;
break;
}
}
gpio_write_pin_low(ES_LED_POWER_IO);
NVIC_SystemReset();
}
void bootloader_jump(void) {
uint16_t Time_Delay = 0;
while (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO)) || Reset_Save_Flash) {
Time_Delay++;
if (Time_Delay >= 36000) {
Time_Delay = 0;
break;
}
}
gpio_write_pin_low(ES_LED_POWER_IO);
/*Remap EFLASH,remap to boot*/
md_fc_lock();
md_syscfg_set_memory_mapping(SYSCFG, MD_SYSCFG_MEMMOD_MAIN);
md_syscfg_set_flash_remap_base(SYSCFG, 0);
md_syscfg_enable_memory_remap(SYSCFG);
NVIC_SystemReset();
}
void mcu_reset(void) {
uint16_t Time_Delay = 0;
while (Spi_Send_Recv_Flg || (gpio_read_pin(ES_SPI_ACK_IO)) || Reset_Save_Flash) {
Time_Delay++;
if (Time_Delay >= 36000) {
Time_Delay = 0;
break;
}
}
gpio_write_pin_low(ES_LED_POWER_IO);
NVIC_SystemReset();
}
void User_Systime_Init(void) { //2ms
md_rcu_enable_bs16t1(RCU);
BS16T1->PRES = 48 - 1;
BS16T1->AR = 2000;
BS16T1->IER = 0x1;
BS16T1->CON1 = 0x1;
NVIC_SetPriority(BS16T1_IRQn, 2);
NVIC_EnableIRQ(BS16T1_IRQn);
}
void User_Systime_Deinit(void) {
md_rcu_enable_bs16t1_reset(RCU);
md_rcu_disable_bs16t1_reset(RCU);
md_rcu_disable_bs16t1(RCU);
}
void User_Sleep(void) {
gpio_set_pin_output(ES_LED_POWER_IO);
gpio_write_pin_low(ES_LED_POWER_IO);
gpio_set_pin_output(ES_SDB_POWER_IO);
gpio_write_pin_low(ES_SDB_POWER_IO);
gpio_set_pin_output(ES_WUKEUP_IO);
gpio_write_pin_low(ES_WUKEUP_IO);
}
void User_Wakeup(void) {
gpio_set_pin_output(ES_WUKEUP_IO);
gpio_write_pin_high(ES_WUKEUP_IO);
}
void Init_Gpio_Infomation(void) {
gpio_write_pin_low(ES_LED_POWER_IO);
gpio_set_pin_output(ES_LED_POWER_IO);
gpio_write_pin_low(ES_LED_POWER_IO);
gpio_write_pin_high(ES_SDB_POWER_IO);
gpio_set_pin_output(ES_SDB_POWER_IO);
gpio_write_pin_high(ES_SDB_POWER_IO);
gpio_write_pin_high(ES_WUKEUP_IO);
gpio_set_pin_output(ES_WUKEUP_IO);
gpio_write_pin_high(ES_WUKEUP_IO);
//STDBT
gpio_set_pin_input_high(ES_BATT_STDBY_IO);
//USB POWER
gpio_set_pin_input(ES_USB_POWER_IO);
md_gpio_inittypedef gpiox;
gpiox.Pin = MD_GPIO_PIN_4;
gpiox.Mode = MD_GPIO_MODE_INPUT;
gpiox.OutputType = MD_GPIO_OUTPUT_PUSHPULL;
gpiox.Pull = MD_GPIO_PULL_DOWN;
gpiox.OutDrive = MD_GPIO_DRIVING_8MA;
gpiox.Function = MD_GPIO_AF0;
md_gpio_init(GPIOA, &gpiox);
md_exti_set_interrupt_pin_0_7(EXTI, MD_EXTI_GPIOA4);
md_exti_enable_it_gpio_pin(EXTI, MD_EXTI_GPIO4);
md_exti_enable_rising_edge_trigger(EXTI, MD_EXTI_GPIO4);
md_exti_enable_falling_edge_trigger(EXTI, MD_EXTI_GPIO4);
NVIC_SetPriority(EXTI_4to15_IRQn, 3);
NVIC_EnableIRQ((IRQn_Type) EXTI_4to15_IRQn); /* EXTI_4to15_IRQn interrupt */
}
void Board_Wakeup_Init(void) {
/*Using USB_SOF to calibrate the internal clock*/
md_rcu_enable_csu(RCU);
CSU->CON |= CSU_CON_AUTOEN_MSK;
CSU->CON |= CSU_CON_CNTEN_MSK;
es_ble_spi_init(); //SPI
User_Adc_Init(); //ADC
rgb_matrix_driver_init(); //PWM DMA
Init_Gpio_Infomation(); //GPIO
User_Systime_Init(); //time
if (Keyboard_Info.Key_Mode == QMK_USB_MODE) {
User_Usb_Init(); //USB
} else {
Usb_Disconnect();
}
Init_Spi_Power_Up = true;
Init_Spi_100ms_Delay = 0;
Spi_Interval = SPI_DELAY_RF_TIME;
NVIC_SetPriority(PendSV_IRQn, 3);
NVIC_SetPriority(SysTick_IRQn, 3);
Keyboard_Status.System_Work_Status = 0;
Keyboard_Status.System_Sleep_Mode = 0;
Usb_Change_Mode_Wakeup = false;
Init_Batt_Infomation();
Led_Power_Up = false;
Emi_Test_Start = false;
}
void es_chibios_user_idle_loop_hook(void) {
uint32_t i;
if(Keyboard_Info.Key_Mode == QMK_USB_MODE) {
if (Usb_Dis_Connect) {
Usb_Dis_Connect = false;
if((g_usb_sof_frame_id != g_usb_sof_frame_id_last) || (Usb_Change_Mode_Wakeup == false)) { //正常通信
g_usb_sof_frame_id_last = g_usb_sof_frame_id;
Usb_Suspend_Delay = 0;
return;
} else {
Usb_If_Ok_Led = false;
Usb_Suspend_Delay++;
if (Usb_Suspend_Delay < 800) { //8S
return;
}
Usb_Suspend_Delay = 0;
while ((DMA1->CHENSET) & 0x4);
User_Sleep();
uint32_t delay = 0;
while (SPI_IDLE != Spi_Ack_Send_Commad(USER_KEYBOARD_SLEEP)) {
delay++;
if(delay >= 3600) {
delay = 0;
User_Wakeup();
Usb_Suspend_Delay = 6000;
return;
}
}
delay = 0;
while (Spi_Send_Recv_Flg) {
delay++;
if(delay >= 36000) {
delay = 0;
User_Wakeup();
return;
}
}
}
} else {
return;
}
} else {
if(!Keyboard_Status.System_Sleep_Mode) { //无线休眠
return;
}
}
/*等待SPI数据发送完成*/
if(Spi_Send_Recv_Flg) {
return;
}
/*680进入休眠之后1.2ms 之后 ACK_IO 会高电平,说明休眠完成*/
uint32_t delay = 0;
while (!gpio_read_pin(ES_SPI_ACK_IO)) {
wait_ms(1);
delay++;
if(delay >= 100) {
delay = 0;
return;
}
}
gpio_set_pin_input_high(ES_SPI_ACK_IO); //ACK_IO
md_tick_disable_csr_tickie(TICK);
NVIC_DisableIRQ((IRQn_Type) SysTick_IRQn);
User_Systime_Deinit();
es_ble_spi_deinit();
User_Pwm_Deinit();
User_Usb_Deinit();
User_Adc_Deinit();
Save_Flash = false;
Save_Flash_3S_Count = 0;
Usb_Change_Mode_Wakeup = false;
Usb_Change_Mode_Delay = 0;
Led_Power_Up = false;
ioline_t User_Pin_Tab_Col[KEYBAORD_COL] = MATRIX_USER_COL_PINS;
ioline_t User_Pin_Tab_Rol[KEYBAORD_ROL] = MATRIX_USER_ROW_PINS;
//唤醒源配置
for(i = 0; i < KEYBAORD_COL; i++) { //COL
gpio_set_pin_output(User_Pin_Tab_Col[i]);
gpio_write_pin_low(User_Pin_Tab_Col[i]);
}
for(i = 0; i < KEYBAORD_ROL; i++) { //ROL
gpio_set_pin_input_high(User_Pin_Tab_Rol[i]);
}
gpio_set_pin_input(ES_USB_POWER_IO);
/*B0 B3 B4 B6 B7 B1*/
uint32_t Gpio_Enable = 0X000000DB;
uint32_t Gpio_Status_H = 0X00000000;
uint32_t Gpio_Status_L = 0X000000DB;
if (gpio_read_pin(ES_USB_POWER_IO)) { //USB C5
Gpio_Status_L |= 0X20;
} else {
Gpio_Status_H |= 0X20;
}
Gpio_Enable |= 0X20;
//GP16C4T2_CH2 PB5
/*PB5 和 PC5 冲突只能用一个*/
GPIOB->MOD &= 0xFFFFF3FF; //选择复用模式 GP16C4T2_CH2
GPIOB->MOD |= 0x00000800; //选择复用模式 NABLE:1 DISABLE:0
GPIOB->AFL &= 0xFF0FFFFF; //选择复用功能
GPIOB->AFL |= 0x00300000; //选择复用模式 NABLE:1 DISABLE:0
md_exti_set_interrupt_pin_0_7(EXTI, MD_EXTI_GPIOB0 | MD_EXTI_GPIOB1 | MD_EXTI_GPIOB3 | MD_EXTI_GPIOB4 | MD_EXTI_GPIOC5 | MD_EXTI_GPIOB6 | MD_EXTI_GPIOB7);
//md_exti_set_interrupt_pin_8_15(EXTI, MD_EXTI_GPIOB10);
md_exti_enable_it_gpio_pin(EXTI, Gpio_Enable); /*0~7 , 10*/
md_exti_enable_rising_edge_trigger(EXTI, Gpio_Status_H); /*0~7 , 10*/
md_exti_enable_falling_edge_trigger(EXTI, Gpio_Status_L); /*0~7 , 10*/
NVIC_EnableIRQ((IRQn_Type) EXTI_0to1_IRQn); /* EXTI_0to1_IRQn interrupt */
NVIC_EnableIRQ((IRQn_Type) EXTI_2to3_IRQn); /* EXTI_2to3_IRQn interrupt */
NVIC_EnableIRQ((IRQn_Type) EXTI_4to15_IRQn); /* EXTI_4to15_IRQn interrupt */
//GP16C4T2_CH2 PB5
md_rcu_enable_gp16c4t2(RCU);
md_timer_set_prescaler_value_pscv(GP16C4T2, 1); //分频系数
md_timer_set_auto_reload_value_arrv(GP16C4T2, 0xffff); //计数最大值
md_timer_set_cc2_func_cc2ssel(GP16C4T2, MD_TIMER_CHMODE_INPUT_DIRECT); //使用当前通道
md_timer_set_cc2_input_edge_cc2pol(GP16C4T2, MD_TIMER_OUTPUTPOLARITY_LOW); //捕捉极性
md_timer_enable_cc2_output_cc2en(GP16C4T2); //通道使能
md_timer_enable_counter_cnten(GP16C4T2); //定时器使能
md_timer_enable_it_ch2(GP16C4T2); //通道中断使能
NVIC_EnableIRQ((IRQn_Type) GP16C4T2_IRQn); /* GP16C4T2_IRQHandler */
md_rcu_enable_gp16c4t2_in_sleep_mode(RCU); /*保持休眠下工作*/
uint8_t Usb_Sleep_Status = 0XAA;
if (!gpio_read_pin(ES_USB_POWER_IO) && (Keyboard_Info.Key_Mode == QMK_USB_MODE)) {
NVIC_DisableIRQ((IRQn_Type) USB_IRQn); /* USB_IRQHandler */
Usb_Sleep_Status = 0XFF;
}
//进入低功耗
SCB->SCR &= ~(1UL << 2); // SCR[2] = 0 (SLEEP)
md_rcu_set_system_clock_source(RCU, MD_RCU_SW_SYSCLK_HRC);
md_rcu_disable_pll0(RCU);
if(Keyboard_Info.Key_Mode != QMK_USB_MODE) {
md_rcu_disable_usb(RCU);
md_rcu_disable_hrc48(RCU);
__WFI(); //Wait For Interrupt
/*唤醒*/
md_rcu_enable_hrc48(RCU);
for(i = 0;i < 99999;) {
if(md_rcu_is_active_flag_hrc48_ready(RCU) == MD_RCU_HRC48RDY_READY)
break;
i++;
}
md_rcu_enable_usb(RCU);
} else { //在USB模式下
md_rcu_enable_usb_in_sleep_mode(RCU);
__WFI(); //Wait For Interrupt
}
md_rcu_set_system_clock_source(RCU, MD_RCU_SW_SYSCLK_HRC48);
if ((Keyboard_Info.Key_Mode == QMK_USB_MODE) && (Usb_Sleep_Status == 0XFF)) {
NVIC_EnableIRQ((IRQn_Type) USB_IRQn);
Usb_Sleep_Status = 0XAA;
}
/*休眠唤醒之后记录唤醒按下按键的位置*/
uint8_t Sleep_Status = 0x00;
for(i = 0; i < KEYBAORD_ROL; i++) { //ROL
if (!gpio_read_pin(User_Pin_Tab_Rol[i])) {
Sleep_Status |= (1 << i);
}
}
NVIC_DisableIRQ((IRQn_Type) EXTI_0to1_IRQn); /* EXTI_0to1_IRQn interrupt */
NVIC_DisableIRQ((IRQn_Type) EXTI_2to3_IRQn); /* EXTI_2to3_IRQn interrupt */
NVIC_DisableIRQ((IRQn_Type) EXTI_4to15_IRQn); /* EXTI_4to15_IRQn interrupt */
NVIC_DisableIRQ((IRQn_Type) GP16C4T2_IRQn); /* GP16C4T2_IRQHandler */
//唤醒源配置输出高电平
for(i = 0; i < KEYBAORD_COL; i++) { //COL
gpio_write_pin_high(User_Pin_Tab_Col[i]);
}
delay = 50;
while(delay--);
uint8_t Rol_Count = 0,Col_Count = 0;
for (i = 0; i < KEYBAORD_ROL; i++) {
if ((1 << i) & Sleep_Status) {
for(uint8_t j = 0; j < KEYBAORD_COL; j++) {
gpio_write_pin_low(User_Pin_Tab_Col[j]);
delay = 50;
while(delay--);
if (!gpio_read_pin(User_Pin_Tab_Rol[i])) {
Rol_Count = i;
Col_Count = j;
break;
}
for(uint8_t k = 0; k < KEYBAORD_COL; k++) {
gpio_write_pin_high(User_Pin_Tab_Col[j]);
}
delay = 50;
while(delay--);
}
}
}
//唤醒源配置输出高电平
for(i = 0; i < KEYBAORD_COL; i++) { //COL
gpio_write_pin_high(User_Pin_Tab_Col[i]);
}
gpio_set_pin_input_low(ES_SPI_ACK_IO); //ACK_IO
md_tick_enable_csr_tickie(TICK);
NVIC_EnableIRQ((IRQn_Type) SysTick_IRQn);
//在USB模式下
if(Keyboard_Info.Key_Mode == QMK_USB_MODE) {
if (USBD1.status & 0x2) {
usb_lld_wakeup_host(0);
uint16_t cnt = 200;
while(cnt--) {
if(USBD1.state != USB_ACTIVE) {
wait_ms(10);
}
}
}
register_code(dynamic_keymap_get_keycode(0, Rol_Count, Col_Count));
wait_ms(2);
unregister_code(dynamic_keymap_get_keycode(0, Rol_Count, Col_Count));
wait_ms(2);
}
Board_Wakeup_Init();
}

View File

@ -0,0 +1,32 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
extern void es_mcu_reset(void);
extern void bootloader_jump(void);
extern void mcu_reset(void);
extern void User_Systime_Init(void);
extern void User_Systime_Deinit(void);
extern void User_Sleep(void);
extern void User_Wakeup(void);
extern void Init_Gpio_Infomation(void);
extern void Board_Wakeup_Init(void);
extern void es_chibios_user_idle_loop_hook(void);

View File

@ -0,0 +1,822 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file rt/templates/chconf.h
* @brief Configuration file template.
* @details A copy of this file must be placed in each project directory, it
* contains the application specific kernel settings.
*
* @addtogroup config
* @details Kernel related settings and hooks.
* @{
*/
#ifndef CHCONF_H
#define CHCONF_H
#define _CHIBIOS_RT_CONF_
#define _CHIBIOS_RT_CONF_VER_7_0_
#define CH_CFG_ST_TIMEDELTA 0
#define CH_CFG_ST_RESOLUTION 16
#define CH_CFG_ST_FREQUENCY 1000
/*===========================================================================*/
/**
* @name System settings
* @{
*/
/*===========================================================================*/
/**
* @brief Handling of instances.
* @note If enabled then threads assigned to various instances can
* interact each other using the same synchronization objects.
* If disabled then each OS instance is a separate world, no
* direct interactions are handled by the OS.
*/
#if !defined(CH_CFG_SMP_MODE)
#define CH_CFG_SMP_MODE FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name System timers settings
* @{
*/
/*===========================================================================*/
/**
* @brief System time counter resolution.
* @note Allowed values are 16, 32 or 64 bits.
*/
#if !defined(CH_CFG_ST_RESOLUTION)
#define CH_CFG_ST_RESOLUTION 32
#endif
/**
* @brief System tick frequency.
* @details Frequency of the system timer that drives the system ticks. This
* setting also defines the system tick time unit.
*/
#if !defined(CH_CFG_ST_FREQUENCY)
#define CH_CFG_ST_FREQUENCY 100000
#endif
/**
* @brief Time intervals data size.
* @note Allowed values are 16, 32 or 64 bits.
*/
#if !defined(CH_CFG_INTERVALS_SIZE)
#define CH_CFG_INTERVALS_SIZE 32
#endif
/**
* @brief Time types data size.
* @note Allowed values are 16 or 32 bits.
*/
#if !defined(CH_CFG_TIME_TYPES_SIZE)
#define CH_CFG_TIME_TYPES_SIZE 32
#endif
/**
* @brief Time delta constant for the tick-less mode.
* @note If this value is zero then the system uses the classic
* periodic tick. This value represents the minimum number
* of ticks that is safe to specify in a timeout directive.
* The value one is not valid, timeouts are rounded up to
* this value.
*/
#if !defined(CH_CFG_ST_TIMEDELTA)
#define CH_CFG_ST_TIMEDELTA 2
#endif
/** @} */
/*===========================================================================*/
/**
* @name Kernel parameters and options
* @{
*/
/*===========================================================================*/
/**
* @brief Round robin interval.
* @details This constant is the number of system ticks allowed for the
* threads before preemption occurs. Setting this value to zero
* disables the preemption for threads with equal priority and the
* round robin becomes cooperative. Note that higher priority
* threads can still preempt, the kernel is always preemptive.
* @note Disabling the round robin preemption makes the kernel more compact
* and generally faster.
* @note The round robin preemption is not supported in tickless mode and
* must be set to zero in that case.
*/
#if !defined(CH_CFG_TIME_QUANTUM)
#define CH_CFG_TIME_QUANTUM 0
#endif
/**
* @brief Idle thread automatic spawn suppression.
* @details When this option is activated the function @p chSysInit()
* does not spawn the idle thread. The application @p main()
* function becomes the idle thread and must implement an
* infinite loop.
*/
#if !defined(CH_CFG_NO_IDLE_THREAD)
#define CH_CFG_NO_IDLE_THREAD FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Performance options
* @{
*/
/*===========================================================================*/
/**
* @brief OS optimization.
* @details If enabled then time efficient rather than space efficient code
* is used when two possible implementations exist.
*
* @note This is not related to the compiler optimization options.
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_OPTIMIZE_SPEED)
#define CH_CFG_OPTIMIZE_SPEED TRUE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Subsystem options
* @{
*/
/*===========================================================================*/
/**
* @brief Time Measurement APIs.
* @details If enabled then the time measurement APIs are included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_TM)
#define CH_CFG_USE_TM FALSE
#endif
/**
* @brief Time Stamps APIs.
* @details If enabled then the time stamps APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_TIMESTAMP)
#define CH_CFG_USE_TIMESTAMP TRUE
#endif
/**
* @brief Threads registry APIs.
* @details If enabled then the registry APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_REGISTRY)
#define CH_CFG_USE_REGISTRY FALSE
#endif
/**
* @brief Threads synchronization APIs.
* @details If enabled then the @p chThdWait() function is included in
* the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_WAITEXIT)
#define CH_CFG_USE_WAITEXIT FALSE
#endif
/**
* @brief Semaphores APIs.
* @details If enabled then the Semaphores APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_SEMAPHORES)
#define CH_CFG_USE_SEMAPHORES TRUE
#endif
/**
* @brief Semaphores queuing mode.
* @details If enabled then the threads are enqueued on semaphores by
* priority rather than in FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special
* requirements.
* @note Requires @p CH_CFG_USE_SEMAPHORES.
*/
#if !defined(CH_CFG_USE_SEMAPHORES_PRIORITY)
#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
#endif
/**
* @brief Mutexes APIs.
* @details If enabled then the mutexes APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_MUTEXES)
#define CH_CFG_USE_MUTEXES TRUE
#endif
/**
* @brief Enables recursive behavior on mutexes.
* @note Recursive mutexes are heavier and have an increased
* memory footprint.
*
* @note The default is @p FALSE.
* @note Requires @p CH_CFG_USE_MUTEXES.
*/
#if !defined(CH_CFG_USE_MUTEXES_RECURSIVE)
#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
#endif
/**
* @brief Conditional Variables APIs.
* @details If enabled then the conditional variables APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_MUTEXES.
*/
#if !defined(CH_CFG_USE_CONDVARS)
#define CH_CFG_USE_CONDVARS FALSE
#endif
/**
* @brief Conditional Variables APIs with timeout.
* @details If enabled then the conditional variables APIs with timeout
* specification are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_CONDVARS.
*/
#if !defined(CH_CFG_USE_CONDVARS_TIMEOUT)
#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
#endif
/**
* @brief Events Flags APIs.
* @details If enabled then the event flags APIs are included in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_EVENTS)
#define CH_CFG_USE_EVENTS TRUE
#endif
/**
* @brief Events Flags APIs with timeout.
* @details If enabled then the events APIs with timeout specification
* are included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_EVENTS.
*/
#if !defined(CH_CFG_USE_EVENTS_TIMEOUT)
#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
#endif
/**
* @brief Synchronous Messages APIs.
* @details If enabled then the synchronous messages APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_MESSAGES)
#define CH_CFG_USE_MESSAGES FALSE
#endif
/**
* @brief Synchronous Messages queuing mode.
* @details If enabled then messages are served by priority rather than in
* FIFO order.
*
* @note The default is @p FALSE. Enable this if you have special
* requirements.
* @note Requires @p CH_CFG_USE_MESSAGES.
*/
#if !defined(CH_CFG_USE_MESSAGES_PRIORITY)
#define CH_CFG_USE_MESSAGES_PRIORITY FALSE
#endif
/**
* @brief Dynamic Threads APIs.
* @details If enabled then the dynamic threads creation APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_WAITEXIT.
* @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
*/
#if !defined(CH_CFG_USE_DYNAMIC)
#define CH_CFG_USE_DYNAMIC FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name OSLIB options
* @{
*/
/*===========================================================================*/
/**
* @brief Mailboxes APIs.
* @details If enabled then the asynchronous messages (mailboxes) APIs are
* included in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_SEMAPHORES.
*/
#if !defined(CH_CFG_USE_MAILBOXES)
#define CH_CFG_USE_MAILBOXES FALSE
#endif
/**
* @brief Core Memory Manager APIs.
* @details If enabled then the core memory manager APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_MEMCORE)
#define CH_CFG_USE_MEMCORE TRUE
#endif
/**
* @brief Managed RAM size.
* @details Size of the RAM area to be managed by the OS. If set to zero
* then the whole available RAM is used. The core memory is made
* available to the heap allocator and/or can be used directly through
* the simplified core memory allocator.
*
* @note In order to let the OS manage the whole RAM the linker script must
* provide the @p __heap_base__ and @p __heap_end__ symbols.
* @note Requires @p CH_CFG_USE_MEMCORE.
*/
#if !defined(CH_CFG_MEMCORE_SIZE)
#define CH_CFG_MEMCORE_SIZE 0
#endif
/**
* @brief Heap Allocator APIs.
* @details If enabled then the memory heap allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
* @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
* @p CH_CFG_USE_SEMAPHORES.
* @note Mutexes are recommended.
*/
#if !defined(CH_CFG_USE_HEAP)
#define CH_CFG_USE_HEAP FALSE
#endif
/**
* @brief Memory Pools Allocator APIs.
* @details If enabled then the memory pools allocator APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_MEMPOOLS)
#define CH_CFG_USE_MEMPOOLS FALSE
#endif
/**
* @brief Objects FIFOs APIs.
* @details If enabled then the objects FIFOs APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_OBJ_FIFOS)
#define CH_CFG_USE_OBJ_FIFOS FALSE
#endif
/**
* @brief Pipes APIs.
* @details If enabled then the pipes APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_PIPES)
#define CH_CFG_USE_PIPES FALSE
#endif
/**
* @brief Objects Caches APIs.
* @details If enabled then the objects caches APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_OBJ_CACHES)
#define CH_CFG_USE_OBJ_CACHES FALSE
#endif
/**
* @brief Delegate threads APIs.
* @details If enabled then the delegate threads APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_DELEGATES)
#define CH_CFG_USE_DELEGATES FALSE
#endif
/**
* @brief Jobs Queues APIs.
* @details If enabled then the jobs queues APIs are included
* in the kernel.
*
* @note The default is @p TRUE.
*/
#if !defined(CH_CFG_USE_JOBS)
#define CH_CFG_USE_JOBS FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Objects factory options
* @{
*/
/*===========================================================================*/
/**
* @brief Objects Factory APIs.
* @details If enabled then the objects factory APIs are included in the
* kernel.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_CFG_USE_FACTORY)
#define CH_CFG_USE_FACTORY FALSE
#endif
/**
* @brief Maximum length for object names.
* @details If the specified length is zero then the name is stored by
* pointer but this could have unintended side effects.
*/
#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
#endif
/**
* @brief Enables the registry of generic objects.
*/
#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
#define CH_CFG_FACTORY_OBJECTS_REGISTRY FALSE
#endif
/**
* @brief Enables factory for generic buffers.
*/
#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
#define CH_CFG_FACTORY_GENERIC_BUFFERS FALSE
#endif
/**
* @brief Enables factory for semaphores.
*/
#if !defined(CH_CFG_FACTORY_SEMAPHORES)
#define CH_CFG_FACTORY_SEMAPHORES FALSE
#endif
/**
* @brief Enables factory for mailboxes.
*/
#if !defined(CH_CFG_FACTORY_MAILBOXES)
#define CH_CFG_FACTORY_MAILBOXES FALSE
#endif
/**
* @brief Enables factory for objects FIFOs.
*/
#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
#endif
/**
* @brief Enables factory for Pipes.
*/
#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
#define CH_CFG_FACTORY_PIPES FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Debug options
* @{
*/
/*===========================================================================*/
/**
* @brief Debug option, kernel statistics.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_STATISTICS)
#define CH_DBG_STATISTICS FALSE
#endif
/**
* @brief Debug option, system state check.
* @details If enabled the correct call protocol for system APIs is checked
* at runtime.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_SYSTEM_STATE_CHECK)
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
#endif
/**
* @brief Debug option, parameters checks.
* @details If enabled then the checks on the API functions input
* parameters are activated.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_CHECKS)
#define CH_DBG_ENABLE_CHECKS FALSE
#endif
/**
* @brief Debug option, consistency checks.
* @details If enabled then all the assertions in the kernel code are
* activated. This includes consistency checks inside the kernel,
* runtime anomalies and port-defined checks.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_ENABLE_ASSERTS)
#define CH_DBG_ENABLE_ASSERTS FALSE
#endif
/**
* @brief Debug option, trace buffer.
* @details If enabled then the trace buffer is activated.
*
* @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
*/
#if !defined(CH_DBG_TRACE_MASK)
#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
#endif
/**
* @brief Trace buffer entries.
* @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
* different from @p CH_DBG_TRACE_MASK_DISABLED.
*/
#if !defined(CH_DBG_TRACE_BUFFER_SIZE)
#define CH_DBG_TRACE_BUFFER_SIZE 128
#endif
/**
* @brief Debug option, stack checks.
* @details If enabled then a runtime stack check is performed.
*
* @note The default is @p FALSE.
* @note The stack check is performed in a architecture/port dependent way.
* It may not be implemented or some ports.
* @note The default failure mode is to halt the system with the global
* @p panic_msg variable set to @p NULL.
*/
#if !defined(CH_DBG_ENABLE_STACK_CHECK)
#define CH_DBG_ENABLE_STACK_CHECK FALSE
#endif
/**
* @brief Debug option, stacks initialization.
* @details If enabled then the threads working area is filled with a byte
* value when a thread is created. This can be useful for the
* runtime measurement of the used stack.
*
* @note The default is @p FALSE.
*/
#if !defined(CH_DBG_FILL_THREADS)
#define CH_DBG_FILL_THREADS FALSE
#endif
/**
* @brief Debug option, threads profiling.
* @details If enabled then a field is added to the @p thread_t structure that
* counts the system ticks occurred while executing the thread.
*
* @note The default is @p FALSE.
* @note This debug option is not currently compatible with the
* tickless mode.
*/
#if !defined(CH_DBG_THREADS_PROFILING)
#define CH_DBG_THREADS_PROFILING FALSE
#endif
/** @} */
/*===========================================================================*/
/**
* @name Kernel hooks
* @{
*/
/*===========================================================================*/
/**
* @brief System structure extension.
* @details User fields added to the end of the @p ch_system_t structure.
*/
#define CH_CFG_SYSTEM_EXTRA_FIELDS \
/* Add system custom fields here.*/
/**
* @brief System initialization hook.
* @details User initialization code added to the @p chSysInit() function
* just before interrupts are enabled globally.
*/
#define CH_CFG_SYSTEM_INIT_HOOK() { \
/* Add system initialization code here.*/ \
}
/**
* @brief OS instance structure extension.
* @details User fields added to the end of the @p os_instance_t structure.
*/
#define CH_CFG_OS_INSTANCE_EXTRA_FIELDS \
/* Add OS instance custom fields here.*/
/**
* @brief OS instance initialization hook.
*
* @param[in] oip pointer to the @p os_instance_t structure
*/
#define CH_CFG_OS_INSTANCE_INIT_HOOK(oip) { \
/* Add OS instance initialization code here.*/ \
}
/**
* @brief Threads descriptor structure extension.
* @details User fields added to the end of the @p thread_t structure.
*/
#define CH_CFG_THREAD_EXTRA_FIELDS \
/* Add threads custom fields here.*/
/**
* @brief Threads initialization hook.
* @details User initialization code added to the @p _thread_init() function.
*
* @note It is invoked from within @p _thread_init() and implicitly from all
* the threads creation APIs.
*
* @param[in] tp pointer to the @p thread_t structure
*/
#define CH_CFG_THREAD_INIT_HOOK(tp) { \
/* Add threads initialization code here.*/ \
}
/**
* @brief Threads finalization hook.
* @details User finalization code added to the @p chThdExit() API.
*
* @param[in] tp pointer to the @p thread_t structure
*/
#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
/* Add threads finalization code here.*/ \
}
/**
* @brief Context switch hook.
* @details This hook is invoked just before switching between threads.
*
* @param[in] ntp thread being switched in
* @param[in] otp thread being switched out
*/
#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
/* Context switch code here.*/ \
}
/**
* @brief ISR enter hook.
*/
#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
/* IRQ prologue code here.*/ \
}
/**
* @brief ISR exit hook.
*/
#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
/* IRQ epilogue code here.*/ \
}
/**
* @brief Idle thread enter hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to activate a power saving mode.
*/
#define CH_CFG_IDLE_ENTER_HOOK() { \
/* Idle-enter code here.*/ \
}
/**
* @brief Idle thread leave hook.
* @note This hook is invoked within a critical zone, no OS functions
* should be invoked from here.
* @note This macro can be used to deactivate a power saving mode.
*/
#define CH_CFG_IDLE_LEAVE_HOOK() { \
/* Idle-leave code here.*/ \
}
/**
* @brief Idle Loop hook.
* @details This hook is continuously invoked by the idle thread loop.
*/
#define CH_CFG_IDLE_LOOP_HOOK() { \
/* Idle loop code here.*/ \
}
/**
* @brief System tick event hook.
* @details This hook is invoked in the system tick handler immediately
* after processing the virtual timers queue.
*/
#define CH_CFG_SYSTEM_TICK_HOOK() { \
/* System tick event code here.*/ \
}
/**
* @brief System halt hook.
* @details This hook is invoked in case to a system halting error before
* the system is halted.
*/
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
/* System halt code here.*/ \
}
/**
* @brief Trace hook.
* @details This hook is invoked each time a new record is written in the
* trace buffer.
*/
#define CH_CFG_TRACE_HOOK(tep) { \
/* Trace code here.*/ \
}
/**
* @brief Runtime Faults Collection Unit hook.
* @details This hook is invoked each time new faults are collected and stored.
*/
#define CH_CFG_RUNTIME_FAULTS_HOOK(mask) { \
/* Faults handling code here.*/ \
}
/** @} */
/*===========================================================================*/
/* Port-specific settings (override port settings defaulted in chcore.h). */
/*===========================================================================*/
#endif /* CHCONF_H */
/** @} */

View File

@ -0,0 +1,97 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
/* Define less important options */
/*
* Force NKRO
*
* Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
* state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
* makefile for this to work.)
*
* If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
* until the next keyboard reset.
*
* NKRO may prevent your keystrokes from being detected in the BIOS, but it is
* fully operational during normal computer usage.
*
* For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
* or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
* bootmagic, NKRO mode will always be enabled until it is toggled again during a
* power-up.
*
*/
#define FORCE_NKRO
/*
* Feature disable options
* These options are also useful to firmware size reduction.
*/
#define MATRIX_UNSELECT_DRIVE_HIGH
#define CORTEX_ENABLE_WFI_IDLE FALSE
/* Ensure we jump to bootloader if the RESET keycode was pressed */
#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE
#define DEBOUNCE 2
#define RGB_MATRIX_LED_COUNT 81
#define RGB_MATRIX_KEYPRESSES
#define RGB_MATRIX_KEYRELEASES
#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
#define RGB_DISABLE_AFTER_TIMEOUT 0
#define RGB_MATRIX_LED_FLUSH_LIMIT 16
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 180
#define RGB_MATRIX_SLEEP
#define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR 1151
#define EEPROM_SIZE 1152
#define FEE_PAGE_SIZE (0x200)
#define FEE_PAGE_COUNT (8)
#define FEE_PAGE_BASE_ADDRESS (0x1F000)
#define FEE_MCU_FLASH_SIZE (0x1000)
#define EECONFIG_USER_DATA_SIZE 4
#define MAX_NAME_LEN (18)
#define USER_BlE_ID (0X0036)
#define USER_BlE1_NAME "SK75-1"
#define USER_BlE2_NAME "SK75-2"
#define USER_BlE3_NAME "SK75-3"
#define KEYBAORD_COL (16)
#define KEYBAORD_ROL (6)
#define MATRIX_USER_COL_PINS { D15, D14, C15, C14, C13, D3, D2, C12, C11, C10, A14, C9, C8, C7, C6, B15 }
#define MATRIX_USER_ROW_PINS { B0, B3, B4, B5, B6, B7 }
#define WIN_COL (1)
#define WIN_ROL (3)
#define MAC_COL (2)
#define MAC_ROL (3)

View File

@ -0,0 +1,172 @@
{
"keyboard_name": "SK 75",
"manufacturer": "WOMIER",
"maintainer": "WOMIER",
"url": "womierkeyboard.com",
"usb": {
"vid": "0x36B0",
"pid": "0x3044",
"device_version": "0.0.0"
},
"matrix_pins": {
"cols": [ "D15", "D14", "C15", "C14", "C13", "D3", "D2", "C12", "C11", "C10", "A14", "C9", "C8", "C7", "C6", "B15" ],
"rows": [ "B0", "B3", "B4", "B5", "B6", "B7" ]
},
"diode_direction": "ROW2COL",
"features": {
"bootmagic": true,
"extrakey": true,
"nkro": true,
"mousekey": true,
"consolekey": true,
"command": false,
"rgb_matrix": true
},
"rgb_matrix": {
"driver": "custom",
"animations": {
"solid_color": true,
"alphas_mods": true,
"gradient_up_down": true,
"gradient_left_right": true,
"breathing": true,
"band_sat": true,
"band_val": true,
"band_pinwheel_sat": true,
"band_pinwheel_val": true,
"band_spiral_sat": true,
"band_spiral_val": true,
"cycle_all": true,
"cycle_left_right": true,
"cycle_up_down": true,
"cycle_out_in": true,
"cycle_out_in_dual": true,
"rainbow_moving_chevron": true,
"cycle_pinwheel": true,
"cycle_spiral": true,
"dual_beacon": true,
"rainbow_beacon": true,
"rainbow_pinwheels": true,
"flower_blooming": true,
"raindrops": true,
"jellybean_raindrops": true,
"hue_breathing": true,
"hue_pendulum": true,
"hue_wave": true,
"pixel_fractal": false,
"pixel_flow": true,
"pixel_rain": false,
"typing_heatmap": false,
"digital_rain": true,
"solid_reactive_simple": false,
"solid_reactive": true,
"solid_reactive_wide": true,
"solid_reactive_multiwide": true,
"solid_reactive_cross": true,
"solid_reactive_multicross": true,
"solid_reactive_nexus": true,
"solid_reactive_multinexus": true,
"splash": true,
"multisplash": true,
"solid_splash": true,
"solid_multisplash": true,
"starlight": true,
"starlight_dual_hue": true,
"starlight_dual_sat": true,
"riverflow": true
}
},
"bootloader": "custom",
"layouts": {
"LAYOUT_tkl_ansi": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1.25, "y": 0},
{"matrix": [0, 2], "x": 2.25, "y": 0},
{"matrix": [0, 3], "x": 3.25, "y": 0},
{"matrix": [0, 4], "x": 4.25, "y": 0},
{"matrix": [0, 5], "x": 5.5, "y": 0},
{"matrix": [0, 6], "x": 6.5, "y": 0},
{"matrix": [0, 7], "x": 7.5, "y": 0},
{"matrix": [0, 8], "x": 8.5, "y": 0},
{"matrix": [0, 9], "x": 9.75, "y": 0},
{"matrix": [0, 10], "x": 10.75, "y": 0},
{"matrix": [0, 11], "x": 11.75, "y": 0},
{"matrix": [0, 12], "x": 12.75, "y": 0},
{"matrix": [2, 14], "x": 14.0, "y": 0},
{"matrix": [1, 15], "x": 15.0, "y": 0},
{"matrix": [1, 0], "x": 0, "y": 1.25},
{"matrix": [1, 1], "x": 1, "y": 1.25},
{"matrix": [1, 2], "x": 2, "y": 1.25},
{"matrix": [1, 3], "x": 3, "y": 1.25},
{"matrix": [1, 4], "x": 4, "y": 1.25},
{"matrix": [1, 5], "x": 5, "y": 1.25},
{"matrix": [1, 6], "x": 6, "y": 1.25},
{"matrix": [1, 7], "x": 7, "y": 1.25},
{"matrix": [1, 8], "x": 8, "y": 1.25},
{"matrix": [1, 9], "x": 9, "y": 1.25},
{"matrix": [1, 10], "x": 10, "y": 1.25},
{"matrix": [1, 11], "x": 11, "y": 1.25},
{"matrix": [1, 12], "x": 12, "y": 1.25},
{"matrix": [1, 13], "x": 13, "y": 1.25, "w": 2.0},
{"matrix": [2, 15], "x": 15.0, "y": 1.25},
{"matrix": [2, 0], "x": 0, "y": 2.25, "w": 1.5},
{"matrix": [2, 1], "x": 1.5, "y": 2.25},
{"matrix": [2, 2], "x": 2.5, "y": 2.25},
{"matrix": [2, 3], "x": 3.5, "y": 2.25},
{"matrix": [2, 4], "x": 4.5, "y": 2.25},
{"matrix": [2, 5], "x": 5.5, "y": 2.25},
{"matrix": [2, 6], "x": 6.5, "y": 2.25},
{"matrix": [2, 7], "x": 7.5, "y": 2.25},
{"matrix": [2, 8], "x": 8.5, "y": 2.25},
{"matrix": [2, 9], "x": 9.5, "y": 2.25},
{"matrix": [2, 10], "x": 10.5, "y": 2.25},
{"matrix": [2, 11], "x": 11.5, "y": 2.25},
{"matrix": [2, 12], "x": 12.5, "y": 2.25},
{"matrix": [2, 13], "x": 13.5, "y": 2.25, "w": 1.5},
{"matrix": [3, 14], "x": 15.0, "y": 2.25},
{"matrix": [3, 0], "x": 0, "y": 3.25, "w": 1.75},
{"matrix": [3, 1], "x": 1.75, "y": 3.25},
{"matrix": [3, 2], "x": 2.75, "y": 3.25},
{"matrix": [3, 3], "x": 3.75, "y": 3.25},
{"matrix": [3, 4], "x": 4.75, "y": 3.25},
{"matrix": [3, 5], "x": 5.75, "y": 3.25},
{"matrix": [3, 6], "x": 6.75, "y": 3.25},
{"matrix": [3, 7], "x": 7.75, "y": 3.25},
{"matrix": [3, 8], "x": 8.75, "y": 3.25},
{"matrix": [3, 9], "x": 9.75, "y": 3.25},
{"matrix": [3, 10], "x": 10.75, "y": 3.25},
{"matrix": [3, 11], "x": 11.75, "y": 3.25},
{"matrix": [3, 13], "x": 12.75, "y": 3.25, "w": 2.25},
{"matrix": [3, 15], "x": 15.0, "y": 3.25},
{"matrix": [4, 0], "x": 0, "y": 4.25, "w": 2.25},
{"matrix": [4, 2], "x": 2.25, "y": 4.25},
{"matrix": [4, 3], "x": 3.25, "y": 4.25},
{"matrix": [4, 4], "x": 4.25, "y": 4.25},
{"matrix": [4, 5], "x": 5.25, "y": 4.25},
{"matrix": [4, 6], "x": 6.25, "y": 4.25},
{"matrix": [4, 7], "x": 7.25, "y": 4.25},
{"matrix": [4, 8], "x": 8.25, "y": 4.25},
{"matrix": [4, 9], "x": 9.25, "y": 4.25},
{"matrix": [4, 10], "x": 10.25, "y": 4.25},
{"matrix": [4, 11], "x": 11.25, "y": 4.25},
{"matrix": [4, 13], "x": 12.25, "y": 4.25, "w": 1.75},
{"matrix": [4, 14], "x": 14.0, "y": 4.25},
{"matrix": [5, 0], "x": 0, "y": 5.25, "w": 1.25},
{"matrix": [5, 1], "x": 1.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 2], "x": 2.5, "y": 5.25, "w": 1.25},
{"matrix": [5, 5], "x": 3.75, "y": 5.25, "w": 6.25},
{"matrix": [5, 9], "x": 10, "y": 5.25, "w": 1.25},
{"matrix": [5, 10], "x": 11.25, "y": 5.25, "w": 1.25},
{"matrix": [5, 13], "x": 13.0, "y": 5.25},
{"matrix": [5, 14], "x": 14.0, "y": 5.25},
{"matrix": [5, 15], "x": 15.0, "y": 5.25}
]
}
}
}

View File

@ -0,0 +1,52 @@
/* Copyright 2024 Yiancar-Designs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "rdmctmzt_common.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_tkl_ansi(
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_HOME,
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_END,
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_K29, KC_PGUP,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(2), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[1] = LAYOUT_tkl_ansi(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_HOME,
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_END,
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_K29, KC_PGUP,
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, MO(3), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
),
[2] = LAYOUT_tkl_ansi(
KC_ESC, KC_BRID, KC_BRIU, KC_WHOM, KC_MAIL, KC_CALC, KC_MSEL, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, RGB_TOG, KC_HOME,
KC_GRV, MD_BLE1, MD_BLE2, MD_BLE3, MD_24G, MD_USB, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, QK_BAT, EE_CLR,
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, RGB_MOD, RGB_SAI,
KC_CAPS, TO(0), TO(1), KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, RGB_HUI, RGB_SAD,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, SIX_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, RGB_VAI,
TEST_CL, QK_WLO, KC_LALT, KC_SPC, KC_NO, KC_RCTL, RGB_SPD, RGB_VAD, RGB_SPI
),
[3] = LAYOUT_tkl_ansi(
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, RGB_TOG, KC_HOME,
KC_GRV, MD_BLE1, MD_BLE2, MD_BLE3, MD_24G, MD_USB, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, QK_BAT, EE_CLR,
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, RGB_MOD, RGB_SAI,
KC_CAPS, TO(0), TO(1), KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, RGB_HUI, RGB_SAD,
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, SIX_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, RGB_VAI,
TEST_CL, QK_WLO, KC_LGUI, KC_SPC, KC_NO, KC_RCTL, RGB_SPD, RGB_VAD, RGB_SPI
)
};

View File

@ -0,0 +1,222 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MCUCONF_H
#define MCUCONF_H
#define ES32_FS026_MCUCONF
#define ES32_ES32F0283_MCUCONF
/*
* HAL driver system settings.
*/
#define ES32_NO_INIT FALSE
/*system_clk select
MD_RCU_SW_SYSCLK_HRC = HRC selected as system clock
MD_RCU_SW_SYSCLK_HOSC = HOSC selected as system clock
MD_RCU_SW_SYSCLK_PLL0 = PLL0 selected as system clock
MD_RCU_SW_SYSCLK_HRC48 = HRC48 selected as system clock
*/
#define ES32_SYSCLK_SOURSE_SELECT MD_RCU_SW_SYSCLK_PLL0
/*external clk config*/
#define ES32_HOSC_CLK_EN FALSE
#define ES32_HOSC_CLK_FREQ 8
/*pll clk config
MD_RCU_PLLSRC_HRC = HRC selected as PLL reference clock
MD_RCU_PLLSRC_HOSC = HOSC selected as PLL reference clock
MD_RCU_PLLSRC_HRC48 = HRC48 selected as PLL reference clock
MD_RCU_PLLCLK_PASS = 0
MD_RCU_PLLCLK_4M = 4000000
MD_RCU_PLLCLK_8M = 8000000
MD_RCU_PLLCLK_12M = 12000000
MD_RCU_PLLCLK_16M = 16000000
MD_RCU_PLLCLK_24M = 24000000
MD_RCU_PLLCLK_32M = 32000000
MD_RCU_PLLCLK_36M = 36000000
MD_RCU_PLLCLK_40M = 40000000
MD_RCU_PLLCLK_48M = 48000000
MD_RCU_PLLCLK_64M = 64000000
MD_RCU_PLLCLK_72M = 72000000
*/
#define ES32_PLL_CLK_EN TRUE
#define ES32_PLL_SOURSE_SELECT MD_RCU_PLLSRC_HRC48
#define ES32_PLL_CLK_FREQ MD_RCU_PLLCLK_72M
/*bus clk config
MD_RCU_HPRE_SYSCLK_DIV_1 = SYSCLK not divided
MD_RCU_HPRE_SYSCLK_DIV_2 = SYSCLK divided by 2
MD_RCU_HPRE_SYSCLK_DIV_4 = SYSCLK divided by 4
MD_RCU_HPRE_SYSCLK_DIV_8 = SYSCLK divided by 8
MD_RCU_HPRE_SYSCLK_DIV_16 = SYSCLK divided by 16
MD_RCU_HPRE_SYSCLK_DIV_64 = SYSCLK divided by 64
MD_RCU_HPRE_SYSCLK_DIV_128 = SYSCLK divided by 128
MD_RCU_HPRE_SYSCLK_DIV_256 = SYSCLK divided by 256
MD_RCU_HPRE_SYSCLK_DIV_512 = @brief SYSCLK divided by 512
MD_RCU_PPRE_HCLK_DIV_1 = HCLK not divided
MD_RCU_PPRE_HCLK_DIV_2 = HCLK divided by 2
MD_RCU_PPRE_HCLK_DIV_4 = HCLK divided by 4
MD_RCU_PPRE_HCLK_DIV_8 = HCLK divided by 8
MD_RCU_PPRE_HCLK_DIV_16 = HCLK divided by 16
*/
#define ES32_BUS_DIV_HPRE MD_RCU_HPRE_SYSCLK_DIV_1
#define ES32_BUS_DIV_PPRE MD_RCU_PPRE_HCLK_DIV_1
/*
* GPIO driver system settings.
*/
#define ES32_USB_USE_GPIO TRUE
/*
* EXTI driver system settings.
*/
#define ES32_IRQ_EXTI0_1_PRIORITY 6
#define ES32_IRQ_EXTI2_3_PRIORITY 6
#define ES32_IRQ_EXTI4_15_PRIORITY 6
/*
* GPT driver system settings.
*/
#define ES32_GPT_USE_AD16C4T1 FALSE
#define ES32_GPT_USE_GP32C4T1 FALSE
#define ES32_GPT_USE_GP16C4T1 FALSE
#define ES32_GPT_USE_GP16C4T2 FALSE
#define ES32_GPT_USE_GP16C4T3 FALSE
#define ES32_GPT_USE_GP16C2T1 FALSE
#define ES32_GPT_USE_GP16C2T2 FALSE
#define ES32_GPT_USE_GP16C2T3 FALSE
#define ES32_GPT_USE_GP16C2T4 FALSE
#define ES32_GPT_USE_BS16T1 FALSE
#define ES32_GPT_AD16C4T1_IRQ_PRIORITY 7
#define ES32_GPT_GP32C4T1_IRQ_PRIORITY 7
#define ES32_GPT_GP16C4T1_IRQ_PRIORITY 7
#define ES32_GPT_GP16C4T2_IRQ_PRIORITY 7
#define ES32_GPT_GP16C4T3_IRQ_PRIORITY 7
#define ES32_GPT_GP16C2T1_IRQ_PRIORITY 7
#define ES32_GPT_GP16C2T2_IRQ_PRIORITY 7
#define ES32_GPT_GP16C2T3_IRQ_PRIORITY 7
#define ES32_GPT_GP16C2T4_IRQ_PRIORITY 7
#define ES32_GPT_BS16T1_IRQ_PRIORITY 7
/*
* ICU driver system settings.
*/
#define ES32_ICU_USE_AD16C4T1 FALSE
#define ES32_ICU_USE_GP32C4T1 FALSE
#define ES32_ICU_USE_GP16C4T1 FALSE
#define ES32_ICU_USE_GP16C4T2 FALSE
#define ES32_ICU_USE_GP16C4T3 FALSE
#define ES32_ICU_USE_GP16C2T1 FALSE
#define ES32_ICU_USE_GP16C2T2 FALSE
#define ES32_ICU_USE_GP16C2T3 FALSE
#define ES32_ICU_USE_GP16C2T4 FALSE
#define ES32_ICU_AD16C4T1_IRQ_PRIORITY 7
#define ES32_ICU_GP32C4T1_IRQ_PRIORITY 7
#define ES32_ICU_GP16C4T1_IRQ_PRIORITY 7
#define ES32_ICU_GP16C4T2_IRQ_PRIORITY 7
#define ES32_ICU_GP16C4T3_IRQ_PRIORITY 7
#define ES32_ICU_GP16C2T1_IRQ_PRIORITY 7
#define ES32_ICU_GP16C2T2_IRQ_PRIORITY 7
#define ES32_ICU_GP16C2T3_IRQ_PRIORITY 7
#define ES32_ICU_GP16C2T4_IRQ_PRIORITY 7
/*
* I2C driver system settings.
*/
#define ES32_I2C_USE_I2C1 FALSE
#define ES32_I2C_USE_I2C2 FALSE
#define ES32_I2C_BUSY_TIMEOUT 50
#define ES32_I2C_I2C1_IRQ_PRIORITY 5
#define ES32_I2C_I2C2_IRQ_PRIORITY 5
/*
* SERIAL driver system settings.
*/
#define ES32_SERIAL_USE_UART1 FALSE
#define ES32_SERIAL_USE_UART2 FALSE
#define ES32_SERIAL_USE_UART3 FALSE
#define ES32_SERIAL_USE_UART4 FALSE
#define ES32_SERIAL_UART1_PRIORITY 7
#define ES32_SERIAL_UART2_PRIORITY 7
#define ES32_SERIAL_UART3_PRIORITY 7
#define ES32_SERIAL_UART4_PRIORITY 7
/*
* SPI driver system settings.
*/
#define ES32_SPI_USE_SPI1 FALSE
#define ES32_SPI_USE_SPI2 FALSE
#define ES32_SPI_USE_SPI3 FALSE
#define ES32_SPI_SPI1_IRQ_PRIORITY 10
#define ES32_SPI_SPI2_IRQ_PRIORITY 10
#define ES32_SPI_SPI3_IRQ_PRIORITY 10
/*
* ST driver system settings.
*/
#define ES32_ST_IRQ_PRIORITY 8
#define ES32_ST_USE_TIMER 2
/*
* UART driver system settings.
*/
#define ES32_UART_USE_UART1 FALSE
#define ES32_UART_USE_UART2 FALSE
#define ES32_UART_USE_UART3 FALSE
#define ES32_UART_USE_UART4 FALSE
#define ES32_UART_UART1_IRQ_PRIORITY 12
#define ES32_UART_UART2_IRQ_PRIORITY 12
#define ES32_UART_UART3_IRQ_PRIORITY 12
#define ES32_UART_UART4_IRQ_PRIORITY 12
/*
* PWM driver system settings.
*/
#define ES32_PWM_USE_AD16C4T1 FALSE
#define ES32_PWM_USE_GP32C4T1 FALSE
#define ES32_PWM_USE_GP16C4T1 FALSE
#define ES32_PWM_USE_GP16C4T2 TRUE
#define ES32_PWM_USE_GP16C4T3 FALSE
#define ES32_PWM_USE_GP16C2T1 FALSE
#define ES32_PWM_USE_GP16C2T2 FALSE
#define ES32_PWM_USE_GP16C2T3 FALSE
#define ES32_PWM_USE_GP16C2T4 FALSE
#define ES32_PWM_AD16C4T1_IRQ_PRIORITY 7
#define ES32_PWM_GP32C4T1_IRQ_PRIORITY 7
#define ES32_PWM_GP16C4T1_IRQ_PRIORITY 7
#define ES32_PWM_GP16C4T2_IRQ_PRIORITY 7
#define ES32_PWM_GP16C4T3_IRQ_PRIORITY 7
#define ES32_PWM_GP16C2T1_IRQ_PRIORITY 7
#define ES32_PWM_GP16C2T2_IRQ_PRIORITY 7
#define ES32_PWM_GP16C2T3_IRQ_PRIORITY 7
#define ES32_PWM_GP16C2T4_IRQ_PRIORITY 7
/*
* USB driver system settings.
*/
#define ES32_USB_USE_USB1 TRUE
#define ES32_USB_USB1_IRQ_PRIORITY 13
#define ES32_USE_USB_SOF_TRIM_HRC48 TRUE
#endif /* MCUCONF_H */

View File

@ -0,0 +1,22 @@
# sk75
![sk75](https://imgur.com/nmvoI6z)
A customizable 81key keyboard.
* Keyboard Maintainer: [LiWenLiu](https://github.com/LiuLiuQMK)
* Hardware Supported: sk75 PCB with ES32FS026 microcontroller
* Hardware Availability: Check the wob page on [sk75's website](www.womierkeyboard.com)
Make example for this keyboard (after setting up your build environment):
make womier/sk75:default
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader
Enter the bootloader in 1 ways:
* **Bootmagic reset**: Hold down the key at (0,0) in the matrix (Esc key) and plug in the keyboard

View File

@ -0,0 +1,51 @@
VPATH += keyboards/womier/common
SRC += rdmctmzt_common.c
SRC += quantum/dynamic_keymap.c
SRC += three_mode.c
SRC += user_battery.c
SRC += user_eeprom.c
SRC += user_emi.c
SRC += user_led_custom.c
SRC += user_spi.c
SRC += user_system.c
VPATH += lib/chibios-contrib/os/common/ext/CMSIS/ES32/FS026/md
# SRC += lib/chibios-contrib/os/common/ext/CMSIS/ES32/FS026/md/md_adc.c
SRC += lib/chibios-contrib/os/common/ext/CMSIS/ES32/FS026/md/md_spi.c
# Board: it should exist either in <chibios>/os/hal/boards/
# or <this_dir>/boards
BOARD = FS026
# Cortex version
MCU = cortex-m0
# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
ARMV = 6
## chip/board settings
# - the next two should match the directories in
# <chibios[-contrib]>/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)
# OR
# <chibios[-contrib]>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = ES32
MCU_SERIES = FS026
# Linker script to use
# - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
# or <keyboard_dir>/ld/
MCU_LDSCRIPT ?= FS026
# Startup code to use
# - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
MCU_STARTUP ?= FS026
USE_FPU ?= no
EEPROM_DRIVER = custom
NO_USB_STARTUP_CHECK = yes
BLUETOOTH_CUSTOM = yes
DEBOUNCE_TYPE = asym_eager_defer_pk

View File

@ -0,0 +1,594 @@
/* Copyright 2024 Finalkey
* Copyright 2024 LiWenLiu <https://github.com/LiuLiuQMK>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rdmctmzt_common.h"
bool Key_Fn_Status = false;
bool User_Key_Batt_Num_Show = false;
uint8_t User_Key_Batt_Count = 0;
uint8_t Led_Point_Count = 0U;
uint8_t Mac_Win_Point_Count = 0U;
bool Test_Led = false;
uint8_t Test_Colour = 0U;
uint8_t Led_Batt_Index_Tab[10] = {
16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25
};
#define LED_CAP_INDEX (45)
#define LED_WIN_L_INDEX (73)
#define LED_BATT_INDEX (0)
#define LED_A_INDEX (46)
#define LED_S_INDEX (47)
#define LED_BLE_1_INDEX (16)
#define LED_BLE_2_INDEX (17)
#define LED_BLE_3_INDEX (18)
#define LED_2P4G_INDEX (19)
#define LED_USB_INDEX (20)
led_config_t g_led_config = { {
{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , NO_LED , NO_LED , NO_LED },
{ 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , NO_LED , 14 },
{ 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 13 , 29 },
{ 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , NO_LED , 57 , 44 , 58 },
{ 59 , NO_LED , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , NO_LED , 70 , 71 , NO_LED },
{ 72 , 73 , 74 , NO_LED , NO_LED , 75 , NO_LED , NO_LED , NO_LED , 76 , 77 , NO_LED , NO_LED , 78 , 79 , 80 }
},{
// "Fine-tuned" complex configuration
{ 0, 10}, { 15, 10}, { 30, 10}, { 45, 10}, { 60, 10}, { 75, 10}, { 90, 10}, { 105, 10}, { 120, 10}, { 135, 10}, { 150, 10}, { 165, 10}, { 180, 10}, { 195, 10}, { 208, 10},
{ 0, 20}, { 15, 20}, { 30, 20}, { 45, 20}, { 60, 20}, { 75, 20}, { 90, 20}, { 105, 20}, { 120, 20}, { 135, 20}, { 150, 20}, { 165, 20}, { 180, 20}, { 195, 20}, { 208, 20},
{ 0, 30}, { 15, 30}, { 30, 30}, { 45, 30}, { 60, 30}, { 75, 30}, { 90, 30}, { 105, 30}, { 120, 30}, { 135, 30}, { 150, 30}, { 165, 30}, { 180, 30}, { 195, 30}, { 208, 30},
{ 0, 40}, { 15, 40}, { 30, 40}, { 45, 40}, { 60, 40}, { 75, 40}, { 90, 40}, { 105, 40}, { 120, 40}, { 135, 40}, { 150, 40}, { 165, 40}, { 195, 40}, { 208, 40},
{ 0, 50}, { 15, 50}, { 30, 50}, { 45, 50}, { 60, 50}, { 75, 50}, { 90, 50}, { 105, 50}, { 120, 50}, { 135, 50}, { 150, 50}, { 165, 50}, { 180, 50},
{ 0, 60}, { 15, 60}, { 30, 60}, { 75, 60}, { 135, 60}, { 150, 60}, { 180, 60}, { 195, 60}, { 208, 60}
}, {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1
} };
void Led_Rf_Mode_Show(void) {
uint8_t Temp_Colour = 0,Led_Index = 0;
if (Keyboard_Info.Key_Mode == QMK_BLE_MODE) {
if (Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_1) {
Temp_Colour = 5;
Led_Index = LED_BLE_1_INDEX;
} else if (Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_2) {
Temp_Colour = 5;
Led_Index = LED_BLE_2_INDEX;
} else if (Keyboard_Info.Ble_Channel == QMK_BLE_CHANNEL_3) {
Temp_Colour = 5;
Led_Index = LED_BLE_3_INDEX;
}
} else if (Keyboard_Info.Key_Mode == QMK_2P4G_MODE) {
Temp_Colour = 3;
Led_Index = LED_2P4G_INDEX;
}
if (Keyboard_Status.System_Connect_Status == KB_MODE_CONNECT_PAIR) {
if (Systick_Led_Count < 10) {
rgb_matrix_set_color(Led_Index, Led_Colour_Tab[Temp_Colour][0], Led_Colour_Tab[Temp_Colour][1], Led_Colour_Tab[Temp_Colour][2]);
} else {
rgb_matrix_set_color(Led_Index, 0, 0, 0);
}
if (Systick_Led_Count >= 20) {
Systick_Led_Count = 0;
}
} else if (Keyboard_Status.System_Connect_Status == KB_MODE_CONNECT_RETURN) {
if (Systick_Led_Count < 25) {
rgb_matrix_set_color(Led_Index, Led_Colour_Tab[Temp_Colour][0], Led_Colour_Tab[Temp_Colour][1], Led_Colour_Tab[Temp_Colour][2]);
} else {
rgb_matrix_set_color(Led_Index, 0, 0, 0);
}
if (Systick_Led_Count >= 50) {
Systick_Led_Count = 0;
}
} else {
rgb_matrix_set_color(Led_Index, Led_Colour_Tab[Temp_Colour][0], Led_Colour_Tab[Temp_Colour][1], Led_Colour_Tab[Temp_Colour][2]);
if (Systick_Led_Count >= 240) {
Systick_Led_Count = 0;
Led_Rf_Pair_Flg = false;
if (Keyboard_Info.Key_Mode == QMK_BLE_MODE) {
User_Batt_Send_Spi = true;
}
}
}
}
void Led_Power_Low_Show(void) {
for (uint8_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) {
rgb_matrix_set_color(i, 0, 0, 0);
}
if (Systick_Led_Count < 25) {
rgb_matrix_set_color(LED_BATT_INDEX, U_PWM, 0x00, 0x00);
} else {
rgb_matrix_set_color(LED_BATT_INDEX, 0x00, 0x00, 0x00);
}
if (Systick_Led_Count >= 50) {
Systick_Led_Count = 0;
}
}
void Led_Point_Flash_Show(void) {
if (Systick_Led_Count < 25) {
if (Led_Point_Count) {
rgb_matrix_driver_set_color_all(U_PWM, U_PWM, U_PWM);
} else {
rgb_matrix_driver_set_color_all(U_PWM, U_PWM, 0X00);
}
} else {
rgb_matrix_driver_set_color_all(0X00, 0X00, 0X00);
}
if (Systick_Led_Count >= 50) {
Systick_Led_Count = 0;
if (Led_Point_Count) {
Led_Point_Count--;
} else if (Mac_Win_Point_Count) {
Mac_Win_Point_Count--;
}
}
}
void Led_Batt_Number_Show(void) {
if (es_stdby_pin_state == 1) {
if (Batt_Led_Count >= 2) {
Batt_Led_Count = 0;
if (User_Key_Batt_Count > 3) {
User_Key_Batt_Count -= 3;
} else {
User_Key_Batt_Count = 127;
}
}
uint8_t Tmep_Pwm = User_Key_Batt_Count;
for (uint8_t i = 0; i < 10; i++) {
rgb_matrix_set_color(Led_Batt_Index_Tab[i], 0X00, Led_Wave_Pwm_Tab[Tmep_Pwm], 0X00);
Tmep_Pwm += 8;
if (Tmep_Pwm >= 128) {
Tmep_Pwm -= 128;
}
}
} else if (es_stdby_pin_state == 2) {
for (uint8_t i = 0; i < 10; i++) {
rgb_matrix_set_color(Led_Batt_Index_Tab[i], 0X00, 0XFF, 0X00);
}
} else {
uint8_t Colour_R = 0, Colour_G = 0, Colour_B = 0;
uint8_t Temp_Count = (Keyboard_Info.Batt_Number / 10) + 1;
if (Temp_Count >= 10) {
Temp_Count = 10;
}
if (Temp_Count < 3) {
Colour_R = 0XFF; Colour_G = 0X00; Colour_B = 0X00;
} else if (Temp_Count < 6) {
Colour_R = 0XFF; Colour_G = 0XFF; Colour_B = 0X00;
} else {
Colour_R = 0X00; Colour_G = 0XFF; Colour_B = 0X00;
}
for (uint8_t i = 0; i < Temp_Count; i++) {
rgb_matrix_set_color(Led_Batt_Index_Tab[i], Colour_R, Colour_G, Colour_B);
}
}
}
void User_Point_Show(void){
if (Led_Point_Count || Mac_Win_Point_Count) {
Led_Point_Flash_Show();
} else {
Systick_Led_Count = 0;
if (Keyboard_Info.Key_Mode == QMK_USB_MODE) {
if (host_keyboard_led_state().caps_lock && Usb_If_Ok_Led) {
rgb_matrix_set_color(LED_CAP_INDEX, U_PWM, U_PWM, U_PWM);
}
} else {
if (Keyboard_Status.System_Led_Status & 0x02) {
rgb_matrix_set_color(LED_CAP_INDEX, U_PWM, U_PWM, U_PWM);
}
}
if (Keyboard_Info.Win_Lock) {
rgb_matrix_set_color(LED_WIN_L_INDEX, U_PWM, U_PWM, U_PWM);
}
}
}
void User_Test_Colour_Show(void){
uint8_t Test_R = 0, Test_G = 0, Test_B = 0;
switch(Test_Colour) {
case 0: Test_R = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_G = 0; Test_B = 0; break;
case 1: Test_R = 0; Test_G = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_B = 0; break;
case 2: Test_R = 0; Test_G = 0; Test_B = RGB_MATRIX_MAXIMUM_BRIGHTNESS; break;
case 3: Test_R = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_G = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_B = RGB_MATRIX_MAXIMUM_BRIGHTNESS; break;
default: Test_R = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_G = RGB_MATRIX_MAXIMUM_BRIGHTNESS; Test_B = RGB_MATRIX_MAXIMUM_BRIGHTNESS; break;
}
rgb_matrix_driver_set_color_all(Test_R, Test_G, Test_B);
}
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
if (User_Power_Low) {
Led_Power_Low_Show();
} else if (Test_Led) {
User_Test_Colour_Show();
} else if (Led_Rf_Pair_Flg && (Keyboard_Info.Key_Mode != QMK_USB_MODE)) {
Led_Rf_Mode_Show();
} else if (User_Key_Batt_Num_Show) {
Led_Batt_Number_Show();
} else {
User_Point_Show();
if (Key_Fn_Status) {
switch (Keyboard_Info.Key_Mode) {
case QMK_BLE_MODE: {
switch (Keyboard_Info.Ble_Channel) {
case QMK_BLE_CHANNEL_1: rgb_matrix_set_color(LED_BLE_1_INDEX, U_PWM, U_PWM, U_PWM); break;
case QMK_BLE_CHANNEL_2: rgb_matrix_set_color(LED_BLE_2_INDEX, U_PWM, U_PWM, U_PWM); break;
case QMK_BLE_CHANNEL_3: rgb_matrix_set_color(LED_BLE_3_INDEX, U_PWM, U_PWM, U_PWM); break;
default: break;
}
} break;
case QMK_2P4G_MODE: rgb_matrix_set_color(LED_2P4G_INDEX, U_PWM, U_PWM, U_PWM); break;
case QMK_USB_MODE: rgb_matrix_set_color(LED_USB_INDEX, U_PWM, U_PWM, U_PWM); break;
default: break;
}
}
}
return false;
}
void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {
if (Keyboard_Info.Key_Mode == QMK_USB_MODE) {
if(usb_device_state == USB_DEVICE_STATE_CONFIGURED) {
Usb_If_Ok_Led = true;
} else {
Usb_If_Ok_Led = false;
}
} else {
Usb_If_Ok_Led = false;
}
}
void matrix_io_delay(void) {
}
void matrix_output_select_delay(void) {
}
void matrix_output_unselect_delay(uint8_t line, bool key_pressed) {
}
void housekeeping_task_user(void) {
if (Keyboard_Reset) {
Keyboard_Reset = false;
Keyboard_Info.Nkro = INIT_ALL_KEY;
Keyboard_Info.Mac_Win_Mode = INIT_WIN_MODE;
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
Reset_Save_Flash = true;
/*将当前模式写入flash*/
eeprom_write_block_user((void *)&Keyboard_Info.Key_Mode, 0, sizeof(Keyboard_Info_t));
Reset_Save_Flash = false;
#ifdef NO_RESET
eeconfig_init();
#else
eeconfig_disable();
soft_reset_keyboard();
#endif
return;
}
es_chibios_user_idle_loop_hook();
}
void board_init(void) {
es_ble_spi_init(); //SPI
User_Adc_Init(); //ADC
eeprom_driver_init(); //EEPROM
rgb_matrix_driver_init(); //PWM DMA
Init_Gpio_Infomation(); //GPIO
Init_Keyboard_Infomation();
Init_Batt_Infomation();
User_Systime_Init();
if (Keyboard_Info.Key_Mode == QMK_USB_MODE) {
User_Usb_Init();
Led_Rf_Pair_Flg = false;
} else {
Usb_Disconnect();
}
Init_Spi_Power_Up = true;
Init_Spi_100ms_Delay = 0;
Spi_Interval = SPI_DELAY_RF_TIME;
NVIC_SetPriority(PendSV_IRQn, 3);
NVIC_SetPriority(SysTick_IRQn, 3);
Usb_If_Ok_Led = false;
Led_Power_Up = false;
Emi_Test_Start = false;
Keyboard_Reset = false;
}
void keyboard_post_init_user(void) {
if (keymap_config.nkro != Keyboard_Info.Nkro) {
keymap_config.nkro = Keyboard_Info.Nkro;
}
if (Keyboard_Info.Mac_Win_Mode) {
uint8_t current_layer = get_highest_layer(layer_state);
if (current_layer != 1) {
layer_on(1);
}
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
Usb_Change_Mode_Delay = 0;
Usb_Change_Mode_Wakeup = false;
if (Test_Led) {
if ((keycode != KC_SPC) && (keycode != MO(2)) && (keycode != MO(3)) && (keycode != KC_LCTL)) {
Test_Led = false;
}
}
switch (keycode) {
case QMK_KB_MODE_2P4G: { //2.4G
if (record->event.pressed) {
Key_2p4g_Status = true;
Usb_Disconnect();
if (Keyboard_Info.Key_Mode != QMK_2P4G_MODE) {
Keyboard_Info.Key_Mode = QMK_2P4G_MODE;
Spi_Send_Commad(USER_SWITCH_2P4G_MODE);
Save_Flash_Set();
Led_Rf_Pair_Flg = true;
}
} else {
Key_2p4g_Status = false;
}
Time_3s_Count = 0;
} return true;
case QMK_KB_MODE_BLE1: {
if (record->event.pressed) {
Key_Ble_1_Status = true;
Usb_Disconnect();
if ((Keyboard_Info.Key_Mode != QMK_BLE_MODE) || ((Keyboard_Info.Key_Mode == QMK_BLE_MODE) && (Keyboard_Info.Ble_Channel != QMK_BLE_CHANNEL_1))) { /*如果当前模式不是BLE模式则切换为BLE或者BLE通道不相同*/
Keyboard_Info.Key_Mode = QMK_BLE_MODE;
Keyboard_Info.Ble_Channel = QMK_BLE_CHANNEL_1;
Spi_Send_Commad(USER_SWITCH_BLE_1_MODE);
Save_Flash_Set();
Led_Rf_Pair_Flg = true;
}
} else {
Key_Ble_1_Status = false;
}
Time_3s_Count = 0;
} return true;
case QMK_KB_MODE_BLE2: {
if (record->event.pressed) {
Key_Ble_2_Status = true;
Usb_Disconnect();
if ((Keyboard_Info.Key_Mode != QMK_BLE_MODE) || ((Keyboard_Info.Key_Mode == QMK_BLE_MODE) && (Keyboard_Info.Ble_Channel != QMK_BLE_CHANNEL_2))) { /*如果当前模式不是BLE模式则切换为BLE或者BLE通道不相同*/
Keyboard_Info.Key_Mode = QMK_BLE_MODE;
Keyboard_Info.Ble_Channel = QMK_BLE_CHANNEL_2;
Spi_Send_Commad(USER_SWITCH_BLE_2_MODE);
Save_Flash_Set();
Led_Rf_Pair_Flg = true;
}
} else {
Key_Ble_2_Status = false;
}
Time_3s_Count = 0;
} return true;
case QMK_KB_MODE_BLE3: {
if (record->event.pressed) {
Key_Ble_3_Status = true;
Usb_Disconnect();
if ((Keyboard_Info.Key_Mode != QMK_BLE_MODE) || ((Keyboard_Info.Key_Mode == QMK_BLE_MODE) && (Keyboard_Info.Ble_Channel != QMK_BLE_CHANNEL_3))) { /*如果当前模式不是BLE模式则切换为BLE或者BLE通道不相同*/
Keyboard_Info.Key_Mode = QMK_BLE_MODE;
Keyboard_Info.Ble_Channel = QMK_BLE_CHANNEL_3;
Spi_Send_Commad(USER_SWITCH_BLE_3_MODE);
Save_Flash_Set();
Led_Rf_Pair_Flg = true;
}
} else {
Key_Ble_3_Status = false;
}
Time_3s_Count = 0;
} return true;
case QMK_KB_MODE_USB: {
if (record->event.pressed) {
if (Keyboard_Info.Key_Mode != QMK_USB_MODE) {
Keyboard_Info.Key_Mode = QMK_USB_MODE;
Spi_Send_Commad(USER_SWITCH_USB_MODE);
es_restart_usb_driver();
Save_Flash_Set();
Led_Rf_Pair_Flg = false;
}
}
} return true;
case QMK_BATT_NUM: {
if (record->event.pressed) {
User_Key_Batt_Num_Show = true;
User_Key_Batt_Count = 0;
} else {
User_Key_Batt_Num_Show = false;
User_Key_Batt_Count = 0;
}
} return true;
case QMK_WIN_LOCK: {
if (!record->event.pressed) {
if (Keyboard_Info.Mac_Win_Mode == INIT_MAC_MODE) {
if (Keyboard_Info.Win_Lock == INIT_WIN_LOCK) {
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
Save_Flash_Set();
}
} else {
if (Keyboard_Info.Win_Lock == INIT_WIN_NLOCK) {
Keyboard_Info.Win_Lock = INIT_WIN_LOCK;
unregister_code(KC_LGUI); unregister_code(KC_RGUI); unregister_code(KC_APP);
} else {
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
}
Save_Flash_Set();
}
}
} return true;
case QMK_KB_SIX_N_CH: {
if (record->event.pressed) {
if(keymap_config.nkro) {
es_change_qmk_nkro_mode_disable();
Mac_Win_Point_Count = 3;
} else {
es_change_qmk_nkro_mode_enable();
Led_Point_Count = 3;
}
}
} return true;
case QMK_TEST_COLOUR: {
if (!record->event.pressed) {
if (Test_Led == false) {
Test_Led = true;
Test_Colour = 0;
}
}
} return true;
case KC_SPC: {
if (!record->event.pressed) {
if (Test_Led) {
Test_Colour++;
if (Test_Colour >= 4) {
Test_Colour = 0;
}
}
}
} return true;
case KC_LGUI: { //key_win_l
if (Keyboard_Info.Win_Lock) {
record->event.pressed = false;
}
} return true;
case KC_RGUI: { //key_win_r
if (Keyboard_Info.Win_Lock) {
record->event.pressed = false;
}
} return true;
case KC_APP: { //key_app
if (Keyboard_Info.Win_Lock) {
record->event.pressed = false;
}
} return true;
case RGB_VAI: {
if (!record->event.pressed) {
if (rgb_matrix_get_val() >= RGB_MATRIX_MAXIMUM_BRIGHTNESS) {
Led_Point_Count = 3;
}
}
} return true;
case RGB_VAD: {
if (!record->event.pressed) {
if (rgb_matrix_get_val() <= 0) {
Led_Point_Count = 3;
}
}
} return true;
case RGB_SPI: {
if (!record->event.pressed) {
if (rgb_matrix_get_speed() >= 255) {
Led_Point_Count = 3;
}
}
} return true;
case RGB_SPD: {
if (!record->event.pressed) {
if (rgb_matrix_get_speed() <= 0) {
Led_Point_Count = 3;
}
}
} return true;
case MO(2): { //FN
if (record->event.pressed) {
Key_Fn_Status = true;
} else {
Key_Fn_Status = false;
}
} return true;
case MO(3): { //FN
if (record->event.pressed) {
Key_Fn_Status = true;
} else {
Key_Fn_Status = false;
}
} return true;
case TO(0): { //WIN
if (!record->event.pressed) {
if ((record->event.key.col == WIN_COL) && (record->event.key.row == WIN_ROL) && (Keyboard_Info.Mac_Win_Mode != INIT_WIN_MODE)) {
Keyboard_Info.Mac_Win_Mode = INIT_WIN_MODE;
Mac_Win_Point_Count = 1;
unregister_code(KC_LALT); unregister_code(KC_LGUI); unregister_code(KC_RALT); unregister_code(KC_RGUI); unregister_code(KC_APP);
Save_Flash_Set();
}
}
} return true;
case TO(1): { //MAC
if (!record->event.pressed) {
if ((record->event.key.col == MAC_COL) && (record->event.key.row == MAC_ROL) && (Keyboard_Info.Mac_Win_Mode != INIT_MAC_MODE)) {
Keyboard_Info.Mac_Win_Mode = INIT_MAC_MODE;
Keyboard_Info.Win_Lock = INIT_WIN_NLOCK;
Mac_Win_Point_Count = 3;
unregister_code(KC_LALT); unregister_code(KC_LGUI); unregister_code(KC_RALT); unregister_code(KC_RGUI); unregister_code(KC_APP);
Save_Flash_Set();
}
}
} return true;
case EE_CLR: {
if (record->event.pressed) {
Key_Reset_Status = true;
record->event.pressed = false;
} else {
Key_Reset_Status = false;
}
Func_Time_3s_Count = 0;
} return true;
default: return true; // Process all other keycodes normally
}
}

View File

@ -1,5 +1,6 @@
"""This script automates the copying of the default keymap into your own keymap. """This script automates the copying of the default keymap into your own keymap.
""" """
import re
import shutil import shutil
from milc import cli from milc import cli
@ -13,6 +14,13 @@ from qmk.keyboard import keyboard_completer, keyboard_folder
from qmk.userspace import UserspaceDefs from qmk.userspace import UserspaceDefs
def validate_keymap_name(name):
"""Returns True if the given keymap name contains only a-z, 0-9 and underscore characters.
"""
regex = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9_]+$')
return bool(regex.match(name))
def prompt_keyboard(): def prompt_keyboard():
prompt = """{fg_yellow}Select Keyboard{style_reset_all} prompt = """{fg_yellow}Select Keyboard{style_reset_all}
If you`re unsure you can view a full list of supported keyboards with {fg_yellow}qmk list-keyboards{style_reset_all}. If you`re unsure you can view a full list of supported keyboards with {fg_yellow}qmk list-keyboards{style_reset_all}.
@ -60,6 +68,10 @@ def new_keymap(cli):
cli.log.error(f'Default keymap {{fg_cyan}}{keymap_path_default}{{fg_reset}} does not exist!') cli.log.error(f'Default keymap {{fg_cyan}}{keymap_path_default}{{fg_reset}} does not exist!')
return False return False
if not validate_keymap_name(user_name):
cli.log.error('Keymap names must contain only {fg_cyan}a-z{fg_reset}, {fg_cyan}0-9{fg_reset} and {fg_cyan}_{fg_reset}! Please choose a different name.')
return False
if keymap_path_new.exists(): if keymap_path_new.exists():
cli.log.error(f'Keymap {{fg_cyan}}{user_name}{{fg_reset}} already exists! Please choose a different name.') cli.log.error(f'Keymap {{fg_cyan}}{user_name}{{fg_reset}} already exists! Please choose a different name.')
return False return False

View File

@ -29,6 +29,7 @@ def _convert_macros(via_macros):
if len(via_macros) == 0: if len(via_macros) == 0:
return list() return list()
split_regex = re.compile(r'(}\,)|(\,{)') split_regex = re.compile(r'(}\,)|(\,{)')
macro_group_regex = re.compile(r'({.+?})')
macros = list() macros = list()
for via_macro in via_macros: for via_macro in via_macros:
# Split VIA macro to its elements # Split VIA macro to its elements
@ -38,13 +39,28 @@ def _convert_macros(via_macros):
macro_data = list() macro_data = list()
for m in macro: for m in macro:
if '{' in m or '}' in m: if '{' in m or '}' in m:
# Found keycode(s) # Split macro groups
keycodes = m.split(',') macro_groups = macro_group_regex.findall(m)
# Remove whitespaces and curly braces from around keycodes for macro_group in macro_groups:
keycodes = list(map(lambda s: s.strip(' {}'), keycodes)) # Remove whitespaces and curly braces from around group
# Remove the KC prefix macro_group = macro_group.strip(' {}')
keycodes = list(map(lambda s: s.replace('KC_', ''), keycodes))
macro_data.append({"action": "tap", "keycodes": keycodes}) macro_action = 'tap'
macro_keycodes = []
if macro_group[0] == '+':
macro_action = 'down'
macro_keycodes.append(macro_group[1:])
elif macro_group[0] == '-':
macro_action = 'up'
macro_keycodes.append(macro_group[1:])
else:
macro_keycodes.extend(macro_group.split(',') if ',' in macro_group else [macro_group])
# Remove the KC prefixes
macro_keycodes = list(map(lambda s: s.replace('KC_', ''), macro_keycodes))
macro_data.append({"action": macro_action, "keycodes": macro_keycodes})
else: else:
# Found text # Found text
macro_data.append(m) macro_data.append(m)
@ -54,13 +70,13 @@ def _convert_macros(via_macros):
def _fix_macro_keys(keymap_data): def _fix_macro_keys(keymap_data):
macro_no = re.compile(r'MACRO0?([0-9]{1,2})') macro_no = re.compile(r'MACRO0?\(([0-9]{1,2})\)')
for i in range(0, len(keymap_data)): for i in range(0, len(keymap_data)):
for j in range(0, len(keymap_data[i])): for j in range(0, len(keymap_data[i])):
kc = keymap_data[i][j] kc = keymap_data[i][j]
m = macro_no.match(kc) m = macro_no.match(kc)
if m: if m:
keymap_data[i][j] = f'MACRO_{m.group(1)}' keymap_data[i][j] = f'MC_{m.group(1)}'
return keymap_data return keymap_data