add raw hid commands for future use

This commit is contained in:
lokher 2024-01-30 12:28:56 +08:00
parent ce5bebd9fc
commit 25bacce4bc
21 changed files with 289 additions and 359 deletions

View File

@ -14,7 +14,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "keychron_common.h"
#include "raw_hid.h"
#include "version.h"
#define PROTOCOL_VERSION 0x02
enum {
kc_get_protocol_version = 0xA0,
kc_get_firmware_version = 0xA1,
kc_get_support_feature = 0xA2,
kc_get_default_layer = 0xA3,
};
enum {
FEATURE_DEFAULT_LAYER = 0x01 << 0,
};
bool is_siri_active = false;
uint32_t siri_timer = 0;
@ -112,6 +129,72 @@ __attribute__((weak)) void keyboard_post_init_kb(void) {
}
#endif
#ifdef PROTOCOL_CHIBIOS
void restart_usb_driver(USBDriver *usbp) {
// Do nothing. Restarting the USB driver on these boards breaks it.
}
#endif
#ifdef RAW_ENABLE
# ifdef FACTORY_TEST_ENABLE
__attribute__((weak)) bool factory_test_rx(uint8_t *data, uint8_t length) {
return false;
}
# endif
void get_support_feature(uint8_t *data) {
data[1] = FEATURE_DEFAULT_LAYER;
}
bool via_command_kb(uint8_t *data, uint8_t length) {
// if (!raw_hid_receive_keychron(data, length))
// return false;
switch (data[0]) {
case kc_get_protocol_version:
data[1] = PROTOCOL_VERSION;
raw_hid_send(data, length);
break;
case kc_get_firmware_version: {
uint8_t i = 1;
data[i++] = 'v';
if ((DEVICE_VER & 0xF000) != 0) itoa((DEVICE_VER >> 12), (char *)&data[i++], 16);
itoa((DEVICE_VER >> 8) & 0xF, (char *)&data[i++], 16);
data[i++] = '.';
itoa((DEVICE_VER >> 4) & 0xF, (char *)&data[i++], 16);
data[i++] = '.';
itoa((DEVICE_VER >> 4) & 0xF, (char *)&data[i++], 16);
data[i++] = ' ';
memcpy(&data[i], QMK_BUILDDATE, sizeof(QMK_BUILDDATE));
i += sizeof(QMK_BUILDDATE);
raw_hid_send(data, length);
} break;
case kc_get_support_feature:
get_support_feature(&data[1]);
raw_hid_send(data, length);
break;
case kc_get_default_layer:
data[1] = get_highest_layer(default_layer_state);
raw_hid_send(data, length);
break;
# ifdef FACTORY_TEST_ENABLE
case 0xAB:
factory_test_rx(data, length);
break;
# endif
default:
return false;
}
return true;
}
# if !defined(VIA_ENABLE)
void raw_hid_receive(uint8_t *data, uint8_t length) {
via_command_kb(data, length);
}
# endif
#endif

View File

@ -49,3 +49,7 @@ typedef struct PACKED {
void housekeeping_task_keychron(void);
bool process_record_keychron(uint16_t keycode, keyrecord_t *record);
#ifdef FACTORY_TEST_ENABLE
bool factory_test_rx(uint8_t *data, uint8_t length);
#endif

View File

@ -178,39 +178,36 @@ bool dip_switch_update_user(uint8_t index, bool active) {
return true;
}
bool via_command_kb(uint8_t *data, uint8_t length) {
if (data[0] == 0xAB) {
uint16_t checksum = 0;
for (uint8_t i = 1; i < RAW_EPSIZE - 3; i++) {
checksum += data[i];
}
/* Verify checksum */
if ((checksum & 0xFF) != data[RAW_EPSIZE - 2] || checksum >> 8 != data[RAW_EPSIZE - 1]) {
return true;
}
switch (data[1]) {
#if defined(DIP_SWITCH_ENABLE)
case FACTORY_TEST_CMD_OS_SWITCH:
report_os_sw_state = data[2];
if (report_os_sw_state) {
dip_switch_read(true);
}
break;
#endif
case FACTORY_TEST_CMD_JUMP_TO_BL:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (memcmp(&data[2], "JumpToBootloader", strlen("JumpToBootloader")) == 0) bootloader_jump();
}
break;
case FACTORY_TEST_CMD_EEPROM_CLEAR:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (data[2]) {
factory_reset();
}
}
break;
}
bool factory_test_rx(uint8_t *data, uint8_t length) {
uint16_t checksum = 0;
for (uint8_t i = 1; i < RAW_EPSIZE - 3; i++) {
checksum += data[i];
}
/* Verify checksum */
if ((checksum & 0xFF) != data[RAW_EPSIZE - 2] || checksum >> 8 != data[RAW_EPSIZE - 1]) {
return true;
}
return false;
switch (data[1]) {
#if defined(DIP_SWITCH_ENABLE)
case FACTORY_TEST_CMD_OS_SWITCH:
report_os_sw_state = data[2];
if (report_os_sw_state) {
dip_switch_read(true);
}
break;
#endif
case FACTORY_TEST_CMD_JUMP_TO_BL:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (memcmp(&data[2], "JumpToBootloader", strlen("JumpToBootloader")) == 0) bootloader_jump();
}
break;
case FACTORY_TEST_CMD_EEPROM_CLEAR:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (data[2]) {
factory_reset();
}
}
break;
}
return true;
}

