diff --git a/keyboards/nuphy/air60_v2/ansi/info.json b/keyboards/nuphy/air60_v2/ansi/info.json
index 6758c44132f1..aaec2890abae 100644
--- a/keyboards/nuphy/air60_v2/ansi/info.json
+++ b/keyboards/nuphy/air60_v2/ansi/info.json
@@ -4,7 +4,7 @@
"usb":{
"vid": "0x19F5",
"pid": "0x3255",
- "device_version": "0.0.1",
+ "device_version": "1.0.2",
"no_startup_check": true
},
"features": {
diff --git a/keyboards/nuphy/air60_v2/ansi/rf.c b/keyboards/nuphy/air60_v2/ansi/rf.c
index 3eb1da89a0e7..b8e4b0e8ae9b 100644
--- a/keyboards/nuphy/air60_v2/ansi/rf.c
+++ b/keyboards/nuphy/air60_v2/ansi/rf.c
@@ -48,8 +48,8 @@ extern host_driver_t *m_host_driver;
extern uint8_t host_mode;
extern uint8_t rf_blink_cnt;
extern uint16_t rf_link_show_time;
-extern uint32_t rf_linking_time;
-extern uint32_t no_act_time;
+extern uint16_t rf_linking_time;
+extern uint16_t no_act_time;
extern bool f_send_channel;
extern bool f_dial_sw_init_ok;
diff --git a/keyboards/nuphy/air75_v2/ansi/ansi.c b/keyboards/nuphy/air75_v2/ansi/ansi.c
index 7fb9268e0222..9da78bf03e98 100644
--- a/keyboards/nuphy/air75_v2/ansi/ansi.c
+++ b/keyboards/nuphy/air75_v2/ansi/ansi.c
@@ -17,6 +17,7 @@ along with this program. If not, see .
#include "ansi.h"
#include "usb_main.h"
+#include "rf_driver.h"
user_config_t user_config;
DEV_INFO_STRUCT dev_info = {
@@ -25,6 +26,7 @@ DEV_INFO_STRUCT dev_info = {
.rf_state = RF_IDLE,
};
+bool f_uart_ack = 0;
bool f_bat_hold = 0;
bool f_sys_show = 0;
bool f_sleep_show = 0;
@@ -34,6 +36,13 @@ bool f_rf_sw_press = 0;
bool f_dev_reset_press = 0;
bool f_rgb_test_press = 0;
bool f_bat_num_show = 0;
+bool f_rf_hand_ok = 0;
+bool f_goto_sleep = 0;
+bool f_rf_read_data_ok = 0;
+bool f_rf_sts_sysc_ok = 0;
+bool f_rf_new_adv_ok = 0;
+bool f_rf_reset = 0;
+bool f_wakeup_prepare = 0;
uint16_t rf_linking_time = 0;
uint16_t rf_link_show_time = 0;
@@ -48,6 +57,7 @@ host_driver_t *m_host_driver = 0;
extern bool f_rf_new_adv_ok;
extern report_keyboard_t *keyboard_report;
+extern report_nkro_t *nkro_report;
extern uint8_t bitkb_report_buf[32];
extern uint8_t bytekb_report_buf[8];
extern uint8_t side_mode;
@@ -197,8 +207,8 @@ void break_all_key(void) {
clear_keyboard();
keymap_config.nkro = 1;
- memset(keyboard_report, 0, sizeof(report_keyboard_t));
- host_keyboard_send(keyboard_report);
+ memset(nkro_report, 0, sizeof(report_nkro_t));
+ host_nkro_send(nkro_report);
wait_ms(10);
keymap_config.nkro = 0;
@@ -241,7 +251,7 @@ void switch_dev_link(uint8_t mode) {
} else {
host_mode = HOST_RF_TYPE;
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
}
@@ -314,7 +324,7 @@ void dial_sw_scan(void) {
f_first = false;
if (dev_info.link_mode != LINK_USB) {
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
}
}
diff --git a/keyboards/nuphy/air75_v2/ansi/ansi.h b/keyboards/nuphy/air75_v2/ansi/ansi.h
index 78e33d9ec0a6..69244a0703b6 100644
--- a/keyboards/nuphy/air75_v2/ansi/ansi.h
+++ b/keyboards/nuphy/air75_v2/ansi/ansi.h
@@ -133,7 +133,7 @@ typedef enum {
#define RF_LONG_PRESS_DELAY 30
#define DEV_RESET_PRESS_DELAY 30
-#define RGB_TEST_PRESS_DELAY 30
+#define RGB_TEST_PRESS_DELAY 30
typedef struct
{
diff --git a/keyboards/nuphy/air75_v2/ansi/config.h b/keyboards/nuphy/air75_v2/ansi/config.h
index ec04d10c5e72..6feef813bd45 100644
--- a/keyboards/nuphy/air75_v2/ansi/config.h
+++ b/keyboards/nuphy/air75_v2/ansi/config.h
@@ -41,4 +41,4 @@ along with this program. If not, see .
#define EECONFIG_USER_DATA_SIZE 8
#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT
-#define RGB_DISABLE_WHEN_USB_SUSPENDED
+#define RGB_MATRIX_SLEEP
diff --git a/keyboards/nuphy/air75_v2/ansi/info.json b/keyboards/nuphy/air75_v2/ansi/info.json
index 3f0494f8f4ca..e67efc70ae30 100644
--- a/keyboards/nuphy/air75_v2/ansi/info.json
+++ b/keyboards/nuphy/air75_v2/ansi/info.json
@@ -4,7 +4,7 @@
"usb":{
"vid": "0x19F5",
"pid": "0x3246",
- "device_version": "0.0.2",
+ "device_version": "1.0.3",
"no_startup_check": true
},
"features": {
diff --git a/keyboards/nuphy/air75_v2/ansi/rf.c b/keyboards/nuphy/air75_v2/ansi/rf.c
index 0be290db6239..210b1979b99c 100644
--- a/keyboards/nuphy/air75_v2/ansi/rf.c
+++ b/keyboards/nuphy/air75_v2/ansi/rf.c
@@ -16,7 +16,8 @@ along with this program. If not, see .
*/
#include "ansi.h"
-#include "uart.h" // qmk uart.h
+#include "uart.h" // qmk uart.h
+#include "rf_driver.h"
USART_MGR_STRUCT Usart_Mgr;
#define RX_SBYTE Usart_Mgr.RXDBuf[0]
@@ -25,20 +26,18 @@ USART_MGR_STRUCT Usart_Mgr;
#define RX_LEN Usart_Mgr.RXDBuf[3]
#define RX_DAT Usart_Mgr.RXDBuf[4]
-bool f_uart_ack = 0;
-bool f_rf_read_data_ok = 0;
-bool f_rf_sts_sysc_ok = 0;
-bool f_rf_new_adv_ok = 0;
-bool f_rf_reset = 0;
-bool f_rf_hand_ok = 0;
-bool f_goto_sleep = 0;
-bool f_wakeup_prepare = 0;
+extern bool f_uart_ack;
+extern bool f_rf_read_data_ok;
+extern bool f_rf_sts_sysc_ok;
+extern bool f_rf_new_adv_ok;
+extern bool f_rf_reset;
+extern bool f_rf_hand_ok;
+extern bool f_goto_sleep;
uint8_t uart_bit_report_buf[32] = {0};
uint8_t func_tab[32] = {0};
uint8_t bitkb_report_buf[32] = {0};
uint8_t bytekb_report_buf[8] = {0};
-uint8_t mouse_report_buf[5] = {0};
uint16_t conkb_report = 0;
uint16_t syskb_report = 0;
uint8_t sync_lost = 0;
@@ -63,42 +62,10 @@ void uart_receive_pro(void);
void break_all_key(void);
uint16_t host_last_consumer_usage(void);
-/**
- * @brief Uart send consumer keys report.
- * @note Call in host.c
- */
-void uart_send_consumer_report(void) {
- no_act_time = 0;
- conkb_report = host_last_consumer_usage();
- uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&conkb_report), 2);
-}
-
-/**
- * @brief Uart send mouse keys report.
- * @note Call in host.c
- */
-void uart_send_mouse_report(void) {
- report_mouse_t mouse_report = mousekey_get_report();
-
- no_act_time = 0;
- memcpy(mouse_report_buf, &mouse_report.buttons, 5);
- uart_send_report(CMD_RPT_MS, mouse_report_buf, 5);
-}
-
-/**
- * @brief Uart send system keys report.
- * @note Call in host.c
- */
-void uart_send_system_report(void) {
- no_act_time = 0;
- syskb_report = host_last_system_usage();
- uart_send_report(CMD_RPT_SYS, (uint8_t *)(&syskb_report), 2);
-}
-
/**
* @brief Uart auto nkey send
*/
-bool f_f_bit_kb_act = 0;
+bool f_bit_kb_act = 0;
static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
{
uint8_t i, j, byte_index;
@@ -124,8 +91,6 @@ static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report
break;
}
}
-
-
if (byte_index >= 8) {
uart_bit_report_buf[i] |= offset_mask;
f_bit_send = 1;
@@ -136,7 +101,6 @@ static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report
bytekb_report_buf[byte_index] = 0;
f_byte_send = 1;
break;
- ;
}
}
if (byte_index >= 8) {
@@ -151,7 +115,7 @@ static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report
}
if (f_bit_send) {
- f_f_bit_kb_act = 1;
+ f_bit_kb_act = 1;
uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
}
@@ -163,7 +127,6 @@ static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report
/**
* @brief Uart send keys report.
- * @note Call in host.c
*/
void uart_send_report_func(void)
{
@@ -172,34 +135,69 @@ void uart_send_report_func(void)
if (dev_info.link_mode == LINK_USB) return;
keyboard_protocol = 1;
- if(keymap_config.nkro)
- keyboard_report->nkro.mods = get_mods() | get_weak_mods();
-
- if ((dev_info.sys_sw_state == SYS_SW_MAC) && (memcmp(bytekb_report_buf, keyboard_report->raw, 8))) {
- no_act_time = 0;
- keyboard_report->raw[1] = 0;
- memcpy(bytekb_report_buf, keyboard_report->raw, 8);
- uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
- }
- else if ((dev_info.sys_sw_state == SYS_SW_WIN) && (memcmp(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1))) {
- no_act_time = 0;
- uart_auto_nkey_send(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- memcpy(&bitkb_report_buf[0], &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- }
- else if (timer_elapsed32(interval_timer) > 100) {
+ if (timer_elapsed32(interval_timer) > 50) {
interval_timer = timer_read32();
- if (no_act_time <= 200) {
+ if (no_act_time <= 2000) {
uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
+ wait_us(200);
- if(f_f_bit_kb_act)
+ if(f_bit_kb_act)
uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
}
else {
- f_f_bit_kb_act = 0;
+ f_bit_kb_act = 0;
}
}
}
+/**
+ * @brief Uart send consumer keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_consumer_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&report->usage), 2);
+}
+
+/**
+ * @brief Uart send mouse keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_mouse_report(report_mouse_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_MS, &report->buttons, 5);
+}
+
+/**
+ * @brief Uart send system keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_system_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_SYS, (uint8_t *)(&report->usage), 2);
+}
+
+/**
+ * @brief Uart send byte keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_keyboard(report_keyboard_t *report) {
+ no_act_time = 0;
+ report->reserved = 0;
+ uart_send_report(CMD_RPT_BYTE_KB, &report->mods, 8);
+ memcpy(bytekb_report_buf, &report->mods, 8);
+}
+
+/**
+ * @brief Uart send bit keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_nkro(report_nkro_t *report) {
+ no_act_time = 0;
+ uart_auto_nkey_send(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS + 1);
+ memcpy(&bitkb_report_buf[0], &nkro_report->mods, NKRO_REPORT_BITS + 1);
+}
+
/**
* @brief Parsing the data received from the RF module.
*/
@@ -396,6 +394,35 @@ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms) {
break;
}
+ case CMD_SET_24G_NAME: {
+ Usart_Mgr.TXDBuf[3] = 44; // uart data len
+ Usart_Mgr.TXDBuf[4] = 44; // name valid len
+ Usart_Mgr.TXDBuf[5] = 3; // 固定
+ Usart_Mgr.TXDBuf[6] = 'N';
+ Usart_Mgr.TXDBuf[8] = 'u';
+ Usart_Mgr.TXDBuf[10] = 'P';
+ Usart_Mgr.TXDBuf[12] = 'h';
+ Usart_Mgr.TXDBuf[14] = 'y';
+ Usart_Mgr.TXDBuf[16] = ' ';
+ Usart_Mgr.TXDBuf[18] = 'A';
+ Usart_Mgr.TXDBuf[20] = 'i';
+ Usart_Mgr.TXDBuf[22] = 'r';
+ Usart_Mgr.TXDBuf[24] = '7';
+ Usart_Mgr.TXDBuf[26] = '5';
+ Usart_Mgr.TXDBuf[28] = ' ';
+ Usart_Mgr.TXDBuf[30] = 'V';
+ Usart_Mgr.TXDBuf[32] = '2';
+ Usart_Mgr.TXDBuf[34] = ' ';
+ Usart_Mgr.TXDBuf[36] = 'D';
+ Usart_Mgr.TXDBuf[38] = 'o';
+ Usart_Mgr.TXDBuf[40] = 'n';
+ Usart_Mgr.TXDBuf[42] = 'g';
+ Usart_Mgr.TXDBuf[44] = 'l';
+ Usart_Mgr.TXDBuf[46] = 'e';
+ Usart_Mgr.TXDBuf[48] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]); // sum
+ break;
+ }
+
case CMD_READ_DATA: {
Usart_Mgr.TXDBuf[3] = 2;
Usart_Mgr.TXDBuf[4] = 0x00;
@@ -467,7 +494,7 @@ void dev_sts_sync(void) {
if (host_mode != HOST_RF_TYPE) {
host_mode = HOST_RF_TYPE;
break_all_key();
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
if (dev_info.rf_state != RF_CONNECT) {
@@ -487,6 +514,10 @@ void dev_sts_sync(void) {
if (link_state_temp != RF_CONNECT) {
link_state_temp = RF_CONNECT;
rf_link_show_time = 0;
+ if (dev_info.link_mode == LINK_RF_24) {
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 30);
+ }
+
}
}
}
@@ -643,4 +674,6 @@ void rf_device_init(void) {
}
uart_send_cmd(CMD_SET_NAME, 10, 20);
+
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 20);
}
diff --git a/keyboards/nuphy/air75_v2/ansi/rf_driver.c b/keyboards/nuphy/air75_v2/ansi/rf_driver.c
new file mode 100644
index 000000000000..1c0876c00349
--- /dev/null
+++ b/keyboards/nuphy/air75_v2/ansi/rf_driver.c
@@ -0,0 +1,65 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "host_driver.h"
+#include "rf_driver.h"
+#include "host.h"
+#include "ansi.h"
+
+/* Variable declaration */
+extern DEV_INFO_STRUCT dev_info;
+
+/* Host driver */
+static uint8_t rf_keyboard_leds(void);
+static void rf_send_keyboard(report_keyboard_t *report);
+static void rf_send_nkro(report_nkro_t *report);
+static void rf_send_mouse(report_mouse_t *report);
+static void rf_send_extra(report_extra_t *report);
+host_driver_t rf_host_driver = {rf_keyboard_leds, rf_send_keyboard, rf_send_nkro, rf_send_mouse, rf_send_extra};
+
+/* defined in rf.c */
+extern void uart_send_report_keyboard(report_keyboard_t *report);
+extern void uart_send_report_nkro(report_nkro_t *report);
+extern void uart_send_mouse_report(report_mouse_t *report);
+extern void uart_send_consumer_report(report_extra_t *report);
+extern void uart_send_system_report(report_extra_t *report);
+
+static uint8_t rf_keyboard_leds(void) {
+ return dev_info.rf_led;
+}
+
+static void rf_send_keyboard(report_keyboard_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_keyboard(report);
+}
+
+static void rf_send_nkro(report_nkro_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_nkro(report);
+}
+
+static void rf_send_mouse(report_mouse_t *report) {
+ uart_send_mouse_report(report);
+}
+
+static void rf_send_extra(report_extra_t *report) {
+ if (report->report_id == REPORT_ID_CONSUMER) {
+ uart_send_consumer_report(report);
+ } else if (report->report_id == REPORT_ID_SYSTEM) {
+ uart_send_system_report(report);
+ }
+}
diff --git a/keyboards/nuphy/air75_v2/ansi/rf_driver.h b/keyboards/nuphy/air75_v2/ansi/rf_driver.h
new file mode 100644
index 000000000000..ad0cf3cb384f
--- /dev/null
+++ b/keyboards/nuphy/air75_v2/ansi/rf_driver.h
@@ -0,0 +1,20 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+extern host_driver_t rf_host_driver;
diff --git a/keyboards/nuphy/air75_v2/ansi/rules.mk b/keyboards/nuphy/air75_v2/ansi/rules.mk
index c8152f44e742..7ef937ac5f14 100644
--- a/keyboards/nuphy/air75_v2/ansi/rules.mk
+++ b/keyboards/nuphy/air75_v2/ansi/rules.mk
@@ -2,4 +2,6 @@ SRC += side.c
SRC += rf.c
SRC += sleep.c
SRC += side_driver.c
-QUANTUM_LIB_SRC += uart.c
+SRC += rf_driver.c
+UART_DRIVER_REQUIRED = yes
+
diff --git a/keyboards/nuphy/air75_v2/ansi/side.c b/keyboards/nuphy/air75_v2/ansi/side.c
index 022158f3d474..5b8a3e16d0f7 100644
--- a/keyboards/nuphy/air75_v2/ansi/side.c
+++ b/keyboards/nuphy/air75_v2/ansi/side.c
@@ -47,7 +47,7 @@ uint8_t side_play_point = 0;
uint8_t side_play_cnt = 0;
uint32_t side_play_timer = 0;
uint8_t r_temp, g_temp, b_temp;
-LED_TYPE side_leds[SIDE_LED_NUM] = {0};
+rgb_led_t side_leds[SIDE_LED_NUM] = {0};
const uint8_t side_speed_table[5][5] = {
[SIDE_WAVE] = {10, 14, 20, 28, 38}, //
@@ -83,7 +83,7 @@ extern bool f_bat_hold;
extern bool f_sys_show;
extern bool f_sleep_show;
-void side_ws2812_setleds(LED_TYPE *ledarray, uint16_t leds);
+void side_ws2812_setleds(rgb_led_t *ledarray, uint16_t leds);
void rgb_matrix_update_pwm_buffers(void);
/**
diff --git a/keyboards/nuphy/air75_v2/ansi/side_driver.c b/keyboards/nuphy/air75_v2/ansi/side_driver.c
index 7d674f351d59..5f20a33c18d5 100644
--- a/keyboards/nuphy/air75_v2/ansi/side_driver.c
+++ b/keyboards/nuphy/air75_v2/ansi/side_driver.c
@@ -88,7 +88,7 @@ void side_sendByte(uint8_t byte)
}
// Setleds for standard RGB
-void side_ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
+void side_ws2812_setleds(rgb_led_t *ledarray, uint16_t leds)
{
// this code is very time dependent, so we need to disable interrupts
chSysLock();
diff --git a/keyboards/nuphy/air96_v2/ansi/ansi.c b/keyboards/nuphy/air96_v2/ansi/ansi.c
index f7321b1817aa..eaacb0c9fc28 100644
--- a/keyboards/nuphy/air96_v2/ansi/ansi.c
+++ b/keyboards/nuphy/air96_v2/ansi/ansi.c
@@ -17,6 +17,7 @@ along with this program. If not, see .
#include "ansi.h"
#include "usb_main.h"
+#include "rf_driver.h"
#define RF_LONG_PRESS_DELAY 30
@@ -84,6 +85,7 @@ extern uint8_t side_speed;
extern uint8_t side_rgb;
extern uint8_t side_colour;
extern report_keyboard_t *keyboard_report;
+extern report_nkro_t *nkro_report;
extern uint8_t uart_bit_report_buf[32];
extern uint8_t bitkb_report_buf[32];
extern uint8_t bytekb_report_buf[8];
@@ -211,8 +213,8 @@ void m_break_all_key(void)
clear_keyboard();
keymap_config.nkro = 1;
- memset(keyboard_report, 0, sizeof(report_keyboard_t));
- host_keyboard_send(keyboard_report);
+ memset(nkro_report, 0, sizeof(report_nkro_t));
+ host_nkro_send(nkro_report);
wait_ms(10);
keymap_config.nkro = 0;
@@ -255,7 +257,7 @@ static void switch_dev_link(uint8_t mode)
}
else {
host_mode = HOST_RF_TYPE;
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
}
@@ -330,7 +332,7 @@ void dial_sw_scan(void)
f_first = false;
if (dev_info.link_mode != LINK_USB) {
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
}
}
diff --git a/keyboards/nuphy/air96_v2/ansi/ansi.h b/keyboards/nuphy/air96_v2/ansi/ansi.h
index 4c999ad4a129..0f3764891756 100644
--- a/keyboards/nuphy/air96_v2/ansi/ansi.h
+++ b/keyboards/nuphy/air96_v2/ansi/ansi.h
@@ -81,7 +81,7 @@ typedef enum {
#define RF_SNIF 6
#define RF_INVAILD 0XFE
#define RF_ERR_STATE 0XFF
-
+#define UART_HEAD 0x5A
#define CMD_POWER_UP 0XF0
#define CMD_SLEEP 0XF1
diff --git a/keyboards/nuphy/air96_v2/ansi/config.h b/keyboards/nuphy/air96_v2/ansi/config.h
index 9cbc7ad959b2..67eee798ccec 100644
--- a/keyboards/nuphy/air96_v2/ansi/config.h
+++ b/keyboards/nuphy/air96_v2/ansi/config.h
@@ -69,5 +69,5 @@ along with this program. If not, see .
#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT
-
+#define RGB_MATRIX_SLEEP
diff --git a/keyboards/nuphy/air96_v2/ansi/info.json b/keyboards/nuphy/air96_v2/ansi/info.json
index 5f302f8aeb9d..79ee48edd2ef 100644
--- a/keyboards/nuphy/air96_v2/ansi/info.json
+++ b/keyboards/nuphy/air96_v2/ansi/info.json
@@ -3,8 +3,8 @@
"manufacturer": "NuPhy",
"usb":{
"vid": "0x19F5",
- "pid": "0x3265",
- "device_version": "0.0.1",
+ "pid": "0x3266",
+ "device_version": "1.0.2",
"no_startup_check": true
},
"features": {
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/via/NuPhy Air96 V2 via3.json b/keyboards/nuphy/air96_v2/ansi/keymaps/via/NuPhy Air96 V2 via3.json
index a751311acfd5..2a7e31de21bb 100644
--- a/keyboards/nuphy/air96_v2/ansi/keymaps/via/NuPhy Air96 V2 via3.json
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/via/NuPhy Air96 V2 via3.json
@@ -1,7 +1,7 @@
{
"name": "NuPhy Air96 V2",
"vendorId": "0x19F5",
- "productId": "0x3265",
+ "productId": "0x3266",
"matrix": {
"rows": 6,
"cols": 21
diff --git a/keyboards/nuphy/air96_v2/ansi/rf.c b/keyboards/nuphy/air96_v2/ansi/rf.c
index 915c749d2e12..fae08091ad9e 100644
--- a/keyboards/nuphy/air96_v2/ansi/rf.c
+++ b/keyboards/nuphy/air96_v2/ansi/rf.c
@@ -1,178 +1,57 @@
-/*
-Copyright 2023 @ Nuphy
-
-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 .
-*/
-
+// Copyright 2023 Persama (@Persama)
+// SPDX-License-Identifier: GPL-2.0-or-later
#include "ansi.h"
-#include "uart.h"
+#include "uart.h" // qmk uart.h
+#include "rf_driver.h"
USART_MGR_STRUCT Usart_Mgr;
-#define RX_SBYTE Usart_Mgr.RXDBuf[0]
-#define RX_CMD Usart_Mgr.RXDBuf[1]
-#define RX_ACK Usart_Mgr.RXDBuf[2]
-#define RX_LEN Usart_Mgr.RXDBuf[3]
-#define RX_DAT Usart_Mgr.RXDBuf[4]
-#define UART_HEAD 0x5A
-
-bool f_bit_kb_act = 0;
-
-uint8_t func_tab[32] = {0};
-uint8_t uart_bit_report_buf[32] = {0};
-uint8_t bitkb_report_buf[32] = {0};
-uint8_t bytekb_report_buf[8] = {0};
-uint8_t mouse_report_buf[5] = {0};
-uint8_t sync_lost = 0;
-uint16_t conkb_report = 0;
-uint16_t syskb_report = 0;
-uint8_t disconnect_delay = 0;
+#define RX_SBYTE Usart_Mgr.RXDBuf[0]
+#define RX_CMD Usart_Mgr.RXDBuf[1]
+#define RX_ACK Usart_Mgr.RXDBuf[2]
+#define RX_LEN Usart_Mgr.RXDBuf[3]
+#define RX_DAT Usart_Mgr.RXDBuf[4]
+
+extern bool f_uart_ack;
+extern bool f_rf_read_data_ok;
+extern bool f_rf_sts_sysc_ok;
+extern bool f_rf_new_adv_ok;
+extern bool f_rf_reset;
+extern bool f_rf_hand_ok;
+extern bool f_goto_sleep;
+
+uint8_t uart_bit_report_buf[32] = {0};
+uint8_t func_tab[32] = {0};
+uint8_t bitkb_report_buf[32] = {0};
+uint8_t bytekb_report_buf[8] = {0};
+uint16_t conkb_report = 0;
+uint16_t syskb_report = 0;
+uint8_t sync_lost = 0;
+uint8_t disconnect_delay = 0;
extern DEV_INFO_STRUCT dev_info;
-extern host_driver_t *m_host_driver;
-extern uint8_t host_mode;
-extern uint8_t rf_blink_cnt;
-extern uint16_t rf_link_show_time;
-extern uint16_t rf_linking_time;
-extern uint16_t no_act_time;
-extern bool f_uart_ack;
-extern bool f_rf_read_data_ok;
-extern bool f_rf_sts_sysc_ok;
-extern bool f_rf_new_adv_ok;
-extern bool f_rf_reset;
-extern bool f_send_channel;
-extern bool f_rf_hand_ok;
-extern bool f_dial_sw_init_ok;
-extern bool f_goto_sleep;
-extern bool f_wakeup_prepare;
-
-void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
-void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length);
-uint8_t get_checksum(uint8_t *buf, uint8_t len);
-void uart_receive_pro(void);
-void m_break_all_key(void);
-uint16_t host_last_consumer_usage(void);
-report_mouse_t mousekey_get_report(void);
-
-
-
-
-
-/**
- * @brief Parsing the data received from the RF module.
- */
-void RF_Protocol_Receive(void)
-{
- uint8_t i, check_sum = 0;
-
- if (Usart_Mgr.RXDState == RX_Done) {
- f_uart_ack = 1;
- sync_lost = 0;
-
- if (Usart_Mgr.RXDLen > 4) {
- for (i = 0; i < RX_LEN; i++)
- check_sum += Usart_Mgr.RXDBuf[4 + i];
-
- if (check_sum != Usart_Mgr.RXDBuf[4 + i]) {
- Usart_Mgr.RXDState = RX_SUM_ERR;
- return;
- }
- } else if (Usart_Mgr.RXDLen == 3) {
- if (Usart_Mgr.RXDBuf[2] == 0xA0)
- {
- f_uart_ack = 1;
- }
- }
-
- switch (RX_CMD) {
-
- case CMD_HAND: {
- f_rf_hand_ok = 1;
- break;
- }
-
- case CMD_24G_SUSPEND: {
- f_goto_sleep = 1;
- break;
- }
-
- case CMD_NEW_ADV: {
- f_rf_new_adv_ok = 1;
- break;
- }
-
- case CMD_RF_STS_SYSC: {
- static uint8_t error_cnt = 0;
- if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) {
- error_cnt = 0;
- dev_info.rf_state = Usart_Mgr.RXDBuf[5];
-
- if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) {
- dev_info.rf_led = Usart_Mgr.RXDBuf[6];
- }
-
- dev_info.rf_charge = Usart_Mgr.RXDBuf[7];
-
- if (Usart_Mgr.RXDBuf[8] <= 100)
- dev_info.rf_baterry = Usart_Mgr.RXDBuf[8];
- if (dev_info.rf_charge & 0x01) dev_info.rf_baterry = 100;
- }
- else {
- if (dev_info.rf_state != RF_INVAILD) {
- if (error_cnt >= 5) {
- error_cnt = 0;
- f_send_channel = 1;
- } else {
- error_cnt++;
- }
- }
- }
-
- f_rf_sts_sysc_ok = 1;
- break;
- }
-
- case CMD_READ_DATA: {
- memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32);
-
- if (func_tab[4] <= LINK_USB) {
- dev_info.link_mode = func_tab[4];
- }
-
- if (func_tab[5] < LINK_USB) {
- dev_info.rf_channel = func_tab[5];
- }
+extern host_driver_t *m_host_driver;
+extern uint8_t host_mode;
+extern uint8_t rf_blink_cnt;
+extern uint16_t rf_link_show_time;
+extern uint16_t rf_linking_time;
+extern uint16_t no_act_time;
+extern bool f_send_channel;
+extern bool f_dial_sw_init_ok;
- if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) {
- dev_info.ble_channel = func_tab[6];
- }
-
- f_rf_read_data_ok = 1;
- break;
- }
-
- }
- Usart_Mgr.RXDLen = 0;
- Usart_Mgr.RXDState = RX_Idle;
- Usart_Mgr.RXDOverTime = 0;
-
- }
-}
+report_mouse_t mousekey_get_report(void);
+void uart_init(uint32_t baud); // qmk uart.c
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length);
+uint8_t get_checksum(uint8_t *buf, uint8_t len);
+void uart_receive_pro(void);
+void m_break_all_key(void);
+uint16_t host_last_consumer_usage(void);
/**
* @brief Uart auto nkey send
*/
-void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
+bool f_bit_kb_act = 0;
+static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
{
uint8_t i, j, byte_index;
uint8_t change_mask, offset_mask;
@@ -197,18 +76,16 @@ void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8
break;
}
}
-
if (byte_index >= 8) {
uart_bit_report_buf[i] |= offset_mask;
f_bit_send = 1;
}
- } else {
+ } else {
for (byte_index = 2; byte_index < 8; byte_index++) {
if (bytekb_report_buf[byte_index] == key_code) {
bytekb_report_buf[byte_index] = 0;
f_byte_send = 1;
break;
- ;
}
}
if (byte_index >= 8) {
@@ -232,9 +109,9 @@ void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8
}
}
+
/**
* @brief Uart send keys report.
- * @note Call in host.c
*/
void uart_send_report_func(void)
{
@@ -243,68 +120,166 @@ void uart_send_report_func(void)
if (dev_info.link_mode == LINK_USB) return;
keyboard_protocol = 1;
- if(keymap_config.nkro){
- keyboard_report->nkro.mods = get_mods() | get_weak_mods();
- }
-
- if ((dev_info.sys_sw_state == SYS_SW_MAC) && (memcmp(bytekb_report_buf, keyboard_report->raw, 8))) {
- no_act_time = 0;
- keyboard_report->raw[1] = 0;
- memcpy(bytekb_report_buf, keyboard_report->raw, 8);
- uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
- }
- else if ((dev_info.sys_sw_state == SYS_SW_WIN) && (memcmp(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1))) {
- no_act_time = 0;
- uart_auto_nkey_send(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- memcpy(&bitkb_report_buf[0], &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- }
- else if (timer_elapsed32(interval_timer) > 100) {
+ if (timer_elapsed32(interval_timer) > 50) {
interval_timer = timer_read32();
- if (no_act_time <= 200) {
+ if (no_act_time <= 2000) {
uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
+ wait_us(200);
+
if(f_bit_kb_act)
uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
}
else {
- f_bit_kb_act = 0;
+ f_bit_kb_act = 0;
}
}
}
/**
* @brief Uart send consumer keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_consumer_report(void)
-{
- no_act_time = 0;
- conkb_report = host_last_consumer_usage();
- uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&conkb_report), 2);
+void uart_send_consumer_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&report->usage), 2);
}
/**
* @brief Uart send mouse keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_mouse_report(void)
-{
- report_mouse_t mouse_report = mousekey_get_report();
-
+void uart_send_mouse_report(report_mouse_t *report) {
no_act_time = 0;
- memcpy(mouse_report_buf, &mouse_report.buttons, 5);
- uart_send_report(CMD_RPT_MS, mouse_report_buf, 5);
+ uart_send_report(CMD_RPT_MS, &report->buttons, 5);
}
+
/**
* @brief Uart send system keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_system_report(void)
-{
- no_act_time = 0;
- syskb_report = host_last_system_usage();
- uart_send_report(CMD_RPT_SYS, (uint8_t *)(&syskb_report), 2);
+void uart_send_system_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_SYS, (uint8_t *)(&report->usage), 2);
}
+/**
+ * @brief Uart send byte keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_keyboard(report_keyboard_t *report) {
+ no_act_time = 0;
+ report->reserved = 0;
+ uart_send_report(CMD_RPT_BYTE_KB, &report->mods, 8);
+ memcpy(bytekb_report_buf, &report->mods, 8);
+}
+
+/**
+ * @brief Uart send bit keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_nkro(report_nkro_t *report) {
+ no_act_time = 0;
+ uart_auto_nkey_send(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS + 1);
+ memcpy(&bitkb_report_buf[0], &nkro_report->mods, NKRO_REPORT_BITS + 1);
+}
+
+/**
+ * @brief Parsing the data received from the RF module.
+ */
+void RF_Protocol_Receive(void) {
+ uint8_t i, check_sum = 0;
+
+ if (Usart_Mgr.RXDState == RX_Done) {
+ f_uart_ack = 1;
+ sync_lost = 0;
+
+ if (Usart_Mgr.RXDLen > 4) {
+ for (i = 0; i < RX_LEN; i++)
+ check_sum += Usart_Mgr.RXDBuf[4 + i];
+
+ if (check_sum != Usart_Mgr.RXDBuf[4 + i]) {
+ Usart_Mgr.RXDState = RX_SUM_ERR;
+ return;
+ }
+ } else if (Usart_Mgr.RXDLen == 3) {
+ if (Usart_Mgr.RXDBuf[2] == 0xA0) {
+ f_uart_ack = 1;
+ }
+ }
+
+ switch (RX_CMD) {
+ case CMD_HAND: {
+ f_rf_hand_ok = 1;
+ break;
+ }
+
+ case CMD_24G_SUSPEND: {
+ f_goto_sleep = 1;
+ break;
+ }
+
+ case CMD_NEW_ADV: {
+ f_rf_new_adv_ok = 1;
+ break;
+ }
+
+ case CMD_RF_STS_SYSC: {
+ static uint8_t error_cnt = 0;
+
+ if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) {
+ error_cnt = 0;
+
+ dev_info.rf_state = Usart_Mgr.RXDBuf[5];
+
+ if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) {
+ dev_info.rf_led = Usart_Mgr.RXDBuf[6];
+ }
+
+ dev_info.rf_charge = Usart_Mgr.RXDBuf[7];
+
+ if (Usart_Mgr.RXDBuf[8] <= 100) dev_info.rf_baterry = Usart_Mgr.RXDBuf[8];
+ if (dev_info.rf_charge & 0x01) dev_info.rf_baterry = 100;
+ }
+ else {
+ if (dev_info.rf_state != RF_INVAILD) {
+ if (error_cnt >= 5) {
+ error_cnt = 0;
+ f_send_channel = 1;
+ } else {
+ error_cnt++;
+ }
+ }
+ }
+
+ f_rf_sts_sysc_ok = 1;
+ break;
+ }
+
+ case CMD_READ_DATA: {
+ memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32);
+
+ if (func_tab[4] <= LINK_USB) {
+ dev_info.link_mode = func_tab[4];
+ }
+
+ if (func_tab[5] < LINK_USB) {
+ dev_info.rf_channel = func_tab[5];
+ }
+
+ if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) {
+ dev_info.ble_channel = func_tab[6];
+ }
+
+ f_rf_read_data_ok = 1;
+ break;
+ }
+ }
+
+ Usart_Mgr.RXDLen = 0;
+ Usart_Mgr.RXDState = RX_Idle;
+ Usart_Mgr.RXDOverTime = 0;
+ }
+}
/**
* @brief Uart send cmd.
@@ -312,104 +287,139 @@ void uart_send_system_report(void)
* @param wait_ack: wait time for ack after sending.
* @param delayms: delay before sending.
*/
-uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
-{
- wait_ms(delayms);
+uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms) {
+ wait_ms(delayms);
memset(&Usart_Mgr.TXDBuf[0], 0, UART_MAX_LEN);
Usart_Mgr.TXDBuf[0] = UART_HEAD;
- Usart_Mgr.TXDBuf[1] = cmd;
- Usart_Mgr.TXDBuf[2] = 0x00;
+ Usart_Mgr.TXDBuf[1] = cmd;
+ Usart_Mgr.TXDBuf[2] = 0x00;
switch (cmd) {
case CMD_SLEEP: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_HAND: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_RF_STS_SYSC: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
break;
}
+
case CMD_SET_LINK: {
- dev_info.rf_state = RF_LINKING;
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+ dev_info.rf_state = RF_LINKING;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
- rf_linking_time = 0;
- disconnect_delay = 0xff;
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
break;
}
+
case CMD_NEW_ADV: {
- dev_info.rf_state = RF_PAIRING;
- Usart_Mgr.TXDBuf[3] = 2;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = 1;
- Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1;
-
- rf_linking_time = 0;
- disconnect_delay = 0xff;
- f_rf_new_adv_ok = 0;
+ dev_info.rf_state = RF_PAIRING;
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = 1;
+ Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1;
+
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
+ f_rf_new_adv_ok = 0;
break;
}
+
case CMD_CLR_DEVICE: {
- Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[3] = 1;
Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_SET_CONFIG: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY;
- Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY;
+ Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY;
break;
}
+
case CMD_SET_NAME: {
- Usart_Mgr.TXDBuf[3] = 17;
- Usart_Mgr.TXDBuf[4] = 1;
- Usart_Mgr.TXDBuf[5] = 15;
- Usart_Mgr.TXDBuf[6] = 'N';
- Usart_Mgr.TXDBuf[7] = 'u';
- Usart_Mgr.TXDBuf[8] = 'P';
- Usart_Mgr.TXDBuf[9] = 'h';
- Usart_Mgr.TXDBuf[10] = 'y';
- Usart_Mgr.TXDBuf[11] = ' ';
- Usart_Mgr.TXDBuf[12] = 'A';
- Usart_Mgr.TXDBuf[13] = 'i';
- Usart_Mgr.TXDBuf[14] = 'r';
- Usart_Mgr.TXDBuf[15] = '9';
- Usart_Mgr.TXDBuf[16] = '6';
- Usart_Mgr.TXDBuf[17] = ' ';
- Usart_Mgr.TXDBuf[18] = 'V';
- Usart_Mgr.TXDBuf[19] = '2';
- Usart_Mgr.TXDBuf[20] = '-';
- Usart_Mgr.TXDBuf[21] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]);
+ Usart_Mgr.TXDBuf[3] = 17;
+ Usart_Mgr.TXDBuf[4] = 1;
+ Usart_Mgr.TXDBuf[5] = 15;
+ Usart_Mgr.TXDBuf[6] = 'N';
+ Usart_Mgr.TXDBuf[7] = 'u';
+ Usart_Mgr.TXDBuf[8] = 'P';
+ Usart_Mgr.TXDBuf[9] = 'h';
+ Usart_Mgr.TXDBuf[10] = 'y';
+ Usart_Mgr.TXDBuf[11] = ' ';
+ Usart_Mgr.TXDBuf[12] = 'A';
+ Usart_Mgr.TXDBuf[13] = 'i';
+ Usart_Mgr.TXDBuf[14] = 'r';
+ Usart_Mgr.TXDBuf[15] = '9';
+ Usart_Mgr.TXDBuf[16] = '6';
+ Usart_Mgr.TXDBuf[17] = ' ';
+ Usart_Mgr.TXDBuf[18] = 'V';
+ Usart_Mgr.TXDBuf[19] = '2';
+ Usart_Mgr.TXDBuf[20] = '-';
+ Usart_Mgr.TXDBuf[21] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]);
+ break;
+ }
+
+ case CMD_SET_24G_NAME: {
+ Usart_Mgr.TXDBuf[3] = 44; // uart data len
+ Usart_Mgr.TXDBuf[4] = 44; // name valid len
+ Usart_Mgr.TXDBuf[5] = 3; // 固定
+ Usart_Mgr.TXDBuf[6] = 'N';
+ Usart_Mgr.TXDBuf[8] = 'u';
+ Usart_Mgr.TXDBuf[10] = 'P';
+ Usart_Mgr.TXDBuf[12] = 'h';
+ Usart_Mgr.TXDBuf[14] = 'y';
+ Usart_Mgr.TXDBuf[16] = ' ';
+ Usart_Mgr.TXDBuf[18] = 'A';
+ Usart_Mgr.TXDBuf[20] = 'i';
+ Usart_Mgr.TXDBuf[22] = 'r';
+ Usart_Mgr.TXDBuf[24] = '9';
+ Usart_Mgr.TXDBuf[26] = '6';
+ Usart_Mgr.TXDBuf[28] = ' ';
+ Usart_Mgr.TXDBuf[30] = 'V';
+ Usart_Mgr.TXDBuf[32] = '2';
+ Usart_Mgr.TXDBuf[34] = ' ';
+ Usart_Mgr.TXDBuf[36] = 'D';
+ Usart_Mgr.TXDBuf[38] = 'o';
+ Usart_Mgr.TXDBuf[40] = 'n';
+ Usart_Mgr.TXDBuf[42] = 'g';
+ Usart_Mgr.TXDBuf[44] = 'l';
+ Usart_Mgr.TXDBuf[46] = 'e';
+ Usart_Mgr.TXDBuf[48] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]); // sum
break;
}
case CMD_READ_DATA: {
- Usart_Mgr.TXDBuf[3] = 2;
- Usart_Mgr.TXDBuf[4] = 0x00;
- Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
- Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN;
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = 0x00;
+ Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
+ Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN;
break;
}
case CMD_RF_DFU: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
@@ -433,14 +443,12 @@ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
}
/**
- * RF state sync
- * Update connection status
+ * @brief RF module state sync.
*/
-void dev_sts_sync(void)
-{
- static uint32_t interval_timer = 0;
- static uint8_t link_state_temp = RF_DISCONNECT;
-
+void dev_sts_sync(void) {
+ static uint32_t interval_timer = 0;
+ static uint8_t link_state_temp = RF_DISCONNECT;
+
if (timer_elapsed32(interval_timer) < 200)
return;
else
@@ -448,11 +456,11 @@ void dev_sts_sync(void)
if (f_rf_reset) {
f_rf_reset = 0;
- wait_ms(300);
- writePinLow(NRF_RESET_PIN);
+ wait_ms(100);
+ writePinLow(NRF_RESET_PIN);
+ wait_ms(50);
+ writePinHigh(NRF_RESET_PIN);
wait_ms(50);
- writePinHigh(NRF_RESET_PIN);
- wait_ms(50);
}
else if (f_send_channel) {
f_send_channel = 0;
@@ -460,25 +468,25 @@ void dev_sts_sync(void)
}
if (dev_info.link_mode == LINK_USB) {
- rf_blink_cnt = 0;
if (host_mode != HOST_USB_TYPE) {
host_mode = HOST_USB_TYPE;
host_set_driver(m_host_driver);
m_break_all_key();
}
+ rf_blink_cnt = 0;
}
else {
if (host_mode != HOST_RF_TYPE) {
host_mode = HOST_RF_TYPE;
m_break_all_key();
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
if (dev_info.rf_state != RF_CONNECT) {
if (disconnect_delay >= 10) {
- link_state_temp = dev_info.rf_state;
- rf_blink_cnt = 3;
- rf_link_show_time = 0;
+ rf_blink_cnt = 3;
+ rf_link_show_time = 0;
+ link_state_temp = dev_info.rf_state;
} else {
disconnect_delay++;
}
@@ -486,97 +494,35 @@ void dev_sts_sync(void)
else if (dev_info.rf_state == RF_CONNECT) {
rf_linking_time = 0;
disconnect_delay = 0;
- rf_blink_cnt = 0;
+ rf_blink_cnt = 0;
if (link_state_temp != RF_CONNECT) {
- link_state_temp = RF_CONNECT;
+ link_state_temp = RF_CONNECT;
rf_link_show_time = 0;
+ if (dev_info.link_mode == LINK_RF_24) {
+ // 连接后设置一次2.4G名称
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 30);
+ }
}
}
}
- if (f_wakeup_prepare || f_goto_sleep) return;
- uart_send_cmd(CMD_RF_STS_SYSC, 1, 1);
+ uart_send_cmd(CMD_RF_STS_SYSC, 1, 1);
if (dev_info.link_mode != LINK_USB) {
- if (++sync_lost >= 5)
- {
+ if (++sync_lost >= 5) {
sync_lost = 0;
f_rf_reset = 1;
}
}
}
-
-/**
- * @brief RF uart initial.
- */
-void rf_uart_init(void) {
- /* set uart buad as 460800 */
- uart_init(460800);
-
- /* Enable parity check */
- USART1->CR1 &= ~((uint32_t)USART_CR1_UE);
- USART1->CR1 |= USART_CR1_M0 | USART_CR1_PCE;
- USART1->CR1 |= USART_CR1_UE;
-
- /* set Rx and Tx pin pull up */
- GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);
- GPIOB->PUPDR |= (GPIO_PUPDR_PUPDR6_0 | GPIO_PUPDR_PUPDR7_0);
-}
-
-
-/**
- * @brief RF module initial.
- */
-void rf_device_init(void)
-{
- uint8_t timeout = 0;
- void uart_receive_pro(void);
-
- timeout = 10;
- f_rf_hand_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_HAND, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_hand_ok)
- break;
- }
-
- timeout = 10;
- f_rf_read_data_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_READ_DATA, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_read_data_ok)
- break;
- }
-
- timeout = 10;
- f_rf_sts_sysc_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_RF_STS_SYSC, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_sts_sysc_ok)
- break;
- }
-
- uart_send_cmd(CMD_SET_NAME, 10, 20);
-}
-
/**
* @brief Uart send bytes.
* @param Buffer data buf
* @param Length data lenght
*/
-void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length)
-{
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length) {
writePinLow(NRF_WAKEUP_PIN);
wait_us(50);
@@ -591,8 +537,7 @@ void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length)
* @param buf data buf
* @param len data lenght
*/
-uint8_t get_checksum(uint8_t *buf, uint8_t len)
-{
+uint8_t get_checksum(uint8_t *buf, uint8_t len) {
uint8_t i;
uint8_t checksum = 0;
@@ -610,16 +555,15 @@ uint8_t get_checksum(uint8_t *buf, uint8_t len)
* @param report_buf report_buf
* @param report_size report_size
*/
-void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size)
-{
- if (f_dial_sw_init_ok == 0) return;
- if (dev_info.link_mode == LINK_USB) return;
- if (dev_info.rf_state != RF_CONNECT) return;
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size) {
+ if (f_dial_sw_init_ok == 0) return;
+ if (dev_info.link_mode == LINK_USB) return;
+ if (dev_info.rf_state != RF_CONNECT) return;
- Usart_Mgr.TXDBuf[0] = UART_HEAD;
- Usart_Mgr.TXDBuf[1] = report_type;
- Usart_Mgr.TXDBuf[2] = 0x01;
- Usart_Mgr.TXDBuf[3] = report_size;
+ Usart_Mgr.TXDBuf[0] = UART_HEAD;
+ Usart_Mgr.TXDBuf[1] = report_type;
+ Usart_Mgr.TXDBuf[2] = 0x01;
+ Usart_Mgr.TXDBuf[3] = report_size;
memcpy(&Usart_Mgr.TXDBuf[4], report_buf, report_size);
Usart_Mgr.TXDBuf[4 + report_size] = get_checksum(&Usart_Mgr.TXDBuf[4], report_size);
@@ -632,8 +576,7 @@ void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_s
/**
* @brief Uart receives data and processes it after completion,.
*/
-void uart_receive_pro(void)
-{
+void uart_receive_pro(void) {
static bool rcv_start = false;
// Receiving serial data from RF module
@@ -660,3 +603,62 @@ void uart_receive_pro(void)
Usart_Mgr.RXDLen = 0;
}
}
+
+/**
+ * @brief RF uart initial.
+ */
+void rf_uart_init(void) {
+ /* set uart buad as 460800 */
+ uart_init(460800);
+
+ /* Enable parity check */
+ USART1->CR1 &= ~((uint32_t)USART_CR1_UE);
+ USART1->CR1 |= USART_CR1_M0 | USART_CR1_PCE;
+ USART1->CR1 |= USART_CR1_UE;
+
+ /* set Rx and Tx pin pull up */
+ GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);
+ GPIOB->PUPDR |= (GPIO_PUPDR_PUPDR6_0 | GPIO_PUPDR_PUPDR7_0);
+}
+
+/**
+ * @brief RF module initial.
+ */
+void rf_device_init(void) {
+ uint8_t timeout = 0;
+ void uart_receive_pro(void);
+
+ timeout = 10;
+ f_rf_hand_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_HAND, 0, 20);
+ wait_ms(5);
+ uart_receive_pro(); // receive data
+ uart_receive_pro(); // parsing data
+ if (f_rf_hand_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_read_data_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_READ_DATA, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_read_data_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_sts_sysc_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_RF_STS_SYSC, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_sts_sysc_ok) break;
+ }
+
+ uart_send_cmd(CMD_SET_NAME, 10, 20);
+
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 20);
+}
diff --git a/keyboards/nuphy/air96_v2/ansi/rf_driver.c b/keyboards/nuphy/air96_v2/ansi/rf_driver.c
new file mode 100644
index 000000000000..1c0876c00349
--- /dev/null
+++ b/keyboards/nuphy/air96_v2/ansi/rf_driver.c
@@ -0,0 +1,65 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "host_driver.h"
+#include "rf_driver.h"
+#include "host.h"
+#include "ansi.h"
+
+/* Variable declaration */
+extern DEV_INFO_STRUCT dev_info;
+
+/* Host driver */
+static uint8_t rf_keyboard_leds(void);
+static void rf_send_keyboard(report_keyboard_t *report);
+static void rf_send_nkro(report_nkro_t *report);
+static void rf_send_mouse(report_mouse_t *report);
+static void rf_send_extra(report_extra_t *report);
+host_driver_t rf_host_driver = {rf_keyboard_leds, rf_send_keyboard, rf_send_nkro, rf_send_mouse, rf_send_extra};
+
+/* defined in rf.c */
+extern void uart_send_report_keyboard(report_keyboard_t *report);
+extern void uart_send_report_nkro(report_nkro_t *report);
+extern void uart_send_mouse_report(report_mouse_t *report);
+extern void uart_send_consumer_report(report_extra_t *report);
+extern void uart_send_system_report(report_extra_t *report);
+
+static uint8_t rf_keyboard_leds(void) {
+ return dev_info.rf_led;
+}
+
+static void rf_send_keyboard(report_keyboard_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_keyboard(report);
+}
+
+static void rf_send_nkro(report_nkro_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_nkro(report);
+}
+
+static void rf_send_mouse(report_mouse_t *report) {
+ uart_send_mouse_report(report);
+}
+
+static void rf_send_extra(report_extra_t *report) {
+ if (report->report_id == REPORT_ID_CONSUMER) {
+ uart_send_consumer_report(report);
+ } else if (report->report_id == REPORT_ID_SYSTEM) {
+ uart_send_system_report(report);
+ }
+}
diff --git a/keyboards/nuphy/air96_v2/ansi/rf_driver.h b/keyboards/nuphy/air96_v2/ansi/rf_driver.h
new file mode 100644
index 000000000000..ad0cf3cb384f
--- /dev/null
+++ b/keyboards/nuphy/air96_v2/ansi/rf_driver.h
@@ -0,0 +1,20 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+extern host_driver_t rf_host_driver;
diff --git a/keyboards/nuphy/air96_v2/ansi/rules.mk b/keyboards/nuphy/air96_v2/ansi/rules.mk
index bcde2dcc0210..ce68d45383af 100644
--- a/keyboards/nuphy/air96_v2/ansi/rules.mk
+++ b/keyboards/nuphy/air96_v2/ansi/rules.mk
@@ -1,4 +1,5 @@
SRC += side.c
SRC += rf.c
SRC += sleep.c
-QUANTUM_LIB_SRC += uart.c
+SRC += rf_driver.c
+UART_DRIVER_REQUIRED = yes
\ No newline at end of file
diff --git a/keyboards/nuphy/air96_v2/ansi/side.c b/keyboards/nuphy/air96_v2/ansi/side.c
index 6e81ed027410..13dcc6565325 100644
--- a/keyboards/nuphy/air96_v2/ansi/side.c
+++ b/keyboards/nuphy/air96_v2/ansi/side.c
@@ -70,7 +70,6 @@ uint8_t r_temp, g_temp, b_temp;
extern DEV_INFO_STRUCT dev_info;
extern bool f_bat_hold;
extern user_config_t user_config;
-extern uint8_t g_pwm_buffer[DRIVER_COUNT][192];
extern uint8_t rf_blink_cnt;
extern uint16_t rf_link_show_time;
@@ -80,12 +79,22 @@ extern uint16_t rf_link_show_time;
* @return true
* @return false
*/
+#define IS31FL3733_PWM_REGISTER_COUNT 192
+#define IS31FL3733_LED_CONTROL_REGISTER_COUNT 24
+typedef struct is31fl3733_driver_t {
+ uint8_t pwm_buffer[IS31FL3733_PWM_REGISTER_COUNT];
+ bool pwm_buffer_dirty;
+ uint8_t led_control_buffer[IS31FL3733_LED_CONTROL_REGISTER_COUNT];
+ bool led_control_buffer_dirty;
+} PACKED is31fl3733_driver_t;
+extern is31fl3733_driver_t driver_buffers[2];
+
bool is_side_rgb_off(void)
{
- is31_led led;
+ is31fl3733_led_t led;
for (int i = SIDE_INDEX; i < SIDE_INDEX + 10; i++) {
memcpy_P(&led, (&g_is31_leds[i]), sizeof(led));
- if ((g_pwm_buffer[led.driver][led.r] != 0) || (g_pwm_buffer[led.driver][led.g] != 0) || (g_pwm_buffer[led.driver][led.b] != 0)) {
+ if ((driver_buffers[led.driver].pwm_buffer[led.r] != 0) || (driver_buffers[led.driver].pwm_buffer[led.g] != 0) || (driver_buffers[led.driver].pwm_buffer[led.b] != 0)) {
return false;
}
}
diff --git a/keyboards/nuphy/gem80/ansi/ansi.c b/keyboards/nuphy/gem80/ansi/ansi.c
index 2ca9a530aaf5..367d1a8d67f7 100644
--- a/keyboards/nuphy/gem80/ansi/ansi.c
+++ b/keyboards/nuphy/gem80/ansi/ansi.c
@@ -4,7 +4,7 @@
#include QMK_KEYBOARD_H
#include "ansi.h"
#include "usb_main.h"
-
+#include "rf_driver.h"
#define RF_LONG_PRESS_DELAY 30
@@ -62,6 +62,7 @@ bool f_rf_send_byte = 0;
bool f_rf_send_consume = 0;
bool f_dial_sw_init_ok = 0;
bool f_rf_sw_press = 0;
+bool f_wakeup_prepare = 0;
bool f_dev_reset_press = 0;
bool f_rgb_test_press = 0;
bool f_win_lock = 0;
@@ -90,7 +91,7 @@ extern void logo_light_speed_contol(uint8_t fast);
extern void logo_light_level_control(uint8_t brighten);
extern void logo_side_colour_control(uint8_t dir);
extern void logo_side_mode_control(uint8_t dir);
-
+extern report_nkro_t *nkro_report;
void flash_data_manage(void)
{
@@ -225,8 +226,8 @@ void m_break_all_key(void)
clear_keyboard();
keymap_config.nkro = 1;
- memset(keyboard_report, 0, sizeof(report_keyboard_t));
- host_keyboard_send(keyboard_report);
+ memset(nkro_report, 0, sizeof(report_nkro_t));
+ host_nkro_send(nkro_report);
wait_ms(10);
keymap_config.nkro = 0;
@@ -272,7 +273,7 @@ static void switch_dev_link(uint8_t mode) {
} else {
host_mode = HOST_RF_TYPE;
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
}
@@ -358,7 +359,7 @@ void dial_sw_scan(void)
#if(WORK_MODE == THREE_MODE)
if (dev_info.link_mode != LINK_USB) {
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
#endif
}
diff --git a/keyboards/nuphy/gem80/ansi/ansi.h b/keyboards/nuphy/gem80/ansi/ansi.h
index 99dde96276c0..15ec41800b5c 100644
--- a/keyboards/nuphy/gem80/ansi/ansi.h
+++ b/keyboards/nuphy/gem80/ansi/ansi.h
@@ -1,5 +1,20 @@
-// Copyright 2023 Persama (@Persama)
-// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
#pragma once
#include "quantum.h"
diff --git a/keyboards/nuphy/gem80/ansi/config.h b/keyboards/nuphy/gem80/ansi/config.h
index 898591e699d9..971affe4218d 100644
--- a/keyboards/nuphy/gem80/ansi/config.h
+++ b/keyboards/nuphy/gem80/ansi/config.h
@@ -30,6 +30,6 @@
#define SD1_RX_PAL_MODE 0
#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CUSTOM_position_mode
#define RGB_DEFAULT_COLOUR 168
-#define RGB_DISABLE_WHEN_USB_SUSPENDED
+#define RGB_MATRIX_SLEEP
diff --git a/keyboards/nuphy/gem80/ansi/info.json b/keyboards/nuphy/gem80/ansi/info.json
index ef02401d1ff6..d46b252bd879 100644
--- a/keyboards/nuphy/gem80/ansi/info.json
+++ b/keyboards/nuphy/gem80/ansi/info.json
@@ -4,7 +4,7 @@
"usb":{
"vid": "0x19F5",
"pid": "0x3275",
- "device_version": "1.0.0",
+ "device_version": "1.0.1",
"no_startup_check": true
},
"features": {
diff --git a/keyboards/nuphy/gem80/ansi/rf.c b/keyboards/nuphy/gem80/ansi/rf.c
index fbbcf24d1cdc..7c48d824adbb 100644
--- a/keyboards/nuphy/gem80/ansi/rf.c
+++ b/keyboards/nuphy/gem80/ansi/rf.c
@@ -2,209 +2,56 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "ansi.h"
#include "uart.h" // qmk uart.h
+#include "rf_driver.h"
-#define UART_HEAD 0x5A
-#define RX_SBYTE Usart_Mgr.RXDBuf[0]
-#define RX_CMD Usart_Mgr.RXDBuf[1]
-#define RX_ACK Usart_Mgr.RXDBuf[2]
-#define RX_LEN Usart_Mgr.RXDBuf[3]
-#define RX_DAT Usart_Mgr.RXDBuf[4]
-
-uint8_t func_tab[32] = {0};
-uint8_t disconnect_delay = 0;
-uint8_t uart_bit_report_buf[32] = {0};
-uint8_t bitkb_report_buf[32] = {0};
-uint8_t bytekb_report_buf[8] = {0};
-uint8_t mouse_report_buf[5] = {0};
-uint8_t sync_lost = 0;
-uint16_t conkb_report;
-uint16_t syskb_report;
-uint16_t host_last_consumer_usage(void);
-
-bool f_wakeup_prepare = 0;
-bool f_bit_kb_act = 0;
-
-extern uint8_t host_mode;
-extern uint8_t rf_blink_cnt;
-extern uint16_t rf_link_show_time;
-extern uint16_t rf_linking_time;
-extern uint16_t no_act_time;
-extern bool f_uart_ack;
-extern bool f_rf_read_data_ok;
-extern bool f_rf_sts_sysc_ok;
-extern bool f_rf_new_adv_ok;
-extern bool f_rf_reset;
-extern bool f_send_channel;
-extern bool f_rf_hand_ok;
-extern bool f_rf_send_bitkb;
-extern bool f_rf_send_byte;
-extern bool f_rf_send_consume;
-extern bool f_dial_sw_init_ok;
-extern bool f_goto_sleep;
-extern host_driver_t *m_host_driver;
-extern DEV_INFO_STRUCT dev_info;
USART_MGR_STRUCT Usart_Mgr;
+#define RX_SBYTE Usart_Mgr.RXDBuf[0]
+#define RX_CMD Usart_Mgr.RXDBuf[1]
+#define RX_ACK Usart_Mgr.RXDBuf[2]
+#define RX_LEN Usart_Mgr.RXDBuf[3]
+#define RX_DAT Usart_Mgr.RXDBuf[4]
+
+extern bool f_uart_ack;
+extern bool f_rf_read_data_ok;
+extern bool f_rf_sts_sysc_ok;
+extern bool f_rf_new_adv_ok;
+extern bool f_rf_reset;
+extern bool f_rf_hand_ok;
+extern bool f_goto_sleep;
+
+uint8_t uart_bit_report_buf[32] = {0};
+uint8_t func_tab[32] = {0};
+uint8_t bitkb_report_buf[32] = {0};
+uint8_t bytekb_report_buf[8] = {0};
+uint16_t conkb_report = 0;
+uint16_t syskb_report = 0;
+uint8_t sync_lost = 0;
+uint8_t disconnect_delay = 0;
-report_mouse_t mousekey_get_report(void);
-void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
-void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length);
-uint8_t get_checksum(uint8_t *buf, uint8_t len);
-void uart_receive_pro(void);
-void m_break_all_key(void);
-
-static void UsartMgr_RXD_Reset(void)
-{
- Usart_Mgr.RXDLen = 0;
- Usart_Mgr.RXDState = RX_Idle;
- Usart_Mgr.RXDOverTime = 0;
-}
-
-/**
- * @brief Parsing the data received from the RF module.
- */
-void RF_Protocol_Receive(void)
-{
- uint8_t i, check_sum = 0;
-
- if (Usart_Mgr.RXDState == RX_Done) {
- f_uart_ack = 1;
- sync_lost = 0;
-
- if (Usart_Mgr.RXDLen > 4) {
- for (i = 0; i < RX_LEN; i++)
- check_sum += Usart_Mgr.RXDBuf[4 + i];
-
- if (check_sum != Usart_Mgr.RXDBuf[4 + i]) {
- Usart_Mgr.RXDState = RX_SUM_ERR;
- return;
- }
- } else if (Usart_Mgr.RXDLen == 3) {
- if (Usart_Mgr.RXDBuf[2] == 0xA0)
- {
- f_uart_ack = 1;
- }
- }
-
- switch (RX_CMD) {
- case CMD_POWER_UP: break;
- case CMD_SLEEP: break;
- case CMD_HAND: {
- f_rf_hand_ok = 1;
- break;
- }
-
- case CMD_24G_SUSPEND: {
- f_goto_sleep = 1;
- break;
- }
-
- case CMD_SET_LINK: {
- break;
- }
-
- case CMD_NEW_ADV: {
- f_rf_new_adv_ok = 1;
- break;
- }
-
- case CMD_RF_STS_SYSC: {
- static uint8_t error_cnt = 0;
- if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) {
- error_cnt = 0;
- dev_info.rf_state = Usart_Mgr.RXDBuf[5];
-
- if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) {
- dev_info.rf_led = Usart_Mgr.RXDBuf[6];
- }
-
- if ((Usart_Mgr.RXDBuf[7] & 0xfc) == 0)
- dev_info.rf_charge = Usart_Mgr.RXDBuf[7];
-
- if (Usart_Mgr.RXDBuf[8] <= 100)
- dev_info.rf_baterry = Usart_Mgr.RXDBuf[8];
- }
- else {
- if (dev_info.rf_state != RF_INVAILD) {
- if (error_cnt >= 5) {
- error_cnt = 0;
- f_send_channel = 1;
- } else {
- error_cnt++;
- }
- }
- }
-
- f_rf_sts_sysc_ok = 1;
- break;
- }
-
- case CMD_CLR_DEVICE: {
- break;
- }
-
- case CMD_GET_NAME:
- break;
-
- case CMD_SET_NAME:
- break;
-
- case CMD_SET_24G_NAME:
- break;
-
- case CMD_RPT_BYTE_KB: {
- f_rf_send_byte = 0;
- break;
- }
-
- case CMD_RPT_BIT_KB: {
- f_rf_send_bitkb = 0;
- break;
- }
-
- case CMD_RPT_CONSUME: {
- f_rf_send_consume = 0;
- break;
- }
-
- case CMD_RPT_SYS:
- break;
-
- case CMD_WRITE_DATA:
- break;
-
- case CMD_READ_DATA: {
- memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32);
-
- if (func_tab[4] <= LINK_USB) {
- dev_info.link_mode = func_tab[4];
- }
-
- if (func_tab[5] < LINK_USB) {
- dev_info.rf_channel = func_tab[5];
- }
-
- if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) {
- dev_info.ble_channel = func_tab[6];
- }
-
- f_rf_read_data_ok = 1;
- break;
- }
-
- default:
- Usart_Mgr.RXDState = RX_CMD_ERR;
- return;
- }
-
- UsartMgr_RXD_Reset();
- }
-}
+extern DEV_INFO_STRUCT dev_info;
+extern host_driver_t *m_host_driver;
+extern uint8_t host_mode;
+extern uint8_t rf_blink_cnt;
+extern uint16_t rf_link_show_time;
+extern uint16_t rf_linking_time;
+extern uint16_t no_act_time;
+extern bool f_send_channel;
+extern bool f_dial_sw_init_ok;
+report_mouse_t mousekey_get_report(void);
+void uart_init(uint32_t baud); // qmk uart.c
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length);
+uint8_t get_checksum(uint8_t *buf, uint8_t len);
+void uart_receive_pro(void);
+void m_break_all_key(void);
+uint16_t host_last_consumer_usage(void);
/**
- * @brief Uart auto send
+ * @brief Uart auto nkey send
*/
-void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
+bool f_bit_kb_act = 0;
+static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
{
uint8_t i, j, byte_index;
uint8_t change_mask, offset_mask;
@@ -229,18 +76,16 @@ void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8
break;
}
}
-
if (byte_index >= 8) {
uart_bit_report_buf[i] |= offset_mask;
f_bit_send = 1;
}
- } else {
+ } else {
for (byte_index = 2; byte_index < 8; byte_index++) {
if (bytekb_report_buf[byte_index] == key_code) {
bytekb_report_buf[byte_index] = 0;
f_byte_send = 1;
break;
- ;
}
}
if (byte_index >= 8) {
@@ -264,9 +109,9 @@ void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8
}
}
+
/**
* @brief Uart send keys report.
- * @note Call in host.c
*/
void uart_send_report_func(void)
{
@@ -275,67 +120,165 @@ void uart_send_report_func(void)
if (dev_info.link_mode == LINK_USB) return;
keyboard_protocol = 1;
- if(keymap_config.nkro) {
- keyboard_report->nkro.mods = get_mods() | get_weak_mods();
- }
-
- if ((dev_info.sys_sw_state == SYS_SW_MAC) && (memcmp(bytekb_report_buf, keyboard_report->raw, 8))) {
- no_act_time = 0;
- keyboard_report->raw[1] = 0;
- memcpy(bytekb_report_buf, keyboard_report->raw, 8);
- uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
- }
- else if ((dev_info.sys_sw_state == SYS_SW_WIN) && (memcmp(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1))) {
- no_act_time = 0;
- uart_auto_nkey_send(bitkb_report_buf, &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- memcpy(&bitkb_report_buf[0], &keyboard_report->nkro.mods, KEYBOARD_REPORT_BITS+1);
- }
- else if (timer_elapsed32(interval_timer) > 100)
- {
+ if (timer_elapsed32(interval_timer) > 50) {
interval_timer = timer_read32();
- if (no_act_time <= 200) {
+ if (no_act_time <= 2000) {
uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
+ wait_us(200);
- if (f_bit_kb_act)
- uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
- } else {
- f_bit_kb_act = 0;
+ if(f_bit_kb_act)
+ uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
+ }
+ else {
+ f_bit_kb_act = 0;
}
}
}
/**
* @brief Uart send consumer keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_consumer_report(void)
-{
- no_act_time = 0;
- conkb_report = host_last_consumer_usage();
- uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&conkb_report), 2);
+void uart_send_consumer_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&report->usage), 2);
}
/**
* @brief Uart send mouse keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_mouse_report(void)
-{
- report_mouse_t mouse_report = mousekey_get_report();
+void uart_send_mouse_report(report_mouse_t *report) {
no_act_time = 0;
- memcpy(mouse_report_buf, &mouse_report.buttons, 5);
- uart_send_report(CMD_RPT_MS, mouse_report_buf, 5);
+ uart_send_report(CMD_RPT_MS, &report->buttons, 5);
}
/**
* @brief Uart send system keys report.
- * @note Call in host.c
+ * @note Call in rf_driver.c
*/
-void uart_send_system_report(void)
-{
- no_act_time = 0;
- syskb_report = host_last_system_usage();
- uart_send_report(CMD_RPT_SYS, (uint8_t *)(&syskb_report), 2);
+void uart_send_system_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_SYS, (uint8_t *)(&report->usage), 2);
+}
+
+/**
+ * @brief Uart send byte keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_keyboard(report_keyboard_t *report) {
+ no_act_time = 0;
+ report->reserved = 0;
+ uart_send_report(CMD_RPT_BYTE_KB, &report->mods, 8);
+ memcpy(bytekb_report_buf, &report->mods, 8);
+}
+
+/**
+ * @brief Uart send bit keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_nkro(report_nkro_t *report) {
+ no_act_time = 0;
+ uart_auto_nkey_send(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS + 1);
+ memcpy(&bitkb_report_buf[0], &nkro_report->mods, NKRO_REPORT_BITS + 1);
+}
+
+/**
+ * @brief Parsing the data received from the RF module.
+ */
+void RF_Protocol_Receive(void) {
+ uint8_t i, check_sum = 0;
+
+ if (Usart_Mgr.RXDState == RX_Done) {
+ f_uart_ack = 1;
+ sync_lost = 0;
+
+ if (Usart_Mgr.RXDLen > 4) {
+ for (i = 0; i < RX_LEN; i++)
+ check_sum += Usart_Mgr.RXDBuf[4 + i];
+
+ if (check_sum != Usart_Mgr.RXDBuf[4 + i]) {
+ Usart_Mgr.RXDState = RX_SUM_ERR;
+ return;
+ }
+ } else if (Usart_Mgr.RXDLen == 3) {
+ if (Usart_Mgr.RXDBuf[2] == 0xA0) {
+ f_uart_ack = 1;
+ }
+ }
+
+ switch (RX_CMD) {
+ case CMD_HAND: {
+ f_rf_hand_ok = 1;
+ break;
+ }
+
+ case CMD_24G_SUSPEND: {
+ f_goto_sleep = 1;
+ break;
+ }
+
+ case CMD_NEW_ADV: {
+ f_rf_new_adv_ok = 1;
+ break;
+ }
+
+ case CMD_RF_STS_SYSC: {
+ static uint8_t error_cnt = 0;
+
+ if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) {
+ error_cnt = 0;
+
+ dev_info.rf_state = Usart_Mgr.RXDBuf[5];
+
+ if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) {
+ dev_info.rf_led = Usart_Mgr.RXDBuf[6];
+ }
+
+ dev_info.rf_charge = Usart_Mgr.RXDBuf[7];
+
+ if (Usart_Mgr.RXDBuf[8] <= 100) dev_info.rf_baterry = Usart_Mgr.RXDBuf[8];
+ if (dev_info.rf_charge & 0x01) dev_info.rf_baterry = 100;
+ }
+ else {
+ if (dev_info.rf_state != RF_INVAILD) {
+ if (error_cnt >= 5) {
+ error_cnt = 0;
+ f_send_channel = 1;
+ } else {
+ error_cnt++;
+ }
+ }
+ }
+
+ f_rf_sts_sysc_ok = 1;
+ break;
+ }
+
+ case CMD_READ_DATA: {
+ memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32);
+
+ if (func_tab[4] <= LINK_USB) {
+ dev_info.link_mode = func_tab[4];
+ }
+
+ if (func_tab[5] < LINK_USB) {
+ dev_info.rf_channel = func_tab[5];
+ }
+
+ if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) {
+ dev_info.ble_channel = func_tab[6];
+ }
+
+ f_rf_read_data_ok = 1;
+ break;
+ }
+ }
+
+ Usart_Mgr.RXDLen = 0;
+ Usart_Mgr.RXDState = RX_Idle;
+ Usart_Mgr.RXDOverTime = 0;
+ }
}
/**
@@ -344,82 +287,72 @@ void uart_send_system_report(void)
* @param wait_ack: wait time for ack after sending.
* @param delayms: delay before sending.
*/
-uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
-{
- uint8_t i;
-
+uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms) {
wait_ms(delayms);
memset(&Usart_Mgr.TXDBuf[0], 0, UART_MAX_LEN);
- Usart_Mgr.TXDBuf[0] = UART_HEAD;
- Usart_Mgr.TXDBuf[1] = cmd;
- Usart_Mgr.TXDBuf[2] = 0x00;
+ Usart_Mgr.TXDBuf[0] = UART_HEAD;
+ Usart_Mgr.TXDBuf[1] = cmd;
+ Usart_Mgr.TXDBuf[2] = 0x00;
switch (cmd) {
- case CMD_POWER_UP: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
- break;
- }
- case CMD_SNIF: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
- break;
- }
case CMD_SLEEP: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_HAND: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_RF_STS_SYSC: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
break;
}
+
case CMD_SET_LINK: {
- dev_info.rf_state = RF_LINKING;
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+ dev_info.rf_state = RF_LINKING;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
- rf_linking_time = 0;
- disconnect_delay = 0xff;
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
break;
}
- case CMD_NEW_ADV: {
- dev_info.rf_state = RF_PAIRING;
- Usart_Mgr.TXDBuf[3] = 2;
- Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
- Usart_Mgr.TXDBuf[5] = 1;
- Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1;
- rf_linking_time = 0;
- disconnect_delay = 0xff;
+ case CMD_NEW_ADV: {
+ dev_info.rf_state = RF_PAIRING;
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = 1;
+ Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1;
- f_rf_new_adv_ok = 0;
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
+ f_rf_new_adv_ok = 0;
break;
}
+
case CMD_CLR_DEVICE: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = 0;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
+
case CMD_SET_CONFIG: {
- Usart_Mgr.TXDBuf[3] = 1;
- Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY;
- Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY;
+ Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY;
break;
}
case CMD_SET_NAME: {
@@ -443,8 +376,8 @@ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
}
case CMD_SET_24G_NAME: {
- Usart_Mgr.TXDBuf[3] = 38;
- Usart_Mgr.TXDBuf[4] = 38;
+ Usart_Mgr.TXDBuf[3] = 38; // uart data len
+ Usart_Mgr.TXDBuf[4] = 38; // name valid len
Usart_Mgr.TXDBuf[5] = 3;
Usart_Mgr.TXDBuf[6] = 'N';
Usart_Mgr.TXDBuf[8] = 'u';
@@ -469,33 +402,17 @@ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
}
case CMD_READ_DATA: {
- Usart_Mgr.TXDBuf[3] = 2;
- Usart_Mgr.TXDBuf[4] = 0x00;
- Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
- Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN;
- break;
- }
- case CMD_WRITE_DATA: {
- func_tab[4] = dev_info.link_mode;
- func_tab[5] = dev_info.rf_channel;
- func_tab[6] = dev_info.ble_channel;
-
- Usart_Mgr.TXDBuf[3] = FUNC_VALID_LEN + 2;
- Usart_Mgr.TXDBuf[4] = 0;
- Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
-
- for (i = 0; i < FUNC_VALID_LEN; i++) {
- Usart_Mgr.TXDBuf[6 + i] = func_tab[i];
- }
- Usart_Mgr.TXDBuf[6 + i] = get_checksum(func_tab, FUNC_VALID_LEN);
- Usart_Mgr.TXDBuf[6 + i] += 0;
- Usart_Mgr.TXDBuf[6 + i] += FUNC_VALID_LEN;
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = 0x00;
+ Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
+ Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN;
break;
}
+
case CMD_RF_DFU: {
- Usart_Mgr.TXDBuf[3] = 1; // len
- Usart_Mgr.TXDBuf[4] = 0; // dat
- Usart_Mgr.TXDBuf[5] = 0; // sum
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
break;
}
@@ -521,21 +438,22 @@ uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms)
/**
* @brief RF module state sync.
*/
-void dev_sts_sync(void)
-{
- static uint32_t interval_timer = 0;
- static uint8_t link_state_temp = RF_DISCONNECT;
+void dev_sts_sync(void) {
+ static uint32_t interval_timer = 0;
+ static uint8_t link_state_temp = RF_DISCONNECT;
- if (timer_elapsed32(interval_timer) < 200) return;
- else interval_timer = timer_read32();
+ if (timer_elapsed32(interval_timer) < 200)
+ return;
+ else
+ interval_timer = timer_read32();
if (f_rf_reset) {
f_rf_reset = 0;
- wait_ms(300);
- writePinLow(NRF_RESET_PIN);
+ wait_ms(100);
+ writePinLow(NRF_RESET_PIN);
wait_ms(50);
writePinHigh(NRF_RESET_PIN);
- wait_ms(50);
+ wait_ms(50);
}
else if (f_send_channel) {
f_send_channel = 0;
@@ -543,25 +461,25 @@ void dev_sts_sync(void)
}
if (dev_info.link_mode == LINK_USB) {
- rf_blink_cnt = 0;
if (host_mode != HOST_USB_TYPE) {
host_mode = HOST_USB_TYPE;
host_set_driver(m_host_driver);
m_break_all_key();
}
+ rf_blink_cnt = 0;
}
else {
if (host_mode != HOST_RF_TYPE) {
host_mode = HOST_RF_TYPE;
m_break_all_key();
- host_set_driver(0);
+ host_set_driver(&rf_host_driver);
}
if (dev_info.rf_state != RF_CONNECT) {
- if (disconnect_delay >= 10) {
- rf_blink_cnt = 3;
- rf_link_show_time = 0;
- link_state_temp = dev_info.rf_state;
+ if (disconnect_delay >= 10) {
+ rf_blink_cnt = 3;
+ rf_link_show_time = 0;
+ link_state_temp = dev_info.rf_state;
} else {
disconnect_delay++;
}
@@ -569,91 +487,49 @@ void dev_sts_sync(void)
else if (dev_info.rf_state == RF_CONNECT) {
rf_linking_time = 0;
disconnect_delay = 0;
- rf_blink_cnt = 0;
+ rf_blink_cnt = 0;
if (link_state_temp != RF_CONNECT) {
- link_state_temp = RF_CONNECT;
+ link_state_temp = RF_CONNECT;
+ rf_link_show_time = 0;
if (dev_info.link_mode == LINK_RF_24) {
- uart_send_cmd(CMD_SET_24G_NAME, 10, 30);
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 30);
}
}
}
}
- uart_send_cmd(CMD_RF_STS_SYSC, 0, 0);
+ uart_send_cmd(CMD_RF_STS_SYSC, 1, 1);
if (dev_info.link_mode != LINK_USB) {
- if (++sync_lost >= 5) {
+ if (++sync_lost >= 5) {
sync_lost = 0;
f_rf_reset = 1;
}
}
}
-/**
- * @brief RF module initial.
- */
-void rf_device_init(void)
-{
- uint8_t timeout = 0;
- void uart_receive_pro(void);
-
- timeout = 10;
- f_rf_hand_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_HAND, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_hand_ok)
- break;
- }
-
- timeout = 10;
- f_rf_read_data_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_READ_DATA, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_read_data_ok)
- break;
- }
-
- timeout = 10;
- f_rf_sts_sysc_ok = 0;
- while (timeout--) {
- uart_send_cmd(CMD_RF_STS_SYSC, 0, 20);
- wait_ms(5);
- uart_receive_pro();
- uart_receive_pro();
- if (f_rf_sts_sysc_ok)
- break;
- }
-
- uart_send_cmd(CMD_SET_24G_NAME, 10, 20);
-
- uart_send_cmd(CMD_SET_NAME, 10, 20);
-}
-
/**
* @brief Uart send bytes.
* @param Buffer data buf
* @param Length data lenght
*/
-void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length)
-{
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length) {
writePinLow(NRF_WAKEUP_PIN);
wait_us(50);
uart_transmit(Buffer, Length);
- wait_us(50 + Length * 22);
+ wait_us(50 + Length * 30);
writePinHigh(NRF_WAKEUP_PIN);
}
-uint8_t get_checksum(uint8_t *buf, uint8_t len)
-{
+/**
+ * @brief get checksum.
+ * @param buf data buf
+ * @param len data lenght
+ */
+uint8_t get_checksum(uint8_t *buf, uint8_t len) {
uint8_t i;
uint8_t checksum = 0;
@@ -665,44 +541,54 @@ uint8_t get_checksum(uint8_t *buf, uint8_t len)
return checksum;
}
-void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size)
-{
- if (f_dial_sw_init_ok == 0) return;
- if (dev_info.link_mode == LINK_USB) return;
- if (dev_info.rf_state != RF_CONNECT) return;
+/**
+ * @brief Uart send report.
+ * @param report_type report_type
+ * @param report_buf report_buf
+ * @param report_size report_size
+ */
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size) {
+ if (f_dial_sw_init_ok == 0) return;
+ if (dev_info.link_mode == LINK_USB) return;
+ if (dev_info.rf_state != RF_CONNECT) return;
- Usart_Mgr.TXDBuf[0] = UART_HEAD;
- Usart_Mgr.TXDBuf[1] = report_type;
- Usart_Mgr.TXDBuf[2] = 0x01;
- Usart_Mgr.TXDBuf[3] = report_size;
+ Usart_Mgr.TXDBuf[0] = UART_HEAD;
+ Usart_Mgr.TXDBuf[1] = report_type;
+ Usart_Mgr.TXDBuf[2] = 0x01;
+ Usart_Mgr.TXDBuf[3] = report_size;
memcpy(&Usart_Mgr.TXDBuf[4], report_buf, report_size);
Usart_Mgr.TXDBuf[4 + report_size] = get_checksum(&Usart_Mgr.TXDBuf[4], report_size);
UART_Send_Bytes(&Usart_Mgr.TXDBuf[0], report_size + 5);
- wait_us(50);
+ wait_us(200);
}
/**
* @brief Uart receives data and processes it after completion,.
*/
-void uart_receive_pro(void)
-{
+void uart_receive_pro(void) {
static bool rcv_start = false;
- if (uart_available()) {
- rcv_start = true;
- while (uart_available()) {
- if (Usart_Mgr.RXDLen >= UART_MAX_LEN) {
- uart_read();
- Usart_Mgr.RXDState = RX_DATA_OV;
- } else {
- Usart_Mgr.RXDBuf[Usart_Mgr.RXDLen++] = uart_read();
- }
+ // Receiving serial data from RF module
+ while (uart_available()) {
+ rcv_start = true;
+
+ if (Usart_Mgr.RXDLen >= UART_MAX_LEN) {
+ uart_read();
+ }
+ else {
+ Usart_Mgr.RXDBuf[Usart_Mgr.RXDLen++] = uart_read();
+ }
+
+ if (!uart_available()) {
+ wait_us(200);
}
+ }
- } else if (rcv_start) {
+ // Processing received serial port protocol
+ if (rcv_start) {
rcv_start = false;
Usart_Mgr.RXDState = RX_Done;
RF_Protocol_Receive();
@@ -725,4 +611,46 @@ void rf_uart_init(void) {
/* set Rx and Tx pin pull up */
GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);
GPIOB->PUPDR |= (GPIO_PUPDR_PUPDR6_0 | GPIO_PUPDR_PUPDR7_0);
-}
\ No newline at end of file
+}
+
+/**
+ * @brief RF module initial.
+ */
+void rf_device_init(void) {
+ uint8_t timeout = 0;
+ void uart_receive_pro(void);
+
+ timeout = 10;
+ f_rf_hand_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_HAND, 0, 20);
+ wait_ms(5);
+ uart_receive_pro(); // receive data
+ uart_receive_pro(); // parsing data
+ if (f_rf_hand_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_read_data_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_READ_DATA, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_read_data_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_sts_sysc_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_RF_STS_SYSC, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_sts_sysc_ok) break;
+ }
+
+ uart_send_cmd(CMD_SET_NAME, 10, 20);
+
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 20);
+}
diff --git a/keyboards/nuphy/gem80/ansi/rf_driver.c b/keyboards/nuphy/gem80/ansi/rf_driver.c
new file mode 100644
index 000000000000..1c0876c00349
--- /dev/null
+++ b/keyboards/nuphy/gem80/ansi/rf_driver.c
@@ -0,0 +1,65 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "host_driver.h"
+#include "rf_driver.h"
+#include "host.h"
+#include "ansi.h"
+
+/* Variable declaration */
+extern DEV_INFO_STRUCT dev_info;
+
+/* Host driver */
+static uint8_t rf_keyboard_leds(void);
+static void rf_send_keyboard(report_keyboard_t *report);
+static void rf_send_nkro(report_nkro_t *report);
+static void rf_send_mouse(report_mouse_t *report);
+static void rf_send_extra(report_extra_t *report);
+host_driver_t rf_host_driver = {rf_keyboard_leds, rf_send_keyboard, rf_send_nkro, rf_send_mouse, rf_send_extra};
+
+/* defined in rf.c */
+extern void uart_send_report_keyboard(report_keyboard_t *report);
+extern void uart_send_report_nkro(report_nkro_t *report);
+extern void uart_send_mouse_report(report_mouse_t *report);
+extern void uart_send_consumer_report(report_extra_t *report);
+extern void uart_send_system_report(report_extra_t *report);
+
+static uint8_t rf_keyboard_leds(void) {
+ return dev_info.rf_led;
+}
+
+static void rf_send_keyboard(report_keyboard_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_keyboard(report);
+}
+
+static void rf_send_nkro(report_nkro_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_nkro(report);
+}
+
+static void rf_send_mouse(report_mouse_t *report) {
+ uart_send_mouse_report(report);
+}
+
+static void rf_send_extra(report_extra_t *report) {
+ if (report->report_id == REPORT_ID_CONSUMER) {
+ uart_send_consumer_report(report);
+ } else if (report->report_id == REPORT_ID_SYSTEM) {
+ uart_send_system_report(report);
+ }
+}
diff --git a/keyboards/nuphy/gem80/ansi/rf_driver.h b/keyboards/nuphy/gem80/ansi/rf_driver.h
new file mode 100644
index 000000000000..ad0cf3cb384f
--- /dev/null
+++ b/keyboards/nuphy/gem80/ansi/rf_driver.h
@@ -0,0 +1,20 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+extern host_driver_t rf_host_driver;
diff --git a/keyboards/nuphy/gem80/ansi/rules.mk b/keyboards/nuphy/gem80/ansi/rules.mk
index c2c4aa6ac9ea..65aa91c4b25d 100644
--- a/keyboards/nuphy/gem80/ansi/rules.mk
+++ b/keyboards/nuphy/gem80/ansi/rules.mk
@@ -3,5 +3,6 @@ SRC += rf.c
SRC += sleep.c
SRC += side_driver.c
SRC += side_logo.c
-QUANTUM_LIB_SRC += uart.c
+SRC += rf_driver.c
+UART_DRIVER_REQUIRED = yes
diff --git a/keyboards/nuphy/gem80/ansi/side.c b/keyboards/nuphy/gem80/ansi/side.c
index 5264f2c7d176..04f1478a95a4 100644
--- a/keyboards/nuphy/gem80/ansi/side.c
+++ b/keyboards/nuphy/gem80/ansi/side.c
@@ -77,8 +77,8 @@ extern uint16_t rf_link_show_time;
extern uint8_t logo_play_cnt;
extern uint32_t logo_play_timer;
-LED_TYPE side_leds[SIDE_LED_NUM] = {0};
-void side_ws2812_setleds(LED_TYPE *ledarray, uint16_t leds);
+rgb_led_t side_leds[SIDE_LED_NUM] = {0};
+void side_ws2812_setleds(rgb_led_t *ledarray, uint16_t leds);
void rgb_matrix_update_pwm_buffers(void);
void m_logo_led_show(void);
diff --git a/keyboards/nuphy/gem80/ansi/side_driver.c b/keyboards/nuphy/gem80/ansi/side_driver.c
index daa1c27e0f1b..45947bb03ed1 100644
--- a/keyboards/nuphy/gem80/ansi/side_driver.c
+++ b/keyboards/nuphy/gem80/ansi/side_driver.c
@@ -73,7 +73,7 @@ void side_sendByte(uint8_t byte)
}
// Setleds for standard RGB
-void side_ws2812_setleds(LED_TYPE *ledarray, uint16_t leds)
+void side_ws2812_setleds(rgb_led_t *ledarray, uint16_t leds)
{
// this code is very time dependent, so we need to disable interrupts
chSysLock();
diff --git a/keyboards/nuphy/halo75/ansi/ansi.c b/keyboards/nuphy/halo75/ansi/ansi.c
new file mode 100644
index 000000000000..89947323095f
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/ansi.c
@@ -0,0 +1,791 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "ansi.h"
+#include "usb_main.h"
+#include "rf_driver.h"
+
+
+user_config_t user_config;
+DEV_INFO_STRUCT dev_info =
+ {
+ .rf_baterry = 100,
+ .link_mode = LINK_USB,
+ .rf_state = RF_IDLE,
+};
+
+uint16_t rf_linking_time = 0;
+uint16_t rf_link_show_time = 0;
+uint8_t rf_blink_cnt = 0;
+uint16_t no_act_time = 0;
+host_driver_t *m_host_driver = 0;
+uint16_t dev_reset_press_delay = 0;
+uint16_t rf_sw_press_delay = 0;
+uint16_t rgb_test_press_delay = 0;
+uint8_t rf_sw_temp = 0;
+uint8_t rgb_light_old = 0;
+uint8_t host_mode;
+
+extern uint8_t side_mode_a;
+extern uint8_t side_light;
+extern uint8_t side_speed;
+extern uint8_t side_rgb;
+extern uint8_t side_colour;
+extern report_keyboard_t *keyboard_report;
+extern report_nkro_t *nkro_report;
+extern uint8_t side_mode_b;
+extern uint8_t uart_bit_report_buf[32];
+extern uint8_t bitkb_report_buf[32];
+extern uint8_t bytekb_report_buf[8];
+
+bool f_uart_ack = 0;
+bool f_bat_show = 0;
+bool f_bat_hold = 0;
+bool f_chg_show = 1;
+bool f_sys_show = 0;
+bool f_sleep_show = 0;
+bool f_usb_offline = 0;
+bool f_rf_read_data_ok = 0;
+bool f_rf_sts_sysc_ok = 0;
+bool f_rf_new_adv_ok = 0;
+bool f_rf_reset = 0;
+bool f_send_channel = 0;
+bool f_rf_hand_ok = 0;
+bool f_rf_send_bitkb = 0;
+bool f_rf_send_byte = 0;
+bool f_rf_send_consume = 0;
+bool f_wakeup_prepare = 0;
+bool f_dial_sw_init_ok = 0;
+bool f_goto_sleep = 0;
+bool f_rf_sw_press = 0;
+bool f_dev_reset_press = 0;
+bool f_rgb_test_press = 0;
+bool f_win_lock = 0;
+
+void rf_device_init(void);
+void rf_uart_init(void);
+void m_side_led_show(void);
+void dev_sts_sync(void);
+void uart_receive_pro(void);
+void Sleep_Handle(void);
+void uart_send_report_func(void);
+uint8_t uart_send_cmd(uint8_t cmd, uint8_t ack_cnt, uint8_t delayms);
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
+void device_reset_show(void);
+void device_reset_init(void);
+void rgb_test_show(void);
+void m_deinit_usb_072(void);
+
+extern void light_speed_contol(uint8_t fast);
+extern void light_level_control(uint8_t brighten);
+extern void side_colour_control(uint8_t dir);
+extern void side_mode_a_control(uint8_t dir);
+extern void side_mode_b_control(uint8_t dir);
+extern bool low_bat_flag;
+
+
+/**
+ * @brief gpio initial.
+ */
+void m_gpio_init(void)
+{
+ setPinOutput(DC_BOOST_PIN); writePinHigh(DC_BOOST_PIN);
+
+ // Initializes the RGB Driver SDB pin
+ setPinOutput(RGB_DRIVER_SDB1); writePinHigh(RGB_DRIVER_SDB1);
+ setPinOutput(RGB_DRIVER_SDB2); writePinHigh(RGB_DRIVER_SDB2);
+
+ // RF wake up pin configuration
+ setPinOutput(NRF_WAKEUP_PIN);
+ writePinHigh(NRF_WAKEUP_PIN);
+
+ // RFboot Control pin
+ setPinInputHigh(NRF_BOOT_PIN);
+
+ // RF reset pin configuration
+ setPinOutput(NRF_RESET_PIN); writePinLow(NRF_RESET_PIN);
+ wait_ms(50);
+ writePinHigh(NRF_RESET_PIN);
+
+ // Switch detection pin
+ setPinInputHigh(DEV_MODE_PIN);
+ setPinInputHigh(SYS_MODE_PIN);
+}
+
+
+/**
+ * @brief long press key process.
+ */
+void long_press_key(void)
+{
+ static uint32_t long_press_timer = 0;
+
+ if (timer_elapsed32(long_press_timer) < 100) return;
+ long_press_timer = timer_read32();
+
+ if (f_rf_sw_press) {
+ rf_sw_press_delay++;
+ if (rf_sw_press_delay >= RF_LONG_PRESS_DELAY) {
+ f_rf_sw_press = 0;
+ dev_info.link_mode = rf_sw_temp;
+ dev_info.rf_channel = rf_sw_temp;
+ dev_info.ble_channel = rf_sw_temp;
+
+ uint8_t timeout = 5;
+ while (timeout--) {
+ uart_send_cmd(CMD_NEW_ADV, 0, 1);
+ wait_ms(20);
+ uart_receive_pro();
+ if (f_rf_new_adv_ok) break;
+ }
+ }
+ } else {
+ rf_sw_press_delay = 0;
+ }
+
+ if (f_dev_reset_press) {
+ dev_reset_press_delay++;
+ if (dev_reset_press_delay >= DEV_RESET_PRESS_DELAY) {
+ f_dev_reset_press = 0;
+
+ if (dev_info.link_mode != LINK_USB) {
+ if (dev_info.link_mode != LINK_RF_24) {
+ dev_info.link_mode = LINK_BT_1;
+ dev_info.ble_channel = LINK_BT_1;
+ dev_info.rf_channel = LINK_BT_1;
+ }
+ } else {
+ dev_info.ble_channel = LINK_BT_1;
+ }
+
+ uart_send_cmd(CMD_SET_LINK, 10, 10);
+ wait_ms(500);
+ uart_send_cmd(CMD_CLR_DEVICE, 10, 10);
+
+ eeconfig_init();
+ device_reset_show();
+ device_reset_init();
+
+ keymap_config.no_gui = 0;
+ f_win_lock = 0;
+
+ if (dev_info.sys_sw_state == SYS_SW_MAC) {
+ default_layer_set(1 << 0); // MAC
+ keymap_config.nkro = 0;
+ } else {
+ default_layer_set(1 << 2); // WIN
+ keymap_config.nkro = 1;
+ }
+ }
+ } else {
+ dev_reset_press_delay = 0;
+ }
+
+ if (f_rgb_test_press) {
+ rgb_test_press_delay++;
+ if (rgb_test_press_delay >= RGB_TEST_PRESS_DELAY) {
+ f_rgb_test_press = 0;
+ rgb_test_show();
+ }
+ } else {
+ rgb_test_press_delay = 0;
+ }
+}
+
+/**
+ * @brief Release all keys, clear keyboard report.
+ */
+void m_break_all_key(void)
+{
+
+ uint8_t report_buf[16];
+ bool nkro_temp = keymap_config.nkro;
+
+ clear_weak_mods();
+ clear_mods();
+ clear_keyboard();
+
+ keymap_config.nkro = 1;
+ memset(nkro_report, 0, sizeof(report_nkro_t));
+ host_nkro_send(nkro_report);
+ wait_ms(10);
+
+ keymap_config.nkro = 0;
+ memset(keyboard_report, 0, sizeof(report_keyboard_t));
+ host_keyboard_send(keyboard_report);
+ wait_ms(10);
+
+ keymap_config.nkro = nkro_temp;
+
+ if (dev_info.link_mode != LINK_USB) {
+ memset(report_buf, 0, 16);
+ uart_send_report(CMD_RPT_BIT_KB, report_buf, 16);
+ wait_ms(10);
+ uart_send_report(CMD_RPT_BYTE_KB, report_buf, 8);
+ wait_ms(10);
+ }
+
+ memset(uart_bit_report_buf, 0, sizeof(uart_bit_report_buf));
+ memset(bitkb_report_buf, 0, sizeof(bitkb_report_buf));
+ memset(bytekb_report_buf, 0, sizeof(bytekb_report_buf));
+}
+
+/**
+ * @brief switch device link mode.
+ * @param mode : link mode
+ */
+static void switch_dev_link(uint8_t mode)
+{
+ if (mode > LINK_USB) return;
+ m_break_all_key();
+
+ dev_info.link_mode = mode;
+ dev_info.rf_state = RF_IDLE;
+ f_send_channel = 1;
+
+ if (mode == LINK_USB) {
+ host_mode = HOST_USB_TYPE;
+ host_set_driver(m_host_driver);
+ rf_link_show_time = 0;
+ }
+ else {
+ host_mode = HOST_RF_TYPE;
+ host_set_driver(&rf_host_driver);
+ }
+}
+
+
+/**
+ * @brief scan dial switch.
+ */
+void dial_sw_scan(void)
+{
+ uint8_t dial_scan = 0;
+ static uint8_t dial_save = 0xf0;
+ static uint8_t debounce = 0;
+ static uint32_t dial_scan_timer = 0;
+ static bool flag_power_on = 1;
+
+ if (!flag_power_on) {
+ if (timer_elapsed32(dial_scan_timer) < 20) return;
+ }
+ dial_scan_timer = timer_read32();
+
+ setPinInputHigh(DEV_MODE_PIN);
+ setPinInputHigh(SYS_MODE_PIN);
+
+ if (readPin(DEV_MODE_PIN)) dial_scan |= 0X01;
+ if (readPin(SYS_MODE_PIN)) dial_scan |= 0X02;
+
+ if (dial_save != dial_scan) {
+ m_break_all_key();
+ dial_save = dial_scan;
+ no_act_time = 0;
+ rf_linking_time = 0;
+ debounce = 25;
+ f_dial_sw_init_ok = 0;
+ return;
+ } else if (debounce) {
+ debounce--;
+ return;
+ }
+
+ if (dial_scan & 0x01) {
+ if (dev_info.link_mode != LINK_USB) {
+ switch_dev_link(LINK_USB);
+ }
+ } else {
+ if (dev_info.link_mode != dev_info.rf_channel) {
+ switch_dev_link(dev_info.rf_channel);
+ }
+ }
+
+ if (dial_scan & 0x02) {
+ if (dev_info.sys_sw_state != SYS_SW_WIN) {
+ f_sys_show = 1;
+ default_layer_set(1 << 2);
+ dev_info.sys_sw_state = SYS_SW_WIN;
+ keymap_config.no_gui = f_win_lock;
+ m_break_all_key();
+ }
+ keymap_config.nkro = 1;
+ } else {
+ if (dev_info.sys_sw_state != SYS_SW_MAC) {
+ f_sys_show = 1;
+ default_layer_set(1 << 0);
+ dev_info.sys_sw_state = SYS_SW_MAC;
+ f_win_lock = keymap_config.no_gui;
+ m_break_all_key();
+ }
+ keymap_config.nkro = 0;
+ keymap_config.no_gui = 0;
+ }
+
+ if (f_dial_sw_init_ok == 0) {
+ f_dial_sw_init_ok = 1;
+ flag_power_on = 0;
+
+ if (dev_info.link_mode != LINK_USB) {
+ host_set_driver(&rf_host_driver);
+ }
+ }
+}
+
+/**
+ * @brief power on scan dial switch.
+ */
+void m_power_on_dial_sw_scan(void)
+{
+ uint8_t dial_scan_dev = 0;
+ uint8_t dial_scan_sys = 0;
+ uint8_t dial_check_dev = 0;
+ uint8_t dial_check_sys = 0;
+ uint8_t debounce = 0;
+
+ f_win_lock = 0;
+
+ setPinInputHigh(DEV_MODE_PIN);
+ setPinInputHigh(SYS_MODE_PIN);
+
+ for(debounce=0; debounce<10; debounce++) {
+ dial_scan_dev = 0;
+ dial_scan_sys = 0;
+ if (readPin(DEV_MODE_PIN)) dial_scan_dev = 0x01;
+ else dial_scan_dev = 0;
+ if (readPin(SYS_MODE_PIN)) dial_scan_sys = 0x01;
+ else dial_scan_sys = 0;
+ if((dial_scan_dev != dial_check_dev)||(dial_scan_sys != dial_check_sys))
+ {
+ dial_check_dev = dial_scan_dev;
+ dial_check_sys = dial_scan_sys;
+ debounce = 0;
+ }
+ wait_ms(1);
+ }
+ if (dial_scan_dev) {
+ if (dev_info.link_mode != LINK_USB) {
+ switch_dev_link(LINK_USB);
+ }
+ } else {
+ if (dev_info.link_mode != dev_info.rf_channel) {
+ switch_dev_link(dev_info.rf_channel);
+ }
+ }
+ // WIN/MAC
+ if (dial_scan_sys) {
+ if (dev_info.sys_sw_state != SYS_SW_WIN) {
+ default_layer_set(1 << 2); // WIN
+ dev_info.sys_sw_state = SYS_SW_WIN;
+ keymap_config.nkro = 1;
+ m_break_all_key();
+ }
+ } else {
+ if (dev_info.sys_sw_state != SYS_SW_MAC) {
+ default_layer_set(1 << 0); // MAC
+ dev_info.sys_sw_state = SYS_SW_MAC;
+ keymap_config.nkro = 0;
+ f_win_lock = keymap_config.no_gui;
+ keymap_config.no_gui = 0;
+ m_break_all_key();
+ }
+ }
+}
+
+
+/**
+ * @brief qmk process record
+ */
+bool process_record_user(uint16_t keycode, keyrecord_t *record)
+{
+ no_act_time = 0;
+ switch (keycode) {
+ case RF_DFU:
+ if (record->event.pressed) {
+ if (dev_info.link_mode != LINK_USB) return false;
+ uart_send_cmd(CMD_RF_DFU, 10, 20);
+ }
+ return false;
+
+ case LNK_USB:
+ if (record->event.pressed) {
+ m_break_all_key();
+ } else {
+ dev_info.link_mode = LINK_USB;
+ uart_send_cmd(CMD_SET_LINK, 10, 10);
+ }
+ return false;
+
+ case LNK_RF:
+ if (record->event.pressed) {
+ if (dev_info.link_mode != LINK_USB) {
+ rf_sw_temp = LINK_RF_24;
+ f_rf_sw_press = 1;
+ m_break_all_key();
+ }
+ } else if (f_rf_sw_press) {
+ f_rf_sw_press = 0;
+ if (rf_sw_press_delay < RF_LONG_PRESS_DELAY) {
+ dev_info.link_mode = rf_sw_temp;
+ dev_info.rf_channel = rf_sw_temp;
+ dev_info.ble_channel = rf_sw_temp;
+ uart_send_cmd(CMD_SET_LINK, 10, 20);
+ }
+ }
+ return false;
+
+ case LNK_BLE1:
+ if (record->event.pressed) {
+ if (dev_info.link_mode != LINK_USB) {
+ rf_sw_temp = LINK_BT_1;
+ f_rf_sw_press = 1;
+ m_break_all_key();
+ }
+ } else if (f_rf_sw_press) {
+ f_rf_sw_press = 0;
+ if (rf_sw_press_delay < RF_LONG_PRESS_DELAY) {
+ dev_info.link_mode = rf_sw_temp;
+ dev_info.rf_channel = rf_sw_temp;
+ dev_info.ble_channel = rf_sw_temp;
+ uart_send_cmd(CMD_SET_LINK, 10, 20);
+ }
+ }
+ return false;
+
+ case LNK_BLE2:
+ if (record->event.pressed) {
+ if (dev_info.link_mode != LINK_USB) {
+ rf_sw_temp = LINK_BT_2;
+ f_rf_sw_press = 1;
+ m_break_all_key();
+ }
+ } else if (f_rf_sw_press) {
+ f_rf_sw_press = 0;
+ if (rf_sw_press_delay < RF_LONG_PRESS_DELAY) {
+ dev_info.link_mode = rf_sw_temp;
+ dev_info.rf_channel = rf_sw_temp;
+ dev_info.ble_channel = rf_sw_temp;
+ uart_send_cmd(CMD_SET_LINK, 10, 20);
+ }
+ }
+ return false;
+
+ case LNK_BLE3:
+ if (record->event.pressed) {
+ if (dev_info.link_mode != LINK_USB) {
+ rf_sw_temp = LINK_BT_3;
+ f_rf_sw_press = 1;
+ m_break_all_key();
+ }
+ } else if (f_rf_sw_press) {
+ f_rf_sw_press = 0;
+ if (rf_sw_press_delay < RF_LONG_PRESS_DELAY) {
+ dev_info.link_mode = rf_sw_temp;
+ dev_info.rf_channel = rf_sw_temp;
+ dev_info.ble_channel = rf_sw_temp;
+ uart_send_cmd(CMD_SET_LINK, 10, 20);
+ }
+ }
+ return false;
+
+ case MAC_TASK:
+ if (record->event.pressed) {
+ host_consumer_send(0x029F);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case MAC_SEARCH:
+ if (record->event.pressed) {
+ register_code(KC_LGUI);
+ register_code(KC_SPACE);
+ wait_ms(20);
+ unregister_code(KC_LGUI);
+ unregister_code(KC_SPACE);
+ }
+ return false;
+
+ case MAC_VOICE:
+ if (record->event.pressed) {
+ host_consumer_send(0xcf);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case MAC_CONSOLE:
+ if (record->event.pressed) {
+ host_consumer_send(0x02A0);
+ } else {
+ host_consumer_send(0);
+ }
+ return false;
+
+ case MAC_DND:
+ if (record->event.pressed) {
+ host_system_send(0x9b);
+ } else {
+ host_system_send(0);
+ }
+ return false;
+
+ case MAC_PRT:
+ if (record->event.pressed) {
+ register_code(KC_LGUI);
+ register_code(KC_LSFT);
+ register_code(KC_3);
+ wait_ms(20);
+ unregister_code(KC_3);
+ unregister_code(KC_LSFT);
+ unregister_code(KC_LGUI);
+ }
+ return false;
+
+ case MAC_PRTA:
+ if (record->event.pressed) {
+ // win
+ if (keymap_config.nkro) {
+ register_code(KC_LGUI);
+ register_code(KC_LSFT);
+ register_code(KC_S);
+ wait_ms(20);
+ unregister_code(KC_S);
+ unregister_code(KC_LSFT);
+ unregister_code(KC_LGUI);
+ }
+ // mac
+ else {
+ register_code(KC_LGUI);
+ register_code(KC_LSFT);
+ register_code(KC_4);
+ wait_ms(20);
+ unregister_code(KC_4);
+ unregister_code(KC_LSFT);
+ unregister_code(KC_LGUI);
+ }
+ }
+ return false;
+
+ case SIDE_VAI:
+ if (record->event.pressed) {
+ if(low_bat_flag && (side_light == 1)) return false;
+ light_level_control(1);
+ }
+ return false;
+
+ case SIDE_VAD:
+ if (record->event.pressed) {
+ light_level_control(0);
+ }
+ return false;
+
+ case SIDE_MOD_A:
+ if (record->event.pressed) {
+ side_mode_a_control(1);
+ }
+ return false;
+
+ case SIDE_MOD_B:
+ if (record->event.pressed) {
+ side_mode_b_control(1);
+ }
+ return false;
+
+ case SIDE_HUI:
+ if (record->event.pressed) {
+ side_colour_control(1);
+ }
+ return false;
+
+ case SIDE_SPI:
+ if (record->event.pressed) {
+ light_speed_contol(1);
+ }
+ return false;
+
+ case SIDE_SPD:
+ if (record->event.pressed) {
+ light_speed_contol(0);
+ }
+ return false;
+
+ case DEV_RESET:
+ if (record->event.pressed) {
+ f_dev_reset_press = 1;
+ m_break_all_key();
+ } else {
+ f_dev_reset_press = 0;
+ }
+ return false;
+
+ case SLEEP_MODE:
+ if (record->event.pressed) {
+ if(f_dev_sleep_enable) f_dev_sleep_enable = false;
+ else f_dev_sleep_enable = true;
+ f_sleep_show = 1;
+ eeconfig_update_user_datablock(&user_config);
+ }
+ return false;
+
+ case BAT_SHOW:
+ if (record->event.pressed) {
+ f_bat_hold = !f_bat_hold;
+ }
+ return false;
+
+ case RGB_VAI:
+ if(low_bat_flag && (rgb_matrix_config.hsv.v == RGB_MATRIX_VAL_STEP)) return false;
+ return true;
+
+ case RGB_TOG:
+ if (record->event.pressed) {
+ rgb_matrix_enable();
+ if(rgb_matrix_config.hsv.v)
+ {
+ rgb_light_old = rgb_matrix_config.hsv.v;
+ rgb_matrix_config.hsv.v = 0;
+ }
+ else
+ {
+ if(rgb_light_old) rgb_matrix_config.hsv.v = rgb_light_old;
+ else rgb_matrix_config.hsv.v = (255 - RGB_MATRIX_SPD_STEP * 2);
+ }
+
+ }
+ return false;
+
+ default:
+ return true;
+ }
+ return true;
+}
+
+
+/**
+ @brief timer process.
+ */
+void timer_pro(void)
+{
+ static uint32_t interval_timer = 0;
+ static bool f_first = true;
+
+ if (f_first) {
+ f_first = false;
+ interval_timer = timer_read32();
+ m_host_driver = host_get_driver();
+ }
+
+ if (timer_elapsed32(interval_timer) < 10) {
+ return;
+ } else if (timer_elapsed32(interval_timer) > 20) {
+ interval_timer = timer_read32();
+ } else {
+ interval_timer += 10;
+ }
+
+ if (rf_link_show_time < RF_LINK_SHOW_TIME)
+ rf_link_show_time++;
+
+ if (no_act_time < 0xffff)
+ no_act_time++;
+
+ if (rf_linking_time < 0xffff)
+ rf_linking_time++;
+
+}
+
+
+/**
+ * @brief londing eeprom data.
+ */
+void m_londing_eeprom_data(void)
+{
+ eeconfig_read_user_datablock(&user_config);
+ if (user_config.default_brightness_flag != 0xA5) {
+ // 出厂默认
+ rgb_matrix_sethsv(RGB_DEFAULT_COLOUR, 255, RGB_MATRIX_MAXIMUM_BRIGHTNESS - RGB_MATRIX_VAL_STEP * 2);
+ user_config.default_brightness_flag = 0xA5;
+ user_config.ee_side_mode_a = side_mode_a;
+ user_config.ee_side_mode_b = side_mode_b;
+ user_config.ee_side_light = side_light;
+ user_config.ee_side_speed = side_speed;
+ user_config.ee_side_rgb = side_rgb;
+ user_config.ee_side_colour = side_colour;
+ f_dev_sleep_enable = true;
+ eeconfig_update_user_datablock(&user_config);
+ } else {
+ side_mode_a = user_config.ee_side_mode_a;
+ side_mode_b = user_config.ee_side_mode_b;
+ side_light = user_config.ee_side_light;
+ side_speed = user_config.ee_side_speed;
+ side_rgb = user_config.ee_side_rgb;
+ side_colour = user_config.ee_side_colour;
+ }
+}
+
+
+/**
+ qmk keyboard post init
+ */
+void keyboard_post_init_user(void)
+{
+ m_gpio_init();
+ rf_uart_init();
+ wait_ms(500);
+ rf_device_init();
+
+ m_break_all_key();
+ m_londing_eeprom_data();
+ m_power_on_dial_sw_scan();
+
+ rf_link_show_time = 0;
+}
+
+/**
+ rgb_matrix_indicators_user
+ */
+bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max)
+{
+ if (keymap_config.no_gui) {
+ rgb_matrix_set_color(72, 0x00, 0x80, 0x00);
+ }
+ return true;
+}
+
+/**
+ housekeeping_task_user
+ */
+void housekeeping_task_user(void)
+{
+
+ timer_pro();
+
+ uart_receive_pro();
+
+ uart_send_report_func();
+
+ dev_sts_sync();
+
+ long_press_key();
+
+ dial_sw_scan();
+
+ m_side_led_show();
+
+ Sleep_Handle();
+
+}
diff --git a/keyboards/nuphy/halo75/ansi/ansi.h b/keyboards/nuphy/halo75/ansi/ansi.h
new file mode 100644
index 000000000000..b5acfebec029
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/ansi.h
@@ -0,0 +1,206 @@
+// Copyright 2023 Persama (@Persama)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+#include "quantum.h"
+
+enum custom_keycodes {
+ RF_DFU = QK_KB_0,
+ LNK_USB,
+ LNK_RF,
+ LNK_BLE1,
+ LNK_BLE2,
+ LNK_BLE3,
+
+ MAC_TASK,
+ MAC_SEARCH,
+ MAC_VOICE,
+ MAC_CONSOLE,
+ MAC_DND,
+ MAC_PRT,
+ MAC_PRTA,
+
+ DEV_RESET,
+ SLEEP_MODE,
+ BAT_SHOW,
+
+ SIDE_VAI,
+ SIDE_VAD,
+ SIDE_MOD_A,
+ SIDE_MOD_B,
+ SIDE_HUI,
+ SIDE_SPI,
+ SIDE_SPD,
+};
+
+extern uint8_t m_sleep_led;
+
+typedef enum {
+ RX_Idle,
+ RX_Receiving,
+ RX_Done,
+ RX_Fail,
+ RX_OV_ERR,
+ RX_SUM_ERR,
+ RX_CMD_ERR,
+ RX_DATA_ERR,
+ RX_DATA_OV,
+ RX_FORMAT_ERR,
+
+ TX_OK = 0XE0,
+ TX_DONE,
+ TX_BUSY,
+ TX_TIMEOUT,
+ TX_DATA_ERR,
+
+} TYPE_RX_STATE;
+
+#define FUNC_VALID_LEN 32
+#define UART_HEAD 0x5A
+
+#define RF_IDLE 0
+#define RF_PAIRING 1
+#define RF_LINKING 2
+#define RF_CONNECT 3
+#define RF_DISCONNECT 4
+#define RF_SLEEP 5
+#define RF_SNIF 6
+#define RF_INVAILD 0XFE
+#define RF_ERR_STATE 0XFF
+
+#define RF_LONG_PRESS_DELAY 30
+#define DEV_RESET_PRESS_DELAY 30
+#define RGB_TEST_PRESS_DELAY 30
+
+#define CMD_POWER_UP 0XF0
+#define CMD_SLEEP 0XF1
+#define CMD_HAND 0XF2
+#define CMD_SNIF 0XF3
+#define CMD_24G_SUSPEND 0XF4
+#define CMD_IDLE_EXIT 0XFE
+
+#define CMD_RPT_MS 0XE0
+#define CMD_RPT_BYTE_KB 0XE1
+#define CMD_RPT_BIT_KB 0XE2
+#define CMD_RPT_CONSUME 0XE3
+#define CMD_RPT_SYS 0XE4
+
+#define CMD_SET_LINK 0XC0
+#define CMD_SET_CONFIG 0XC1
+#define CMD_GET_CONFIG 0XC2
+#define CMD_SET_NAME 0XC3
+#define CMD_GET_NAME 0XC4
+#define CMD_CLR_DEVICE 0XC5
+#define CMD_NEW_ADV 0XC7
+#define CMD_RF_STS_SYSC 0XC9
+#define CMD_SET_24G_NAME 0XCA
+#define CMD_GO_TEST 0XCF
+
+#define CMD_RF_DFU 0XB1
+
+#define CMD_WRITE_DATA 0X80
+#define CMD_READ_DATA 0X81
+
+#define CMD_WBAT_CFG 0X82
+#define CMD_RBAT_CFG 0X83
+
+#define LINK_RF_24 0
+#define LINK_BT_1 1
+#define LINK_BT_2 2
+#define LINK_BT_3 3
+#define LINK_USB 4
+
+#define UART_MAX_LEN 64
+typedef struct
+{
+ uint8_t RXDState;
+ uint8_t RXDLen;
+ uint8_t RXDOverTime;
+ uint8_t TXDLenBack;
+ uint8_t TXDOffset;
+ uint8_t TXDBuf[UART_MAX_LEN];
+ uint8_t RXDBuf[UART_MAX_LEN];
+} USART_MGR_STRUCT;
+
+typedef struct
+{
+ uint8_t link_mode;
+ uint8_t rf_channel;
+ uint8_t ble_channel;
+ uint8_t rf_state;
+ uint8_t rf_charge;
+ uint8_t rf_led;
+ uint8_t rf_baterry;
+ uint8_t sys_sw_state;
+} DEV_INFO_STRUCT;
+
+#define DELAY_2MS 2
+#define DELAY_4MS 4
+#define DELAY_5MS 5
+#define DELAY_6MS 6
+#define DELAY_8MS 8
+#define DELAY_10MS 10
+#define DELAY_15MS 15
+#define DELAY_20MS 20
+#define DELAY_30MS 30
+#define DELAY_40MS 40
+#define DELAY_50MS 50
+#define DELAY_100MS 100
+#define DELAY_200MS 200
+#define DELAY_300MS 300
+#define DELAY_400MS 400
+#define DELAY_500MS 500
+#define DELAY_800MS 800
+#define DELAY_1SEC 1000
+#define DELAY_2SEC 2000
+#define DELAY_3SEC 3000
+#define DELAY_4SEC 4000
+#define DELAY_5SEC 5000
+
+#define SYS_SW_WIN 0xa1
+#define SYS_SW_MAC 0xa2
+
+#define RF_LINK_SHOW_TIME 300
+
+#define HOST_USB_TYPE 0
+#define HOST_BLE_TYPE 1
+#define HOST_RF_TYPE 2
+
+#if (1)
+#define LINK_TIMEOUT (uint32_t)(100 * 120)
+#define SLEEP_TIME_DELAY (uint32_t)(100 * 360)
+#define POWER_DOWN_DELAY (uint16_t)(24)
+
+#else
+#define LINK_TIMEOUT (100 * 10)
+#define SLEEP_TIME_DELAY (100 * 30)
+#define POWER_DOWN_DELAY (30)
+
+#endif
+
+typedef struct
+{
+ uint8_t bit0: 1;
+ uint8_t bit1: 1;
+ uint8_t bit2: 1;
+ uint8_t bit3: 1;
+ uint8_t bit4: 1;
+ uint8_t bit5: 1;
+ uint8_t bit6: 1;
+ uint8_t bit7: 1;
+}m_8bit;
+
+typedef struct
+{
+ uint8_t default_brightness_flag;
+ uint8_t ee_side_mode_a;
+ uint8_t ee_side_mode_b;
+ uint8_t ee_side_light;
+ uint8_t ee_side_speed;
+ uint8_t ee_side_rgb;
+ uint8_t ee_side_colour;
+ m_8bit ee_dev_config;
+} user_config_t;
+
+extern user_config_t user_config;
+#define f_dev_sleep_enable user_config.ee_dev_config.bit0
\ No newline at end of file
diff --git a/keyboards/nuphy/halo75/ansi/config.h b/keyboards/nuphy/halo75/ansi/config.h
new file mode 100644
index 000000000000..2a2694e70785
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/config.h
@@ -0,0 +1,85 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#pragma once
+
+#define RGB_MATRIX_LED_FLUSH_LIMIT 32
+
+#define TAP_CODE_DELAY 8
+#define DYNAMIC_KEYMAP_MACRO_DELAY 8
+// This is the size of the EEPROM for the custom VIA-specific data
+#define EECONFIG_USER_DATA_SIZE 12
+
+#define DEV_MODE_PIN C0
+#define SYS_MODE_PIN C1
+#define DC_BOOST_PIN C2
+#define NRF_RESET_PIN B4
+#define NRF_BOOT_PIN B5
+#define NRF_WAKEUP_PIN C4
+
+#define RGB_DRIVER_SDB1 C6
+#define RGB_DRIVER_SDB2 C7
+
+#define SERIAL_DRIVER SD1
+#define SD1_TX_PIN B6
+#define SD1_TX_PAL_MODE 0
+#define SD1_RX_PIN B7
+#define SD1_RX_PAL_MODE 0
+
+// This is a 7-bit address, that gets left-shifted and bit 0
+// set to 0 for write, 1 for read (as per I2C protocol)
+// The address will vary depending on your wiring:
+// 0b1110100 AD <-> GND
+// 0b1110111 AD <-> VCC
+// 0b1110101 AD <-> SCL
+// 0b1110110 AD <-> SDA
+#define DRIVER_ADDR_1 0b1010000
+#define DRIVER_ADDR_2 0b1010011
+
+#define ISSI_TIMEOUT 1
+
+/* I2C Alternate function settings */
+#define I2C_DRIVER I2CD1
+#define I2C1_SCL_PIN B8
+#define I2C1_SDA_PIN B9
+#define I2C1_CLOCK_SPEED 1000000
+
+#define I2C1_SCL_PAL_MODE 1
+#define I2C1_SDA_PAL_MODE 1
+
+#define I2C1_TIMINGR_PRESC 0U
+#define I2C1_TIMINGR_SCLDEL 0U
+#define I2C1_TIMINGR_SDADEL 0U
+#define I2C1_TIMINGR_SCLH 0U
+#define I2C1_TIMINGR_SCLL 0U
+#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_16_9
+
+#define DRIVER_COUNT 2
+#define DRIVER_1_LED_TOTAL 64
+#define DRIVER_2_LED_TOTAL 64
+#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
+
+#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CUSTOM_position_mode
+#define RGB_DEFAULT_COLOUR 168
+
+#define RGB_MATRIX_SLEEP // turn off effects when suspended
+
+#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+#define RGB_MATRIX_KEYPRESSES
+#define RGB_MATRIX_KEYRELEASES
+
+#define IS31FL3733_SW_PULLUP PUR_05KR
+#define IS31FL3733_CS_PULLDOWN PUR_05KR
diff --git a/keyboards/nuphy/halo75/ansi/halconf.h b/keyboards/nuphy/halo75/ansi/halconf.h
new file mode 100644
index 000000000000..a98b7214a9eb
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/halconf.h
@@ -0,0 +1,28 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#pragma once
+
+#undef HAL_USE_SERIAL
+#define HAL_USE_SERIAL TRUE
+
+#undef HAL_USE_I2C
+#define HAL_USE_I2C TRUE
+
+#undef HAL_USE_DMA
+#define HAL_USE_DMA TRUE
+
+#include_next
diff --git a/keyboards/nuphy/halo75/ansi/info.json b/keyboards/nuphy/halo75/ansi/info.json
new file mode 100644
index 000000000000..8bd600268f07
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/info.json
@@ -0,0 +1,318 @@
+{
+ "keyboard_name": "NuPhy Halo75 V2",
+ "manufacturer": "NuPhy",
+ "usb":{
+ "vid": "0x19F5",
+ "pid": "0x32F5",
+ "device_version": "1.0.0",
+ "no_startup_check": true
+ },
+ "features": {
+ "bootmagic": true,
+ "mousekey": true,
+ "extrakey": true,
+ "console": true,
+ "command": false,
+ "nkro": true,
+ "key_lock": true,
+ "encoder": false,
+ "rgb_matrix": true
+ },
+ "processor": "STM32F072",
+ "bootloader": "stm32-dfu",
+ "dynamic_keymap": {
+ "layer_count": 8
+ },
+ "debounce": 5,
+ "build": {
+ "debounce_type": "sym_eager_pk"
+ },
+ "matrix_pins": {
+ "cols": ["A4", "A5", "A6", "A7", "B0", "B1", "B10", "B11", "B12", "B13", "B14", "B15", "A8", "A9", "A10", "A15", "B3"],
+ "rows": ["C14", "C15", "A0", "A1", "A2", "A3"]
+ },
+ "diode_direction": "COL2ROW",
+ "rgb_matrix": {
+ "driver": "is31fl3733",
+ "center_point": [70, 20],
+ "max_brightness": 255,
+ "val_steps": 64,
+ "speed_steps": 52,
+ "animations": {
+ "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,
+ "rainbow_moving_chevron": true,
+ "cycle_out_in": true,
+ "cycle_out_in_dual": true,
+ "cycle_pinwheel": true,
+ "cycle_spiral": true,
+ "dual_beacon": true,
+ "rainbow_beacon": true,
+ "rainbow_pinwheels": true,
+ "raindrops": true,
+ "jellybean_raindrops": true,
+ "hue_breathing": true,
+ "hue_pendulum": true,
+ "hue_wave": true,
+ "typing_heatmap": true,
+ "digital_rain": true,
+ "solid_reactive_simple": true,
+ "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
+ },
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0, "flags": 4},
+ {"matrix": [0, 1], "x": 10, "y": 0, "flags": 4},
+ {"matrix": [0, 2], "x": 20, "y": 0, "flags": 4},
+ {"matrix": [0, 3], "x": 30, "y": 0, "flags": 4},
+ {"matrix": [0, 4], "x": 40, "y": 0, "flags": 4},
+ {"matrix": [0, 5], "x": 50, "y": 0, "flags": 4},
+ {"matrix": [0, 6], "x": 60, "y": 0, "flags": 4},
+ {"matrix": [0, 7], "x": 70, "y": 0, "flags": 4},
+ {"matrix": [0, 8], "x": 80, "y": 0, "flags": 4},
+ {"matrix": [0, 9], "x": 90, "y": 0, "flags": 4},
+ {"matrix": [0, 10], "x": 100, "y": 0, "flags": 4},
+ {"matrix": [0, 11], "x": 110, "y": 0, "flags": 4},
+ {"matrix": [0, 12], "x": 120, "y": 0, "flags": 4},
+ {"matrix": [0, 13], "x": 130, "y": 0, "flags": 4},
+ {"matrix": [0, 15], "x": 140, "y": 0, "flags": 4},
+ {"matrix": [0, 14], "x": 150, "y": 0, "flags": 4},
+
+ {"matrix": [1, 0], "x": 0, "y": 10, "flags": 4},
+ {"matrix": [1, 1], "x": 10, "y": 10, "flags": 4},
+ {"matrix": [1, 2], "x": 20, "y": 10, "flags": 4},
+ {"matrix": [1, 3], "x": 30, "y": 10, "flags": 4},
+ {"matrix": [1, 4], "x": 40, "y": 10, "flags": 4},
+ {"matrix": [1, 5], "x": 50, "y": 10, "flags": 4},
+ {"matrix": [1, 6], "x": 60, "y": 10, "flags": 4},
+ {"matrix": [1, 7], "x": 70, "y": 10, "flags": 4},
+ {"matrix": [1, 8], "x": 80, "y": 10, "flags": 4},
+ {"matrix": [1, 9], "x": 90, "y": 10, "flags": 4},
+ {"matrix": [1, 10], "x": 100, "y": 10, "flags": 4},
+ {"matrix": [1, 11], "x": 110, "y": 10, "flags": 4},
+ {"matrix": [1, 12], "x": 120, "y": 10, "flags": 4},
+ {"matrix": [1, 13], "x": 130, "y": 10, "flags": 4},
+ {"matrix": [1, 15], "x": 150, "y": 10, "flags": 4},
+
+ {"matrix": [2, 0], "x": 0, "y": 20, "flags": 4},
+ {"matrix": [2, 1], "x": 15, "y": 20, "flags": 4},
+ {"matrix": [2, 2], "x": 25, "y": 20, "flags": 4},
+ {"matrix": [2, 3], "x": 35, "y": 20, "flags": 4},
+ {"matrix": [2, 4], "x": 45, "y": 20, "flags": 4},
+ {"matrix": [2, 5], "x": 55, "y": 20, "flags": 4},
+ {"matrix": [2, 6], "x": 65, "y": 20, "flags": 4},
+ {"matrix": [2, 7], "x": 75, "y": 20, "flags": 4},
+ {"matrix": [2, 8], "x": 85, "y": 20, "flags": 4},
+ {"matrix": [2, 9], "x": 95, "y": 20, "flags": 4},
+ {"matrix": [2, 10], "x": 105, "y": 20, "flags": 4},
+ {"matrix": [2, 11], "x": 115, "y": 20, "flags": 4},
+ {"matrix": [2, 12], "x": 125, "y": 20, "flags": 4},
+ {"matrix": [2, 13], "x": 135, "y": 20, "flags": 4},
+ {"matrix": [2, 15], "x": 150, "y": 20, "flags": 4},
+
+ {"matrix": [3, 0], "x": 0, "y": 30, "flags": 4},
+ {"matrix": [3, 1], "x": 17.5, "y": 30, "flags": 4},
+ {"matrix": [3, 2], "x": 27.5, "y": 30, "flags": 4},
+ {"matrix": [3, 3], "x": 37.5, "y": 30, "flags": 4},
+ {"matrix": [3, 4], "x": 47.5, "y": 30, "flags": 4},
+ {"matrix": [3, 5], "x": 57.5, "y": 30, "flags": 4},
+ {"matrix": [3, 6], "x": 67.5, "y": 30, "flags": 4},
+ {"matrix": [3, 7], "x": 77.5, "y": 30, "flags": 4},
+ {"matrix": [3, 8], "x": 87.5, "y": 30, "flags": 4},
+ {"matrix": [3, 9], "x": 97.5, "y": 30, "flags": 4},
+ {"matrix": [3, 10], "x": 107.5, "y": 30, "flags": 4},
+ {"matrix": [3, 11], "x": 117.5, "y": 30, "flags": 4},
+ {"matrix": [3, 13], "x": 127.5, "y": 30, "flags": 4},
+ {"matrix": [3, 15], "x": 150, "y": 30, "flags": 4},
+
+ {"matrix": [4, 0], "x": 0, "y": 40, "flags": 4},
+ {"matrix": [4, 2], "x": 22.5, "y": 40, "flags": 4},
+ {"matrix": [4, 3], "x": 32.5, "y": 40, "flags": 4},
+ {"matrix": [4, 4], "x": 42.5, "y": 40, "flags": 4},
+ {"matrix": [4, 5], "x": 52.5, "y": 40, "flags": 4},
+ {"matrix": [4, 6], "x": 62.5, "y": 40, "flags": 4},
+ {"matrix": [4, 7], "x": 72.5, "y": 40, "flags": 4},
+ {"matrix": [4, 8], "x": 82.5, "y": 40, "flags": 4},
+ {"matrix": [4, 9], "x": 92.5, "y": 40, "flags": 4},
+ {"matrix": [4, 10], "x": 102.5, "y": 40, "flags": 4},
+ {"matrix": [4, 11], "x": 112.5, "y": 40, "flags": 4},
+ {"matrix": [4, 13], "x": 122.5, "y": 40, "flags": 4},
+ {"matrix": [4, 14], "x": 140, "y": 40, "flags": 4},
+ {"matrix": [4, 15], "x": 150, "y": 40, "flags": 4},
+
+ {"matrix": [5, 0], "x": 0, "y": 50, "flags": 4},
+ {"matrix": [5, 1], "x": 12.5, "y": 50, "flags": 4},
+ {"matrix": [5, 2], "x": 25, "y": 50, "flags": 4},
+ {"matrix": [5, 6], "x": 37.5, "y": 50, "flags": 4},
+ {"matrix": [5, 9], "x": 100, "y": 50, "flags": 4},
+ {"matrix": [5, 10], "x": 112.5, "y": 50, "flags": 4},
+ {"matrix": [5, 13], "x": 130.0, "y": 50, "flags": 4},
+ {"matrix": [5, 14], "x": 140.0, "y": 50, "flags": 4},
+ {"matrix": [5, 15], "x": 150.0, "y": 50, "flags": 4},
+
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0},
+ {"flags": 0}
+
+ ]
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"label": "Esc", "matrix": [0, 0], "x": 0, "y": 0},
+ {"label": "F1", "matrix": [0, 1], "x": 1, "y": 0},
+ {"label": "F2", "matrix": [0, 2], "x": 2, "y": 0},
+ {"label": "F3", "matrix": [0, 3], "x": 3, "y": 0},
+ {"label": "F4", "matrix": [0, 4], "x": 4, "y": 0},
+ {"label": "F5", "matrix": [0, 5], "x": 5, "y": 0},
+ {"label": "F6", "matrix": [0, 6], "x": 6, "y": 0},
+ {"label": "F7", "matrix": [0, 7], "x": 7, "y": 0},
+ {"label": "F8", "matrix": [0, 8], "x": 8, "y": 0},
+ {"label": "F9", "matrix": [0, 9], "x": 9, "y": 0},
+ {"label": "F10", "matrix": [0, 10], "x": 10, "y": 0},
+ {"label": "F11", "matrix": [0, 11], "x": 11, "y": 0},
+ {"label": "F12", "matrix": [0, 12], "x": 12, "y": 0},
+ {"label": "PRT", "matrix": [0, 13], "x": 13, "y": 0},
+ {"label": "INS", "matrix": [0, 15], "x": 14, "y": 0},
+ {"label": "Del", "matrix": [0, 14], "x": 15, "y": 0},
+
+ {"label": "~`", "matrix": [1, 0], "x": 0, "y": 1},
+ {"label": "!1", "matrix": [1, 1], "x": 1, "y": 1},
+ {"label": "@2", "matrix": [1, 2], "x": 2, "y": 1},
+ {"label": "#3", "matrix": [1, 3], "x": 3, "y": 1},
+ {"label": "$4", "matrix": [1, 4], "x": 4, "y": 1},
+ {"label": "%5", "matrix": [1, 5], "x": 5, "y": 1},
+ {"label": "^6", "matrix": [1, 6], "x": 6, "y": 1},
+ {"label": "&7", "matrix": [1, 7], "x": 7, "y": 1},
+ {"label": "*8", "matrix": [1, 8], "x": 8, "y": 1},
+ {"label": "(9", "matrix": [1, 9], "x": 9, "y": 1},
+ {"label": ")0", "matrix": [1, 10], "x": 10, "y": 1},
+ {"label": "_-", "matrix": [1, 11], "x": 11, "y": 1},
+ {"label": "+=", "matrix": [1, 12], "x": 12, "y": 1},
+ {"label": "Backsp", "matrix": [1, 13], "x": 13, "y": 1, "w": 2},
+ {"label": "HOME", "matrix": [1, 15], "x": 15, "y": 1},
+
+ {"label": "Tab", "matrix": [2, 0], "x": 0, "y": 2, "w": 1.5},
+ {"label": "Q", "matrix": [2, 1], "x": 1.5, "y": 2},
+ {"label": "W", "matrix": [2, 2], "x": 2.5, "y": 2},
+ {"label": "E", "matrix": [2, 3], "x": 3.5, "y": 2},
+ {"label": "R", "matrix": [2, 4], "x": 4.5, "y": 2},
+ {"label": "T", "matrix": [2, 5], "x": 5.5, "y": 2},
+ {"label": "Y", "matrix": [2, 6], "x": 6.5, "y": 2},
+ {"label": "U", "matrix": [2, 7], "x": 7.5, "y": 2},
+ {"label": "I", "matrix": [2, 8], "x": 8.5, "y": 2},
+ {"label": "O", "matrix": [2, 9], "x": 9.5, "y": 2},
+ {"label": "P", "matrix": [2, 10], "x": 10.5, "y": 2},
+ {"label": "{[", "matrix": [2, 11], "x": 11.5, "y": 2},
+ {"label": "}]", "matrix": [2, 12], "x": 12.5, "y": 2},
+ {"label": "|\\", "matrix": [2, 13], "x": 13.5, "y": 2, "w": 1.5},
+ {"label": "END", "matrix": [2, 15], "x": 15, "y": 2},
+
+ {"label": "Caps", "matrix": [3, 0], "x": 0, "y": 3, "w": 1.75},
+ {"label": "A", "matrix": [3, 1], "x": 1.75, "y": 3},
+ {"label": "S", "matrix": [3, 2], "x": 2.75, "y": 3},
+ {"label": "D", "matrix": [3, 3], "x": 3.75, "y": 3},
+ {"label": "F", "matrix": [3, 4], "x": 4.75, "y": 3},
+ {"label": "G", "matrix": [3, 5], "x": 5.75, "y": 3},
+ {"label": "H", "matrix": [3, 6], "x": 6.75, "y": 3},
+ {"label": "J", "matrix": [3, 7], "x": 7.75, "y": 3},
+ {"label": "K", "matrix": [3, 8], "x": 8.75, "y": 3},
+ {"label": "L", "matrix": [3, 9], "x": 9.75, "y": 3},
+ {"label": ":", "matrix": [3, 10], "x": 10.75, "y": 3},
+ {"label": "\"", "matrix": [3, 11], "x": 11.75, "y": 3},
+ {"label": "Enter", "matrix": [3, 13], "x": 12.75, "y": 3, "w": 2.25},
+ {"label": "PageUP", "matrix": [3, 15], "x": 15.00, "y": 2},
+
+ {"label": "Shift", "matrix": [4, 0], "x": 0, "y": 4, "w": 2.25},
+ {"label": "Z", "matrix": [4, 2], "x": 2.25, "y": 4},
+ {"label": "X", "matrix": [4, 3], "x": 3.25, "y": 4},
+ {"label": "C", "matrix": [4, 4], "x": 4.25, "y": 4},
+ {"label": "V", "matrix": [4, 5], "x": 5.25, "y": 4},
+ {"label": "B", "matrix": [4, 6], "x": 6.25, "y": 4},
+ {"label": "N", "matrix": [4, 7], "x": 7.25, "y": 4},
+ {"label": "M", "matrix": [4, 8], "x": 8.25, "y": 4},
+ {"label": "<,", "matrix": [4, 9], "x": 9.25, "y": 4},
+ {"label": ">.", "matrix": [4, 10], "x": 10.25, "y": 4},
+ {"label": "?/", "matrix": [4, 11], "x": 11.25, "y": 4},
+ {"label": "Shift", "matrix": [4, 13], "x": 12.25, "y": 4, "w": 1.75},
+ {"label": "↑", "matrix": [4, 14], "x": 14.00, "y": 4},
+ {"label": "↑", "matrix": [4, 15], "x": 15.00, "y": 4},
+
+ {"label": "Ctrl", "matrix": [5, 0], "x": 0, "y": 5, "w": 1.25},
+ {"label": "Opt", "matrix": [5, 1], "x": 1.25, "y": 5, "w": 1.25},
+ {"label": "Cmd", "matrix": [5, 2], "x": 2.5, "y": 5, "w": 1.25},
+ {"label": "Space", "matrix": [5, 6], "x": 3.75, "y": 5, "w": 6.25},
+ {"label": "Cmd", "matrix": [5, 9], "x": 10, "y": 5, "w": 1.25},
+ {"label": "Fn", "matrix": [5, 10], "x": 11.25, "y": 5, "w": 1.25},
+ {"label": "←", "matrix": [5, 13], "x": 13, "y": 5},
+ {"label": "↓", "matrix": [5, 14], "x": 14, "y": 5},
+ {"label": "→", "matrix": [5, 15], "x": 15, "y": 5}
+
+ ]
+ }
+ }
+}
+
diff --git a/keyboards/nuphy/halo75/ansi/keymaps/via/NuPhy Halo75 via3.json b/keyboards/nuphy/halo75/ansi/keymaps/via/NuPhy Halo75 via3.json
new file mode 100644
index 000000000000..b312b2e31517
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/keymaps/via/NuPhy Halo75 via3.json
@@ -0,0 +1,197 @@
+{
+ "name": "NuPhy Halo75",
+ "vendorId": "0x19F5",
+ "productId": "0x32F5",
+ "matrix": {
+ "rows": 6,
+ "cols": 17
+ },
+ "layouts": {
+ "keymap": [
+ ["0,0","0,1","0,2","0,3","0,4","0,5","0,6","0,7","0,8","0,9","0,10","0,11","0,12","0,13","0,14","0,15"],
+ ["1,0","1,1","1,2","1,3","1,4","1,5","1,6","1,7","1,8","1,9","1,10","1,11","1,12",{"w":2},"1,13","1,15"],
+ [{"w":1.5},"2,0","2,1","2,2","2,3","2,4","2,5","2,6","2,7","2,8","2,9","2,10","2,11","2,12",{"w":1.5},"2,13","2,15"],
+ [{"w":1.75},"3,0","3,1","3,2","3,3","3,4","3,5","3,6","3,7","3,8","3,9","3,10","3,11",{"w":2.25},"3,13","3,15"],
+ [{"w":2.25},"4,0","4,2","4,3","4,4","4,5","4,6","4,7","4,8","4,9","4,10","4,11",{"w":1.75},"4,13","4,14","4,15"],
+ [{"w":1.25},"5,0",{"w":1.25},"5,1",{"w":1.25},"5,2",{"w":6.25},"5,6",{"w":1.25},"5,9",{"w":1.25},"5,10",{"x":0.5},"5,13","5,14","5,15"]
+ ]
+ },
+ "menus": [
+ {
+ "label": "Lighting",
+ "content": [
+ {
+ "label": "Backlight",
+ "content": [
+ {
+ "label": "Brightness",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_brightness", 3, 1]
+ },
+ {
+ "label": "Effect",
+ "type": "dropdown",
+ "content": ["id_qmk_rgb_matrix_effect", 3, 2],
+ "options": [
+ "All Off",
+ "Solid Color",
+ "Gradient Up/Down",
+ "Gradient Left/Right",
+ "Breathing",
+ "Band Sat.",
+ "Band Val.",
+ "Pinwheel Sat.",
+ "Pinwheel Val.",
+ "Spiral Sat.",
+ "Spiral Val.",
+ "Cycle All",
+ "Cycle Left/Right",
+ "Cycle Up/Down",
+ "Rainbow Moving Chevron",
+ "Cycle Out/In",
+ "Cycle Out/In Dual",
+ "Cycle Pinwheel",
+ "Cycle Spiral",
+ "Dual Beacon",
+ "Rainbow Beacon",
+ "Rainbow Pinwheels",
+ "Raindrops",
+ "Jellybean Raindrops",
+ "Hue Breathing",
+ "Hue Pendulum",
+ "Hue Wave",
+ "Typing Heatmap",
+ "Digital Rain",
+ "Reactive Simple",
+ "Reactive",
+ "Reactive Wide",
+ "Reactive Multiwide",
+ "Reactive Cross",
+ "Reactive Multicross",
+ "Reactive Nexus",
+ "Reactive MultiNexus",
+ "Splash",
+ "MultiSplash",
+ "Solid Splash",
+ "Solid MultiSplash",
+ "game_mode",
+ "position_mode"
+ ]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0",
+ "label": "Effect Speed",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_effect_speed", 3, 3]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0",
+ "label": "Color",
+ "type": "color",
+ "content": ["id_qmk_rgb_matrix_color", 3, 4]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+"keycodes": [
+ "qmk_lighting"
+],
+"customKeycodes": [
+ {
+ "name": "RF\nDFU",
+ "title": "RF DFU"
+ },
+ {
+ "name": "Link\nUSB",
+ "title": "Link USB"
+ },
+ {
+ "name": "Link\nRF",
+ "title": "Link RF"
+ },
+ {
+ "name": "Link\nBLE_1",
+ "title": "Link BLE_1"
+ },
+ {
+ "name": "Link\nBLE_2",
+ "title": "Link BLE_2"
+ },
+ {
+ "name": "Link\nBLE_3",
+ "title": "Link BLE_3"
+ },
+ {
+ "name": "Mac\nTask",
+ "title": "Mac Task"
+ },
+ {
+ "name": "Mac\nSearch",
+ "title": "Mac Search"
+ },
+ {
+ "name": "Mac\nVoice",
+ "title": "Mac Siri Voice"
+ },
+ {
+ "name": "Mac\nConsole",
+ "title": "Mac Console"
+ },
+ {
+ "name": "Mac\nDnt",
+ "title": "Mac Dnt"
+ },
+ {
+ "name": "Print\nWhole",
+ "title": "PrintWhole"
+ },
+ {
+ "name": "Print\nArea",
+ "title": "PrintArea"
+ },
+ {
+ "name": "Dev\nReset",
+ "title": "Device Reset"
+ },
+ {
+ "name": "Sleep\nMode",
+ "title": "Auto Sleep"
+ },
+ {
+ "name": "Bat\nShow",
+ "title": "Battery Show"
+ },
+ {
+ "name": "Side\nLight+",
+ "title": "Side Light +"
+ },
+ {
+ "name": "Side\nLight-",
+ "title": "Side Light -"
+ },
+ {
+ "name": "Side\nMode_A",
+ "title": "Side Next Mode"
+ },
+ {
+ "name": "Side\nMode_B",
+ "title": "Side Next Mode"
+ },
+ {
+ "name": "Side\nColor",
+ "title": "Side Next Color"
+ },
+ {
+ "name": "Side\nFast",
+ "title": "Side Speed +"
+ },
+ {
+ "name": "Side\nSlow",
+ "title": "Side Speed -"
+ }
+]
+}
diff --git a/keyboards/nuphy/halo75/ansi/keymaps/via/keymap.c b/keyboards/nuphy/halo75/ansi/keymaps/via/keymap.c
new file mode 100644
index 000000000000..64031b9d1331
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/keymaps/via/keymap.c
@@ -0,0 +1,185 @@
+#include QMK_KEYBOARD_H
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// layer Mac
+[0] = LAYOUT(
+ KC_ESC, KC_SCRL, KC_PAUSE, MAC_TASK, MAC_SEARCH, MAC_VOICE, MAC_DND, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, MAC_PRTA, KC_DEL, KC_INS,
+ 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_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_END,
+ 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_PGUP,
+ 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_PGDN,
+ KC_LCTL, KC_LOPT, KC_LCMD, KC_SPC, KC_RCMD, MO(1), KC_LEFT, KC_DOWN, KC_RIGHT),
+// layer Mac Fn
+[1] = LAYOUT(
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MAC_PRT, _______, _______,
+ _______, LNK_BLE1, LNK_BLE2, LNK_BLE3, LNK_RF, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, DEV_RESET, SLEEP_MODE, BAT_SHOW, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, MO(4), RGB_SPD, RGB_SPI, _______, _______, RGB_VAI, _______,
+ _______, _______, _______, _______, _______, MO(1), RGB_MOD, RGB_VAD, RGB_HUI),
+// layer win
+[2] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MAC_PRTA, KC_DEL, KC_INS,
+ 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_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_END,
+ 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_PGUP,
+ 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_PGDN,
+ KC_LCTL, KC_LWIN, KC_LALT, KC_SPC, KC_RALT, MO(3), KC_LEFT, KC_DOWN, KC_RIGHT),
+// layer win Fn
+[3] = LAYOUT(
+ _______, KC_BRID, KC_BRIU, KC_F3, KC_F4, KC_F5, KC_F6, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_PSCR, _______, _______,
+ _______, LNK_BLE1, LNK_BLE2, LNK_BLE3, LNK_RF, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, DEV_RESET, SLEEP_MODE, BAT_SHOW, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, MO(4), RGB_SPD, RGB_SPI, _______, _______, RGB_VAI, _______,
+ _______, _______, _______, _______, _______, MO(3), RGB_MOD, RGB_VAD, RGB_HUI),
+// layer 4
+[4] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, SIDE_SPD, SIDE_SPI, SIDE_MOD_B, _______, SIDE_VAI, _______,
+ _______, _______, _______, _______, _______, MO(4), SIDE_MOD_A, SIDE_VAD, SIDE_HUI),
+};
+
+
+const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = {
+ {0, A_6, B_6, C_6},
+ {0, A_7, B_7, C_7},
+ {0, A_8, B_8, C_8},
+ {0, A_9, B_9, C_9},
+ {0, A_10, B_10, C_10},
+ {0, A_11, B_11, C_11},
+ {0, A_12, B_12, C_12},
+ {1, A_1, B_1, C_1},
+ {1, A_2, B_2, C_2},
+ {1, A_3, B_3, C_3},
+ {1, A_4, B_4, C_4},
+ {1, A_5, B_5, C_5},
+ {1, A_6, B_6, C_6},
+ {1, A_7, B_7, C_7},
+ {1, A_9, B_9, C_9},
+ {1, A_8, B_8, C_8},
+
+ {0, D_1, E_1, F_1},
+ {0, D_2, E_2, F_2},
+ {0, D_3, E_3, F_3},
+ {0, D_4, E_4, F_4},
+ {0, A_13, B_13, C_13},
+ {0, A_14, B_14, C_14},
+ {0, A_15, B_15, C_15},
+ {0, A_16, B_16, C_16},
+ {1, A_10, B_10, C_10},
+ {1, A_11, B_11, C_11},
+ {1, A_12, B_12, C_12},
+ {1, A_13, B_13, C_13},
+ {1, A_14, B_14, C_14},
+ {1, A_15, B_15, C_15},
+ {1, A_16, B_16, C_16},
+
+ {0, D_5, E_5, F_5},
+ {0, D_6, E_6, F_6},
+ {0, D_7, E_7, F_7},
+ {0, D_8, E_8, F_8},
+ {0, D_9, E_9, F_9},
+ {0, D_10, E_10, F_10},
+ {0, D_11, E_11, F_11},
+ {1, D_1, E_1, F_1},
+ {1, D_2, E_2, F_2},
+ {1, D_3, E_3, F_3},
+ {1, D_4, E_4, F_4},
+ {1, D_5, E_5, F_5},
+ {1, D_6, E_6, F_6},
+ {1, D_7, E_7, F_7},
+ {1, D_8, E_8, F_8},
+
+ {0, G_1, H_1, I_1},
+ {0, G_2, H_2, I_2},
+ {0, G_3, H_3, I_3},
+ {0, G_4, H_4, I_4},
+ {0, G_5, H_5, I_5},
+ {0, G_6, H_6, I_6},
+ {0, G_7, H_7, I_7},
+ {0, G_8, H_8, I_8},
+ {1, G_1, H_1, I_1},
+ {1, G_2, H_2, I_2},
+ {1, G_3, H_3, I_3},
+ {1, G_4, H_4, I_4},
+ {1, G_5, H_5, I_5},
+ {1, G_6, H_6, I_6},
+
+ {0, J_1, K_1, L_1},
+ {0, J_2, K_2, L_2},
+ {0, J_3, K_3, L_3},
+ {0, J_4, K_4, L_4},
+ {0, J_5, K_5, L_5},
+ {0, J_6, K_6, L_6},
+ {0, J_7, K_7, L_7},
+ {0, J_8, K_8, L_8},
+ {1, J_1, K_1, L_1},
+ {1, J_2, K_2, L_2},
+ {1, J_3, K_3, L_3},
+ {1, J_4, K_4, L_4},
+ {1, J_5, K_5, L_5},
+ {1, J_8, K_8, L_8},
+
+ {0, J_9, K_9, L_9},
+ {0, J_10, K_10, L_10},
+ {0, J_11, K_11, L_11},
+ {0, J_12, K_12, L_12},
+ {1, J_6, K_6, L_6},
+ {1, J_7, K_7, L_7},
+ {1, J_9, K_9, L_9},
+ {1, J_10, K_10, L_10},
+ {1, J_11, K_11, L_11},
+
+ {0, A_1, B_1, C_1},
+ {0, A_2, B_2, C_2},
+ {0, A_3, B_3, C_3},
+ {0, A_4, B_4, C_4},
+ {0, A_5, B_5, C_5},
+
+ {1, J_12, K_12, L_12},
+ {1, J_13, K_13, L_13},
+ {1, J_14, K_14, L_14},
+ {1, J_15, K_15, L_15},
+ {1, J_16, K_16, L_16},
+
+ {0, D_12, E_12, F_12},
+ {0, D_13, E_13, F_13},
+ {0, D_14, E_14, F_14},
+ {0, D_15, E_15, F_15},
+ {0, D_16, E_16, F_16},
+ {0, G_16, H_16, I_16},
+ {0, G_15, H_15, I_15},
+ {0, G_14, H_14, I_14},
+ {0, G_13, H_13, I_13},
+ {0, G_12, H_12, I_12},
+ {0, G_11, H_11, I_11},
+ {0, G_10, H_10, I_10},
+ {0, G_9, H_9, I_9},
+ {0, J_16, K_16, L_16},
+ {0, J_15, K_15, L_15},
+ {0, J_14, K_14, L_14},
+ {0, J_13, K_13, L_13},
+ {1, D_16, E_16, F_16},
+ {1, D_15, E_15, F_15},
+ {1, D_14, E_14, F_14},
+ {1, D_13, E_13, F_13},
+ {1, D_12, E_12, F_12},
+ {1, D_11, E_11, F_11},
+ {1, D_10, E_10, F_10},
+ {1, D_9, E_9, F_9},
+ {1, G_7, H_7, I_7},
+ {1, G_8, H_8, I_8},
+ {1, G_9, H_9, I_9},
+ {1, G_10, H_10, I_10},
+ {1, G_11, H_11, I_11},
+ {1, G_12, H_12, I_12},
+ {1, G_13, H_13, I_13},
+ {1, G_14, H_14, I_14},
+ {1, G_15, H_15, I_15},
+ {1, G_16, H_16, I_16},
+
+};
diff --git a/keyboards/nuphy/halo75/ansi/keymaps/via/rgb_matrix_user.inc b/keyboards/nuphy/halo75/ansi/keymaps/via/rgb_matrix_user.inc
new file mode 100644
index 000000000000..5ef8defd31aa
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/keymaps/via/rgb_matrix_user.inc
@@ -0,0 +1,51 @@
+
+RGB_MATRIX_EFFECT(game_mode)
+RGB_MATRIX_EFFECT(position_mode)
+
+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
+
+extern rgb_config_t rgb_matrix_config;
+
+static bool game_mode(effect_params_t* params) {
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
+
+ for (uint8_t i = led_min; i < led_max; i++) {
+ if(i<83)
+ rgb_matrix_set_color(i, 0x00, 0x00, 0x00);
+ }
+
+ RGB rgb = hsv_to_rgb(rgb_matrix_config.hsv);
+ rgb_matrix_set_color(0, rgb.r, rgb.g, rgb.b); // ESC
+
+ rgb_matrix_set_color(33, rgb.r, rgb.g, rgb.b); // W
+ rgb_matrix_set_color(47, rgb.r, rgb.g, rgb.b); // D
+ rgb_matrix_set_color(48, rgb.r, rgb.g, rgb.b); // S
+ rgb_matrix_set_color(49, rgb.r, rgb.g, rgb.b); // A
+
+ rgb_matrix_set_color(72, rgb.r, rgb.g, rgb.b); // up
+ rgb_matrix_set_color(80, rgb.r, rgb.g, rgb.b); // right
+ rgb_matrix_set_color(81, rgb.r, rgb.g, rgb.b); // down
+ rgb_matrix_set_color(82, rgb.r, rgb.g, rgb.b); // left
+
+ return rgb_matrix_check_finished_leds(led_max);
+}
+
+static bool position_mode(effect_params_t* params) {
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
+
+ for (uint8_t i = led_min; i < led_max; i++) {
+ if(i<83)
+ rgb_matrix_set_color(i, 0x00, 0x00, 0x00);
+ }
+
+ RGB rgb = hsv_to_rgb(rgb_matrix_config.hsv);
+
+ rgb_matrix_set_color(50, rgb.r, rgb.g, rgb.b); // F
+ rgb_matrix_set_color(53, rgb.r, rgb.g, rgb.b); // J
+ rgb_matrix_set_color(72, rgb.r, rgb.g, rgb.b); // up
+
+ return rgb_matrix_check_finished_leds(led_max);
+}
+
+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
+
diff --git a/keyboards/nuphy/halo75/ansi/keymaps/via/rules.mk b/keyboards/nuphy/halo75/ansi/keymaps/via/rules.mk
new file mode 100644
index 000000000000..d475530c871c
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/keymaps/via/rules.mk
@@ -0,0 +1,3 @@
+VIA_ENABLE = yes
+
+RGB_MATRIX_CUSTOM_USER = yes
diff --git a/keyboards/nuphy/halo75/ansi/mcuconf.h b/keyboards/nuphy/halo75/ansi/mcuconf.h
new file mode 100644
index 000000000000..e52966a99165
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/mcuconf.h
@@ -0,0 +1,37 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#pragma once
+
+#include_next
+
+#undef STM32_SERIAL_USE_USART1
+#define STM32_SERIAL_USE_USART1 TRUE
+
+#undef STM32_I2C_USE_I2C1
+#define STM32_I2C_USE_I2C1 TRUE
+
+#undef STM32_I2C_USE_DMA
+#define STM32_I2C_USE_DMA TRUE
+
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 3
+#define STM32_I2C_I2C1_DMA_PRIORITY 1
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+#undef STM32_I2C_I2C1_RX_DMA_STREAM
+#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
+#undef STM32_I2C_I2C1_TX_DMA_STREAM
+#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
\ No newline at end of file
diff --git a/keyboards/nuphy/halo75/ansi/rf.c b/keyboards/nuphy/halo75/ansi/rf.c
new file mode 100644
index 000000000000..7a1cc3663d95
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/rf.c
@@ -0,0 +1,708 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#include "ansi.h"
+#include "uart.h" // qmk uart.h
+#include "rf_driver.h"
+
+USART_MGR_STRUCT Usart_Mgr;
+#define RX_SBYTE Usart_Mgr.RXDBuf[0]
+#define RX_CMD Usart_Mgr.RXDBuf[1]
+#define RX_ACK Usart_Mgr.RXDBuf[2]
+#define RX_LEN Usart_Mgr.RXDBuf[3]
+#define RX_DAT Usart_Mgr.RXDBuf[4]
+
+extern bool f_uart_ack;
+extern bool f_rf_read_data_ok;
+extern bool f_rf_sts_sysc_ok;
+extern bool f_rf_new_adv_ok;
+extern bool f_rf_reset;
+extern bool f_rf_hand_ok;
+extern bool f_goto_sleep;
+
+uint8_t uart_bit_report_buf[32] = {0};
+uint8_t func_tab[32] = {0};
+uint8_t bitkb_report_buf[32] = {0};
+uint8_t bytekb_report_buf[8] = {0};
+uint16_t conkb_report = 0;
+uint16_t syskb_report = 0;
+uint8_t sync_lost = 0;
+uint8_t disconnect_delay = 0;
+
+extern DEV_INFO_STRUCT dev_info;
+extern host_driver_t *m_host_driver;
+extern uint8_t host_mode;
+extern uint8_t rf_blink_cnt;
+extern uint16_t rf_link_show_time;
+extern uint16_t rf_linking_time;
+extern uint16_t no_act_time;
+extern bool f_send_channel;
+extern bool f_dial_sw_init_ok;
+
+report_mouse_t mousekey_get_report(void);
+void uart_init(uint32_t baud); // qmk uart.c
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size);
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length);
+uint8_t get_checksum(uint8_t *buf, uint8_t len);
+void uart_receive_pro(void);
+void m_break_all_key(void);
+uint16_t host_last_consumer_usage(void);
+
+/**
+ * @brief Uart auto nkey send
+ */
+bool f_bit_kb_act = 0;
+static void uart_auto_nkey_send(uint8_t *pre_bit_report, uint8_t *now_bit_report, uint8_t size)
+{
+ uint8_t i, j, byte_index;
+ uint8_t change_mask, offset_mask;
+ uint8_t key_code = 0;
+ bool f_byte_send = 0, f_bit_send = 0;
+
+ if (pre_bit_report[0] ^ now_bit_report[0]) {
+ bytekb_report_buf[0] = now_bit_report[0];
+ f_byte_send = 1;
+ }
+
+ for (i = 1; i < size; i++) {
+ change_mask = pre_bit_report[i] ^ now_bit_report[i];
+ offset_mask = 1;
+ for (j = 0; j < 8; j++) {
+ if (change_mask & offset_mask) {
+ if (now_bit_report[i] & offset_mask) {
+ for (byte_index = 2; byte_index < 8; byte_index++) {
+ if (bytekb_report_buf[byte_index] == 0) {
+ bytekb_report_buf[byte_index] = key_code;
+ f_byte_send = 1;
+ break;
+ }
+ }
+ if (byte_index >= 8) {
+ uart_bit_report_buf[i] |= offset_mask;
+ f_bit_send = 1;
+ }
+ } else {
+ for (byte_index = 2; byte_index < 8; byte_index++) {
+ if (bytekb_report_buf[byte_index] == key_code) {
+ bytekb_report_buf[byte_index] = 0;
+ f_byte_send = 1;
+ break;
+ }
+ }
+ if (byte_index >= 8) {
+ uart_bit_report_buf[i] &= ~offset_mask;
+ f_bit_send = 1;
+ }
+ }
+ }
+ key_code++;
+ offset_mask <<= 1;
+ }
+ }
+
+ if (f_bit_send) {
+ f_bit_kb_act = 1;
+ uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
+ }
+
+ if (f_byte_send) {
+ uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
+ }
+}
+
+
+/**
+ * @brief Uart send keys report.
+ */
+void uart_send_report_func(void)
+{
+ static uint32_t interval_timer = 0;
+
+ if (dev_info.link_mode == LINK_USB) return;
+ keyboard_protocol = 1;
+
+ if (timer_elapsed32(interval_timer) > 300) {
+ interval_timer = timer_read32();
+ if (no_act_time <= 2000) {
+ uart_send_report(CMD_RPT_BYTE_KB, bytekb_report_buf, 8);
+ wait_us(200);
+
+ if(f_bit_kb_act)
+ uart_send_report(CMD_RPT_BIT_KB, uart_bit_report_buf, 16);
+ }
+ else {
+ f_bit_kb_act = 0;
+ }
+ }
+}
+
+/**
+ * @brief Uart send consumer keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_consumer_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_CONSUME, (uint8_t *)(&report->usage), 2);
+}
+
+/**
+ * @brief Uart send mouse keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_mouse_report(report_mouse_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_MS, &report->buttons, 5);
+}
+
+/**
+ * @brief Uart send system keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_system_report(report_extra_t *report) {
+ no_act_time = 0;
+ uart_send_report(CMD_RPT_SYS, (uint8_t *)(&report->usage), 2);
+}
+
+/**
+ * @brief Uart send byte keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_keyboard(report_keyboard_t *report) {
+ no_act_time = 0;
+ report->reserved = 0;
+ uart_send_report(CMD_RPT_BYTE_KB, &report->mods, 8);
+ memcpy(bytekb_report_buf, &report->mods, 8);
+}
+
+/**
+ * @brief Uart send bit keys report.
+ * @note Call in rf_driver.c
+ */
+void uart_send_report_nkro(report_nkro_t *report) {
+ no_act_time = 0;
+ uart_auto_nkey_send(bitkb_report_buf, &nkro_report->mods, NKRO_REPORT_BITS + 1);
+ memcpy(&bitkb_report_buf[0], &nkro_report->mods, NKRO_REPORT_BITS + 1);
+}
+
+/**
+ * @brief Parsing the data received from the RF module.
+ */
+void RF_Protocol_Receive(void) {
+ uint8_t i, check_sum = 0;
+
+ if (Usart_Mgr.RXDState == RX_Done) {
+ f_uart_ack = 1;
+ sync_lost = 0;
+
+ if (Usart_Mgr.RXDLen > 4) {
+ for (i = 0; i < RX_LEN; i++)
+ check_sum += Usart_Mgr.RXDBuf[4 + i];
+
+ if (check_sum != Usart_Mgr.RXDBuf[4 + i]) {
+ Usart_Mgr.RXDState = RX_SUM_ERR;
+ return;
+ }
+ } else if (Usart_Mgr.RXDLen == 3) {
+ if (Usart_Mgr.RXDBuf[2] == 0xA0) {
+ f_uart_ack = 1;
+ }
+ }
+
+ switch (RX_CMD) {
+ case CMD_HAND: {
+ f_rf_hand_ok = 1;
+ break;
+ }
+
+ case CMD_24G_SUSPEND: {
+ f_goto_sleep = 1;
+ break;
+ }
+
+ case CMD_NEW_ADV: {
+ f_rf_new_adv_ok = 1;
+ break;
+ }
+
+ case CMD_RF_STS_SYSC: {
+ static uint8_t error_cnt = 0;
+
+ if (dev_info.link_mode == Usart_Mgr.RXDBuf[4]) {
+ error_cnt = 0;
+
+ dev_info.rf_state = Usart_Mgr.RXDBuf[5];
+
+ if ((dev_info.rf_state == RF_CONNECT) && ((Usart_Mgr.RXDBuf[6] & 0xf8) == 0)) {
+ dev_info.rf_led = Usart_Mgr.RXDBuf[6];
+ }
+
+ dev_info.rf_charge = Usart_Mgr.RXDBuf[7];
+
+ if (Usart_Mgr.RXDBuf[8] <= 100) dev_info.rf_baterry = Usart_Mgr.RXDBuf[8];
+ if (dev_info.rf_charge & 0x01) dev_info.rf_baterry = 100;
+ }
+ else {
+ if (dev_info.rf_state != RF_INVAILD) {
+ if (error_cnt >= 5) {
+ error_cnt = 0;
+ f_send_channel = 1;
+ } else {
+ error_cnt++;
+ }
+ }
+ }
+
+ f_rf_sts_sysc_ok = 1;
+ break;
+ }
+
+ case CMD_READ_DATA: {
+ memcpy(func_tab, &Usart_Mgr.RXDBuf[4], 32);
+
+ if (func_tab[4] <= LINK_USB) {
+ dev_info.link_mode = func_tab[4];
+ }
+
+ if (func_tab[5] < LINK_USB) {
+ dev_info.rf_channel = func_tab[5];
+ }
+
+ if ((func_tab[6] <= LINK_BT_3) && (func_tab[6] >= LINK_BT_1)) {
+ dev_info.ble_channel = func_tab[6];
+ }
+
+ f_rf_read_data_ok = 1;
+ break;
+ }
+ }
+
+ Usart_Mgr.RXDLen = 0;
+ Usart_Mgr.RXDState = RX_Idle;
+ Usart_Mgr.RXDOverTime = 0;
+ }
+}
+
+/**
+ * @brief Uart send cmd.
+ * @param cmd: cmd.
+ * @param wait_ack: wait time for ack after sending.
+ * @param delayms: delay before sending.
+ */
+uint8_t uart_send_cmd(uint8_t cmd, uint8_t wait_ack, uint8_t delayms) {
+ wait_ms(delayms);
+
+ memset(&Usart_Mgr.TXDBuf[0], 0, UART_MAX_LEN);
+
+ Usart_Mgr.TXDBuf[0] = UART_HEAD;
+ Usart_Mgr.TXDBuf[1] = cmd;
+ Usart_Mgr.TXDBuf[2] = 0x00;
+
+ switch (cmd) {
+ case CMD_SLEEP: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
+ break;
+ }
+
+ case CMD_HAND: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
+ break;
+ }
+
+ case CMD_RF_STS_SYSC: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+ break;
+ }
+
+ case CMD_SET_LINK: {
+ dev_info.rf_state = RF_LINKING;
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = dev_info.link_mode;
+
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
+ break;
+ }
+
+ case CMD_NEW_ADV: {
+ dev_info.rf_state = RF_PAIRING;
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = dev_info.link_mode;
+ Usart_Mgr.TXDBuf[5] = 1;
+ Usart_Mgr.TXDBuf[6] = dev_info.link_mode + 1;
+
+ rf_linking_time = 0;
+ disconnect_delay = 0xff;
+ f_rf_new_adv_ok = 0;
+ break;
+ }
+
+ case CMD_CLR_DEVICE: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
+ break;
+ }
+
+ case CMD_SET_CONFIG: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = POWER_DOWN_DELAY;
+ Usart_Mgr.TXDBuf[5] = POWER_DOWN_DELAY;
+ break;
+ }
+ case CMD_SET_NAME: {
+ Usart_Mgr.TXDBuf[3] = 18;
+ Usart_Mgr.TXDBuf[4] = 1;
+ Usart_Mgr.TXDBuf[5] = 16;
+ Usart_Mgr.TXDBuf[6] = 'N';
+ Usart_Mgr.TXDBuf[7] = 'u';
+ Usart_Mgr.TXDBuf[8] = 'P';
+ Usart_Mgr.TXDBuf[9] = 'h';
+ Usart_Mgr.TXDBuf[10] = 'y';
+ Usart_Mgr.TXDBuf[11] = ' ';
+ Usart_Mgr.TXDBuf[12] = 'H';
+ Usart_Mgr.TXDBuf[13] = 'a';
+ Usart_Mgr.TXDBuf[14] = 'l';
+ Usart_Mgr.TXDBuf[15] = 'o';
+ Usart_Mgr.TXDBuf[16] = '7';
+ Usart_Mgr.TXDBuf[17] = '5';
+ Usart_Mgr.TXDBuf[18] = ' ';
+ Usart_Mgr.TXDBuf[19] = 'V';
+ Usart_Mgr.TXDBuf[20] = '2';
+ Usart_Mgr.TXDBuf[21] = '-';
+ Usart_Mgr.TXDBuf[22] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]); // sum
+ break;
+ }
+
+ case CMD_SET_24G_NAME: {
+ Usart_Mgr.TXDBuf[3] = 46;
+ Usart_Mgr.TXDBuf[4] = 46;
+ Usart_Mgr.TXDBuf[5] = 3;
+ Usart_Mgr.TXDBuf[6] = 'N';
+ Usart_Mgr.TXDBuf[8] = 'u';
+ Usart_Mgr.TXDBuf[10] = 'P';
+ Usart_Mgr.TXDBuf[12] = 'h';
+ Usart_Mgr.TXDBuf[14] = 'y';
+ Usart_Mgr.TXDBuf[16] = ' ';
+ Usart_Mgr.TXDBuf[18] = 'H';
+ Usart_Mgr.TXDBuf[20] = 'a';
+ Usart_Mgr.TXDBuf[22] = 'l';
+ Usart_Mgr.TXDBuf[24] = 'o';
+ Usart_Mgr.TXDBuf[26] = '7';
+ Usart_Mgr.TXDBuf[28] = '5';
+ Usart_Mgr.TXDBuf[30] = ' ';
+ Usart_Mgr.TXDBuf[32] = 'V';
+ Usart_Mgr.TXDBuf[34] = '2';
+ Usart_Mgr.TXDBuf[36] = ' ';
+ Usart_Mgr.TXDBuf[38] = 'D';
+ Usart_Mgr.TXDBuf[40] = 'o';
+ Usart_Mgr.TXDBuf[42] = 'n';
+ Usart_Mgr.TXDBuf[44] = 'g';
+ Usart_Mgr.TXDBuf[46] = 'l';
+ Usart_Mgr.TXDBuf[48] = 'e';
+ Usart_Mgr.TXDBuf[50] = get_checksum(Usart_Mgr.TXDBuf + 4, Usart_Mgr.TXDBuf[3]); // sum
+ break;
+ }
+
+ case CMD_READ_DATA: {
+ Usart_Mgr.TXDBuf[3] = 2;
+ Usart_Mgr.TXDBuf[4] = 0x00;
+ Usart_Mgr.TXDBuf[5] = FUNC_VALID_LEN;
+ Usart_Mgr.TXDBuf[6] = FUNC_VALID_LEN;
+ break;
+ }
+
+ case CMD_RF_DFU: {
+ Usart_Mgr.TXDBuf[3] = 1;
+ Usart_Mgr.TXDBuf[4] = 0;
+ Usart_Mgr.TXDBuf[5] = 0;
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ f_uart_ack = 0;
+ UART_Send_Bytes(Usart_Mgr.TXDBuf, Usart_Mgr.TXDBuf[3] + 5);
+
+ if (wait_ack) {
+ while (wait_ack--) {
+ wait_ms(1);
+ if (f_uart_ack) return TX_OK;
+ }
+ } else {
+ return TX_OK;
+ }
+
+ return TX_TIMEOUT;
+}
+
+/**
+ * @brief RF module state sync.
+ */
+void dev_sts_sync(void) {
+ static uint32_t interval_timer = 0;
+ static uint8_t link_state_temp = RF_DISCONNECT;
+
+ if (timer_elapsed32(interval_timer) < 200)
+ return;
+ else
+ interval_timer = timer_read32();
+
+ if (f_rf_reset) {
+ f_rf_reset = 0;
+ wait_ms(100);
+ writePinLow(NRF_RESET_PIN);
+ wait_ms(50);
+ writePinHigh(NRF_RESET_PIN);
+ wait_ms(50);
+ }
+ else if (f_send_channel) {
+ f_send_channel = 0;
+ uart_send_cmd(CMD_SET_LINK, 10, 10);
+ }
+
+ if (dev_info.link_mode == LINK_USB) {
+ if (host_mode != HOST_USB_TYPE) {
+ host_mode = HOST_USB_TYPE;
+ host_set_driver(m_host_driver);
+ m_break_all_key();
+ }
+ rf_blink_cnt = 0;
+ }
+ else {
+ if (host_mode != HOST_RF_TYPE) {
+ host_mode = HOST_RF_TYPE;
+ m_break_all_key();
+ host_set_driver(&rf_host_driver);
+ }
+
+ if (dev_info.rf_state != RF_CONNECT) {
+ if (disconnect_delay >= 10) {
+ rf_blink_cnt = 3;
+ rf_link_show_time = 0;
+ link_state_temp = dev_info.rf_state;
+ } else {
+ disconnect_delay++;
+ }
+ }
+ else if (dev_info.rf_state == RF_CONNECT) {
+ rf_linking_time = 0;
+ disconnect_delay = 0;
+ rf_blink_cnt = 0;
+
+ if (link_state_temp != RF_CONNECT) {
+ link_state_temp = RF_CONNECT;
+ rf_link_show_time = 0;
+ if (dev_info.link_mode == LINK_RF_24) {
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 30);
+ }
+ }
+ }
+ }
+
+ uart_send_cmd(CMD_RF_STS_SYSC, 1, 1);
+
+ if (dev_info.link_mode != LINK_USB) {
+ if (++sync_lost >= 5) {
+ sync_lost = 0;
+ f_rf_reset = 1;
+ }
+ }
+}
+
+#define BAT_CFG_LEN 80
+const uint8_t battery_acfg_tab[BAT_CFG_LEN] = {
+ 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xB4, 0xC2, 0xB4, 0xA8, 0x9B, 0x96, 0xF8, 0xF2,
+ 0xF3, 0xC3, 0xA8, 0x8A, 0x65, 0x55, 0x49, 0x41,
+ 0x39, 0x34, 0x2E, 0xA9, 0xAE, 0xD3, 0x28, 0xFF,
+ 0xFF, 0xF1, 0xD3, 0xCE, 0xCB, 0xC8, 0xC3, 0xB8,
+ 0xAE, 0xA7, 0xA8, 0xA6, 0x82, 0x6D, 0x65, 0x63,
+ 0x69, 0x79, 0x8D, 0xA4, 0xB7, 0xC8, 0xA4, 0x16,
+ 0x20, 0x00, 0xA7, 0x10, 0x00, 0xB1, 0x28, 0x00,
+ 0x00, 0x00, 0x64, 0x43, 0xC0, 0x53, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+};
+
+void UART_Send_BatCfg(void)
+{
+ uint8_t buf[128] = {0};
+
+ buf[0] = UART_HEAD;
+ buf[1] = CMD_WBAT_CFG;
+ buf[2] = 0x01;
+ buf[3] = BAT_CFG_LEN;
+ memcpy(&buf[4], battery_acfg_tab, BAT_CFG_LEN);
+ buf[4 + BAT_CFG_LEN] = get_checksum(&buf[4], BAT_CFG_LEN);
+ UART_Send_Bytes(buf, BAT_CFG_LEN + 5);
+ wait_ms(50);
+}
+
+/**
+ * @brief Uart send bytes.
+ * @param Buffer data buf
+ * @param Length data lenght
+ */
+void UART_Send_Bytes(uint8_t *Buffer, uint32_t Length) {
+ writePinLow(NRF_WAKEUP_PIN);
+ wait_us(50);
+
+ uart_transmit(Buffer, Length);
+
+ wait_us(50 + Length * 30);
+ writePinHigh(NRF_WAKEUP_PIN);
+}
+
+/**
+ * @brief get checksum.
+ * @param buf data buf
+ * @param len data lenght
+ */
+uint8_t get_checksum(uint8_t *buf, uint8_t len) {
+ uint8_t i;
+ uint8_t checksum = 0;
+
+ for (i = 0; i < len; i++)
+ checksum += *buf++;
+
+ checksum ^= UART_HEAD;
+
+ return checksum;
+}
+
+/**
+ * @brief Uart send report.
+ * @param report_type report_type
+ * @param report_buf report_buf
+ * @param report_size report_size
+ */
+void uart_send_report(uint8_t report_type, uint8_t *report_buf, uint8_t report_size) {
+ if (f_dial_sw_init_ok == 0) return;
+ if (dev_info.link_mode == LINK_USB) return;
+ if (dev_info.rf_state != RF_CONNECT) return;
+
+ Usart_Mgr.TXDBuf[0] = UART_HEAD;
+ Usart_Mgr.TXDBuf[1] = report_type;
+ Usart_Mgr.TXDBuf[2] = 0x01;
+ Usart_Mgr.TXDBuf[3] = report_size;
+
+ memcpy(&Usart_Mgr.TXDBuf[4], report_buf, report_size);
+ Usart_Mgr.TXDBuf[4 + report_size] = get_checksum(&Usart_Mgr.TXDBuf[4], report_size);
+
+ UART_Send_Bytes(&Usart_Mgr.TXDBuf[0], report_size + 5);
+
+ wait_us(200);
+}
+
+/**
+ * @brief Uart receives data and processes it after completion,.
+ */
+void uart_receive_pro(void) {
+ static bool rcv_start = false;
+
+ // Receiving serial data from RF module
+ while (uart_available()) {
+ rcv_start = true;
+
+ if (Usart_Mgr.RXDLen >= UART_MAX_LEN) {
+ uart_read();
+ }
+ else {
+ Usart_Mgr.RXDBuf[Usart_Mgr.RXDLen++] = uart_read();
+ }
+
+ if (!uart_available()) {
+ wait_us(200);
+ }
+ }
+
+ // Processing received serial port protocol
+ if (rcv_start) {
+ rcv_start = false;
+ Usart_Mgr.RXDState = RX_Done;
+ RF_Protocol_Receive();
+ Usart_Mgr.RXDLen = 0;
+ }
+}
+
+/**
+ * @brief RF uart initial.
+ */
+void rf_uart_init(void) {
+ /* set uart buad as 460800 */
+ uart_init(460800);
+
+ /* Enable parity check */
+ USART1->CR1 &= ~((uint32_t)USART_CR1_UE);
+ USART1->CR1 |= USART_CR1_M0 | USART_CR1_PCE;
+ USART1->CR1 |= USART_CR1_UE;
+
+ /* set Rx and Tx pin pull up */
+ GPIOB->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR6 | GPIO_OSPEEDER_OSPEEDR7);
+ GPIOB->PUPDR |= (GPIO_PUPDR_PUPDR6_0 | GPIO_PUPDR_PUPDR7_0);
+}
+
+/**
+ * @brief RF module initial.
+ */
+void rf_device_init(void) {
+ uint8_t timeout = 0;
+ void uart_receive_pro(void);
+
+ timeout = 10;
+ f_rf_hand_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_HAND, 0, 20);
+ wait_ms(5);
+ uart_receive_pro(); // receive data
+ uart_receive_pro(); // parsing data
+ if (f_rf_hand_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_read_data_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_READ_DATA, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_read_data_ok) break;
+ }
+
+ timeout = 10;
+ f_rf_sts_sysc_ok = 0;
+ while (timeout--) {
+ uart_send_cmd(CMD_RF_STS_SYSC, 0, 20);
+ wait_ms(5);
+ uart_receive_pro();
+ uart_receive_pro();
+ if (f_rf_sts_sysc_ok) break;
+ }
+
+ UART_Send_BatCfg();
+
+ uart_send_cmd(CMD_SET_NAME, 10, 20);
+
+ uart_send_cmd(CMD_SET_24G_NAME, 10, 20);
+}
diff --git a/keyboards/nuphy/halo75/ansi/rf_driver.c b/keyboards/nuphy/halo75/ansi/rf_driver.c
new file mode 100644
index 000000000000..1c0876c00349
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/rf_driver.c
@@ -0,0 +1,65 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "host_driver.h"
+#include "rf_driver.h"
+#include "host.h"
+#include "ansi.h"
+
+/* Variable declaration */
+extern DEV_INFO_STRUCT dev_info;
+
+/* Host driver */
+static uint8_t rf_keyboard_leds(void);
+static void rf_send_keyboard(report_keyboard_t *report);
+static void rf_send_nkro(report_nkro_t *report);
+static void rf_send_mouse(report_mouse_t *report);
+static void rf_send_extra(report_extra_t *report);
+host_driver_t rf_host_driver = {rf_keyboard_leds, rf_send_keyboard, rf_send_nkro, rf_send_mouse, rf_send_extra};
+
+/* defined in rf.c */
+extern void uart_send_report_keyboard(report_keyboard_t *report);
+extern void uart_send_report_nkro(report_nkro_t *report);
+extern void uart_send_mouse_report(report_mouse_t *report);
+extern void uart_send_consumer_report(report_extra_t *report);
+extern void uart_send_system_report(report_extra_t *report);
+
+static uint8_t rf_keyboard_leds(void) {
+ return dev_info.rf_led;
+}
+
+static void rf_send_keyboard(report_keyboard_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_keyboard(report);
+}
+
+static void rf_send_nkro(report_nkro_t *report) {
+ keyboard_protocol = 1;
+ uart_send_report_nkro(report);
+}
+
+static void rf_send_mouse(report_mouse_t *report) {
+ uart_send_mouse_report(report);
+}
+
+static void rf_send_extra(report_extra_t *report) {
+ if (report->report_id == REPORT_ID_CONSUMER) {
+ uart_send_consumer_report(report);
+ } else if (report->report_id == REPORT_ID_SYSTEM) {
+ uart_send_system_report(report);
+ }
+}
diff --git a/keyboards/nuphy/halo75/ansi/rf_driver.h b/keyboards/nuphy/halo75/ansi/rf_driver.h
new file mode 100644
index 000000000000..ad0cf3cb384f
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/rf_driver.h
@@ -0,0 +1,20 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+extern host_driver_t rf_host_driver;
diff --git a/keyboards/nuphy/halo75/ansi/rules.mk b/keyboards/nuphy/halo75/ansi/rules.mk
new file mode 100644
index 000000000000..5d29abf41008
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/rules.mk
@@ -0,0 +1,5 @@
+SRC += side.c
+SRC += rf.c
+SRC += sleep.c
+SRC += rf_driver.c
+UART_DRIVER_REQUIRED = yes
diff --git a/keyboards/nuphy/halo75/ansi/side.c b/keyboards/nuphy/halo75/ansi/side.c
new file mode 100644
index 000000000000..a71f4db087a9
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/side.c
@@ -0,0 +1,1192 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#include "ansi.h"
+#include "side.h"
+//------------------------------------------------
+#define SIDE_WAVE 0
+#define SIDE_MIX 1
+#define SIDE_NEW 2
+#define SIDE_BREATH 3
+#define SIDE_STATIC 4
+
+#define SIDE_MODE_1 0
+#define SIDE_MODE_2 1
+#define SIDE_MODE_3 2
+#define SIDE_MODE_4 3
+#define SIDE_MODE_5 4
+#define SIDE_MODE_6 5
+#define SIDE_MODE_7 6
+
+#define LIGHT_COLOUR_MAX 8
+#define SIDE_COLOUR_MAX 8
+#define LIGHT_SPEED_MAX 4
+
+const uint8_t side_speed_table[5][5] = {
+ [SIDE_WAVE] = {10, 20, 25, 30, 45},
+ [SIDE_MIX] = {25, 30, 40, 50, 60},
+ [SIDE_NEW] = {30, 50, 60, 70, 100},
+ [SIDE_BREATH] = {25, 30, 40, 50, 60},
+ [SIDE_STATIC] = {10, 20, 25, 30, 45},
+};
+
+#define SIDE_BLINK_LIGHT 128
+const uint8_t side_light_table[5] = {
+ 0,
+ 64,
+ 128,
+ 192,
+ 255,
+};
+
+#define SIDE_INDEX 83
+
+const uint8_t side_led_index_tab[45] =
+ {
+ SIDE_INDEX + 10,
+ SIDE_INDEX + 11,
+ SIDE_INDEX + 12,
+ SIDE_INDEX + 13,
+ SIDE_INDEX + 14,
+ SIDE_INDEX + 15,
+ SIDE_INDEX + 16,
+ SIDE_INDEX + 17,
+ SIDE_INDEX + 18,
+ SIDE_INDEX + 19,
+ SIDE_INDEX + 20,
+ SIDE_INDEX + 21,
+ SIDE_INDEX + 22,
+ SIDE_INDEX + 23,
+ SIDE_INDEX + 24,
+ SIDE_INDEX + 25,
+ SIDE_INDEX + 26,
+ SIDE_INDEX + 27,
+
+ SIDE_INDEX + 0,
+ SIDE_INDEX + 1,
+ SIDE_INDEX + 2,
+ SIDE_INDEX + 3,
+ SIDE_INDEX + 4,
+
+ SIDE_INDEX + 28,
+ SIDE_INDEX + 29,
+ SIDE_INDEX + 30,
+ SIDE_INDEX + 31,
+ SIDE_INDEX + 32,
+ SIDE_INDEX + 33,
+ SIDE_INDEX + 34,
+ SIDE_INDEX + 35,
+ SIDE_INDEX + 36,
+ SIDE_INDEX + 37,
+ SIDE_INDEX + 38,
+ SIDE_INDEX + 39,
+ SIDE_INDEX + 40,
+ SIDE_INDEX + 41,
+ SIDE_INDEX + 42,
+ SIDE_INDEX + 43,
+ SIDE_INDEX + 44,
+
+ SIDE_INDEX + 9,
+ SIDE_INDEX + 8,
+ SIDE_INDEX + 7,
+ SIDE_INDEX + 6,
+ SIDE_INDEX + 5,
+};
+
+
+uint8_t side_line = 45;
+
+bool f_charging = 1;
+uint8_t side_mode_a = 0;
+uint8_t side_mode_b = 3;
+uint8_t side_light = 2;
+uint8_t side_speed = 2;
+uint8_t side_rgb = 1;
+uint8_t side_colour = 0;
+uint8_t side_play_point = 0;
+uint32_t bat_show_time = 0;
+bool bat_show_flag = true;
+
+uint16_t side_play_cnt = 0;
+uint32_t side_play_timer = 0;
+
+uint8_t r_temp, g_temp, b_temp;
+
+extern DEV_INFO_STRUCT dev_info;
+extern bool f_bat_hold;
+extern user_config_t user_config;
+extern uint16_t rf_link_show_time;
+
+#define IS31FL3733_PWM_REGISTER_COUNT 192
+#define IS31FL3733_LED_CONTROL_REGISTER_COUNT 24
+typedef struct is31fl3733_driver_t {
+ uint8_t pwm_buffer[IS31FL3733_PWM_REGISTER_COUNT];
+ bool pwm_buffer_dirty;
+ uint8_t led_control_buffer[IS31FL3733_LED_CONTROL_REGISTER_COUNT];
+ bool led_control_buffer_dirty;
+} PACKED is31fl3733_driver_t;
+extern is31fl3733_driver_t driver_buffers[2];
+bool is_side_rgb_off(void)
+{
+ is31fl3733_led_t led;
+ for (int i = SIDE_INDEX; i < SIDE_INDEX + 10; i++) {
+ memcpy_P(&led, (&g_is31_leds[i]), sizeof(led));
+ if ((driver_buffers[led.driver].pwm_buffer[led.r] != 0) || (driver_buffers[led.driver].pwm_buffer[led.g] != 0) || (driver_buffers[led.driver].pwm_buffer[led.b] != 0)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * @brief suspend_power_down_kb
+ *
+ */
+void suspend_power_down_kb(void)
+{
+ rgb_matrix_set_suspend_state(true);
+}
+
+/**
+ * @brief suspend_wakeup_init_kb
+ *
+ */
+void suspend_wakeup_init_kb(void)
+{
+ rgb_matrix_set_suspend_state(false);
+}
+/**
+ * @brief Adjusting the brightness of side lights.
+ * @param dir: 0 - decrease, 1 - increase.
+ * @note save to eeprom.
+ */
+void light_level_control(uint8_t brighten)
+{
+ if (brighten)
+ {
+ if (side_light == 4) {
+ return;
+ } else
+ side_light++;
+ } else
+ {
+ if (side_light == 0) {
+ return;
+ } else
+ side_light--;
+ }
+ user_config.ee_side_light = side_light;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+/**
+ * @brief Adjusting the speed of side lights.
+ * @param dir: 0 - decrease, 1 - increase.
+ * @note save to eeprom.
+ */
+void light_speed_contol(uint8_t fast)
+{
+ if ((side_speed) > LIGHT_SPEED_MAX)
+ (side_speed) = LIGHT_SPEED_MAX / 2;
+
+ if (fast) {
+ if ((side_speed)) side_speed--;
+ } else {
+ if ((side_speed) < LIGHT_SPEED_MAX) side_speed++;
+ }
+ user_config.ee_side_speed = side_speed;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+/**
+ * @brief Switch to the next color of side lights.
+ * @param dir: 0 - prev, 1 - next.
+ * @note save to eeprom.
+ */
+uint8_t light_colour_max = 8;
+void side_colour_control(uint8_t dir)
+{
+ if(side_mode_a == SIDE_NEW) light_colour_max = 3;
+ else light_colour_max = 8;
+ if ((side_mode_a != SIDE_WAVE)&&(side_mode_a != SIDE_BREATH)){
+ if (side_rgb) {
+ side_rgb = 0;
+ side_colour = 0;
+ }
+ }
+
+ if (dir) {
+ if (side_rgb) {
+ side_rgb = 0;
+ side_colour = 0;
+ } else {
+ side_colour++;
+ if (side_colour >= light_colour_max) {
+ side_rgb = 1;
+ side_colour = 0;
+ }
+ }
+ } else {
+ if (side_rgb) {
+ side_rgb = 0;
+ side_colour = light_colour_max - 1;
+ } else {
+ side_colour--;
+ if (side_colour >= light_colour_max) {
+ side_rgb = 1;
+ side_colour = 0;
+ }
+ }
+ }
+ user_config.ee_side_rgb = side_rgb;
+ user_config.ee_side_colour = side_colour;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+/**
+ * @brief Change the color mode of side lights.
+ * @param dir: 0 - prev, 1 - next.
+ * @note save to eeprom.
+ */
+uint8_t side_old_color = 0;
+void side_mode_a_control(uint8_t dir)
+{
+ if (dir) {
+ side_mode_a++;
+ if (side_mode_a > SIDE_STATIC) {
+ side_mode_a = 0;
+ }
+ } else {
+ if (side_mode_a > 0) {
+ side_mode_a--;
+ } else {
+ side_mode_a = 0;
+ }
+ }
+ if(side_mode_a == SIDE_NEW)
+ {
+ side_old_color = side_colour;
+ side_colour = 0;
+ }
+ else if(side_mode_a == SIDE_BREATH)
+ {
+ side_colour = side_old_color;
+ }
+
+ side_play_point = 0;
+ user_config.ee_side_mode_a = side_mode_a;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+void side_mode_b_control(uint8_t dir)
+{
+ if (dir) {
+ side_mode_b++;
+ if (side_mode_b > SIDE_MODE_7) {
+ side_mode_b = SIDE_MODE_1;
+ }
+ } else {
+ if (side_mode_b > 0) {
+ side_mode_b--;
+ } else {
+ side_mode_b = SIDE_MODE_1;
+ }
+ }
+ side_play_point = 0;
+ user_config.ee_side_mode_b = side_mode_b;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+/**
+ * @brief set left side leds.
+ * @param ...
+ */
+void set_left_rgb(uint8_t r, uint8_t g, uint8_t b)
+{
+ for (int i = 0; i < 5; i++)
+ rgb_matrix_set_color(SIDE_INDEX + i, r, g, b);
+}
+
+void set_all_side_off(void)
+{
+ for (int i = 0; i < 45; i++)
+ rgb_matrix_set_color(SIDE_INDEX + i, 0, 0, 0);
+}
+
+
+/**
+ * @brief mac or win system indicate
+ */
+void sys_sw_led_show(void)
+{
+ static uint32_t sys_show_timer = 0;
+ static bool sys_show_flag = false;
+ extern bool f_sys_show;
+
+ if (f_sys_show) {
+ f_sys_show = false;
+ sys_show_timer = timer_read32(); // store time of last refresh
+ sys_show_flag = true;
+ }
+
+ if (sys_show_flag) {
+ if (dev_info.sys_sw_state == SYS_SW_MAC) {
+ r_temp = colour_lib[7][0];
+ g_temp = colour_lib[7][1];
+ b_temp = colour_lib[7][2];
+ } else {
+ r_temp = colour_lib[5][0];
+ g_temp = colour_lib[5][1];
+ b_temp = colour_lib[5][2];
+ }
+ if ((timer_elapsed32(sys_show_timer) / 500) % 2 == 0) {
+ set_left_rgb(r_temp, g_temp, b_temp);
+ } else {
+ set_left_rgb(0x00, 0x00, 0x00);
+ }
+ if (timer_elapsed32(sys_show_timer) >= (3000-50)) {
+ sys_show_flag = false;
+ }
+ }
+}
+
+/**
+ * @brief sleep enable or disable indicate
+ */
+void sleep_sw_led_show(void)
+{
+ static uint32_t sleep_show_timer = 0;
+ static bool sleep_show_flag = false;
+ extern bool f_sleep_show;
+
+ if (f_sleep_show) {
+ f_sleep_show = false;
+ sleep_show_timer = timer_read32(); // store time of last refresh
+ sleep_show_flag = true;
+ }
+
+ if (sleep_show_flag) {
+ if (f_dev_sleep_enable) {
+ r_temp = 0x00;
+ g_temp = SIDE_BLINK_LIGHT;
+ b_temp = 0x00;
+ } else {
+ r_temp = 0xff;
+ g_temp = 0x00;
+ b_temp = 0x00;
+ }
+ if ((timer_elapsed32(sleep_show_timer) / 500) % 2 == 0) {
+ set_left_rgb(r_temp, g_temp, b_temp);
+ } else {
+ set_left_rgb(0x00, 0x00, 0x00);
+ }
+ if (timer_elapsed32(sleep_show_timer) >= (3000-50)) {
+ sleep_show_flag = false;
+ }
+ }
+}
+
+
+/**
+ * @brief host system led indicate.
+ */
+void sys_led_show(void)
+{
+ if (dev_info.link_mode == LINK_USB) {
+ // caps lock led
+ if (host_keyboard_led_state().caps_lock) {
+ set_left_rgb(colour_lib[4][0], colour_lib[4][1], colour_lib[4][2]);
+ }
+ }
+ else {
+ if (dev_info.rf_led & 0x02) {
+ set_left_rgb(colour_lib[4][0], colour_lib[4][1], colour_lib[4][2]);
+ }
+ }
+}
+
+/**
+ * @brief light_point_playing.
+ * @param trend:
+ * @param step:
+ * @param len:
+ * @param point:
+ */
+static void light_point_playing(uint8_t trend, uint8_t step, uint8_t len, uint8_t *point)
+{
+ if (trend) {
+ *point += step;
+ if (*point >= len) *point -= len;
+ } else {
+ *point -= step;
+ if (*point >= len) *point = len - (255 - *point) - 1;
+ }
+}
+
+/**
+ * @brief count_rgb_light.
+ * @param light_temp:
+ */
+static void count_rgb_light(uint8_t light_temp)
+{
+ uint16_t temp;
+
+ temp = (light_temp)*r_temp + r_temp;
+ r_temp = temp >> 8;
+
+ temp = (light_temp)*g_temp + g_temp;
+ g_temp = temp >> 8;
+
+ temp = (light_temp)*b_temp + b_temp;
+ b_temp = temp >> 8;
+}
+
+/**
+ * @brief auxiliary_rgb_light.
+ */
+uint8_t f_side_flag = 0x1f;
+uint8_t key_pwm_tab[45] = {0x00};
+uint8_t power_play_index = 0;
+uint8_t f_power_show = 1;
+uint8_t is_side_rgb_on(uint8_t index)
+{
+ if((((index >= 0)&&(index <= 10))||((index >= 37)&&(index <= 39)))&&(f_side_flag&0x01)) return true;
+ else if((((index >= 11)&&(index <= 17))||((index >= 23)&&(index <= 29))||((index >= 32)&&(index <= 36)))&&(f_side_flag&0x02)) return true;
+ else if(((index >= 40)&&(index <= 44))&&(f_side_flag&0x04)) return true;
+ else if(((index >= 18)&&(index <= 22))&&(f_side_flag&0x08)) return true;
+ else if(((index >= 30)&&(index <= 31))&&(f_side_flag&0x10)) return true;
+ else return false;
+}
+
+
+static void side_power_mode_show(void)
+{
+ if (side_play_cnt <= side_speed_table[0][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[0][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ if(power_play_index <= 45) {
+ key_pwm_tab[power_play_index] = 0xff;
+ power_play_index++;
+ }
+
+ uint8_t i;
+
+ for (i = 0; i < 45; i++) {
+
+ r_temp = colour_lib[side_colour][0];
+ g_temp = colour_lib[side_colour][1];
+ b_temp = colour_lib[side_colour][2];
+
+ count_rgb_light(key_pwm_tab[i]);
+ count_rgb_light(side_light_table[2]);
+ rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ }
+
+ for(i=0; i<45; i++)
+ {
+ if(key_pwm_tab[i] & 0x80) key_pwm_tab[i] -= 8;
+ else if(key_pwm_tab[i] & 0x40) key_pwm_tab[i] -= 6;
+ else if(key_pwm_tab[i] & 0x20) key_pwm_tab[i] -= 4;
+ else if(key_pwm_tab[i] & 0x10) key_pwm_tab[i] -= 3;
+ else if(key_pwm_tab[i] & 0x08) key_pwm_tab[i] -= 2;
+ else if(key_pwm_tab[i]) key_pwm_tab[i]--;
+ }
+
+ if(key_pwm_tab[44] == 1)
+ {
+ f_power_show = 0;
+ rf_link_show_time = 0;
+ bat_show_flag = true;
+ f_charging = true;
+ bat_show_time = timer_read32();
+ }
+}
+
+
+/**
+ * @brief side_wave_mode_show.
+ */
+static void side_wave_mode_show(void)
+{
+ uint8_t play_index;
+ uint8_t play_index_1;
+
+ if (side_play_cnt <= side_speed_table[side_mode_a][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[side_mode_a][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ if (side_rgb)
+ light_point_playing(0, 1, FLOW_COLOUR_TAB_LEN, &side_play_point);
+ else
+ light_point_playing(0, 1, WAVE_TAB_LEN, &side_play_point);
+
+ play_index = side_play_point;
+ if(side_line == 0) set_all_side_off();
+ for (int i = 0; i <= side_line - 5; i++) {
+ if (side_rgb) {
+ r_temp = flow_rainbow_colour_tab[play_index][0];
+ g_temp = flow_rainbow_colour_tab[play_index][1];
+ b_temp = flow_rainbow_colour_tab[play_index][2];
+
+ light_point_playing(1, 5, FLOW_COLOUR_TAB_LEN, &play_index);
+
+ } else {
+ r_temp = colour_lib[side_colour][0];
+ g_temp = colour_lib[side_colour][1];
+ b_temp = colour_lib[side_colour][2];
+
+ light_point_playing(1, 5, WAVE_TAB_LEN, &play_index);
+ count_rgb_light(wave_data_tab[play_index]);
+ }
+
+ count_rgb_light(side_light_table[side_light]);
+
+ play_index_1 = play_index;
+
+ if(i == 40)
+ {
+ if(f_side_flag == 0x1f)
+ {
+ for(;i<45;i++)
+ {
+ if (side_rgb) {
+ r_temp = flow_rainbow_colour_tab[play_index_1][0] * 0.4;
+ g_temp = flow_rainbow_colour_tab[play_index_1][1] * 0.4;
+ b_temp = flow_rainbow_colour_tab[play_index_1][2] * 0.4;
+ } else {
+ r_temp = colour_lib[side_colour][0] * 0.4;
+ g_temp = colour_lib[side_colour][1] * 0.4;
+ b_temp = colour_lib[side_colour][2] * 0.4;
+ count_rgb_light(wave_data_tab[play_index_1]);
+ }
+ count_rgb_light(side_light_table[side_light]);
+ rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ }
+ return;
+ }
+ else {
+ for(;i<45;i++)
+ {
+ rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+ return;
+ }
+
+ }
+ if(is_side_rgb_on(i)) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ else rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+
+ }
+}
+
+static void side_new_mode_show(void)
+{
+ uint8_t play_index;
+
+ if (side_play_cnt <= side_speed_table[side_mode_a][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[side_mode_a][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ light_point_playing(0, 1, (side_line - 5), &side_play_point);
+ play_index = side_play_point;
+ if(side_line == 0) set_all_side_off();
+ for (int i = 0; i <= (side_line - 5); i++) {
+
+ if (play_index < (side_line - 5)/2) {
+ r_temp = dual_colour_lib[side_colour][0];
+ g_temp = dual_colour_lib[side_colour][1];
+ b_temp = dual_colour_lib[side_colour][2];
+ } else {
+ r_temp = dual_colour_lib[side_colour][3];
+ g_temp = dual_colour_lib[side_colour][4];
+ b_temp = dual_colour_lib[side_colour][5];
+ }
+
+ light_point_playing(1, 1, (side_line - 5), &play_index);
+
+ count_rgb_light(side_light_table[side_light]);
+
+ if(i == 40)
+ {
+ if(f_side_flag == 0x1f)
+ {
+ r_temp = r_temp * 0.3;
+ g_temp = g_temp * 0.3;
+ b_temp = b_temp * 0.3;
+
+ for(;i<45;i++ ) {
+ rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ }
+ return;
+ }
+ else {
+ for(;i<45;i++ ) {
+ rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+ return;
+ }
+ }
+ if(is_side_rgb_on(i)) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ else rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+}
+
+static void side_spectrum_mode_show(void)
+{
+ if (side_play_cnt <= side_speed_table[side_mode_a][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[side_mode_a][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ if(side_line == 0) set_all_side_off();
+
+ light_point_playing(1, 1, FLOW_COLOUR_TAB_LEN, &side_play_point);
+
+ r_temp = flow_rainbow_colour_tab[side_play_point][0];
+ g_temp = flow_rainbow_colour_tab[side_play_point][1];
+ b_temp = flow_rainbow_colour_tab[side_play_point][2];
+
+ count_rgb_light(side_light_table[side_light]);
+
+ for (int i = 0; i <= 40; i++) {
+ if(i == 40)
+ {
+ if(f_side_flag == 0x1f){
+ r_temp = r_temp * 0.3;
+ g_temp = g_temp * 0.3;
+ b_temp = b_temp * 0.3;
+ for(;i<45;i++) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ return;
+ } else {
+ for(;i<45;i++) rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ return;
+ }
+ }
+ if(is_side_rgb_on(i)) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ else rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+}
+
+static void side_breathe_mode_show(void)
+{
+ static uint8_t play_point = 0;
+ static uint8_t colour = 0;
+
+ if (side_play_cnt <= side_speed_table[side_mode_a][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[side_mode_a][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ if(side_line == 0) set_all_side_off();
+
+ light_point_playing(0, 1, BREATHE_TAB_LEN, &play_point);
+
+ if (side_rgb) {
+ if(play_point == 0)
+ {
+ if(++colour >= LIGHT_COLOUR_MAX)
+ colour = 0;
+ }
+ r_temp = colour_lib[colour][0];
+ g_temp = colour_lib[colour][1];
+ b_temp = colour_lib[colour][2];
+
+ } else {
+ r_temp = colour_lib[side_colour][0];
+ g_temp = colour_lib[side_colour][1];
+ b_temp = colour_lib[side_colour][2];
+ }
+ count_rgb_light(breathe_data_tab[play_point]);
+ count_rgb_light(side_light_table[side_light]);
+
+ for (int i = 0; i <= 40; i++) {
+ if(i == 40)
+ {
+ if(f_side_flag == 0x1f){
+ r_temp = r_temp * 0.3;
+ g_temp = g_temp * 0.3;
+ b_temp = b_temp * 0.3;
+ for(;i<45;i++) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ return;
+ } else {
+ for(;i<45;i++) rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ return;
+ }
+ }
+ if(is_side_rgb_on(i)) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ else rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+}
+
+/**
+ * @brief side_static_mode_show.
+ */
+static void side_static_mode_show(void)
+{
+ if (side_play_cnt <= side_speed_table[side_mode_a][side_speed])
+ return;
+ else
+ side_play_cnt -= side_speed_table[side_mode_a][side_speed];
+ if (side_play_cnt > 20) side_play_cnt = 0;
+
+ if(side_line == 0) set_all_side_off();
+
+ if (side_play_point >= SIDE_COLOUR_MAX) side_play_point = 0;
+
+ for (int i = 0; i < side_line; i++) {
+
+ r_temp = colour_lib[side_colour][0];
+ g_temp = colour_lib[side_colour][1];
+ b_temp = colour_lib[side_colour][2];
+
+ if((side_led_index_tab[i] <= SIDE_INDEX+9)&&(side_led_index_tab[i] >= SIDE_INDEX))
+ {
+ r_temp = colour_lib_1[side_colour][0] * 0.7;
+ g_temp = colour_lib_1[side_colour][1] * 0.7;
+ b_temp = colour_lib_1[side_colour][2] * 0.7;
+ }
+
+
+ count_rgb_light(side_light_table[side_light]);
+
+ if(is_side_rgb_on(i)) rgb_matrix_set_color(side_led_index_tab[i], r_temp, g_temp, b_temp);
+ else rgb_matrix_set_color(side_led_index_tab[i], 0, 0, 0);
+ }
+}
+
+/**
+ * @brief bat_chargeing_breathe.
+ */
+void bat_charging_breathe(void)
+{
+ static uint32_t interval_timer = 0;
+ static uint8_t play_point = 0;
+
+ if (timer_elapsed32(interval_timer) > 30) {
+ interval_timer = timer_read32();
+ light_point_playing(0, 2, BREATHE_TAB_LEN, &play_point);
+ }
+
+ r_temp = 0x80; g_temp = 0x40; b_temp = 0x00;
+ count_rgb_light(breathe_data_tab[play_point]);
+ set_left_rgb(r_temp, g_temp, b_temp);
+
+}
+
+/**
+ * @brief bat_chargeing_design.
+ */
+void bat_charging_design(uint8_t init, uint8_t r, uint8_t g, uint8_t b)
+{
+ static uint32_t interval_timer = 0;
+ static uint16_t show_mask = 0x00;
+ static bool f_move_trend = 0;
+ uint16_t bit_mask = 1;
+ uint8_t i;
+
+ if (timer_elapsed32(interval_timer) > 100) {
+ interval_timer = timer_read32();
+
+ if (f_move_trend) {
+ show_mask >>= 1;
+ if (show_mask == 0x1f >> (side_line - init))
+ f_move_trend = 0;
+ } else {
+ show_mask <<= 1;
+ show_mask |= 1;
+ if (show_mask == 0x7f)
+ f_move_trend = 1;
+ }
+ }
+
+ for (i = 0; i < side_line; i++) {
+ if (show_mask & bit_mask) {
+ rgb_matrix_set_color(i, r, g, b);
+ } else {
+ rgb_matrix_set_color(i, 0x00, 0x00, 0x00);
+ }
+ bit_mask <<= 1;
+ }
+}
+
+/**
+ * @brief rf state indicate
+ */
+#define RF_LED_LINK_PERIOD 500
+#define RF_LED_PAIR_PERIOD 250
+void rf_led_show(void)
+{
+ static uint32_t rf_blink_timer = 0;
+ static bool flag_power_on = 1;
+ uint16_t rf_blink_priod = 0;
+ extern uint8_t rf_blink_cnt;
+
+ if (dev_info.link_mode == LINK_RF_24)
+ {
+ r_temp = colour_lib[3][0];
+ g_temp = colour_lib[3][1];
+ b_temp = colour_lib[3][2];
+ } else if (dev_info.link_mode == LINK_USB) {
+ r_temp = colour_lib[2][0];
+ g_temp = colour_lib[2][1];
+ b_temp = colour_lib[2][2];
+ if (flag_power_on && (rf_link_show_time < RF_LINK_SHOW_TIME)) return;
+ } else
+ {
+ r_temp = colour_lib[5][0];
+ g_temp = colour_lib[5][1];
+ b_temp = colour_lib[5][2];
+ }
+
+ flag_power_on = 0;
+
+ if (rf_blink_cnt)
+ {
+ if (dev_info.rf_state == RF_PAIRING)
+ rf_blink_priod = RF_LED_PAIR_PERIOD;
+ else
+ rf_blink_priod = RF_LED_LINK_PERIOD;
+
+ if (timer_elapsed32(rf_blink_timer) < (rf_blink_priod >> 1)) {
+ } else {
+ r_temp = 0x00;
+ g_temp = 0x00;
+ b_temp = 0x00;
+ }
+
+ if (timer_elapsed32(rf_blink_timer) >= rf_blink_priod) {
+ rf_blink_cnt--;
+ rf_blink_timer = timer_read32();
+ }
+ } else if (rf_link_show_time < RF_LINK_SHOW_TIME) {
+ } else {
+ rf_blink_timer = timer_read32();
+ return;
+ }
+
+ set_left_rgb(r_temp, g_temp, b_temp);
+}
+
+uint8_t low_bat_blink_cnt = 6;
+#define LOW_BAT_BLINK_PRIOD 500
+void low_bat_show(void)
+{
+ static uint32_t interval_timer = 0;
+
+ r_temp = 0x80, g_temp = 0, b_temp = 0;
+
+ if(low_bat_blink_cnt)
+ {
+ if (timer_elapsed32(interval_timer) > (LOW_BAT_BLINK_PRIOD >> 1)) {
+ r_temp = 0x00; g_temp = 0x00; b_temp = 0x00;
+ }
+
+ if (timer_elapsed32(interval_timer) >= LOW_BAT_BLINK_PRIOD) {
+ interval_timer = timer_read32();
+ low_bat_blink_cnt--;
+ }
+ }
+ set_left_rgb(r_temp, g_temp, b_temp);
+}
+
+
+
+
+uint8_t bat_pwm_buf[6 * 3] = {0};
+uint8_t bat_end_led = 0;
+uint8_t bat_r, bat_g, bat_b;
+
+/**
+ * @brief Battery level indicator
+ */
+void bat_percent_led(uint8_t bat_percent)
+{
+ uint8_t i;
+
+ if (bat_percent <= 20) {
+ bat_end_led = 1;
+ bat_r = colour_lib[0][0]; bat_g = colour_lib[0][1]; bat_b = colour_lib[0][2];
+ } else if (bat_percent <= 50) {
+ bat_end_led = 2;
+ bat_r = colour_lib[1][0]; bat_g = colour_lib[1][1]; bat_b = colour_lib[1][2];
+ } else if (bat_percent <= 80){
+ bat_end_led = 4;
+ bat_r = colour_lib[2][0]; bat_g = colour_lib[2][1]; bat_b = colour_lib[2][2];
+ } else{
+ bat_end_led = 5;
+ bat_r = colour_lib[3][0]; bat_g = colour_lib[3][1]; bat_b = colour_lib[3][2];
+ }
+ if (f_charging) {
+ low_bat_blink_cnt = 6;
+ #if (CHARGING_SHIFT)
+ bat_charging_design(bat_end_led, bat_r >> 2, bat_g >> 2, bat_b >> 2);
+ #else
+ bat_charging_breathe();
+ #endif
+ }
+ else if(bat_percent < 10) {
+ low_bat_show();
+ }
+ else {
+ bat_end_led = 4;
+ low_bat_blink_cnt = 6;
+ for (i = 0; i <= bat_end_led; i++)
+ rgb_matrix_set_color(SIDE_INDEX + i, bat_r, bat_g, bat_b);
+ }
+}
+
+bool low_bat_flag = 0;
+/**
+ * @brief battery state indicate
+ */
+void bat_led_show(void)
+{
+ static bool bat_show_flag = true;
+ static uint32_t bat_show_time = 0;
+ static uint32_t bat_sts_debounce = 0;
+ static uint32_t bat_per_debounce = 0;
+ static uint8_t charge_state = 0;
+ static uint8_t bat_percent = 0;
+ static bool f_init = 1;
+
+ if(dev_info.link_mode != LINK_USB)
+ {
+ if(rf_link_show_time < RF_LINK_SHOW_TIME)
+ return;
+
+ if(dev_info.rf_state != RF_CONNECT)
+ return;
+ }
+
+ if (f_init) {
+ f_init = 0;
+ bat_show_time = timer_read32();
+ charge_state = dev_info.rf_charge;
+ bat_percent = dev_info.rf_baterry;
+ }
+
+ if (charge_state != dev_info.rf_charge) {
+ if (timer_elapsed32(bat_sts_debounce) > 1000){
+ if(((charge_state & 0x01) == 0) && ((dev_info.rf_charge & 0x01) != 0)) {
+ bat_show_flag = true;
+ f_charging = true;
+ bat_show_time = timer_read32();
+ }
+ charge_state = dev_info.rf_charge;
+ }
+ }
+ else {
+ bat_sts_debounce = timer_read32();
+ if(f_charging) {
+ if (timer_elapsed32(bat_show_time) > 10000) {
+ bat_show_flag = false;
+ f_charging = false;
+ }
+ } else {
+ if (timer_elapsed32(bat_show_time) > 5000) {
+ bat_show_flag = false;
+ }
+ }
+ if (charge_state == 0x03) {
+ f_charging = true;
+ } else if (!(charge_state & 0x01)) {
+ f_charging = 0;
+ }
+ }
+
+ if (bat_percent != dev_info.rf_baterry) {
+ if (timer_elapsed32(bat_per_debounce) > 1000) {
+ bat_percent = dev_info.rf_baterry;
+ }
+ }
+ else {
+ bat_per_debounce = timer_read32();
+
+ if( (bat_percent < 10) && (!(charge_state&0x01)))
+ {
+ bat_show_flag = true;
+ bat_show_time = timer_read32();
+ low_bat_flag = 1;
+ if(rgb_matrix_config.hsv.v > RGB_MATRIX_VAL_STEP) {
+ rgb_matrix_config.hsv.v = RGB_MATRIX_VAL_STEP;
+ }
+
+ if(side_light > 1) {
+ side_light = 1;
+ }
+ }
+ else low_bat_flag = 0;
+ }
+ if (f_bat_hold || bat_show_flag) {
+ bat_percent_led(bat_percent);
+ }
+}
+
+
+/**
+ * @brief device_reset_show.
+ */
+void rgb_matrix_update_pwm_buffers(void);
+void device_reset_show(void)
+{
+ writePinHigh(DC_BOOST_PIN);
+ writePinHigh(RGB_DRIVER_SDB1);
+ writePinHigh(RGB_DRIVER_SDB2);
+ for (int blink_cnt = 0; blink_cnt < 3; blink_cnt++) {
+ rgb_matrix_set_color_all(0xFF, 0xFF, 0xFF);
+ rgb_matrix_update_pwm_buffers();
+ wait_ms(200);
+
+ rgb_matrix_set_color_all(0x00, 0x00, 0x00);
+ rgb_matrix_update_pwm_buffers();
+ wait_ms(200);
+ }
+}
+
+void device_reset_init(void)
+{
+ side_mode_a = 0;
+ side_mode_b = 3;
+ side_light = 2;
+ side_speed = 2;
+ side_rgb = 1;
+ side_colour = 0;
+ side_play_point = 0;
+
+ side_play_cnt = 0;
+ side_play_timer = timer_read32();
+
+ f_bat_hold = false;
+
+ rgb_matrix_enable();
+ rgb_matrix_mode(RGB_MATRIX_DEFAULT_MODE);
+ rgb_matrix_set_speed(255 - RGB_MATRIX_SPD_STEP * 2);
+ rgb_matrix_sethsv(RGB_DEFAULT_COLOUR, 255, RGB_MATRIX_MAXIMUM_BRIGHTNESS - RGB_MATRIX_VAL_STEP * 2);
+
+ user_config.default_brightness_flag = 0xA5;
+ user_config.ee_side_mode_a = side_mode_a;
+ user_config.ee_side_mode_b = side_mode_b;
+ user_config.ee_side_light = side_light;
+ user_config.ee_side_speed = side_speed;
+ user_config.ee_side_rgb = side_rgb;
+ user_config.ee_side_colour = side_colour;
+ f_dev_sleep_enable = true;
+ eeconfig_update_user_datablock(&user_config);
+}
+
+/**
+ * @brief rgb test
+ */
+void rgb_test_show(void)
+{
+ writePinHigh(DC_BOOST_PIN);
+ writePinHigh(RGB_DRIVER_SDB1);
+ writePinHigh(RGB_DRIVER_SDB2);
+ rgb_matrix_set_color_all(0xFF, 0x00, 0x00);
+ rgb_matrix_update_pwm_buffers();
+ wait_ms(1000);
+ rgb_matrix_set_color_all(0x00, 0xFF, 0x00);
+ rgb_matrix_update_pwm_buffers();
+ wait_ms(1000);
+ rgb_matrix_set_color_all(0x00, 0x00, 0xFF);
+ rgb_matrix_update_pwm_buffers();
+ wait_ms(1000);
+}
+
+/**
+ * @brief side_led_show.
+ */
+void m_side_led_show(void)
+{
+ static bool flag_power_on = 1;
+ extern bool f_dial_sw_init_ok;
+
+ side_play_cnt += timer_elapsed32(side_play_timer);
+ side_play_timer = timer_read32();
+
+ if (flag_power_on) {
+ if (!f_dial_sw_init_ok) return;
+ flag_power_on = 0;
+ }
+
+ if(f_power_show) {
+ side_power_mode_show();
+ return;
+ }
+
+ switch(side_mode_b){
+ case SIDE_MODE_1:
+ side_line = 0;
+ f_side_flag = 0;
+ break;
+
+ case SIDE_MODE_2:
+ side_line = 45;
+ f_side_flag = 0x08;
+ break;
+
+ case SIDE_MODE_3:
+ side_line = 45;
+ f_side_flag = 0x18;
+ break;
+
+ case SIDE_MODE_4:
+ side_line = 45;
+ f_side_flag = 0x1f;
+ break;
+
+ case SIDE_MODE_5:
+ side_line = 45;
+ f_side_flag = 0x01;
+ break;
+
+ case SIDE_MODE_6:
+ side_line = 45;
+ f_side_flag = 0x09;
+ break;
+
+ case SIDE_MODE_7:
+ side_line = 45;
+ f_side_flag = 0x19;
+ break;
+ default: break;
+ }
+
+ switch (side_mode_a) {
+ case SIDE_WAVE: side_wave_mode_show(); break;
+ case SIDE_NEW: side_new_mode_show(); break;
+ case SIDE_MIX: side_spectrum_mode_show(); break;
+ case SIDE_BREATH: side_breathe_mode_show(); break;
+ case SIDE_STATIC: side_static_mode_show(); break;
+ }
+
+ bat_led_show();
+ sys_led_show();
+ sys_sw_led_show();
+ sleep_sw_led_show();
+ rf_led_show();
+
+
+}
diff --git a/keyboards/nuphy/halo75/ansi/side.h b/keyboards/nuphy/halo75/ansi/side.h
new file mode 100644
index 000000000000..275b9d84c6f0
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/side.h
@@ -0,0 +1,326 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+#pragma once
+
+#define STARRY_INDEX_LEN (160)
+#define WAVE_TAB_LEN 112
+#define BREATHE_TAB_LEN 128
+#define MIXCOLOUR_TAB_LEN 144
+#define FLOW_COLOUR_TAB_LEN 192
+#define FIREWORK_INDEX_LEN (158)
+#define STARRY_DATA_LEN 96
+#define TIDE_DATA_LEN 120
+
+
+const uint8_t light_value_tab[101] =
+{
+ 0, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 36, 37, 39, 40, 42, 43,
+ 45, 47, 49, 51, 53, 55, 57, 59,
+ 61, 63, 65, 67, 69, 71, 73, 75,
+ 77, 79, 81, 83, 85, 87, 89, 91,
+ 94, 96, 99, 101, 104, 106, 109, 111,
+ 114, 116, 119, 121, 124, 126, 129, 131,
+ 134, 137, 140, 143, 146, 149, 152, 155,
+ 158, 161, 164, 167, 170, 173, 176, 179,
+ 182, 185, 188, 191, 194, 197, 200, 203,
+ 206, 209, 213, 216, 220, 223, 227, 230,
+ 234, 237, 241, 245, 248, 251, 255, 255,
+ 255,
+};
+
+const uint8_t breathe_data_tab[BREATHE_TAB_LEN]=
+{
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 12, 14, 16, 18, 20,
+ 22, 24, 27, 30, 33, 36, 39, 42,
+ 45, 49, 53, 57, 61, 65, 69, 73,
+ 77, 81, 85, 89, 94, 99, 104, 109,
+ 114, 119, 124, 129, 134, 140, 146, 152,
+ 158, 164, 170, 176, 182, 188, 194, 200,
+ 206, 213, 220, 227, 234, 241, 248, 255,
+
+ 255, 248, 241, 234, 227, 220, 213, 206,
+ 200, 194, 188, 182, 176, 170, 164, 158,
+ 152, 146, 140, 134, 129, 124, 119, 114,
+ 109, 104, 99, 94, 89, 85, 81, 77,
+ 73, 69, 65, 61, 57, 53, 49, 45,
+ 42, 39, 36, 33, 30, 27, 24, 22,
+ 20, 18, 16, 14, 12, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0,
+};
+
+const uint8_t wave_data_tab[WAVE_TAB_LEN]=
+{
+ 22, 23, 24, 25, 27, 28, 30, 31,
+ 33, 34, 36, 37, 39, 40, 42, 43,
+ 45, 47, 49, 51, 53, 55, 57, 59,
+ 61, 63, 65, 76, 69, 71, 73, 75,
+ 77, 81, 85, 89, 94, 99, 104, 109,
+ 114, 119, 124, 129, 134, 140, 146, 152,
+ 158, 164, 170, 176, 182, 188, 194, 200,
+ 206, 213, 220, 227, 234, 241, 248, 255,
+
+ 255, 248, 241, 234, 227, 220, 213, 206,
+ 200, 194, 188, 182, 176, 170, 164, 158,
+ 152, 146, 140, 134, 129, 124, 119, 114,
+ 109, 104, 99, 94, 89, 85, 81, 77,
+ 73, 69, 65, 61, 57, 53, 49, 45,
+ 42, 39, 36, 33, 30, 27, 24, 22,
+};
+
+const uint8_t flow_rainbow_colour_tab[FLOW_COLOUR_TAB_LEN][3]=
+{
+ {255, 8, 8},
+ {255, 8, 8},
+ {255, 8, 8},
+ {255, 8, 8},
+ {255, 10, 8},
+ {255, 14, 8},
+ {255, 18, 8},
+ {255, 22, 8},
+ {255, 26, 8},
+ {255, 32, 8},
+ {255, 38, 8},
+ {255, 44, 8},
+ {255, 50, 8},
+ {255, 57, 8},
+ {255, 65, 8},
+ {255, 73, 8},
+
+ {255, 81, 8},
+ {255, 89, 8},
+ {255, 99, 8},
+ {255, 109, 8},
+ {255, 119, 8},
+ {255, 129, 8},
+ {255, 140, 8},
+ {255, 152, 8},
+ {255, 164, 8},
+ {255, 176, 8},
+ {255, 188, 8},
+ {255, 200, 8},
+ {255, 213, 8},
+ {255, 227, 8},
+ {255, 241, 8},
+ {255, 255, 8},
+
+ {248, 255, 8},
+ {234, 255, 8},
+ {220, 255, 8},
+ {206, 255, 8},
+ {194, 255, 8},
+ {182, 255, 8},
+ {170, 255, 8},
+ {158, 255, 8},
+ {146, 255, 8},
+ {134, 255, 8},
+ {124, 255, 8},
+ {114, 255, 8},
+ {104, 255, 8},
+ {94, 255, 8},
+ {85, 255, 8},
+ {77, 255, 8},
+
+ {69, 255, 8},
+ {61, 255, 8},
+ {53, 255, 8},
+ {47, 255, 8},
+ {41, 255, 8},
+ {35, 255, 8},
+ {29, 255, 8},
+ {24, 255, 8},
+ {20, 255, 8},
+ {16, 255, 8},
+ {12, 255, 8},
+ {8, 255, 8},
+ {8, 255, 8},
+ {8, 255, 8},
+ {8, 255, 8},
+ {8, 255, 8},
+
+ {8, 255, 8, },
+ {8, 255, 8, },
+ {8, 255, 8, },
+ {8, 255, 8, },
+ {8, 255, 10, },
+ {8, 255, 14, },
+ {8, 255, 18, },
+ {8, 255, 22, },
+ {8, 255, 26, },
+ {8, 255, 32, },
+ {8, 255, 38, },
+ {8, 255, 44, },
+ {8, 255, 50, },
+ {8, 255, 57, },
+ {8, 255, 65, },
+ {8, 255, 73, },
+
+ {8, 255, 81, },
+ {8, 255, 89, },
+ {8, 255, 99, },
+ {8, 255, 109,},
+ {8, 255, 119,},
+ {8, 255, 129,},
+ {8, 255, 140 },
+ {8, 255, 152 },
+ {8, 255, 164,},
+ {8, 255, 176, },
+ {8, 255, 188,},
+ {8, 255, 200,},
+ {8, 255, 213,},
+ {8, 255, 227,},
+ {8, 255, 241,},
+ {8, 255, 255,},
+
+ {8, 248, 255,},
+ {8, 234, 255,},
+ {8, 220, 255,},
+ {8, 206, 255,},
+ {8, 194, 255,},
+ {8, 182, 255,},
+ {8, 170, 255,},
+ {8, 158, 255,},
+ {8, 146, 255,},
+ {8, 134, 255,},
+ {8, 124, 255,},
+ {8, 114, 255,},
+ {8, 104, 255,},
+ {8, 94, 255,},
+ {8, 85, 255,},
+ {8, 77, 255,},
+
+ {8, 69, 255,},
+ {8, 61, 255,},
+ {8, 53, 255,},
+ {8, 47, 255,},
+ {8, 41, 255,},
+ {8, 35, 255,},
+ {8, 29, 255,},
+ {8, 24, 255,},
+ {8, 20, 255,},
+ {8, 16, 255,},
+ {8, 12, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {8, 8, 255,},
+ {10, 8, 255,},
+ {14, 8, 255,},
+ {18, 8, 255,},
+ {22, 8, 255,},
+ {26, 8, 255,},
+ {32, 8, 255,},
+ {38, 8, 255,},
+ {44, 8, 255,},
+ {50, 8, 255,},
+ {57, 8, 255,},
+ {65, 8, 255,},
+ {73, 8, 255,},
+
+ {81, 8, 255,},
+ {89, 8, 255,},
+ {99, 8, 255,},
+ {109, 8, 255,},
+ {119, 8, 255,},
+ {129, 8, 255,},
+ {140, 8, 255,},
+ {152, 8, 255,},
+ {164, 8, 255,},
+ {176, 8, 255,},
+ {188, 8, 255,},
+ {200, 8, 255,},
+ {213, 8, 255,},
+ {227, 8, 255,},
+ {241, 8, 255,},
+ {255, 8, 255,},
+
+ {255, 8, 248,},
+ {255, 8, 234,},
+ {255, 8, 220,},
+ {255, 8, 206,},
+ {255, 8, 194,},
+ {255, 8, 182,},
+ {255, 8, 170,},
+ {255, 8, 158,},
+ {255, 8, 146,},
+ {255, 8, 134,},
+ {255, 8, 124,},
+ {255, 8, 114,},
+ {255, 8, 104,},
+ {255, 8, 94, },
+ {255, 8, 85, },
+ {255, 8, 77, },
+
+ {255, 8, 69, },
+ {255, 8, 61, },
+ {255, 8, 53, },
+ {255, 8, 47, },
+ {255, 8, 41, },
+ {255, 8, 35, },
+ {255, 8, 29, },
+ {255, 8, 24, },
+ {255, 8, 20, },
+ {255, 8, 16, },
+ {255, 8, 12, },
+ {255, 8, 8, },
+ {255, 8, 8, },
+ {255, 8, 8, },
+ {255, 8, 8, },
+ {255, 8, 8, },
+};
+
+
+const uint8_t dual_colour_lib[3][6] =
+{
+ {0, 255, 255, 0, 0, 255},
+ {0, 0, 255, 255, 0, 160},
+ {0, 255, 255, 255, 64, 64 },
+
+};
+
+const uint8_t colour_lib[9][3] =
+{
+ {0xff, 0x00, 0x00},
+ {0xff, 0x20, 0x00},
+ {0x80, 0x40, 0x00},
+ {0x00, 0x80, 0x00},
+ {0x00, 0x80, 0x80},
+ {0x00, 0x00, 0x80},
+ {0xff, 0x00, 0xa0},
+ {0xff, 0xa0, 0xa0},
+ {0x00, 0x00, 0x00},
+};
+const uint8_t colour_lib_1[9][3] =
+{
+ {0x70, 0x00, 0x00},
+ {0x70, 0x20, 0x00},
+ {0x60, 0x30, 0x00},
+ {0x00, 0x70, 0x00},
+ {0x00, 0x70, 0x70},
+ {0x00, 0x00, 0x70},
+ {0x70, 0x00, 0x70},
+ {0x40, 0x70, 0x60},
+ {0x00, 0x00, 0x00},
+};
diff --git a/keyboards/nuphy/halo75/ansi/sleep.c b/keyboards/nuphy/halo75/ansi/sleep.c
new file mode 100644
index 000000000000..74115d626aae
--- /dev/null
+++ b/keyboards/nuphy/halo75/ansi/sleep.c
@@ -0,0 +1,107 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "ansi.h"
+#include "hal_usb.h"
+#include "usb_main.h"
+
+extern user_config_t user_config;
+extern DEV_INFO_STRUCT dev_info;
+extern uint16_t rf_linking_time;
+extern uint16_t no_act_time;
+
+extern bool f_wakeup_prepare;
+extern bool f_goto_sleep;
+
+uint8_t uart_send_cmd(uint8_t cmd, uint8_t ack_cnt, uint8_t delayms);
+
+
+/**
+ * @brief Sleep Handle.
+ */
+void Sleep_Handle(void) {
+ static uint32_t delay_step_timer = 0;
+ static uint8_t usb_suspend_debounce = 0;
+ static uint32_t rf_disconnect_time = 0;
+
+ /* 50ms interval */
+ if (timer_elapsed32(delay_step_timer) < 50) return;
+ delay_step_timer = timer_read32();
+
+ // sleep process
+ if (f_goto_sleep) {
+ f_goto_sleep = 0;
+
+ if(f_dev_sleep_enable) {
+ if (dev_info.rf_state == RF_CONNECT)
+ uart_send_cmd(CMD_SET_CONFIG, 5, 5);
+ else
+ uart_send_cmd(CMD_SLEEP, 5, 5);
+
+ // power off led
+ writePinLow(DC_BOOST_PIN);
+ writePinLow(RGB_DRIVER_SDB1);
+ writePinLow(RGB_DRIVER_SDB2);
+ }
+
+ f_wakeup_prepare = 1;
+ }
+
+ // wakeup check
+ if (f_wakeup_prepare && (no_act_time < 10)) {
+ f_wakeup_prepare = 0;
+
+ writePinHigh(DC_BOOST_PIN);
+ writePinHigh(RGB_DRIVER_SDB1);
+ writePinHigh(RGB_DRIVER_SDB2);
+
+ uart_send_cmd(CMD_HAND, 0, 1);
+
+ if (dev_info.link_mode == LINK_USB) {
+ usb_lld_wakeup_host(&USB_DRIVER);
+ restart_usb_driver(&USB_DRIVER);
+ }
+ }
+
+ // sleep check
+ if (f_goto_sleep || f_wakeup_prepare)
+ return;
+ if (dev_info.link_mode == LINK_USB) {
+ if (USB_DRIVER.state == USB_SUSPENDED) {
+ usb_suspend_debounce++;
+ if (usb_suspend_debounce >= 20) {
+ f_goto_sleep = 1;
+ }
+ } else {
+ usb_suspend_debounce = 0;
+ }
+ } else if (dev_info.rf_state == RF_CONNECT) {
+ rf_disconnect_time = 0;
+ if (no_act_time >= SLEEP_TIME_DELAY) {
+ f_goto_sleep = 1;
+ }
+ } else if (rf_linking_time >= LINK_TIMEOUT) {
+ rf_linking_time = 0;
+ f_goto_sleep = 1;
+ } else if (dev_info.rf_state == RF_DISCONNECT) {
+ rf_disconnect_time++;
+ if (rf_disconnect_time > 5 * 20) {
+ rf_disconnect_time = 0;
+ f_goto_sleep = 1;
+ }
+ }
+}