Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable Caps Word #308

Open
wants to merge 61 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
4ae5990
Added wireless support; Added Lemokey L3; Added Keychron V1 Max
lokher Jan 10, 2024
cca8df6
Added shutdown fucntion to snled driver
lokher Jan 11, 2024
15a2edc
Added K3 Max
lokher Jan 11, 2024
74b0845
Added Q1 Max; Updated V1 Max
lokher Jan 11, 2024
8521378
Changed LED_MATRIX_SHUTDOWN_ENABLE to LED_MATRIX_DRIVER_SHUTDOWN_ENA…
lokher Jan 12, 2024
625e099
Added K1 Max ANSI
lokher Jan 13, 2024
2ecd0e7
Added Q60/65 Max ANSI
lokher Jan 13, 2024
6c8de3a
Added Q3 Max
lokher Jan 30, 2024
2f38391
Added Q2 Max
lokher Jan 31, 2024
f45cb07
Added V2 Max
lokher Jan 31, 2024
0b812c9
Add Q5/Q6/Q8/K5/K7/V5 Max
lokher Jan 31, 2024
f9f4cf4
Remove *_CALLBACK_ENABLE related code; Fix V2 Max device name
lokher Feb 1, 2024
6edb298
Add Q10 Pro and Q13 Pro
lokher Feb 17, 2024
4a63b50
Fix Bug #228
lokher Feb 17, 2024
6d12e23
Add Q10 Max ANSI Encoder
lokher Feb 18, 2024
08e8e81
Add K13 Max ANSI
lokher Feb 19, 2024
4fe24e8
Add V3 Max
lokher Mar 2, 2024
a56ef87
Add V6 Max
lokher Mar 2, 2024
f7a0879
Add K17 Pro
lokher Mar 7, 2024
0cd4ee0
fix delay of macro doens't work properly except cable mode
lokher Mar 18, 2024
a07246a
Add V10 Max
lokher Mar 18, 2024
9adbd8b
Fix compiling error of lemokey keyboard
lokher Mar 20, 2024
fd70215
Fix boot magic key position of V10 Max
lokher Mar 21, 2024
53c2c1b
Remove KC_TRANS assignments for keys not existing on keyboards that d…
tam1m Feb 3, 2024
0cddb71
Add defines for keychron custom keycodes when LK_WIRELESS_ENABLE and/…
tam1m Mar 8, 2024
07208a1
Merge pull request #222 from tam1m/wireless_playground
lokher Mar 30, 2024
eba583c
Fix compiling error caused by commit 0cd4ee
lokher Mar 30, 2024
57c5939
Fix incorrect minor version response of kc_get_firmware_version
lokher Apr 2, 2024
9a9cfbb
Fix Q10 Pro compilation error
lokher Apr 12, 2024
c1724ac
Add Q1 Pro VIA json
lokher Apr 12, 2024
e5e57f4
Fixed NKRO issue in wireless mode
lokher Apr 12, 2024
fd04262
Add Lemokey L1
lokher Apr 25, 2024
6aa63c3
Add adaptive NKRO feature
lokher Apr 28, 2024
dda1480
Fixed gpio controlled caps lock LED is cleared incorrectly in wireles…
lokher Apr 28, 2024
b6d42d8
Pick upstream PR #21656
lokher May 21, 2024
0804f78
Added Q0 Max
lokher Jun 1, 2024
7fbf1e2
Added factory test command to get device UUID
lokher Jun 4, 2024
8e390f9
Reset HID report mode on USB_EVENT_RESET event
lokher Jun 18, 2024
0c05eef
Fixed macro doesn't work correctly with NKRO
lokher Jun 22, 2024
1011db8
Added K11 Max ANSI
lokher Jul 1, 2024
790824a
Added Q12 Max ANSI and Q3 Max ISO
lokher Jul 12, 2024
2ef1985
Added V4 Max ANSI
lokher Jul 15, 2024
e073a2b
Added Q6 Max ISO
lokher Jul 15, 2024
bc57b3d
Fixed mode switch doesn't work on some charger
lokher Jul 16, 2024
9ecf8d7
Added Q15 Max ANSI
lokher Aug 19, 2024
57449c6
Added K5 Max ISO
lokher Aug 19, 2024
818f605
Added K13 Pro ISO
lokher Aug 19, 2024
7e7063f
Added K13 Pro ISO
lokher Aug 19, 2024
f05306b
Added Q14 Max ANSI
lokher Aug 19, 2024
e097e79
Added K11 Max ISO
lokher Aug 20, 2024
b71b83f
Added V8 Max ANSI
lokher Aug 20, 2024
62030ee
Added Lemokey P1 Pro
lokher Aug 21, 2024
d3c413b
Move WB32_EXTI_REQUIRED to config.h of board GENERIC_WB32_F3G71XX
lokher Aug 21, 2024
671d3c3
Fixed incorret BAT_LOW_LED_PIN of V6 Max
lokher Aug 22, 2024
e156172
Added V5 Max ISO
lokher Aug 29, 2024
abefc1d
Added K15 Max ANSI and ISO
lokher Aug 29, 2024
664ae91
Fixed some LEDs of Q15 Max doesn't work
lokher Sep 2, 2024
58118c1
Added K13 Max ISO
lokher Sep 4, 2024
568ab37
Fixed TAP_HOLD_CAPS_DELAY doens't work with wireless mode
lokher Sep 11, 2024
13a18f6
Fixed WIN_BASE layer keymap of Q15 Max
lokher Sep 18, 2024
9490354
enable Caps Word in rules.mk
n-xlkt Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[submodule "lib/chibios"]
path = lib/chibios
url = https://github.com/qmk/ChibiOS
url = https://github.com/Keychron/ChibiOS.git
branch = master
[submodule "lib/chibios-contrib"]
path = lib/chibios-contrib
url = https://github.com/qmk/ChibiOS-Contrib
url = https://github.com/Keychron/ChibiOS-Contrib
branch = master
[submodule "lib/googletest"]
path = lib/googletest
Expand Down
16 changes: 14 additions & 2 deletions builddefs/common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ LED_MATRIX_DRIVER := snled27351
endif