View File

@ -232,6 +232,7 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
rgb_matrix_set_color(i, factory_reset_count % 2 ? 0 : RGB_RED);
}
}
return false;
} else if (led_test_mode) {
switch (led_test_mode) {
case LED_TEST_MODE_WHITE:
@ -273,6 +274,7 @@ bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
default:
break;
}
return false;
}
return true;
}
@ -287,6 +289,7 @@ void housekeeping_task_keychron_ft(void) {
}
}
#ifdef RAW_ENABLE
static void system_switch_state_report(uint8_t index, bool active) {
uint16_t checksum = 0;
uint8_t data[RAW_EPSIZE] = {0};
@ -295,11 +298,11 @@ static void system_switch_state_report(uint8_t index, bool active) {
if (report_os_sw_state) {
payload[0] = FACTORY_TEST_CMD_OS_SWITCH;
payload[1] = OS_SWITCH;
#if defined(OS_SWITCH_REVERSE)
# if defined(OS_SWITCH_REVERSE)
payload[2] = !active;
#else
# else
payload[2] = active;
#endif
# endif
data[0] = 0xAB;
memcpy(&data[1], payload, 3);
for (uint8_t i = 1; i < RAW_EPSIZE - 3; i++) {
@ -317,61 +320,59 @@ bool dip_switch_update_user(uint8_t index, bool active) {
return true;
}
bool via_command_kb(uint8_t *data, uint8_t length) {
if (data[0] == 0xAB) {
uint16_t checksum = 0;
for (uint8_t i = 1; i < RAW_EPSIZE - 3; i++) {
checksum += data[i];
}
/* Verify checksum */
if ((checksum & 0xFF) != data[RAW_EPSIZE - 2] || checksum >> 8 != data[RAW_EPSIZE - 1]) {
return true;
}
switch (data[1]) {
#if defined(RGB_MATRIX_ENABLE)
case FACTORY_TEST_CMD_BACKLIGHT:
led_test_mode = data[2];
# if defined(SPLIT_KEYBOARD)
if (led_test_mode) {
light_test_state += 1;
if (light_test_state == 1) {
led_state = rgb_matrix_get_mode();
hsv = rgb_matrix_get_hsv();
}
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
} else {
if (light_test_state) {
light_test_state = 0;
rgb_matrix_mode_noeeprom(led_state);
rgb_matrix_sethsv_noeeprom(hsv.h, hsv.s, hsv.v);
}
}
# endif
timer_3s_buffer = 0;
break;
#endif
#if defined(DIP_SWITCH_ENABLE)
case FACTORY_TEST_CMD_OS_SWITCH:
report_os_sw_state = data[2];
if (report_os_sw_state) {
dip_switch_read(true);
}
break;
#endif
case FACTORY_TEST_CMD_JUMP_TO_BL:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (memcmp(&data[2], "JumpToBootloader", strlen("JumpToBootloader")) == 0) bootloader_jump();
}
break;
case FACTORY_TEST_CMD_EEPROM_CLEAR:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (data[2]) {
factory_reset();
}
}
break;
}
bool factory_test_rx(uint8_t *data, uint8_t length) {
uint16_t checksum = 0;
for (uint8_t i = 1; i < RAW_EPSIZE - 3; i++) {
checksum += data[i];
}
/* Verify checksum */
if ((checksum & 0xFF) != data[RAW_EPSIZE - 2] || checksum >> 8 != data[RAW_EPSIZE - 1]) {
return true;
}
return false;
switch (data[1]) {
# if defined(RGB_MATRIX_ENABLE)
case FACTORY_TEST_CMD_BACKLIGHT:
led_test_mode = data[2];
# if defined(SPLIT_KEYBOARD)
if (led_test_mode) {
light_test_state += 1;
if (light_test_state == 1) {
led_state = rgb_matrix_get_mode();
hsv = rgb_matrix_get_hsv();
}
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
} else {
if (light_test_state) {
light_test_state = 0;
rgb_matrix_mode_noeeprom(led_state);
rgb_matrix_sethsv_noeeprom(hsv.h, hsv.s, hsv.v);
}
}
# endif
timer_3s_buffer = 0;
break;
# endif
# if defined(DIP_SWITCH_ENABLE)
case FACTORY_TEST_CMD_OS_SWITCH:
report_os_sw_state = data[2];
if (report_os_sw_state) {
dip_switch_read(true);
}
break;
# endif
case FACTORY_TEST_CMD_JUMP_TO_BL:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (memcmp(&data[2], "JumpToBootloader", strlen("JumpToBootloader")) == 0) bootloader_jump();
}
break;
case FACTORY_TEST_CMD_EEPROM_CLEAR:
if (matrix[0] & 0x1 && matrix[MATRIX_ROWS - 1] & (0x1 << (MATRIX_COLS - 1))) {
if (data[2]) {
factory_reset();
}
}
break;
}
return true;
}
#endif

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
// clang-format off
#include "keychron_ft_common.h"
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_ansi_82(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
@ -64,11 +64,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,4 +1,3 @@
VIA_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
// clang-format off
#include "keychron_ft_common.h"
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_ansi_82(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_MUTE,
@ -60,8 +60,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
};
// clang-format on
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[MAC_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
@ -72,10 +70,17 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
#endif // ENCODER_MAP_ENABLE
// clang-format on
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,5 +1,4 @@
VIA_ENABLE = yes
ENCODER_MAP_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -31,6 +31,18 @@
/* DIP switch */
#define DIP_SWITCH_MATRIX_GRID { {5,4} }
/* HC595 Driver Configuration */
#define HC595_STCP B0
#define HC595_SHCP B1
#define HC595_DS A7
#define HC595_START_INDEX 8
#define HC595_END_INDEX 15
/* Factory test keys */
#define FN_KEY1 MO(1)
#define FN_KEY2 MO(3)
/* RGB Matrix Driver Configuration */
#define DRIVER_COUNT 2
#define DRIVER_ADDR_1 0b1110111

View File

@ -17,5 +17,8 @@
#pragma once
#define HAL_USE_I2C TRUE
#ifdef ENCODER_ENABLE
# define PAL_USE_CALLBACKS TRUE
#endif
#include_next <halconf.h>

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
#include "keychron_ft_common.h"
// clang-format off
enum layers {
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_iso_83(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
@ -62,9 +62,17 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format on
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,4 +1,3 @@
VIA_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
// clang-format off
#include "keychron_ft_common.h"
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_iso_83(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_MUTE,
@ -60,8 +60,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______)
};
// clang-format on
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[MAC_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
@ -72,10 +70,17 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
#endif // ENCODER_MAP_ENABLE
// clang-format on
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,5 +1,4 @@
VIA_ENABLE = yes
ENCODER_MAP_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
// clang-format off
#include "keychron_ft_common.h"
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_jis_86(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_INS,
@ -62,9 +62,17 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format on
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,4 +1,3 @@
VIA_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -16,16 +16,16 @@
#include QMK_KEYBOARD_H
#include "keychron_common.h"
// clang-format off
#include "keychron_ft_common.h"
enum layers{
MAC_BASE,
MAC_FN,
WIN_BASE,
WIN_FN
WIN_FN,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[MAC_BASE] = LAYOUT_jis_86(
KC_ESC, KC_BRID, KC_BRIU, KC_MCTL, KC_LPAD, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_DEL, KC_MUTE,
@ -60,8 +60,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
};
// clang-format on
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[MAC_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
@ -72,10 +70,17 @@ const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
#endif // ENCODER_MAP_ENABLE
// clang-format on
void housekeeping_task_user(void) {
housekeeping_task_keychron();
housekeeping_task_keychron_ft();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (!process_record_keychron(keycode, record)) {
return false;
}
if (!process_record_keychron_ft(keycode, record)) {
return false;
}
return true;
}

View File

@ -1,5 +1,4 @@
VIA_ENABLE = yes
ENCODER_MAP_ENABLE = yes
VPATH += keyboards/keychron/common
SRC += keychron_common.c
include keyboards/keychron/common/common.mk

View File

@ -1,222 +0,0 @@
/* Copyright 2022 @ Keychron (https://www.keychron.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "matrix.h"
#include "quantum.h"
// Pin connected to DS of 74HC595
#define DATA_PIN A7
// Pin connected to SH_CP of 74HC595
#define CLOCK_PIN B1
// Pin connected to ST_CP of 74HC595
#define LATCH_PIN B0
#ifdef MATRIX_ROW_PINS
static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
#endif // MATRIX_ROW_PINS
#ifdef MATRIX_COL_PINS
static pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
#endif // MATRIX_COL_PINS
#define ROWS_PER_HAND MATRIX_ROWS
static inline void setPinOutput_writeLow(pin_t pin) {
ATOMIC_BLOCK_FORCEON {
setPinOutput(pin);
writePinLow(pin);
}
}
static inline void setPinOutput_writeHigh(pin_t pin) {
ATOMIC_BLOCK_FORCEON {
setPinOutput(pin);
writePinHigh(pin);
}
}
static inline void setPinInputHigh_atomic(pin_t pin) {
ATOMIC_BLOCK_FORCEON {
setPinInputHigh(pin);
}
}
static inline uint8_t readMatrixPin(pin_t pin) {
if (pin != NO_PIN) {
return readPin(pin);
} else {
return 1;
}
}
// At 3.6V input, three nops (37.5ns) should be enough for all signals
#define small_delay() __asm__ __volatile__("nop;nop;nop;\n\t" ::: "memory")
#define compiler_barrier() __asm__ __volatile__("" ::: "memory")
static void shiftOut(uint8_t dataOut) {
ATOMIC_BLOCK_FORCEON {
for (uint8_t i = 0; i < 8; i++) {
compiler_barrier();
if (dataOut & 0x1) {
writePinHigh(DATA_PIN);
} else {
writePinLow(DATA_PIN);
}
dataOut = dataOut >> 1;
compiler_barrier();
writePinHigh(CLOCK_PIN);
small_delay();
writePinLow(CLOCK_PIN);
}
compiler_barrier();
writePinHigh(LATCH_PIN);
small_delay();
writePinLow(LATCH_PIN);
compiler_barrier();
}
}
static void shiftOut_single(uint8_t data) {
ATOMIC_BLOCK_FORCEON {
compiler_barrier();
if (data & 0x1) {
writePinHigh(DATA_PIN);
} else {
writePinLow(DATA_PIN);
}
compiler_barrier();
writePinHigh(CLOCK_PIN);
small_delay();
writePinLow(CLOCK_PIN);
compiler_barrier();
writePinHigh(LATCH_PIN);
small_delay();
writePinLow(LATCH_PIN);
compiler_barrier();
}
}
static bool select_col(uint8_t col) {
pin_t pin = col_pins[col];
if (pin != NO_PIN) {
setPinOutput_writeLow(pin);
return true;
} else {
if (col == 8) {
shiftOut_single(0x00);
}
return true;
}
return false;
}
static void unselect_col(uint8_t col) {
pin_t pin = col_pins[col];
if (pin != NO_PIN) {
#ifdef MATRIX_UNSELECT_DRIVE_HIGH
setPinOutput_writeHigh(pin);
#else
setPinInputHigh_atomic(pin);
#endif
} else {
shiftOut_single(0x01);
}
}
static void unselect_cols(void) {
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
pin_t pin = col_pins[x];
if (pin != NO_PIN) {
#ifdef MATRIX_UNSELECT_DRIVE_HIGH
setPinOutput_writeHigh(pin);
#else
setPinInputHigh_atomic(pin);
#endif
} else {
if (x == 8)
// unselect shift Register
shiftOut(0xFF);
}
}
}
static void matrix_init_pins(void) {
setPinOutput(DATA_PIN);
setPinOutput(CLOCK_PIN);
setPinOutput(LATCH_PIN);
#ifdef MATRIX_UNSELECT_DRIVE_HIGH
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
if (col_pins[x] != NO_PIN) {
setPinOutput(col_pins[x]);
}
}
#endif
unselect_cols();
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
if (row_pins[x] != NO_PIN) {
setPinInputHigh_atomic(row_pins[x]);
}
}
}
static void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) {
bool key_pressed = false;
// Select col
if (!select_col(current_col)) { // select col
return; // skip NO_PIN col
}
matrix_output_select_delay();
// For each row...
for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) {
// Check row pin state
if (readMatrixPin(row_pins[row_index]) == 0) {
// Pin LO, set col bit
current_matrix[row_index] |= row_shifter;
key_pressed = true;
} else {
// Pin HI, clear col bit
current_matrix[row_index] &= ~row_shifter;
}
}
// Unselect col
unselect_col(current_col);
matrix_output_unselect_delay(current_col, key_pressed); // wait for all Row signals to go HIGH
}
void matrix_init_custom(void) {
// initialize key pins
matrix_init_pins();
}
bool matrix_scan_custom(matrix_row_t current_matrix[]) {
matrix_row_t curr_matrix[MATRIX_ROWS] = {0};
// Set col, read rows
matrix_row_t row_shifter = MATRIX_ROW_SHIFTER;
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++, row_shifter <<= 1) {
matrix_read_rows_on_col(curr_matrix, current_col, row_shifter);
}
bool changed = memcmp(current_matrix, curr_matrix, sizeof(curr_matrix)) != 0;
if (changed) memcpy(current_matrix, curr_matrix, sizeof(curr_matrix));
return changed;
}

View File

@ -0,0 +1,2 @@
VPATH += $(TOP_DIR)/keyboards/keychron/common
SRC += matrix.c

View File

@ -16,6 +16,7 @@
#include "quantum.h"
// clang-format off
const matrix_row_t matrix_mask[] = {
0b1111111111111111,
0b1111111111111111,
@ -24,6 +25,7 @@ const matrix_row_t matrix_mask[] = {
0b1111111111111111,
0b1111111111101111,
};
// clang-format on
#ifdef DIP_SWITCH_ENABLE
@ -42,11 +44,21 @@ bool dip_switch_update_kb(uint8_t index, bool active) {
#if defined(RGB_MATRIX_ENABLE) && defined(CAPS_LOCK_LED_INDEX)
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
if (!process_record_user(keycode, record)) { return false; }
if (!process_record_user(keycode, record)) {
return false;
}
switch (keycode) {
#ifdef RGB_MATRIX_ENABLE
# ifdef RGB_MATRIX_ENABLE
case RGB_TOG:
if (!rgb_matrix_is_enabled()) {
rgb_matrix_set_flags(LED_FLAG_ALL);
rgb_matrix_enable();
}
if (record->event.pressed) {
if (rgb_matrix_get_val() == 0) {
rgb_matrix_increase_val();
if (rgb_matrix_get_flags() == LED_FLAG_ALL) return false;
}
switch (rgb_matrix_get_flags()) {
case LED_FLAG_ALL: {
rgb_matrix_set_flags(LED_FLAG_NONE);
@ -57,25 +69,34 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
} break;
}
}
return false;
case RGB_VAI:
if (!rgb_matrix_is_enabled()) {
rgb_matrix_set_flags(LED_FLAG_ALL);
rgb_matrix_enable();
}
return false;
#endif
if (rgb_matrix_get_flags() == LED_FLAG_NONE) {
rgb_matrix_set_flags(LED_FLAG_ALL);
return false;
}
break;
# endif
}
return true;
}
bool rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) {
if (!rgb_matrix_indicators_advanced_user(led_min, led_max)) { return false; }
if (!rgb_matrix_indicators_advanced_user(led_min, led_max)) {
return false;
}
// RGB_MATRIX_INDICATOR_SET_COLOR(index, red, green, blue);
if (host_keyboard_led_state().caps_lock) {
RGB_MATRIX_INDICATOR_SET_COLOR(CAPS_LOCK_LED_INDEX, 255, 255, 255);
} else {
if (!rgb_matrix_get_flags()) {
RGB_MATRIX_INDICATOR_SET_COLOR(CAPS_LOCK_LED_INDEX, 0, 0, 0);
RGB_MATRIX_INDICATOR_SET_COLOR(CAPS_LOCK_LED_INDEX, 0, 0, 0);
}
}
return true;