This commit is contained in:
LiuLiuQMK 2024-11-14 14:19:09 +08:00
parent 4757ef281f
commit 54b4dc4ed1
24 changed files with 5359 additions and 0 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
}
}