LED_MATRIX_ENABLE ?= no
VALID_LED_MATRIX_TYPES := is31fl3218 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 custom
VALID_LED_MATRIX_TYPES := is31fl3218 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 snled27351_spi custom

ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
ifeq ($(filter $(LED_MATRIX_DRIVER),$(VALID_LED_MATRIX_TYPES)),)
Expand Down Expand Up @@ -428,6 +428,12 @@ ifeq ($(strip $(LED_MATRIX_ENABLE)), yes)
SRC += snled27351-simple.c
endif

ifeq ($(strip $(LED_MATRIX_DRIVER)), snled27351_spi)
SPI_DRIVER_REQUIRED = yes
COMMON_VPATH += $(DRIVER_PATH)/led
SRC += snled27351-simple-spi.c
endif

endif

# Deprecated driver names - do not use
Expand All @@ -440,7 +446,7 @@ endif

RGB_MATRIX_ENABLE ?= no

VALID_RGB_MATRIX_TYPES := aw20216s is31fl3218 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 ws2812 custom
VALID_RGB_MATRIX_TYPES := aw20216s is31fl3218 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a snled27351 snled27351_spi ws2812 custom
ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),)
$(call CATASTROPHIC_ERROR,Invalid RGB_MATRIX_DRIVER,RGB_MATRIX_DRIVER="$(RGB_MATRIX_DRIVER)" is not a valid matrix type)
Expand Down Expand Up @@ -535,6 +541,12 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes)
SRC += snled27351.c
endif

ifeq ($(strip $(RGB_MATRIX_DRIVER)), snled27351_spi)
SPI_DRIVER_REQUIRED = yes
COMMON_VPATH += $(DRIVER_PATH)/led
SRC += snled27351-spi.c
endif

ifeq ($(strip $(RGB_MATRIX_DRIVER)), ws2812)
WS2812_DRIVER_REQUIRED := yes
endif
Expand Down
235 changes: 235 additions & 0 deletions drivers/led/snled27351-simple-spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/* Copyright 2021 @ 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 "snled27351-simple-spi.h"
#include "spi_master.h"

#define SNLED27351_PWM_REGISTER_COUNT 192
#define SNLED27351_LED_CONTROL_REGISTER_COUNT 24


#ifndef SNLED27351_PHASE_CHANNEL
# define SNLED27351_PHASE_CHANNEL MSKPHASE_12CHANNEL
#endif

#ifndef SNLED27351_CURRENT_TUNE
# define SNLED27351_CURRENT_TUNE \
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
#endif

#define SNLED27351_WRITE (0 << 7)
#define SNLED27351_READ (1 << 7)
#define SNLED27351_PATTERN (2 << 4)

#ifdef DRIVER_CS_PINS
pin_t cs_pins[] = DRIVER_CS_PINS;
#else
error "no DRIVER_CS_PINS defined"
#endif

// These buffers match the snled27351 PWM registers.
// The control buffers match the PG0 LED On/Off registers.
// Storing them like this is optimal for I2C transfers to the registers.
// We could optimize this and take out the unused registers from these
// buffers and the transfers in snled27351_write_pwm_buffer() but it's
// probably not worth the extra complexity.
uint8_t g_pwm_buffer[SNLED27351_DRIVER_COUNT][SNLED27351_PWM_REGISTER_COUNT];
bool g_pwm_buffer_update_required[SNLED27351_DRIVER_COUNT] = {false};

uint8_t g_led_control_registers[SNLED27351_DRIVER_COUNT][SNLED27351_LED_CONTROL_REGISTER_COUNT] = {0};
bool g_led_control_registers_update_required[SNLED27351_DRIVER_COUNT] = {false};



bool snled27351_write(uint8_t index, uint8_t page, uint8_t reg, uint8_t *data, uint8_t len) {
static uint8_t spi_transfer_buffer[2] = {0};

if (index > ARRAY_SIZE(((pin_t[])DRIVER_CS_PINS)) - 1) return false;

if (!spi_start(cs_pins[index], false, 0, SNLED23751_SPI_DIVISOR)) {
spi_stop();
return false;
}

spi_transfer_buffer[0] = SNLED27351_WRITE | SNLED27351_PATTERN | (page & 0x0F);
spi_transfer_buffer[1] = reg;

if (spi_transmit(spi_transfer_buffer, 2) != SPI_STATUS_SUCCESS) {
spi_stop();
return false;
}

if (spi_transmit(data, len) != SPI_STATUS_SUCCESS) {
spi_stop();
return false;
}

spi_stop();
return true;
}

bool snled27351_write_register(uint8_t index, uint8_t page, uint8_t reg, uint8_t data) {
return snled27351_write(index, page, reg, &data, 1);
}

bool snled27351_write_pwm_buffer(uint8_t index, uint8_t *pwm_buffer) {
if (g_pwm_buffer_update_required[index]) {
snled27351_write(index, LED_PWM_PAGE, 0, g_pwm_buffer[index], SNLED27351_PWM_REGISTER_COUNT);
}
g_pwm_buffer_update_required[index] = false;
return true;
}

void snled27351_init_drivers(void) {
#if defined(LED_DRIVER_SHUTDOWN_PIN)
setPinOutput(LED_DRIVER_SHUTDOWN_PIN);
writePinHigh(LED_DRIVER_SHUTDOWN_PIN);
#endif

spi_init();

for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++)
snled27351_init(i);

for (int index = 0; index < SNLED27351_LED_COUNT; index++) {
snled27351_set_led_control_register(index, true);
}

for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++)
snled27351_update_led_control_registers(i);
}

void snled27351_init(uint8_t index) {
setPinOutput(cs_pins[index]);
writePinHigh(cs_pins[index]);
// Setting LED driver to shutdown mode
snled27351_write_register(index, FUNCTION_PAGE, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
// Setting internal channel pulldown/pullup
snled27351_write_register(index, FUNCTION_PAGE, PDU_REG, MSKSET_CA_CB_CHANNEL);
// Select number of scan phase
snled27351_write_register(index, FUNCTION_PAGE, SCAN_PHASE_REG, SNLED27351_PHASE_CHANNEL);
// Setting PWM Delay Phase
snled27351_write_register(index, FUNCTION_PAGE, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE);
// Setting Driving/Sinking Channel Slew Rate
snled27351_write_register(index, FUNCTION_PAGE, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE);
// Setting Iref
snled27351_write_register(index, FUNCTION_PAGE, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE);

// Set LED CONTROL PAGE (Page 0)
uint8_t on_off_reg[LED_CONTROL_ON_OFF_LENGTH] = {0};
snled27351_write(index, LED_CONTROL_PAGE, 0, on_off_reg, LED_CONTROL_ON_OFF_LENGTH);

// Set PWM PAGE (Page 1)
uint8_t pwm_reg[LED_PWM_LENGTH];
memset(pwm_reg, 0, LED_PWM_LENGTH);
snled27351_write(index, LED_PWM_PAGE, 0, pwm_reg, LED_PWM_LENGTH);

// Set CURRENT PAGE (Page 4)
uint8_t current_tune_reg[LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE;
snled27351_write(index, CURRENT_TUNE_PAGE, 0, current_tune_reg, LED_CURRENT_TUNE_LENGTH);

// // Enable LEDs ON/OFF
// memset(on_off_reg, 0xFF, LED_CONTROL_ON_OFF_LENGTH);
// snled27351_write(index, LED_CONTROL_PAGE, 0, on_off_reg, LED_CONTROL_ON_OFF_LENGTH);

// Setting LED driver to normal mode
snled27351_write_register(index, FUNCTION_PAGE, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
}

void snled27351_set_value(int index, uint8_t value) {
snled27351_led_t led;
if (index >= 0 && index < SNLED27351_LED_COUNT) {
memcpy_P(&led, (&g_snled27351_leds[index]), sizeof(led));

g_pwm_buffer[led.driver][led.v] = value;
g_pwm_buffer_update_required[led.driver] = true;
}
}

void snled27351_set_value_all(uint8_t value) {
for (int i = 0; i < SNLED27351_LED_COUNT; i++) {
snled27351_set_value(i, value);
}
}

void snled27351_set_led_control_register(uint8_t index, bool value) {
snled27351_led_t led;
memcpy_P(&led, (&g_snled27351_leds[index]), sizeof(led));

uint8_t control_register = led.v / 8;
uint8_t bit_value = led.v % 8;

if (value) {
g_led_control_registers[led.driver][control_register] |= (1 << bit_value);
} else {
g_led_control_registers[led.driver][control_register] &= ~(1 << bit_value);
}

g_led_control_registers_update_required[led.driver] = true;
}

void snled27351_update_pwm_buffers(uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
if (!snled27351_write_pwm_buffer(index, g_pwm_buffer[index])) {
g_led_control_registers_update_required[index] = true;
}
}
g_pwm_buffer_update_required[index] = false;
}

void snled27351_update_led_control_registers(uint8_t index) {
if (g_led_control_registers_update_required[index]) {
snled27351_write(index, LED_CONTROL_PAGE, 0, g_led_control_registers[index], 24);
}
g_led_control_registers_update_required[index] = false;
}

void snled27351_flush(void) {
for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++)
snled27351_update_pwm_buffers(i);
}

void snled27351_shutdown(void) {
# if defined(LED_DRIVER_SHUTDOWN_PIN)
writePinLow(LED_DRIVER_SHUTDOWN_PIN);
# else
for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++)
snled27351_sw_shutdown(i);
# endif
}

void snled27351_exit_shutdown(void) {
# if defined(LED_DRIVER_SHUTDOWN_PIN)
writePinHigh(LED_DRIVER_SHUTDOWN_PIN);
# else
for (uint8_t i = 0; i < SNLED27351_DRIVER_COUNT; i++)
snled27351_sw_return_normal(i);
# endif
}

void snled27351_sw_return_normal(uint8_t index) {
// Select to function page
// Setting LED driver to normal mode
snled27351_write_register(index, FUNCTION_PAGE, CONFIGURATION_REG, MSKSW_NORMAL_MODE);
}

void snled27351_sw_shutdown(uint8_t index) {
// Select to function page
// Setting LED driver to shutdown mode
snled27351_write_register(index, FUNCTION_PAGE, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE);
// Write SW Sleep Register
snled27351_write_register(index, FUNCTION_PAGE, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE);
}
Loading